Compare commits

..

12 Commits

Author SHA1 Message Date
zarroboogs dc55d5be8f linux appimage versioning changes synced with windows artifact version 2018-02-24 15:06:08 +00:00
zarroboogs 06546b5195 windows artifact versioning changes, plus a small syntax fix 2018-02-24 15:06:08 +00:00
zarroboogs ca9c1674f7 minor syntax changes 2018-02-24 15:06:08 +00:00
scribam ede76033a7 Add callbacks for cellMusic 2018-02-24 02:38:43 +04:00
Nikolay Amiantov 41bd07274f Fix quoting in cmake 2018-02-23 19:06:37 +00:00
Megamouse 5266dd6c60 Update for Qt 5.10 (#4202)
* Update Readme for Qt 5.10

* Update cmake for Qt 5.10

* Update travis to Qt 5.10.1
2018-02-23 02:08:14 +04:00
Megamouse cf1c45dfe8 Qt: use setAttribute(AA_DisableWindowContextHelpButton) instead of flags
probably needs Qt 5.10.1 to work propery
2018-02-22 00:18:14 +04:00
Megamouse ae7e275a9d sceNpTrophyGetRequiredDiskSpace: take vfs into account for trophy dir 2018-02-22 00:18:14 +04:00
Megamouse b60f29282a Qt: add translation to save manager messageboxes 2018-02-22 00:18:14 +04:00
Megamouse bda466c3bd Qt: improve VFS dialog a bit
- use normal selection instead of doubleclick
- move SaveSettings out of the tabs to reduce file access
- translate EmptyPath as well
- some other minor refactors to reduce lines of code
2018-02-22 00:18:14 +04:00
kd-11 4c6ceeff11 rsx/vk: Cleanup
- Silence some warnings, remove dprints
2018-02-21 14:59:46 +03:00
kd-11 77f2b521e1 vulkan: Swapchains reimplemented
- Adds support for abstract implementations
- Adds native windowing implementations for WIN32 and X11 as fallbacks
  when present support is lacking (headless configs)
2018-02-21 14:59:46 +03:00
89 changed files with 1034 additions and 1241 deletions
-1
View File
@@ -60,7 +60,6 @@ rpcs3/git-version.h
# Visual Studio Files
.vs/*
.vscode/*
*.ipch
*.vspx
*.psess
*.VC.*
+3 -7
View File
@@ -7,14 +7,14 @@
ignore = dirty
[submodule "llvm"]
path = llvm
url = https://github.com/llvm-mirror/llvm
url = https://github.com/RPCS3/llvm
branch = release_60
[submodule "GSL"]
path = 3rdparty/GSL
url = https://github.com/Microsoft/GSL.git
[submodule "libpng"]
path = 3rdparty/libpng
url = https://github.com/Zangetsu38/libpng
url = https://github.com/RPCS3/libpng
ignore = dirty
[submodule "Vulkan/glslang"]
path = Vulkan/glslang
@@ -33,7 +33,7 @@
url = https://github.com/madler/zlib
[submodule "3rdparty/hidapi"]
path = 3rdparty/hidapi
url = https://github.com/Zangetsu38/hidapi
url = https://github.com/RPCS3/hidapi
branch = master
ignore = dirty
[submodule "3rdparty/Optional"]
@@ -42,7 +42,3 @@
[submodule "3rdparty/pugixml"]
path = 3rdparty/pugixml
url = https://github.com/zeux/pugixml
[submodule "polly"]
path = polly
url = https://github.com/llvm-mirror/polly
branch = release_60
+3 -1
View File
@@ -81,7 +81,9 @@ before_script:
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}_linux64 --upload-file ./RPCS3*.AppImage;
COMM_TAG="$(git describe --tags $(git rev-list --tags --max-count=1))"
COMM_COUNT="$(git rev-list --count HEAD)"
curl "${UPLOAD_URL}${TRAVIS_COMMIT:0:8}&t=${COMM_TAG}&a=${COMM_COUNT}" --upload-file ./RPCS3*.AppImage;
fi;
script:
+5 -5
View File
@@ -20,11 +20,11 @@ If you want to contribute please take a look at the [Coding Style](https://githu
## Dependencies
### Windows
* [Visual Studio 2017](https://www.visualstudio.com/en/downloads/)
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
* [Visual Studio 2015](https://www.visualstudio.com/vs/older-downloads/)
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
* [Cmake 3.1.0+](https://www.cmake.org/download/) (required; add to PATH)
* [Python 3.3+](https://www.python.org/downloads/) (required; add to PATH)
* [Qt 5.10+](https://www.qt.io/download-open-source/) (required; add QTDIR environment variable if you do not want to use the Visual Studio Qt Plugin: e.g. `<QtInstallFolder>\5.10.1\msvc2017_64\`)
* [Qt 5.10+](https://www.qt.io/download-open-source/) (required; add QTDIR environment variable if you do not want to use the Visual Studio Qt Plugin: e.g. `<QtInstallFolder>\5.10.1\msvc2015_64\`)
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
### Linux
@@ -48,14 +48,14 @@ To initialize the repository don't forget to execute `git submodule update --ini
### Configuring Qt
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
1) Add `QTDIR` environment variable and set it to e.g `<QtInstallFolder>\5.10.1\msvc2017_64\` </br>
1) Add `QTDIR` environment variable and set it to e.g `<QtInstallFolder>\5.10.1\msvc2015_64\` </br>
Open `rpcs3.sln`
*If you wish to use the Visual Studio plugin for Qt:* </br>
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.10.1\msvc2017_64`. </br>
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.10.1\msvc2015_64`. </br>
2) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
### Building the projects
+3 -3
View File
@@ -293,7 +293,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
}
virtual void deregisterEHFrames() override
void deregisterEHFrames(u8* addr, u64 load_addr, std::size_t size) override
{
}
};
@@ -376,11 +376,11 @@ public:
LOG_SUCCESS(GENERAL, "LLVM: Created module: %s", module->getName().data());
}
static std::unique_ptr<llvm::WritableMemoryBuffer> load(const std::string& path)
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
{
if (fs::file cached{path, fs::read})
{
auto buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(cached.size());
auto buf = llvm::MemoryBuffer::getNewUninitMemBuffer(cached.size());
cached.read(const_cast<char*>(buf->getBufferStart()), buf->getBufferSize());
return buf;
}
+6 -8
View File
@@ -1890,34 +1890,32 @@ u16 thread_ctrl::get_affinity_mask(thread_class group)
}
case native_core_arrangement::amd_ccx:
{
u16 spu_mask, ppu_mask, rsx_mask, general;
u16 spu_mask, ppu_mask, rsx_mask;
if (thread_count >= 16)
{
// Threadripper, R7
// Assign threads 1-16
// Assign threads 8-16
// It appears some windows code is bound to lower core addresses, binding 8-16 is alot faster than 0-7
ppu_mask = spu_mask = 0b1111111100000000;
rsx_mask = 0b11110000;
general = 0b00001111;
rsx_mask = all_cores_mask;
}
else if (thread_count == 12)
{
// 1600/2600 (x)
ppu_mask = spu_mask = 0b111111000000;
rsx_mask = 0b111000;
general = 0b000111;
rsx_mask = all_cores_mask;
}
else
{
// R5 & R3 don't seem to improve performance no matter how these are shuffled
ppu_mask = spu_mask = rsx_mask = general = 0b11111111;
ppu_mask = spu_mask = rsx_mask = 0b11111111 & all_cores_mask;
}
switch (group)
{
default:
case thread_class::general:
return general = all_cores_mask;
return all_cores_mask;
case thread_class::rsx:
return rsx_mask;
case thread_class::ppu:
+2 -12
View File
@@ -14,10 +14,7 @@ void shared_mutex::imp_lock_shared(s64 _old)
for (int i = 0; i < 10; i++)
{
if (i != 0)
{
busy_wait();
}
busy_wait();
const s64 value = m_value.load();
@@ -176,10 +173,7 @@ void shared_mutex::imp_lock(s64 _old)
for (int i = 0; i < 10; i++)
{
if (i != 0)
{
busy_wait();
}
busy_wait();
const s64 value = m_value.load();
@@ -242,10 +236,6 @@ void shared_mutex::imp_lock_degrade()
bool shared_mutex::try_lock_shared()
{
if (m_value < c_min) // Fast path
{
return false;
}
// Conditional decrement
return m_value.fetch_op([](s64& value) { if (value >= c_min) value -= c_min; }) >= c_min;
}
+1 -1
View File
@@ -19,7 +19,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -40,23 +40,23 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>start /W /B pre-build.bat
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,24 +39,24 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
+17 -10
View File
@@ -1,10 +1,10 @@
version: '{build}'
image: Visual Studio 2017
image: Visual Studio 2015
environment:
QTDIR: C:\Qt\5.10.0\msvc2017_64
QTDIR: C:\Qt\5.10.0\msvc2015_64
LLVMLIBS: https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8
VULKAN: https://drive.google.com/uc?export=download&id=1A2eOMmCO714i0U7J0qI4aEMKnuWl8l_R
COMPATDB: https://rpcs3.net/compatibility?api=v1&export
@@ -16,12 +16,19 @@ cache:
install:
- ps: | # set env vars for versioning
$commDate = $env:APPVEYOR_REPO_COMMIT_TIMESTAMP.Substring(0,10)
$commSha = $env:APPVEYOR_REPO_COMMIT.Substring(0,8)
$commTag = $(git describe --tags $(git rev-list --tags --max-count=1))
$commCount = $(git rev-list --count HEAD)
$commHash = $env:APPVEYOR_REPO_COMMIT.Substring(0,8)
if ($env:APPVEYOR_PULL_REQUEST_NUMBER) {
$env:BUILD = "{0}-{1}" -f $commTag, $commHash
}
else {
$env:BUILD = "{0}-{1}-{2}" -f $commTag, $commCount, $commHash
}
$env:AVVER = "{0}-{1}" -f $commTag.TrimStart("v"), $env:APPVEYOR_BUILD_NUMBER
$env:BUILD = "rpcs3-{0}-{1}-{2}_win64.7z" -f $commTag, $commDate, $commSha
$env:RPCS3 = "rpcs3-{0}_win64.7z" -f $env:BUILD
- ps: | # used for experimental build warnings for pr builds
$env:BRANCH = "{0}/{1}/#{2}" -f $env:APPVEYOR_REPO_NAME, `
@@ -75,20 +82,20 @@ after_build:
copy-item compat_database.dat .\bin\GuiConfigs\compat_database.dat
- ps: | # package artifacts
7z a -m0=LZMA2 -mx9 $env:BUILD .\bin\*
7z a -m0=LZMA2 -mx9 $env:RPCS3 .\bin\*
7z a -m0=LZMA2 -mx9 openssl_win64.7z C:\OpenSSL-Win64\bin\libeay32.dll `
C:\OpenSSL-Win64\bin\ssleay32.dll
- ps: | # generate sha256 hashes
(Get-FileHash $env:BUILD -Algorithm SHA256).Hash | Out-File -encoding ASCII "$($env:BUILD).sha256"
(Get-FileHash openssl_win64.7z -Algorithm SHA256).Hash | Out-File -encoding ASCII "openssl_win64.7z.sha256"
(get-filehash $env:RPCS3 -algorithm SHA256).Hash > ("{0}.sha256" -f $env:RPCS3)
(get-filehash openssl_win64.7z -algorithm SHA256).Hash > "openssl_win64.7z.sha256"
test: off
artifacts:
- path: $(BUILD)
- path: $(RPCS3)
name: rpcs3
- path: $(BUILD).sha256
- path: $(RPCS3).sha256
name: rpcs3 sha256 hash
- path: openssl_win64.7z
name: openssl
+1 -1
View File
@@ -93,7 +93,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+1 -1
Submodule llvm updated: 16ebb58ea4...4423e35117
+1 -1
View File
@@ -1,7 +1,7 @@
REM You need cmake and python to update the project files
REM this script relies on CWD being the path that this script is in
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
RD /S /Q cmake
RD /S /Q CMakeFiles
+8 -8
View File
@@ -18,12 +18,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,30 +39,30 @@
<NMakePreprocessorDefinitions>
</NMakePreprocessorDefinitions>
<NMakeBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakePreprocessorDefinitions />
<NMakeBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXTERNAL_POLLY_SOURCE_DIR=../polly -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=ON -DLLVM_INCLUDE_UTILS=ON -DWITH_POLLY=ON -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
</NMakeCleanCommandLine>
</PropertyGroup>
-3
View File
@@ -62,9 +62,6 @@ vcxproj_files = ["lib\Analysis\LLVMAnalysis.vcxproj",
"lib\Transforms\Utils\LLVMTransformUtils.vcxproj",
"lib\Transforms\Vectorize\LLVMVectorize.vcxproj",
"include\llvm\IR\intrinsics_gen.vcxproj",
"tools\polly\lib\Polly.vcxproj",
"tools\polly\lib\External\PollyISL.vcxproj",
"tools\polly\lib\External\PollyPPCG.vcxproj",
"utils\TableGen\llvm-tblgen.vcxproj",
]
Submodule polly deleted from 7f7d8e3954
+2 -2
View File
@@ -20,14 +20,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
+2 -5
View File
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
EndProject
@@ -243,7 +243,4 @@ Global
{FDC361C5-7734-493B-8CFB-037308B35122} = {DDF904CA-2771-441A-8629-5DF2EB922A79}
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {FA1E6C16-CA63-45F8-8D52-E21DF396BE36}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
EndGlobalSection
EndGlobal
+2 -30
View File
@@ -96,7 +96,7 @@ if(NOT MSVC)
if(NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--exclude-libs,ALL")
endif()
if(WIN32)
set(CMAKE_RC_COMPILER_INIT windres)
enable_language(RC)
@@ -173,7 +173,7 @@ set(CMAKE_MODULE_PATH "${RPCS3_SRC_DIR}/cmake_modules")
find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
if(NOT WITHOUT_LLVM)
find_package(LLVM 6.0 CONFIG)
find_package(LLVM 4.0 CONFIG)
if(NOT LLVM_FOUND)
message("System LLVM was not found, LLVM will be built from the submodule.")
@@ -198,28 +198,6 @@ if(NOT WITHOUT_LLVM)
endif()
endif()
endif()
# Now let's look for polly.
find_package(Polly)
if(Polly_FOUND)
add_definitions(-DPOLLY_AVAILABLE)
endif()
# Polly LLVM Compiler checks
CHECK_C_COMPILER_FLAG("-mllvm -polly" HAS_POLLY)
CHECK_C_COMPILER_FLAG("-mllvm -polly-target=hybrid" HAS_POLLY_HYBRID)
CHECK_C_COMPILER_FLAG("-mllvm -polly-target=cpu" HAS_POLLY_CPU)
if (HAS_POLLY)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -polly -mllvm -polly-parallel -lgomp -mllvm -polly-vectorizer=stripmine")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mllvm -polly -mllvm -polly-parallel -lgomp -mllvm -polly-vectorizer=stripmine")
if(HAS_POLLY_HYBRID)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -polly-target=hybrid")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -polly-target=cpu")
elseif(HAS_POLLY_CPU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -polly-target=cpu")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -polly-target=cpu")
endif()
endif()
if(APPLE)
@@ -296,7 +274,6 @@ endif()
include_directories(
${OPENAL_INCLUDE_DIR}
${LLVM_INCLUDE_DIRS}
${Polly_INCLUDE_DIRS}
"${RPCS3_SRC_DIR}/../3rdparty/pugixml/src"
"${RPCS3_SRC_DIR}"
"${RPCS3_SRC_DIR}/Loader"
@@ -342,7 +319,6 @@ endif()
link_directories(
"${RPCS3_SRC_DIR}/../3rdparty/minidx12/"
"${RPCS3_SRC_DIR}/../Vulkan"
"${Polly_LIBRARY_DIRS}"
)
@@ -417,10 +393,6 @@ if(NOT MSVC)
target_link_libraries(rpcs3 GLEW::GLEW)
endif()
if(Polly_FOUND)
target_link_libraries(rpcs3 Polly PollyISL PollyPPCG)
endif()
if(WIN32)
target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib gdi32.lib VKstatic.1 glslang OSDependent OGLCompiler SPIRV HLSL setupapi.lib hidapi-hid Shlwapi.lib)
if(NOT MSVC)
+1 -1
View File
@@ -31,7 +31,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+32
View File
@@ -711,6 +711,38 @@ public:
return result;
}
template <typename T, typename T2>
value_t<T> bitcast(T2 expr)
{
value_t<T> result;
result.value = m_ir->CreateBitCast(expr.eval(m_ir), result.get_type(m_context));
return result;
}
template <typename T, typename T2>
value_t<T> trunc(T2 expr)
{
value_t<T> result;
result.value = m_ir->CreateTrunc(expr.eval(m_ir), result.get_type(m_context));
return result;
}
template <typename T, typename T2>
value_t<T> sext(T2 expr)
{
value_t<T> result;
result.value = m_ir->CreateSExt(expr.eval(m_ir), result.get_type(m_context));
return result;
}
template <typename T, typename T2>
value_t<T> zext(T2 expr)
{
value_t<T> result;
result.value = m_ir->CreateZExt(expr.eval(m_ir), result.get_type(m_context));
return result;
}
// Get unsigned addition carry into the sign bit (s = a + b)
template <typename T>
static inline auto ucarry(T a, T b, T s)
+5 -6
View File
@@ -176,16 +176,14 @@ void mfc_thread::cpu_task()
data = to_write;
vm::reservation_update(cmd.eal, 128);
_xend();
vm::notify(cmd.eal, 128);
_xend();
}
else
{
{
vm::writer_lock lock(0);
data = to_write;
vm::reservation_update(cmd.eal, 128);
}
vm::writer_lock lock(0);
data = to_write;
vm::reservation_update(cmd.eal, 128);
vm::notify(cmd.eal, 128);
}
}
@@ -358,6 +356,7 @@ void mfc_thread::cpu_task()
}
else
{
vm::reader_lock lock;
vm::notify_all();
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
@@ -554,7 +554,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
//Something happens
}
//Something happens?
return -1;
return CELL_OK;
}
s32 cellFontRenderCharGlyphImageVertical()
+4 -4
View File
@@ -1436,7 +1436,7 @@ void ppu_module::analyse(u32 lib_toc, u32 entry)
void ppu_acontext::UNK(ppu_opcode_t op)
{
std::fill_n(gpr, 32, spec_gpr());
std::fill_n(gpr, 32, spec_gpr{});
LOG_ERROR(PPU, "Unknown/Illegal opcode: 0x%08x at 0x%x" HERE, op.opcode, cia);
}
@@ -2563,7 +2563,7 @@ void ppu_acontext::MULHW(ppu_opcode_t op)
void ppu_acontext::LDARX(ppu_opcode_t op)
{
gpr[op.rd] = spec_gpr();
gpr[op.rd] = {};
}
void ppu_acontext::DCBF(ppu_opcode_t op)
@@ -2879,7 +2879,7 @@ void ppu_acontext::LVRX(ppu_opcode_t op)
void ppu_acontext::LSWI(ppu_opcode_t op)
{
std::fill_n(gpr, 32, spec_gpr());
std::fill_n(gpr, 32, spec_gpr{});
}
void ppu_acontext::LFSUX(ppu_opcode_t op)
@@ -3106,7 +3106,7 @@ void ppu_acontext::STHU(ppu_opcode_t op)
void ppu_acontext::LMW(ppu_opcode_t op)
{
std::fill_n(gpr, 32, spec_gpr());
std::fill_n(gpr, 32, spec_gpr{});
}
void ppu_acontext::STMW(ppu_opcode_t op)
+14 -36
View File
@@ -40,12 +40,6 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Vectorize.h"
#ifdef POLLY_AVAILABLE
#include <polly/RegisterPasses.h>
#include <polly/ScopDetection.h>
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
@@ -967,18 +961,14 @@ extern bool ppu_stwcx(ppu_thread& ppu, u32 addr, u32 reg_value)
return result;
}
bool result;
vm::writer_lock lock(0);
const bool result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u32)) && data.compare_and_swap_test(static_cast<u32>(ppu.rdata), reg_value);
if (result)
{
vm::writer_lock lock(0);
result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u32)) && data.compare_and_swap_test(static_cast<u32>(ppu.rdata), reg_value);
if (result)
{
vm::reservation_update(addr, sizeof(u32));
lock.unlock();
vm::notify(addr, sizeof(u32));
}
vm::reservation_update(addr, sizeof(u32));
vm::notify(addr, sizeof(u32));
}
ppu.raddr = 0;
@@ -1015,18 +1005,14 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value)
return result;
}
bool result;
vm::writer_lock lock(0);
const bool result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u64)) && data.compare_and_swap_test(ppu.rdata, reg_value);
if (result)
{
vm::writer_lock lock(0);
result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u64)) && data.compare_and_swap_test(ppu.rdata, reg_value);
if (result)
{
vm::reservation_update(addr, sizeof(u64));
lock.unlock();
vm::notify(addr, sizeof(u64));
}
vm::reservation_update(addr, sizeof(u64));
vm::notify(addr, sizeof(u64));
}
ppu.raddr = 0;
@@ -1478,11 +1464,6 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co
}
}
#ifdef POLLY_AVAILABLE
PassRegistry &Registry = *PassRegistry::getPassRegistry();
polly::initializePollyPasses(Registry);
initializeAnalysis(Registry);
#endif
std::shared_ptr<MsgDialogBase> dlg;
{
@@ -1500,9 +1481,6 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co
//pm.add(createLoopInstSimplifyPass());
//pm.add(createNewGVNPass());
pm.add(createDeadStoreEliminationPass());
#ifdef POLLY_AVAILABLE
polly::registerPollyPasses(pm);
#endif
//pm.add(createSCCPPass());
//pm.add(createReassociatePass());
//pm.add(createInstructionCombiningPass());
+1 -1
View File
@@ -14,7 +14,7 @@ const ppu_decoder<PPUTranslator> s_ppu_decoder;
PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, const ppu_module& info)
: cpu_translator(context, module, false)
, m_info(info)
, m_pure_attr(AttributeList::get(m_context,AttributeList::FunctionIndex, AttrBuilder().addAttribute(Attribute::NoUnwind).addAttribute(Attribute::ReadNone)))
, m_pure_attr(AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadNone}))
{
// There is no weak linkage on JIT, so let's create variables with different names for each module part
const u32 gsuffix = m_info.name.empty() ? info.funcs[0].addr : info.funcs[0].addr - m_info.segs[0].addr;
+306 -115
View File
@@ -10,6 +10,11 @@
#include <cmath>
#define ASMJIT_STATIC
#define ASMJIT_DEBUG
#include "asmjit.h"
#define SPU_OFF_128(x, ...) asmjit::x86::oword_ptr(*cpu, offset32(&SPUThread::x, ##__VA_ARGS__))
#define SPU_OFF_64(x, ...) asmjit::x86::qword_ptr(*cpu, offset32(&SPUThread::x, ##__VA_ARGS__))
#define SPU_OFF_32(x, ...) asmjit::x86::dword_ptr(*cpu, offset32(&SPUThread::x, ##__VA_ARGS__))
@@ -31,25 +36,25 @@ spu_recompiler::spu_recompiler()
}
}
bool spu_recompiler::compile(spu_function_contents_t* f)
void spu_recompiler::compile(spu_function_t& f)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (f->compiled)
if (f.compiled)
{
// return if function already compiled
return true;
return;
}
if (f->addr >= 0x40000 || f->addr % 4 || f->size == 0 || f->size > 0x40000 - f->addr || f->size % 4)
if (f.addr >= 0x40000 || f.addr % 4 || f.size == 0 || f.size > 0x40000 - f.addr || f.size % 4)
{
fmt::throw_exception("Invalid SPU function (addr=0x%05x, size=0x%x)" HERE, f->addr, f->size);
fmt::throw_exception("Invalid SPU function (addr=0x%05x, size=0x%x)" HERE, f.addr, f.size);
}
using namespace asmjit;
SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode);
dis_asm.offset = reinterpret_cast<u8*>(f->data.data()) - f->addr;
dis_asm.offset = reinterpret_cast<u8*>(f.data.data()) - f.addr;
StringLogger logger;
logger.addOptions(Logger::kOptionBinaryForm);
@@ -58,10 +63,10 @@ bool spu_recompiler::compile(spu_function_contents_t* f)
if (g_cfg.core.spu_debug)
{
fmt::append(log, "========== SPU FUNCTION 0x%05x - 0x%05x ==========\n\n", f->addr, f->addr + f->size);
fmt::append(log, "========== SPU FUNCTION 0x%05x - 0x%05x ==========\n\n", f.addr, f.addr + f.size);
}
this->m_func = f;
this->m_func = &f;
asmjit::CodeHolder code;
code.init(m_jit->getCodeInfo());
@@ -116,13 +121,13 @@ bool spu_recompiler::compile(spu_function_contents_t* f)
compiler.alloc(vec_vars[5], asmjit::x86::xmm5);
// Initialize labels
this->labels = std::unique_ptr<Label[]>(reinterpret_cast<Label*>(new u8[0x10000 * sizeof(Label)]()));
auto pos_labels = this->labels.get();
std::vector<Label> pos_labels{ 0x10000 };
this->labels = pos_labels.data();
// Register labels for block entries
for (const u32 addr : f->blocks)
for (const u32 addr : f.blocks)
{
if (addr < f->addr || addr >= f->addr + f->size || addr % 4)
if (addr < f.addr || addr >= f.addr + f.size || addr % 4)
{
fmt::throw_exception("Invalid function block entry (0x%05x)" HERE, addr);
}
@@ -131,15 +136,15 @@ bool spu_recompiler::compile(spu_function_contents_t* f)
}
// Register label for post-the-end address
pos_labels[(f->addr + f->size) / 4 % 0x10000] = compiler.newLabel();
pos_labels[(f.addr + f.size) / 4 % 0x10000] = compiler.newLabel();
// Register label for jump table resolver
Label jt_label = compiler.newLabel();
this->jt = &jt_label;
for (const u32 addr : f->jtable)
for (const u32 addr : f.jtable)
{
if (addr < f->addr || addr >= f->addr + f->size || addr % 4)
if (addr < f.addr || addr >= f.addr + f.size || addr % 4)
{
fmt::throw_exception("Invalid jump table entry (0x%05x)" HERE, addr);
}
@@ -150,16 +155,24 @@ bool spu_recompiler::compile(spu_function_contents_t* f)
this->end = &end_label;
// Start compilation
m_pos = f->addr;
m_pos = f.addr;
for (const u32 op : f->data)
if (utils::has_avx())
{
compiler.vzeroupper();
//compiler.pxor(asmjit::x86::xmm0, asmjit::x86::xmm0);
//compiler.vptest(asmjit::x86::ymm0, asmjit::x86::ymm0);
//compiler.jnz(end_label);
}
for (const u32 op : f.data)
{
// Bind label if initialized
if (pos_labels[m_pos / 4].isValid())
{
compiler.bind(pos_labels[m_pos / 4]);
if (f->blocks.find(m_pos) != f->blocks.end())
if (f.blocks.find(m_pos) != f.blocks.end())
{
compiler.comment("Block:");
}
@@ -206,12 +219,12 @@ bool spu_recompiler::compile(spu_function_contents_t* f)
// Generate jump table resolver (uses addr_var)
compiler.bind(jt_label);
if (f->jtable.size())
if (f.jtable.size())
{
compiler.comment("Jump table resolver:");
}
for (const u32 addr : f->jtable)
for (const u32 addr : f.jtable)
{
if ((addr % 4) == 0 && addr < 0x40000 && pos_labels[addr / 4].isValid())
{
@@ -240,8 +253,8 @@ bool spu_recompiler::compile(spu_function_contents_t* f)
Func fn;
m_jit->add(&fn, codeHolder);
f->compiled = asmjit::Internal::ptr_cast<decltype(f->compiled)>(fn);
f.compiled = asmjit::Internal::ptr_cast<decltype(f.compiled)>(fn);
if (g_cfg.core.spu_debug)
{
// Add ASMJIT logs
@@ -449,29 +462,16 @@ void spu_recompiler::LNOP(spu_opcode_t op)
{
}
void invalidate_jit(SPUThread* _spu)
{
for (u32 i = _spu->first_clean_func_index; i < _spu->last_clean_func_index; i++)
{
_spu->compiled_functions[i].dirty_bit = true;
}
_spu->first_clean_func_index = -1;
_spu->last_clean_func_index = 0;
}
void spu_recompiler::SYNC(spu_opcode_t op)
{
asmjit::CCFuncCall* call = c->call(asmjit::imm_ptr(asmjit::Internal::ptr_cast<void*, void(SPUThread*)>(invalidate_jit)), asmjit::FuncSignature1<u32, SPUThread*>(asmjit::CallConv::kIdHost));
call->setArg(0, *cpu);
// This instruction must be used following a store instruction that modifies the instruction stream.
c->mfence();
}
void spu_recompiler::DSYNC(spu_opcode_t op)
{
// This instruction forces all earlier load, store, and channel instructions to complete before proceeding.
c->mfence();
asmjit::CCFuncCall* call = c->call(asmjit::imm_ptr(asmjit::Internal::ptr_cast<void*, void(SPUThread*)>(invalidate_jit)), asmjit::FuncSignature1<u32, SPUThread*>(asmjit::CallConv::kIdHost));
call->setArg(0, *cpu);
}
void spu_recompiler::MFSPR(spu_opcode_t op)
@@ -623,6 +623,16 @@ void spu_recompiler::ROT(spu_opcode_t op)
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->vprotd(vt, va, vb);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](u32* t, const u32* a, const s32* b) noexcept
{
for (u32 i = 0; i < 4; i++)
@@ -662,6 +672,22 @@ void spu_recompiler::ROTM(spu_opcode_t op)
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->psubd(vb, XmmConst(_mm_set1_epi32(1)));
c->pandn(vb, XmmConst(_mm_set1_epi32(0x3f)));
c->pxor(vt, vt);
c->psubd(vt, vb);
c->pcmpgtd(vb, XmmConst(_mm_set1_epi32(31)));
c->vpshld(vt, va, vt);
c->vpandn(vt, vb, vt);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](u32* t, const u32* a, const u32* b) noexcept
{
for (u32 i = 0; i < 4; i++)
@@ -702,6 +728,21 @@ void spu_recompiler::ROTMA(spu_opcode_t op)
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->psubd(vb, XmmConst(_mm_set1_epi32(1)));
c->pandn(vb, XmmConst(_mm_set1_epi32(0x3f)));
c->pxor(vt, vt);
c->pminud(vb, XmmConst(_mm_set1_epi32(31)));
c->psubd(vt, vb);
c->vpshad(vt, va, vt);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](s32* t, const s32* a, const u32* b) noexcept
{
for (u32 i = 0; i < 4; i++)
@@ -741,6 +782,19 @@ void spu_recompiler::SHL(spu_opcode_t op)
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->pand(vb, XmmConst(_mm_set1_epi32(0x3f)));
c->vpcmpgtd(vt, vb, XmmConst(_mm_set1_epi32(31)));
c->vpshld(vb, va, vb);
c->pandn(vt, vb);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](u32* t, const u32* a, const u32* b) noexcept
{
for (u32 i = 0; i < 4; i++)
@@ -774,13 +828,24 @@ void spu_recompiler::ROTH(spu_opcode_t op) //nf
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
const XmmLink& v4 = XmmAlloc();
c->movdqa(v4, XmmConst(_mm_set1_epi16(0xf)));
c->pand(vb, v4);
c->vpsllvw(vt, va, vb);
c->psubw(vb, XmmConst(_mm_set1_epi16(1)));
c->pandn(vb, v4);
c->vpsrlvw(va, va, vb);
c->por(vt, va);
c->vmovdqa(v4, XmmConst(_mm_set_epi32(0x0d0c0d0c, 0x09080908, 0x05040504, 0x01000100)));
c->vpshufb(vt, va, v4); // duplicate low word
c->vpsrld(va, va, 16);
c->vpshufb(va, va, v4);
c->vpsrld(v4, vb, 16);
c->vprolvd(va, va, v4);
c->vprolvd(vb, vt, vb);
c->vpblendw(vt, vb, va, 0xaa);
c->vmovdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->vprotw(vt, va, vb);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
@@ -824,6 +889,42 @@ void spu_recompiler::ROTHM(spu_opcode_t op)
return;
}
if (utils::has_avx2())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
const XmmLink& v4 = XmmAlloc();
const XmmLink& v5 = XmmAlloc();
c->psubw(vb, XmmConst(_mm_set1_epi16(1)));
c->pandn(vb, XmmConst(_mm_set1_epi16(0x1f)));
c->movdqa(vt, XmmConst(_mm_set1_epi32(0xffff0000))); // mask: select high words
c->vpsrld(v4, vb, 16);
c->vpsubusw(v5, vb, vt); // clear high words (using saturation sub for throughput)
c->vpandn(vb, vt, va); // clear high words
c->vpsrlvd(va, va, v4);
c->vpsrlvd(vb, vb, v5);
c->vpblendw(vt, vb, va, 0xaa); // can use vpblendvb with 0xffff0000 mask (vt)
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->psubw(vb, XmmConst(_mm_set1_epi16(1)));
c->pandn(vb, XmmConst(_mm_set1_epi16(0x1f)));
c->pxor(vt, vt);
c->psubw(vt, vb);
c->pcmpgtw(vb, XmmConst(_mm_set1_epi16(15)));
c->vpshlw(vt, va, vt);
c->vpandn(vt, vb, vt);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](u16* t, const u16* a, const u16* b) noexcept
{
for (u32 i = 0; i < 8; i++)
@@ -864,6 +965,43 @@ void spu_recompiler::ROTMAH(spu_opcode_t op)
return;
}
if (utils::has_avx2())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
const XmmLink& v4 = XmmAlloc();
const XmmLink& v5 = XmmAlloc();
c->psubw(vb, XmmConst(_mm_set1_epi16(1)));
c->movdqa(vt, XmmConst(_mm_set1_epi16(0x1f)));
c->vpandn(v4, vb, vt);
c->vpand(v5, vb, vt);
c->movdqa(vt, XmmConst(_mm_set1_epi32(0x2f)));
c->vpsrld(v4, v4, 16);
c->vpsubusw(v5, vt, v5); // clear high word and add 16 to low word
c->vpslld(vb, va, 16);
c->vpsravd(va, va, v4);
c->vpsravd(vb, vb, v5);
c->vpblendw(vt, vb, va, 0xaa);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->psubw(vb, XmmConst(_mm_set1_epi16(1)));
c->pandn(vb, XmmConst(_mm_set1_epi16(0x1f)));
c->pxor(vt, vt);
c->pminuw(vb, XmmConst(_mm_set1_epi16(15)));
c->psubw(vt, vb);
c->vpshaw(vt, va, vt);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](s16* t, const s16* a, const u16* b) noexcept
{
for (u32 i = 0; i < 8; i++)
@@ -903,6 +1041,38 @@ void spu_recompiler::SHLH(spu_opcode_t op)
return;
}
if (utils::has_avx2())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
const XmmLink& v4 = XmmAlloc();
const XmmLink& v5 = XmmAlloc();
c->pand(vb, XmmConst(_mm_set1_epi16(0x1f)));
c->movdqa(vt, XmmConst(_mm_set1_epi32(0xffff0000))); // mask: select high words
c->vpsrld(v4, vb, 16);
c->vpsubusw(v5, vb, vt); // clear high words (using saturation sub for throughput)
c->vpand(vb, vt, va); // clear low words
c->vpsllvd(va, va, v5);
c->vpsllvd(vb, vb, v4);
c->vpblendw(vt, vb, va, 0x55);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->pand(vb, XmmConst(_mm_set1_epi16(0x1f)));
c->vpcmpgtw(vt, vb, XmmConst(_mm_set1_epi16(15)));
c->vpshlw(vb, va, vb);
c->pandn(vt, vb);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
return;
}
auto body = [](u16* t, const u16* a, const u16* b) noexcept
{
for (u32 i = 0; i < 8; i++)
@@ -941,6 +1111,14 @@ void spu_recompiler::ROTI(spu_opcode_t op)
return;
}
if (utils::has_xop())
{
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
c->vprotd(va, va, s);
c->movdqa(SPU_OFF_128(gpr, op.rt), va);
return;
}
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& v1 = XmmAlloc();
c->movdqa(v1, va);
@@ -1538,50 +1716,57 @@ void spu_recompiler::CDX(spu_opcode_t op)
void spu_recompiler::ROTQBI(spu_opcode_t op)
{
c->mov(*qw0, SPU_OFF_64(gpr, op.ra, &v128::_u64, 0));
c->mov(*qw1, SPU_OFF_64(gpr, op.ra, &v128::_u64, 1));
c->mov(*qw2, *qw0);
c->mov(*addr, SPU_OFF_32(gpr, op.rb, &v128::_u32, 3));
c->and_(*addr, 7);
c->shld(*qw0, *qw1, *addr);
c->shld(*qw1, *qw2, *addr);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 0), *qw0);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 1), *qw1);
c->unuse(*addr);
c->unuse(*qw0);
c->unuse(*qw1);
c->unuse(*qw2);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
const XmmLink& v4 = XmmAlloc();
c->psrldq(vb, 12);
c->pand(vb, XmmConst(_mm_set_epi64x(0, 7)));
c->movdqa(v4, XmmConst(_mm_set_epi64x(0, 64)));
c->pshufd(vt, va, 0x4e);
c->psubq(v4, vb);
c->psllq(va, vb);
c->psrlq(vt, v4);
c->por(vt, va);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
}
void spu_recompiler::ROTQMBI(spu_opcode_t op)
{
c->mov(*qw0, SPU_OFF_64(gpr, op.ra, &v128::_u64, 0));
c->mov(*qw1, SPU_OFF_64(gpr, op.ra, &v128::_u64, 1));
c->mov(*addr, SPU_OFF_32(gpr, op.rb, &v128::_u32, 3));
c->neg(*addr);
c->and_(*addr, 7);
c->shrd(*qw0, *qw1, *addr);
c->shr(*qw1, *addr);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 0), *qw0);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 1), *qw1);
c->unuse(*addr);
c->unuse(*qw0);
c->unuse(*qw1);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmAlloc();
const XmmLink& vt = XmmGet(op.rb, XmmType::Int);
const XmmLink& v4 = XmmAlloc();
c->psrldq(vt, 12);
c->pxor(vb, vb);
c->psubq(vb, vt);
c->pand(vb, XmmConst(_mm_set_epi64x(0, 7)));
c->movdqa(v4, XmmConst(_mm_set_epi64x(0, 64)));
c->movdqa(vt, va);
c->psrldq(vt, 8);
c->psubq(v4, vb);
c->psrlq(va, vb);
c->psllq(vt, v4);
c->por(vt, va);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
}
void spu_recompiler::SHLQBI(spu_opcode_t op)
{
c->mov(*qw0, SPU_OFF_64(gpr, op.ra, &v128::_u64, 0));
c->mov(*qw1, SPU_OFF_64(gpr, op.ra, &v128::_u64, 1));
c->mov(*addr, SPU_OFF_32(gpr, op.rb, &v128::_u32, 3));
c->and_(*addr, 7);
c->shld(*qw1, *qw0, *addr);
c->shl(*qw0, *addr);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 0), *qw0);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 1), *qw1);
c->unuse(*addr);
c->unuse(*qw0);
c->unuse(*qw1);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vb = XmmGet(op.rb, XmmType::Int);
const XmmLink& vt = XmmAlloc();
const XmmLink& v4 = XmmAlloc();
c->psrldq(vb, 12);
c->pand(vb, XmmConst(_mm_set_epi64x(0, 7)));
c->movdqa(v4, XmmConst(_mm_set_epi64x(0, 64)));
c->movdqa(vt, va);
c->pslldq(vt, 8);
c->psubq(v4, vb);
c->psllq(va, vb);
c->psrlq(vt, v4);
c->por(vt, va);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
}
void spu_recompiler::ROTQBY(spu_opcode_t op)
@@ -1682,16 +1867,14 @@ void spu_recompiler::SHLQBY(spu_opcode_t op)
void spu_recompiler::ORX(spu_opcode_t op)
{
c->mov(*addr, SPU_OFF_32(gpr, op.ra, &v128::_u32, 0));
c->or_(*addr, SPU_OFF_32(gpr, op.ra, &v128::_u32, 1));
c->or_(*addr, SPU_OFF_32(gpr, op.ra, &v128::_u32, 2));
c->or_(*addr, SPU_OFF_32(gpr, op.ra, &v128::_u32, 3));
c->mov(SPU_OFF_32(gpr, op.rt, &v128::_u32, 3), *addr);
c->xor_(*addr, *addr);
c->mov(SPU_OFF_32(gpr, op.rt, &v128::_u32, 0), *addr);
c->mov(SPU_OFF_32(gpr, op.rt, &v128::_u32, 1), *addr);
c->mov(SPU_OFF_32(gpr, op.rt, &v128::_u32, 2), *addr);
c->unuse(*addr);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& v1 = XmmAlloc();
c->pshufd(v1, va, 0xb1);
c->por(va, v1);
c->pshufd(v1, va, 0x4e);
c->por(va, v1);
c->pslldq(va, 12);
c->movdqa(SPU_OFF_128(gpr, op.rt), va);
}
void spu_recompiler::CBD(spu_opcode_t op)
@@ -1798,40 +1981,37 @@ void spu_recompiler::CDD(spu_opcode_t op)
void spu_recompiler::ROTQBII(spu_opcode_t op)
{
c->mov(*qw0, SPU_OFF_64(gpr, op.ra, &v128::_u64, 0));
c->mov(*qw1, SPU_OFF_64(gpr, op.ra, &v128::_u64, 1));
c->mov(*qw2, *qw0);
c->shld(*qw0, *qw1, op.i7 & 0x7);
c->shld(*qw1, *qw2, op.i7 & 0x7);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 0), *qw0);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 1), *qw1);
c->unuse(*qw0);
c->unuse(*qw1);
c->unuse(*qw2);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->pshufd(vt, va, 0x4e); // swap 64-bit parts
c->psllq(va, (op.i7 & 0x7));
c->psrlq(vt, 64 - (op.i7 & 0x7));
c->por(vt, va);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
}
void spu_recompiler::ROTQMBII(spu_opcode_t op)
{
c->mov(*qw0, SPU_OFF_64(gpr, op.ra, &v128::_u64, 0));
c->mov(*qw1, SPU_OFF_64(gpr, op.ra, &v128::_u64, 1));
c->shrd(*qw0, *qw1, 0-op.i7 & 0x7);
c->shr(*qw1, 0-op.i7 & 0x7);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 0), *qw0);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 1), *qw1);
c->unuse(*qw0);
c->unuse(*qw1);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->movdqa(vt, va);
c->psrldq(vt, 8);
c->psrlq(va, ((0 - op.i7) & 0x7));
c->psllq(vt, 64 - ((0 - op.i7) & 0x7));
c->por(vt, va);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
}
void spu_recompiler::SHLQBII(spu_opcode_t op)
{
c->mov(*qw0, SPU_OFF_64(gpr, op.ra, &v128::_u64, 0));
c->mov(*qw1, SPU_OFF_64(gpr, op.ra, &v128::_u64, 1));
c->shld(*qw1, *qw0, op.i7 & 0x7);
c->shl(*qw0, op.i7 & 0x7);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 0), *qw0);
c->mov(SPU_OFF_64(gpr, op.rt, &v128::_u64, 1), *qw1);
c->unuse(*qw0);
c->unuse(*qw1);
const XmmLink& va = XmmGet(op.ra, XmmType::Int);
const XmmLink& vt = XmmAlloc();
c->movdqa(vt, va);
c->pslldq(vt, 8);
c->psllq(va, (op.i7 & 0x7));
c->psrlq(vt, 64 - (op.i7 & 0x7));
c->por(vt, va);
c->movdqa(SPU_OFF_128(gpr, op.rt), vt);
}
void spu_recompiler::ROTQBYI(spu_opcode_t op)
@@ -3298,6 +3478,13 @@ void spu_recompiler::SELB(spu_opcode_t op)
return;
}
if (utils::has_xop())
{
c->vpcmov(vc, vb, SPU_OFF_128(gpr, op.ra), vc);
c->movdqa(SPU_OFF_128(gpr, op.rt4), vc);
return;
}
c->pand(vb, vc);
c->pandn(vc, SPU_OFF_128(gpr, op.ra));
c->por(vb, vc);
@@ -3422,6 +3609,10 @@ void spu_recompiler::SHUFB(spu_opcode_t op)
{
c->vpternlogd(vc, va, vb, 0xca /* A?B:C */);
}
else if (utils::has_xop())
{
c->vpcmov(vc, va, vb, vc);
}
else
{
c->pand(va, vc);
+13 -7
View File
@@ -1,12 +1,18 @@
#pragma once
#define ASMJIT_STATIC
#define ASMJIT_DEBUG
#include "asmjit.h"
#include "SPURecompiler.h"
namespace asmjit
{
struct JitRuntime;
struct CodeHolder;
struct X86Compiler;
struct X86Gp;
struct X86Xmm;
struct X86Mem;
struct Label;
}
// SPU ASMJIT Recompiler
class spu_recompiler : public spu_recompiler_base
{
@@ -15,7 +21,7 @@ class spu_recompiler : public spu_recompiler_base
public:
spu_recompiler();
virtual bool compile(spu_function_contents_t* f) override;
virtual void compile(spu_function_t& f) override;
private:
// emitter:
@@ -35,7 +41,7 @@ private:
std::array<asmjit::X86Xmm*, 6> vec;
// labels:
std::unique_ptr<asmjit::Label[]> labels; // array[0x10000]
asmjit::Label* labels; // array[0x10000]
asmjit::Label* jt; // jump table resolver (uses *addr)
asmjit::Label* end; // function end (return *addr)
+19 -54
View File
@@ -5,18 +5,16 @@
const spu_decoder<spu_itype> s_spu_itype;
spu_function_contents_t* SPUDatabase::find(const be_t<u32>* data, u64 key, u32 max_size, void* ignore)
spu_function_t* SPUDatabase::find(const be_t<u32>* data, u64 key, u32 max_size)
{
for (auto found = m_db.equal_range(key); found.first != found.second; found.first++)
{
const auto & func = found.first->second;
// TODO remove code after a while if it hasn't been touched, else there's a big memory bloat here and switch memcmp with compare_func
const auto& func = found.first->second;
// Compare binary data explicitly (TODO: optimize)
if (func != ignore && LIKELY(func->size <= max_size) && std::memcmp(func->data.data(), data, func->size) == 0)
if (LIKELY(func->size <= max_size) && std::memcmp(func->data.data(), data, func->size) == 0)
{
return func;
return func.get();
}
}
@@ -35,17 +33,8 @@ SPUDatabase::~SPUDatabase()
// TODO: serialize database
}
bool IsDeterministicBranch(spu_itype::type type)
spu_function_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, u32 max_limit)
{
return type == spu_itype::BR || type == spu_itype::BRSL
|| type == spu_itype::BRA || type == spu_itype::BRASL
|| type == spu_itype::BI || type == spu_itype::BISL
|| type == spu_itype::IRET;
}
spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, void* ignore /*=nullptr*/)
{
const u32 max_limit = 0x40000;
// Check arguments (bounds and alignment)
if (max_limit > 0x40000 || entry >= max_limit || entry % 4 || max_limit % 4)
{
@@ -53,12 +42,7 @@ spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, vo
}
// Key for multimap
u32 xor_base = 0;
for (u32 i = 0; i < 10; i++)
{
xor_base ^= ls[(entry / 4) + i];
}
const u64 key = entry | u64{ xor_base } << 32;
const u64 key = entry | u64{ ls[entry / 4] } << 32;
const be_t<u32>* base = ls + entry / 4;
const u32 block_sz = max_limit - entry;
@@ -72,11 +56,19 @@ spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, vo
}
}
{
writer_lock lock(m_mutex);
// Double-check
if (auto func = find(base, key, block_sz))
{
return func;
}
}
// Initialize block entries with the function entry point
std::set<u32> blocks{ entry };
std::vector<u32> blocks_size;
// Entries of adjacent functions; jump table entries
std::set<u32> adjacent, jt;
@@ -92,21 +84,15 @@ spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, vo
// Find preliminary set of possible block entries (first pass), `start` is the current block address
for (u32 start = entry, pos = entry; pos < limit; pos += 4)
{
u32 xor_base = 0;
for (u32 i = 0; i < 10; i++)
{
xor_base ^= ls[(pos / 4) + i];
}
const spu_opcode_t op{ ls[pos / 4] };
const auto type = s_spu_itype.decode(op.opcode);
if (pos != entry)
{
reader_lock lock(m_mutex);
// Find existing function
if (find(ls + pos / 4, pos | u64{ ls[pos / 4] } << 32, limit - pos))
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
{
limit = pos;
break;
@@ -321,27 +307,8 @@ spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, vo
return nullptr;
}
blocks_size.reserve(blocks.size());
for (u32 block : blocks)
{
u32 size = 0;
for (u32 i = block / 4; i < 0x10000; i++)
{
if (ls[i] == 0 || IsDeterministicBranch(s_spu_itype.decode(ls[i])))
{
size = (i * 4) - block + 4;
break;
}
}
if (size == 0)
{
verify("No way out of a block"), size != 0;
}
blocks_size.push_back(size);
}
// Prepare new function (set addr and size)
auto func = new spu_function_contents_t(entry, limit - entry);
auto func = std::make_shared<spu_function_t>(entry, limit - entry);
// Copy function contents
func->data = { ls + entry / 4, ls + limit / 4 };
@@ -373,8 +340,6 @@ spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, vo
}
}
func->blocks_size = std::move(blocks_size);
// Set whether the function can reset stack
func->does_reset_stack = ila_sp_pos < limit;
@@ -389,5 +354,5 @@ spu_function_contents_t* SPUDatabase::analyse(const be_t<u32>* ls, u32 entry, vo
LOG_NOTICE(SPU, "Function detected [0x%05x-0x%05x] (size=0x%x)", func->addr, func->addr + func->size, func->size);
return func;
return func.get();
}
+8 -33
View File
@@ -2,9 +2,7 @@
#include "Utilities/mutex.h"
#include <map>
#include <set>
#include <memory>
// SPU Instruction Type
struct spu_itype
@@ -248,10 +246,8 @@ struct spu_itype
class SPUThread;
typedef u32(*CompiledFunc)(SPUThread* _spu, be_t<u32>* _ls);
// SPU basic function information structure
struct spu_function_contents_t
struct spu_function_t
{
// Entry point (LS address)
const u32 addr;
@@ -265,9 +261,6 @@ struct spu_function_contents_t
// Basic blocks (start addresses)
std::set<u32> blocks;
// Basic blocks size
std::vector<u32> blocks_size;
// Functions possibly called by this function (may not be available)
std::set<u32> adjacent;
@@ -278,48 +271,30 @@ struct spu_function_contents_t
bool does_reset_stack;
// Pointer to the compiled function
CompiledFunc compiled = nullptr;
u32(*compiled)(SPUThread* _spu, be_t<u32>* _ls) = nullptr;
spu_function_contents_t(u32 addr, u32 size)
: addr(addr),
size(size)
spu_function_t(u32 addr, u32 size)
: addr(addr)
, size(size)
{
}
};
// A single instance of a compiled function, currently in use
union spu_function_t
{
// The function itself and its data
spu_function_contents_t * contents;
// Whether pages the function is in were written to since its last execution
bool dirty_bit : 1;
operator bool()
{
return contents != nullptr;
}
spu_function_t() : contents(nullptr) {};
~spu_function_t() {};
};
// SPU Function Database (must be global or PS3 process-local)
class SPUDatabase final : spu_itype
{
shared_mutex m_mutex;
// All registered functions (uses addr and first instruction as a key)
std::unordered_multimap<u64, spu_function_contents_t*> m_db;
std::unordered_multimap<u64, std::shared_ptr<spu_function_t>> m_db;
// For internal use
spu_function_contents_t* find(const be_t<u32>* data, u64 key, u32 max_size, void* ignore = nullptr);
spu_function_t* find(const be_t<u32>* data, u64 key, u32 max_size);
public:
SPUDatabase();
~SPUDatabase();
// Try to retrieve SPU function information
spu_function_contents_t* analyse(const be_t<u32>* ls, u32 entry, void * ignore=nullptr);
spu_function_t* analyse(const be_t<u32>* ls, u32 entry, u32 limit = 0x40000);
};
+1 -2
View File
@@ -101,8 +101,7 @@ void spu_interpreter::RDCH(SPUThread& spu, spu_opcode_t op)
}
else
{
memset(&spu.gpr[op.rt], 0, 3*sizeof(u32));
spu.gpr[op.rt]._u32[3] = result;
spu.gpr[op.rt] = v128::from32r(result);
}
}
+11 -29
View File
@@ -24,57 +24,39 @@ void spu_recompiler_base::enter(SPUThread& spu)
const auto _ls = vm::_ptr<u32>(spu.offset);
// Search if cached data matches
auto func_ptr = spu.compiled_cache[spu.pc / 4];
auto func = spu.compiled_cache[spu.pc / 4];
// Dirty bit check commented out until another code invalidation is found - SYNC, SYNCC, DSYNC and DMAs aren't covering everything
if (func_ptr/* && func_ptr->dirty_bit*/)
// Check shared db if we dont have a match
if (!func || !std::equal(func->data.begin(), func->data.end(), _ls + spu.pc / 4, [](const be_t<u32>& l, const be_t<u32>& r) { return *(u32*)(u8*)&l == *(u32*)(u8*)&r; }))
{
auto & func = *func_ptr;
func.dirty_bit = false;
u32 index = (reinterpret_cast<size_t>(func_ptr) - reinterpret_cast<size_t>(&spu.compiled_functions[0])) / sizeof(func);
spu.first_clean_func_index = std::min<u32>(index, spu.first_clean_func_index);
spu.last_clean_func_index = std::max<u32>(index + 1, spu.last_clean_func_index);
if (!spu.same_function(func.contents, _ls + (spu.pc / 4)))
{
func.contents = spu.spu_db->analyse(_ls, spu.pc, func.contents);
}
}
else if (!func_ptr)
{
auto & func = spu.compiled_functions[++spu.next_compiled_func_index];
func.contents = spu.spu_db->analyse(_ls, spu.pc);
func_ptr = &func;
spu.compiled_cache[spu.pc / 4] = func_ptr;
spu.last_clean_func_index = spu.next_compiled_func_index + 1;
spu.first_clean_func_index = std::min<u32>(spu.first_clean_func_index, spu.next_compiled_func_index);
func = spu.spu_db->analyse(_ls, spu.pc);
spu.compiled_cache[spu.pc / 4] = func;
}
// Reset callstack if necessary
if ((func_ptr->contents->does_reset_stack && spu.recursion_level) || spu.recursion_level >= 128)
if ((func->does_reset_stack && spu.recursion_level) || spu.recursion_level >= 128)
{
spu.state += cpu_flag::ret;
return;
}
// Compile if needed
if (!func_ptr->contents->compiled)
if (!func->compiled)
{
if (!spu.spu_rec)
{
spu.spu_rec = fxm::get_always<spu_recompiler>();
}
spu.spu_rec->compile(func_ptr->contents);
spu.spu_rec->compile(*func);
if (!func_ptr->contents->compiled) fmt::throw_exception("Compilation failed" HERE);
if (!func->compiled) fmt::throw_exception("Compilation failed" HERE);
}
const u32 res = func_ptr->contents->compiled(&spu, _ls);
const u32 res = func->compiled(&spu, _ls);
if (spu.pending_exception)
if (const auto exception = spu.pending_exception)
{
const auto exception = spu.pending_exception;
spu.pending_exception = nullptr;
std::rethrow_exception(exception);
}
+2 -2
View File
@@ -10,7 +10,7 @@ class spu_recompiler_base
protected:
std::mutex m_mutex; // must be locked in compile()
const spu_function_contents_t* m_func; // current function
const spu_function_t* m_func; // current function
u32 m_pos; // current position
@@ -18,7 +18,7 @@ public:
virtual ~spu_recompiler_base();
// Compile specified function
virtual bool compile(spu_function_contents_t*) = 0;
virtual void compile(spu_function_t& f) = 0;
// Run
static void enter(class SPUThread&);
+129 -126
View File
@@ -41,18 +41,6 @@ bool operator ==(const u128& lhs, const u128& rhs)
}
#endif
#ifndef _MSC_VER
FORCE_INLINE void __movsq(unsigned long * Destination, const unsigned long * Source, size_t Count)
{
__asm__ __volatile__
(
"rep; movsq" :
[Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
"[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
);
}
#endif
extern u64 get_timebased_time();
extern u64 get_system_time();
@@ -146,8 +134,8 @@ namespace spu
{
if (timeout_ms > 0)
{
const auto timeout = timeout_ms * 1000ull; //convert to microseconds
const auto start = get_system_time();
const u64 timeout = timeout_ms * 1000u; //convert to microseconds
const u64 start = get_system_time();
auto remaining = timeout;
while (atomic_instruction_table[pc_offset].load(std::memory_order_consume) >= max_concurrent_instructions)
@@ -174,14 +162,14 @@ namespace spu
}
}
++atomic_instruction_table[pc_offset];
atomic_instruction_table[pc_offset]++;
}
void release_pc_address(u32 pc)
{
const u32 pc_offset = pc >> 2;
--atomic_instruction_table[pc_offset];
atomic_instruction_table[pc_offset]--;
}
struct concurrent_execution_watchdog
@@ -302,8 +290,6 @@ void SPUThread::on_spawn()
{
thread_ctrl::set_native_priority(-1);
}
++g_num_spu_threads;
}
void SPUThread::on_init(const std::shared_ptr<void>& _this)
@@ -470,7 +456,6 @@ void SPUThread::do_dma_transfer(const spu_mfc_cmd& args, bool from_mfc)
u32 eal = args.eal;
u32 lsa = args.lsa & 0x3ffff;
SPUThread * spu = nullptr;
if (eal >= SYS_SPU_THREAD_BASE_LOW && offset < RAW_SPU_BASE_ADDR) // SPU Thread Group MMIO (LS and SNR)
{
@@ -479,15 +464,15 @@ void SPUThread::do_dma_transfer(const spu_mfc_cmd& args, bool from_mfc)
if (group && index < group->num && group->threads[index])
{
spu = group->threads[index].get();
auto& spu = static_cast<SPUThread&>(*group->threads[index]);
if (offset + args.size - 1 < 0x40000) // LS access
{
eal = spu->offset + offset; // redirect access
eal = spu.offset + offset; // redirect access
}
else if (!is_get && args.size == 4 && (offset == SYS_SPU_THREAD_SNR1 || offset == SYS_SPU_THREAD_SNR2))
{
spu->push_snr(SYS_SPU_THREAD_SNR2 == offset, _ref<u32>(lsa));
spu.push_snr(SYS_SPU_THREAD_SNR2 == offset, _ref<u32>(lsa));
return;
}
else
@@ -547,27 +532,82 @@ void SPUThread::do_dma_transfer(const spu_mfc_cmd& args, bool from_mfc)
}
default:
{
auto vdst = static_cast<u64*>(dst);
auto vsrc = static_cast<const u64*>(src);
auto vcnt = size / sizeof(u64);
auto vdst = static_cast<__m128i*>(dst);
auto vsrc = static_cast<const __m128i*>(src);
auto vcnt = size / sizeof(__m128i);
__movsq(vdst, vsrc, vcnt);
}
}
if (spu)
{
for (u32 i = 0; i < spu->next_compiled_func_index; i++)
//if (is_get && !from_mfc)
{
auto& func = spu->compiled_functions[i];
auto faddr = func.contents->addr;
auto fsize = func.contents->size;
if (fsize + faddr > eal && eal + args.size > faddr)
while (vcnt >= 8)
{
func.dirty_bit = true;
const __m128i data[]
{
_mm_load_si128(vsrc + 0),
_mm_load_si128(vsrc + 1),
_mm_load_si128(vsrc + 2),
_mm_load_si128(vsrc + 3),
_mm_load_si128(vsrc + 4),
_mm_load_si128(vsrc + 5),
_mm_load_si128(vsrc + 6),
_mm_load_si128(vsrc + 7),
};
_mm_store_si128(vdst + 0, data[0]);
_mm_store_si128(vdst + 1, data[1]);
_mm_store_si128(vdst + 2, data[2]);
_mm_store_si128(vdst + 3, data[3]);
_mm_store_si128(vdst + 4, data[4]);
_mm_store_si128(vdst + 5, data[5]);
_mm_store_si128(vdst + 6, data[6]);
_mm_store_si128(vdst + 7, data[7]);
vcnt -= 8;
vsrc += 8;
vdst += 8;
}
while (vcnt--)
{
_mm_store_si128(vdst++, _mm_load_si128(vsrc++));
}
break;
}
// Disabled
while (vcnt >= 8)
{
const __m128i data[]
{
_mm_load_si128(vsrc + 0),
_mm_load_si128(vsrc + 1),
_mm_load_si128(vsrc + 2),
_mm_load_si128(vsrc + 3),
_mm_load_si128(vsrc + 4),
_mm_load_si128(vsrc + 5),
_mm_load_si128(vsrc + 6),
_mm_load_si128(vsrc + 7),
};
_mm_stream_si128(vdst + 0, data[0]);
_mm_stream_si128(vdst + 1, data[1]);
_mm_stream_si128(vdst + 2, data[2]);
_mm_stream_si128(vdst + 3, data[3]);
_mm_stream_si128(vdst + 4, data[4]);
_mm_stream_si128(vdst + 5, data[5]);
_mm_stream_si128(vdst + 6, data[6]);
_mm_stream_si128(vdst + 7, data[7]);
vcnt -= 8;
vsrc += 8;
vdst += 8;
}
while (vcnt--)
{
_mm_stream_si128(vdst++, _mm_load_si128(vsrc++));
}
}
}
if (is_get && from_mfc)
@@ -622,14 +662,15 @@ void SPUThread::process_mfc_cmd()
if (is_polling)
{
vm::waiter* waiter = new vm::waiter();
waiter->owner = this;
waiter->addr = raddr;
waiter->stamp = rtime;
waiter->data = rdata.data();
waiter->init();
vm::waiter waiter;
waiter.owner = this;
waiter.addr = raddr;
waiter.size = 128;
waiter.stamp = rtime;
waiter.data = rdata.data();
waiter.init();
while (vm::reservation_acquire(raddr, 128) == waiter->stamp && rdata == data)
while (vm::reservation_acquire(raddr, 128) == waiter.stamp && rdata == data)
{
if (test(state, cpu_flag::stop))
{
@@ -638,9 +679,6 @@ void SPUThread::process_mfc_cmd()
thread_ctrl::wait_for(100);
}
waiter->remove();
waiter = nullptr;
}
else if (s_use_rtm && utils::transaction_enter())
{
@@ -666,11 +704,9 @@ void SPUThread::process_mfc_cmd()
if (is_polling || UNLIKELY(vm::reservation_acquire(raddr, 128) != rtime))
{
// TODO: vm::check_addr
{
vm::reader_lock lock;
rtime = vm::reservation_acquire(raddr, 128);
}
memcpy(rdata.data(), data.data(), rdata.size() * sizeof(rdata[0]));
vm::reader_lock lock;
rtime = vm::reservation_acquire(raddr, 128);
rdata = data;
}
// Copy to LS
@@ -687,13 +723,12 @@ void SPUThread::process_mfc_cmd()
bool result = false;
// Check for fast exit in the beginning as well
if (raddr == ch_mfc_cmd.eal && rtime == vm::reservation_acquire(raddr, 128) && rdata == data)
{
// TODO: vm::check_addr
if (s_use_rtm && utils::transaction_enter())
{
if (!vm::reader_lock{ vm::try_to_lock })
if (!vm::reader_lock{vm::try_to_lock})
{
_xabort(0);
}
@@ -711,16 +746,14 @@ void SPUThread::process_mfc_cmd()
}
else
{
// TODO maybe timeout and check if the lock is still needed in long waits (If rtime changes, no use)
vm::writer_lock lock;
if (rtime == vm::reservation_acquire(raddr, 128))
if (rtime == vm::reservation_acquire(raddr, 128) && rdata == data)
{
data = to_write;
vm::reservation_update(raddr, 128);
lock.unlock();
result = true;
vm::reservation_update(raddr, 128);
vm::notify(raddr, 128);
}
}
@@ -733,10 +766,11 @@ void SPUThread::process_mfc_cmd()
else
{
ch_atomic_stat.set_value(MFC_PUTLLC_FAILURE);
if (raddr)
{
ch_event_stat |= SPU_EVENT_LR;
}
}
if (raddr && !result)
{
ch_event_stat |= SPU_EVENT_LR;
}
raddr = 0;
@@ -774,11 +808,9 @@ void SPUThread::process_mfc_cmd()
return;
}
vm::writer_lock lock(0);
data = to_write;
{
vm::writer_lock lock(0);
vm::reservation_update(ch_mfc_cmd.eal, 128);
}
vm::reservation_update(ch_mfc_cmd.eal, 128);
vm::notify(ch_mfc_cmd.eal, 128);
ch_atomic_stat.set_value(MFC_PUTLLUC_SUCCESS);
@@ -809,22 +841,18 @@ void SPUThread::process_mfc_cmd()
// Try to process small transfers immediately
if (ch_mfc_cmd.size <= max_imm_dma_size && mfc_queue.size() == 0)
{
/* TODO catch the exception (Currently they are ignored and slow things down by grabbing a lock)
vm::reader_lock lock(vm::try_to_lock);
if (!lock)
{
vm::reader_lock lock(vm::try_to_lock);
if (!lock)
{
break;
}
if (!vm::check_addr(ch_mfc_cmd.eal, ch_mfc_cmd.size, vm::page_readable | (ch_mfc_cmd.cmd & MFC_PUT_CMD ? vm::page_writable : 0)))
{
// TODO
break;
}
break;
}
if (!vm::check_addr(ch_mfc_cmd.eal, ch_mfc_cmd.size, vm::page_readable | (ch_mfc_cmd.cmd & MFC_PUT_CMD ? vm::page_writable : 0)))
{
// TODO
break;
}
*/
do_dma_transfer(ch_mfc_cmd, false);
return;
@@ -844,6 +872,13 @@ void SPUThread::process_mfc_cmd()
{
if (ch_mfc_cmd.size <= max_imm_dma_size && mfc_queue.size() == 0)
{
vm::reader_lock lock(vm::try_to_lock);
if (!lock)
{
break;
}
struct list_element
{
be_t<u16> sb;
@@ -874,20 +909,11 @@ void SPUThread::process_mfc_cmd()
break;
}
/* TODO Catch and handle exceptions here
if (!vm::check_addr(addr, size, vm::page_readable | (ch_mfc_cmd.cmd & MFC_PUT_CMD ? vm::page_writable : 0)))
{
vm::reader_lock lock(vm::try_to_lock);
if (!lock)
{
break;
}
if (!vm::check_addr(addr, size, vm::page_readable | (ch_mfc_cmd.cmd & MFC_PUT_CMD ? vm::page_writable : 0)))
{
// TODO
break;
}
}*/
// TODO
break;
}
spu_mfc_cmd transfer;
transfer.eal = addr;
@@ -1163,35 +1189,28 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
return true;
}
vm::waiter* waiter = nullptr;
vm::waiter waiter;
if (ch_event_mask & SPU_EVENT_LR)
{
waiter = new vm::waiter();
waiter->owner = this;
waiter->addr = raddr;
waiter->stamp = rtime;
waiter->data = rdata.data();
waiter->init();
waiter.owner = this;
waiter.addr = raddr;
waiter.size = 128;
waiter.stamp = rtime;
waiter.data = rdata.data();
waiter.init();
}
while (!(res = get_events(true)))
{
if (test(state & cpu_flag::stop))
{
waiter->remove();
waiter = nullptr;
return false;
}
thread_ctrl::wait_for(100);
}
if (waiter != nullptr)
{
waiter->remove();
waiter = nullptr;
}
out = res;
return true;
}
@@ -1823,22 +1842,6 @@ bool SPUThread::stop_and_signal(u32 code)
}
}
bool SPUThread::same_function(const spu_function_contents_t * func, const void * addr)
{
auto size = func->blocks_size.cbegin();
auto dst = reinterpret_cast<const u8 *>(addr);
auto src = vm::ps3::_ptr<u8>(offset);
for (auto block : func->blocks)
{
u32 offset = block - func->addr;
if (memcmp(src + offset, dst + offset, *size) != 0) return false;
size++;
}
return true;
}
void SPUThread::halt()
{
LOG_TRACE(SPU, "halt()");
+14 -17
View File
@@ -3,7 +3,6 @@
#include "Emu/Cell/Common.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/Cell/SPUInterpreter.h"
#include "Emu/Cell/SPURecompiler.h"
#include "MFC.h"
struct lv2_event_queue;
@@ -213,14 +212,21 @@ public:
// returns true on success
bool try_pop(u32& out)
{
const auto old = data.fetch_op([](sync_var_t& data)
const auto old = data.fetch_op([&](sync_var_t& data)
{
sync_var_t t{};
t.wait = !data.count;
data = t;
});
if (data.count)
{
data.wait = false;
out = data.value;
}
else
{
data.wait = true;
}
out = old.value;
data.count = false;
data.value = 0; // ???
});
return old.count;
}
@@ -579,15 +585,7 @@ public:
std::exception_ptr pending_exception;
// No need for shared_ptr in the following two, as whenever something is removed or added to one,
// the same goes for the other.
std::array<spu_function_t*, 65536> compiled_cache{};
std::array<spu_function_t, 65536> compiled_functions{};
u32 next_compiled_func_index = -1;
u32 first_clean_func_index = 0;
u32 last_clean_func_index = 0;
std::array<struct spu_function_t*, 65536> compiled_cache{};
std::shared_ptr<class SPUDatabase> spu_db;
std::shared_ptr<class spu_recompiler_base> spu_rec;
u32 recursion_level = 0;
@@ -603,7 +601,6 @@ public:
bool get_ch_value(u32 ch, u32& out);
bool set_ch_value(u32 ch, u32 value);
bool stop_and_signal(u32 code);
bool same_function(const spu_function_contents_t * func, const void * addr);
void halt();
void fast_call(u32 ls_addr);
-6
View File
@@ -777,12 +777,6 @@ error_code sys_spu_thread_write_ls(u32 id, u32 lsa, u64 value, u32 type)
default: return CELL_EINVAL;
}
auto func = thread->compiled_cache[lsa / 4];
if (func)
{
func->dirty_bit = true;
}
return CELL_OK;
}
+10 -5
View File
@@ -131,20 +131,25 @@ u64 get_timebased_time()
// Returns some relative time in microseconds, don't change this fact
u64 get_system_time()
{
#ifdef _WIN32
// Pull the time directly from Windows shared page (Constant location on all Windows machines)
return *reinterpret_cast<u64*>(0x7ffe0014) / 10;
#else
while (true)
{
#ifdef _WIN32
LARGE_INTEGER count;
verify(HERE), QueryPerformanceCounter(&count);
const u64 time = count.QuadPart;
const u64 freq = s_time_aux_info.perf_freq;
const u64 result = time / freq * 1000000u + (time % freq) * 1000000u / freq;
#else
struct timespec ts;
verify(HERE), ::clock_gettime(CLOCK_MONOTONIC, &ts) == 0;
const u64 result = static_cast<u64>(ts.tv_sec) * 1000000u + static_cast<u64>(ts.tv_nsec) / 1000u;
#endif
if (result) return result;
}
#endif
}
// Functions
+76 -76
View File
@@ -8,15 +8,16 @@
#include "Emu/Cell/lv2/sys_memory.h"
#include "Emu/RSX/GSRender.h"
#include <atomic>
#include <deque>
namespace vm
{
std::array<memory_page, 0x100000000 / 4096> g_pages{};
static u8* memory_reserve_4GiB(const std::uintptr_t _addr = 0)
static u8* memory_reserve_4GiB(std::uintptr_t _addr = 0)
{
for (auto addr = _addr + 0x100000000;; addr += 0x100000000)
for (u64 addr = _addr + 0x100000000;; addr += 0x100000000)
{
if (const auto ptr = utils::memory_reserve(0x100000000, reinterpret_cast<void*>(addr)))
if (auto ptr = utils::memory_reserve(0x100000000, (void*)addr))
{
return static_cast<u8*>(ptr);
}
@@ -38,13 +39,11 @@ namespace vm
// Memory locations
std::vector<std::shared_ptr<block_t>> g_locations;
// Registered waiters
std::vector<vm::waiter*> g_waiters;
shared_mutex g_waiters_lock;
// Reservations (lock lines) in a single memory page
using reservation_info = std::array<std::atomic<u64>, 4096 / 128>;
// Waiters which will be removed once the lock is freed
shared_mutex g_waiters_to_remove_lock;
std::vector<vm::waiter*> g_waiters_to_remove;
// Registered waiters
std::deque<vm::waiter*> g_waiters;
// Memory mutex core
shared_mutex g_mutex;
@@ -202,38 +201,78 @@ namespace vm
{
}
void writer_lock::unlock()
writer_lock::~writer_lock()
{
if (locked)
{
g_mutex.unlock();
locked = false;
}
}
writer_lock::~writer_lock()
// Page information
struct memory_page
{
unlock();
// Memory flags
atomic_t<u8> flags;
atomic_t<u32> waiters;
// Reservations
atomic_t<reservation_info*> reservations;
// Access reservation info
std::atomic<u64>& operator [](u32 addr)
{
auto ptr = reservations.load();
if (!ptr)
{
// Opportunistic memory allocation
ptr = new reservation_info{};
if (auto old_ptr = reservations.compare_and_swap(nullptr, ptr))
{
delete ptr;
ptr = old_ptr;
}
}
return (*ptr)[(addr & 0xfff) >> 7];
}
};
// Memory pages
std::array<memory_page, 0x100000000 / 4096> g_pages{};
u64 reservation_acquire(u32 addr, u32 _size)
{
// Access reservation info: stamp and the lock bit
return g_pages[addr >> 12][addr].load(std::memory_order_acquire);
}
void reservation_update(u32 addr, u32 _size)
{
// Update reservation info with new timestamp (unsafe, assume allocated)
(*g_pages[addr >> 12].reservations)[(addr & 0xfff) >> 7].store(__rdtsc(), std::memory_order_release);
}
void waiter::init()
{
// Register waiter
g_waiters_lock.lock();
writer_lock lock(0);
g_waiters.emplace_back(this);
g_waiters_lock.unlock();
}
void waiter::test() const
{
const auto owner_copy = owner;
if (!owner_copy)
if (std::memcmp(data, vm::base(addr), size) == 0)
{
return;
}
memory_page& page = g_pages[addr >> 12];
if (page.reservations == nullptr)
{
return;
@@ -244,44 +283,28 @@ namespace vm
return;
}
if (memcmp(data, vm::base(addr), size) == 0)
if (owner)
{
return;
}
owner_copy->notify();
}
void remove_old_waiters()
{
if (!g_waiters_to_remove.empty())
{
g_waiters_to_remove_lock.lock();
for (auto ptr : g_waiters_to_remove)
{
const auto found = std::find(g_waiters.cbegin(), g_waiters.cend(), ptr);
if (found != g_waiters.cend())
{
g_waiters.erase(found);
}
delete ptr;
}
g_waiters_to_remove.clear();
g_waiters_to_remove_lock.unlock();
owner->notify();
}
}
void waiter::remove()
waiter::~waiter()
{
this->owner = nullptr; // Iterations of the object will ignore it from now on
g_waiters_to_remove_lock.lock();
g_waiters_to_remove.push_back(this);
g_waiters_to_remove_lock.unlock();
// Unregister waiter
writer_lock lock(0);
// Find waiter
const auto found = std::find(g_waiters.cbegin(), g_waiters.cend(), this);
if (found != g_waiters.cend())
{
g_waiters.erase(found);
}
}
void notify(u32 addr, u32 size)
{
g_waiters_lock.lock_shared();
for (const waiter* ptr : g_waiters)
{
if (ptr->addr / 128 == addr / 128)
@@ -289,37 +312,14 @@ namespace vm
ptr->test();
}
}
if (g_waiters_to_remove.size() > 10)
{
g_waiters_lock.lock_upgrade();
remove_old_waiters();
g_waiters_lock.unlock();
}
else
{
g_waiters_lock.unlock_shared();
}
}
void notify_all()
{
g_waiters_lock.lock_shared();
for (const waiter* ptr : g_waiters)
{
ptr->test();
}
if (g_waiters_to_remove.size() > 10)
{
g_waiters_lock.lock_upgrade();
remove_old_waiters();
g_waiters_lock.unlock();
}
else
{
g_waiters_lock.unlock_shared();
}
}
void _page_map(u32 addr, u32 size, u8 flags)
@@ -369,8 +369,8 @@ namespace vm
const u8 flags_both = flags_set & flags_clear;
flags_test |= page_allocated;
flags_set &= ~flags_both;
flags_test |= page_allocated;
flags_set &= ~flags_both;
flags_clear &= ~flags_both;
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
@@ -736,7 +736,7 @@ namespace vm
{
writer_lock lock(0);
for (auto it = g_locations.begin(); it != g_locations.end(); ++it)
for (auto it = g_locations.begin(); it != g_locations.end(); it++)
{
if (*it && (*it)->addr == addr)
{
@@ -835,7 +835,7 @@ void fmt_class_string<vm::_ptr_base<const char>>::format(std::string& out, u64 a
out += u8"";
for (vm::_ptr_base<const volatile char> ptr = vm::cast(arg);; ++ptr)
for (vm::_ptr_base<const volatile char> ptr = vm::cast(arg);; ptr++)
{
if (!vm::check_addr(ptr.addr()))
{
+8 -51
View File
@@ -1,8 +1,8 @@
#pragma once
#include <map>
#include <functional>
#include <memory>
#include <atomic>
class named_thread;
class cpu_thread;
@@ -42,9 +42,9 @@ namespace vm
{
named_thread* owner;
u32 addr;
u32 size;
u64 stamp;
const void* data;
static const u32 size = 128; // Always 128 currently
waiter() = default;
@@ -53,7 +53,7 @@ namespace vm
void init();
void test() const;
void remove();
~waiter();
};
// Address type
@@ -90,64 +90,21 @@ namespace vm
struct writer_lock final
{
bool locked;
const bool locked;
writer_lock(const writer_lock&) = delete;
writer_lock(int full = 1);
writer_lock(const try_to_lock_t&);
void unlock();
~writer_lock();
explicit operator bool() const { return locked; }
};
// Reservations (lock lines) in a single memory page
using reservation_info = std::array<std::atomic<u64>, 4096 / 128>;
// Get reservation status for further atomic update: last update timestamp
u64 reservation_acquire(u32 addr, u32 size);
// Page information
struct memory_page
{
// Reservations
atomic_t<reservation_info*> reservations;
//atomic_t<u32> waiters;
// Memory flags
atomic_t<u8> flags;
// Access reservation info
FORCE_INLINE std::atomic<u64>& operator [](const u32 addr)
{
auto ptr = reservations.load();
if (!ptr)
{
ptr = new reservation_info();
// Opportunistic memory allocation
if (const auto old_ptr = reservations.compare_and_swap(nullptr, ptr))
{
delete ptr;
ptr = old_ptr;
}
}
return (*ptr)[(addr & 0xfff) >> 7];
}
};
// Memory pages
extern std::array<memory_page, 0x100000000 / 4096> g_pages;
FORCE_INLINE u64 reservation_acquire(u32 addr, u32 _size)
{
// Access reservation info: stamp and the lock bit
return g_pages[addr >> 12][addr].load(std::memory_order_acquire);
}
FORCE_INLINE void reservation_update(u32 addr, u32 _size)
{
// Update reservation info with new timestamp (unsafe, assume allocated)
(*g_pages[addr >> 12].reservations)[(addr & 0xfff) >> 7].store(__rdtsc(), std::memory_order_release);
}
// End atomic update
void reservation_update(u32 addr, u32 size);
// Check and notify memory changes at address
void notify(u32 addr, u32 size);
+3 -3
View File
@@ -532,7 +532,7 @@ std::tuple<T, T, u32> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::spa
verify(HERE), (dst.size_bytes() >= src.size_bytes());
u32 dst_idx = -1;
u32 dst_idx = 0;
for (T index : src)
{
if (is_primitive_restart_enabled && index == primitive_restart_index)
@@ -549,9 +549,9 @@ std::tuple<T, T, u32> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::spa
min_index = std::min(min_index, index);
}
dst[++dst_idx] = index;
dst[dst_idx++] = index;
}
return std::make_tuple(min_index, max_index, dst_idx + 1);
return std::make_tuple(min_index, max_index, dst_idx);
}
template<typename T>
@@ -111,7 +111,7 @@ void FragmentProgramDecompiler::SetDst(std::string code, bool append_mask)
}
u32 reg_index = dst.fp16 ? dst.dest_reg >> 1 : dst.dest_reg;
temp_registers[reg_index].tag(dst.dest_reg, !!dst.fp16, dst.mask_x, dst.mask_y, dst.mask_z, dst.mask_w);
temp_registers[reg_index].tag(dst.dest_reg, !!dst.fp16);
}
void FragmentProgramDecompiler::AddFlowOp(std::string code)
@@ -283,15 +283,14 @@ std::string FragmentProgramDecompiler::Format(const std::string& code, bool igno
{ "$_i", [this]() -> std::string {return std::to_string(dst.tex_num);} },
{ "$m", std::bind(std::mem_fn(&FragmentProgramDecompiler::GetMask), this) },
{ "$ifcond ", [this]() -> std::string
{
const std::string& cond = GetCond();
if (cond == "true") return "";
return "if(" + cond + ") ";
}
{
const std::string& cond = GetCond();
if (cond == "true") return "";
return "if(" + cond + ") ";
}
},
{ "$cond", std::bind(std::mem_fn(&FragmentProgramDecompiler::GetCond), this) },
{ "$_c", std::bind(std::mem_fn(&FragmentProgramDecompiler::AddConst), this) },
{ "$float4", [this]() -> std::string { return getFloatTypeName(4); } }
{ "$_c", std::bind(std::mem_fn(&FragmentProgramDecompiler::AddConst), this) }
};
if (!ignore_redirects)
@@ -408,13 +407,20 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
dst.opcode == RSX_FP_OPCODE_UPB ||
dst.opcode == RSX_FP_OPCODE_UPG)
{
//TODO: Implement aliased gather for half floats
bool xy_read = false;
bool zw_read = false;
if (src.swizzle_x < 2 || src.swizzle_y < 2 || src.swizzle_z < 2 || src.swizzle_w < 2)
xy_read = true;
if (src.swizzle_x > 1 || src.swizzle_y > 1 || src.swizzle_z > 1 || src.swizzle_w > 1)
zw_read = true;
auto &reg = temp_registers[src.tmp_reg_index];
if (reg.requires_gather(src.swizzle_x))
if (reg.requires_gather(xy_read, zw_read))
{
properties.has_gather_op = true;
AddReg(src.tmp_reg_index, src.fp16);
ret = getFloatTypeName(4) + reg.gather_r();
break;
AddCode(reg.gather_r());
}
}
}
@@ -24,41 +24,25 @@ class FragmentProgramDecompiler
bool aliased_r0 = false;
bool aliased_h0 = false;
bool aliased_h1 = false;
bool last_write_half[4] = { false, false, false, false };
bool last_write_half = false;
u32 real_index = UINT32_MAX;
void tag(u32 index, bool half_register, bool x, bool y, bool z, bool w)
void tag(u32 index, bool half_register)
{
if (half_register)
{
last_write_half = true;
if (index & 1)
{
if (x) last_write_half[2] = true;
if (y) last_write_half[2] = true;
if (z) last_write_half[3] = true;
if (w) last_write_half[3] = true;
aliased_h1 = true;
}
else
{
if (x) last_write_half[0] = true;
if (y) last_write_half[0] = true;
if (z) last_write_half[1] = true;
if (w) last_write_half[1] = true;
aliased_h0 = true;
}
}
else
{
if (x) last_write_half[0] = false;
if (y) last_write_half[1] = false;
if (z) last_write_half[2] = false;
if (w) last_write_half[3] = false;
aliased_r0 = true;
last_write_half = false;
}
if (real_index == UINT32_MAX)
@@ -70,19 +54,12 @@ class FragmentProgramDecompiler
}
}
bool requires_gather(u8 channel) const
bool requires_gather(bool xy, bool zw) const
{
//Data fetched from the single precision register requires merging of the two half registers
verify(HERE), channel < 4;
if (aliased_h0 && channel < 2)
{
return last_write_half[channel];
}
if (aliased_h1 && channel > 1)
{
return last_write_half[channel];
}
//TODO: Check individual swizzle channels
if ((aliased_h0 && xy) || (aliased_h1 && zw))
return last_write_half;
return false;
}
@@ -90,7 +67,7 @@ class FragmentProgramDecompiler
bool requires_split(u32 /*index*/) const
{
//Data fetched from any of the two half registers requires sync with the full register
if (!(last_write_half[0] || last_write_half[1]) && aliased_r0)
if (!last_write_half && aliased_r0)
{
//r0 has been written to
//TODO: Check for specific elements in real32 register
@@ -108,12 +85,15 @@ class FragmentProgramDecompiler
std::string ret = "//Invalid gather";
if (aliased_h0 && aliased_h1)
ret = "(gather(" + h0 + ", " + h1 + "))";
ret = reg + " = gather(" + h0 + ", " + h1 + ");";
else if (aliased_h0)
ret = "(gather(" + h0 + "), " + reg + ".zw)";
ret = reg + ".xy = gather(" + h0 + ");";
else if (aliased_h1)
ret = "(" + reg + ".xy, gather(" + h1 + "))";
ret = reg + ".zw = gather(" + h1 + ");";
last_write_half = false;
aliased_h0 = false;
aliased_h1 = false;
return ret;
}
};
+2 -10
View File
@@ -78,7 +78,6 @@ namespace program_hash_util
* - static void recompile_fragment_program(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID);
* - static void recompile_vertex_program(RSXVertexProgram *RSXVP, VertexProgramData& vertexProgramData, size_t ID);
* - static PipelineData build_program(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData);
* - static void validate_pipeline_properties(const VertexProgramData &vertexProgramData, const FragmentProgramData &fragmentProgramData, PipelineProperties& props);
*/
template<typename backend_traits>
class program_state_cache
@@ -262,7 +261,7 @@ public:
pipeline_storage_type& getGraphicPipelineState(
const RSXVertexProgram& vertexShader,
const RSXFragmentProgram& fragmentShader,
pipeline_properties& pipelineProperties,
const pipeline_properties& pipelineProperties,
Args&& ...args
)
{
@@ -274,7 +273,6 @@ public:
bool already_existing_fragment_program = std::get<1>(fp_search);
bool already_existing_vertex_program = std::get<1>(vp_search);
backend_traits::validate_pipeline_properties(vertex_program, fragment_program, pipelineProperties);
pipeline_key key = { vertex_program.id, fragment_program.id, pipelineProperties };
if (already_existing_fragment_program && already_existing_vertex_program)
@@ -307,7 +305,7 @@ public:
return 0;
}
void fill_fragment_constants_buffer(gsl::span<f32, gsl::dynamic_range> dst_buffer, const RSXFragmentProgram &fragment_program, bool sanitize = false) const
void fill_fragment_constants_buffer(gsl::span<f32, gsl::dynamic_range> dst_buffer, const RSXFragmentProgram &fragment_program) const
{
const auto I = m_fragment_shader_cache.find(fragment_program);
if (I == m_fragment_shader_cache.end())
@@ -347,12 +345,6 @@ public:
}
}
}
else if (sanitize)
{
//Lower NaNs to 0
const auto mask = _mm_cmpunord_ps((__m128&)shuffled_vector, _mm_set1_ps(1.f));
_mm_stream_si128((__m128i*)dst, (__m128i&)_mm_andnot_ps(mask, (__m128&)shuffled_vector));
}
else
{
_mm_stream_si128((__m128i*)dst, shuffled_vector);
@@ -131,9 +131,4 @@ public:
else
fmt::throw_exception("m_put_pos == m_get_pos!" HERE);
}
size_t size() const
{
return m_size;
}
};
+1 -19
View File
@@ -370,7 +370,6 @@ namespace rsx
virtual void set_up_remap_vector(section_storage_type& section, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
virtual void insert_texture_barrier(commandbuffer_type&, image_storage_type* tex) = 0;
virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, u32 gcm_format, u16 size, const std::array<image_resource_type, 6>& sources) = 0;
virtual bool render_target_format_is_compatible(image_storage_type* tex, u32 gcm_format) = 0;
constexpr u32 get_block_size() const { return 0x1000000; }
inline u32 get_block_address(u32 address) const { return (address & ~0xFFFFFF); }
@@ -1386,12 +1385,6 @@ namespace rsx
}
}
if (!requires_processing)
{
//Check if we need to do anything about the formats
requires_processing = !render_target_format_is_compatible(texptr, format);
}
if (requires_processing)
{
const auto w = rsx::apply_resolution_scale(internal_width, true);
@@ -1627,24 +1620,13 @@ namespace rsx
auto subresources_layout = get_subresources_layout(tex);
auto remap_vector = tex.decoded_remap();
bool is_depth_format = false;
switch (format)
{
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
is_depth_format = true;
break;
}
//Invalidate with writing=false, discard=false, rebuild=false, native_flush=true
invalidate_range_impl_base(texaddr, tex_size, false, false, false, true, std::forward<Args>(extras)...);
m_texture_memory_in_use += (tex_pitch * tex_height);
return{ upload_image_from_cpu(cmd, texaddr, tex_width, tex_height, depth, tex.get_exact_mipmap_count(), tex_pitch, format,
texture_upload_context::shader_read, subresources_layout, extended_dimension, is_swizzled, remap_vector)->get_raw_view(),
texture_upload_context::shader_read, is_depth_format, scale_x, scale_y, extended_dimension };
texture_upload_context::shader_read, false, scale_x, scale_y, extended_dimension };
}
template <typename surface_store_type, typename blitter_type, typename ...Args>
-5
View File
@@ -145,11 +145,6 @@ struct D3D12Traits
vertexProgramData.id = (u32)ID;
}
static
void validate_pipeline_properties(const vertex_program_type&, const fragment_program_type&, pipeline_properties&)
{
}
static
pipeline_storage_type build_pipeline(
const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData, const pipeline_properties &pipelineProperties,
+17 -14
View File
@@ -736,16 +736,14 @@ void GLGSRender::on_init_thread()
m_index_ring_buffer.reset(new gl::ring_buffer());
}
m_attrib_ring_buffer->create(gl::buffer::target::texture, 256 * 0x100000);
m_index_ring_buffer->create(gl::buffer::target::element_array, 64 * 0x100000);
m_transform_constants_buffer->create(gl::buffer::target::uniform, 64 * 0x100000);
m_fragment_constants_buffer->create(gl::buffer::target::uniform, 16 * 0x100000);
m_vertex_state_buffer->create(gl::buffer::target::uniform, 16 * 0x100000);
m_attrib_ring_buffer->create(gl::buffer::target::texture, std::min<GLsizeiptr>(m_max_texbuffer_size, 256 * 0x100000));
m_index_ring_buffer->create(gl::buffer::target::element_array, std::min<GLsizeiptr>(m_max_texbuffer_size, 64 * 0x100000));
m_transform_constants_buffer->create(gl::buffer::target::uniform, std::min<GLsizeiptr>(m_max_texbuffer_size, 16 * 0x100000));
m_fragment_constants_buffer->create(gl::buffer::target::uniform, std::min<GLsizeiptr>(m_max_texbuffer_size, 16 * 0x100000));
m_vertex_state_buffer->create(gl::buffer::target::uniform, std::min<GLsizeiptr>(m_max_texbuffer_size, 16 * 0x100000));
m_persistent_stream_view.update(m_attrib_ring_buffer.get(), 0, m_max_texbuffer_size);
m_volatile_stream_view.update(m_attrib_ring_buffer.get(), 0, m_max_texbuffer_size);
m_gl_persistent_stream_buffer.copy_from(m_persistent_stream_view);
m_gl_volatile_stream_buffer.copy_from(m_volatile_stream_view);
m_gl_persistent_stream_buffer.copy_from(*m_attrib_ring_buffer, GL_R8UI, 0, (u32)m_attrib_ring_buffer->size());
m_gl_volatile_stream_buffer.copy_from(*m_attrib_ring_buffer, GL_R8UI, 0, (u32)m_attrib_ring_buffer->size());
m_vao.element_array_buffer = *m_index_ring_buffer;
@@ -1036,7 +1034,7 @@ bool GLGSRender::check_program_state()
return (rsx::method_registers.shader_program_address() != 0);
}
void GLGSRender::load_program(const gl::vertex_upload_info& upload_info)
void GLGSRender::load_program(const vertex_upload_info& upload_info)
{
get_current_fragment_program(fs_sampler_state);
verify(HERE), current_fragment_program.valid;
@@ -1112,10 +1110,7 @@ void GLGSRender::load_program(const gl::vertex_upload_info& upload_info)
buf = static_cast<u8*>(mapping.first);
fragment_constants_offset = mapping.second;
if (fragment_constants_size)
{
m_prog_buffer.fill_fragment_constants_buffer({ reinterpret_cast<float*>(buf), gsl::narrow<int>(fragment_constants_size) },
fragment_program, gl::get_driver_caps().vendor_NVIDIA);
}
m_prog_buffer.fill_fragment_constants_buffer({ reinterpret_cast<float*>(buf), gsl::narrow<int>(fragment_constants_size) }, fragment_program);
// Fragment state
fill_fragment_state_buffer(buf+fragment_constants_size, fragment_program);
@@ -1404,6 +1399,14 @@ void GLGSRender::flip(int buffer)
m_textures_upload_time = 0;
}
u64 GLGSRender::timestamp() const
{
GLint64 result;
glGetInteger64v(GL_TIMESTAMP, &result);
return result;
}
bool GLGSRender::on_access_violation(u32 address, bool is_writing)
{
bool can_flush = (std::this_thread::get_id() == m_thread_id);
+14 -15
View File
@@ -21,16 +21,6 @@ namespace gl
using null_vertex_cache = vertex_cache;
using shader_cache = rsx::shaders_cache<void*, GLProgramBuffer>;
struct vertex_upload_info
{
u32 vertex_draw_count;
u32 allocated_vertex_count;
u32 vertex_index_base;
u32 persistent_mapping_offset;
u32 volatile_mapping_offset;
std::optional<std::tuple<GLenum, u32> > index_info;
};
}
struct work_item
@@ -98,7 +88,7 @@ struct driver_state
return !!test;
}
inline bool test_property(GLenum property, u32 test) const
const bool test_property(GLenum property, u32 test) const
{
auto found = properties.find(property);
if (found == properties.end())
@@ -265,6 +255,16 @@ struct driver_state
}
};
struct vertex_upload_info
{
u32 vertex_draw_count;
u32 allocated_vertex_count;
u32 vertex_index_base;
u32 persistent_mapping_offset;
u32 volatile_mapping_offset;
std::optional<std::tuple<GLenum, u32> > index_info;
};
class GLGSRender : public GSRender
{
private:
@@ -279,8 +279,6 @@ private:
gl::texture_cache m_gl_texture_cache;
gl::buffer_view m_persistent_stream_view;
gl::buffer_view m_volatile_stream_view;
gl::texture m_gl_persistent_stream_buffer;
gl::texture m_gl_volatile_stream_buffer;
@@ -342,14 +340,14 @@ private:
driver_state gl_state;
// Return element to draw and in case of indexed draw index type and offset in index buffer
gl::vertex_upload_info set_vertex_buffer();
vertex_upload_info set_vertex_buffer();
rsx::vertex_input_layout m_vertex_layout = {};
void clear_surface(u32 arg);
void init_buffers(rsx::framebuffer_creation_context context, bool skip_reading = false);
bool check_program_state();
void load_program(const gl::vertex_upload_info& upload_info);
void load_program(const vertex_upload_info& upload_info);
void update_draw_state();
@@ -376,6 +374,7 @@ protected:
void on_exit() override;
bool do_method(u32 id, u32 arg) override;
void flip(int buffer) override;
u64 timestamp() const override;
void do_local_task(bool idle) override;
+25 -90
View File
@@ -85,9 +85,8 @@ namespace gl
bool ARB_texture_barrier_supported = false;
bool NV_texture_barrier_supported = false;
bool initialized = false;
bool vendor_INTEL = false; //has broken GLSL compiler
bool vendor_AMD = false; //has broken ARB_multidraw
bool vendor_NVIDIA = false; //has NaN poisoning issues
bool vendor_INTEL = false;
bool vendor_AMD = false;
void initialize()
{
@@ -105,35 +104,35 @@ namespace gl
if (ext_name == "GL_ARB_shader_draw_parameters")
{
ARB_shader_draw_parameters_supported = true;
find_count--;
find_count --;
continue;
}
if (ext_name == "GL_EXT_direct_state_access")
{
EXT_dsa_supported = true;
find_count--;
find_count --;
continue;
}
if (ext_name == "GL_ARB_direct_state_access")
{
ARB_dsa_supported = true;
find_count--;
find_count --;
continue;
}
if (ext_name == "GL_ARB_buffer_storage")
{
ARB_buffer_storage_supported = true;
find_count--;
find_count --;
continue;
}
if (ext_name == "GL_ARB_texture_buffer_object")
{
ARB_texture_buffer_supported = true;
find_count--;
find_count --;
continue;
}
@@ -196,10 +195,6 @@ namespace gl
if (!EXT_dsa_supported && glGetTextureImageEXT && glTextureBufferRangeEXT)
EXT_dsa_supported = true;
}
else if (vendor_string.find("nvidia") != std::string::npos)
{
vendor_NVIDIA = true;
}
#ifdef _WIN32
else if (vendor_string.find("amd") != std::string::npos || vendor_string.find("ati") != std::string::npos)
{
@@ -869,7 +864,7 @@ namespace gl
buffer::create();
glBindBuffer((GLenum)m_target, m_id);
glBufferStorage((GLenum)m_target, size, data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
glBufferStorage((GLenum)m_target, size, data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_CLIENT_STORAGE_BIT | GL_MAP_COHERENT_BIT);
m_memory_mapping = glMapBufferRange((GLenum)m_target, 0, size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
verify(HERE), m_memory_mapping != nullptr;
@@ -891,19 +886,15 @@ namespace gl
if ((offset + alloc_size) > m_size)
{
if (!m_fence.is_empty())
{
m_fence.wait_for_signal();
}
else
{
LOG_ERROR(RSX, "OOM Error: Ring buffer was likely being used without notify() being called");
glFinish();
}
m_data_loc = 0;
offset = 0;
}
if (!m_data_loc)
m_fence.reset();
//Align data loc to 256; allows some "guard" region so we dont trample our own data inadvertently
m_data_loc = align(offset + alloc_size, 256);
return std::make_pair(((char*)m_memory_mapping) + offset, offset);
@@ -937,8 +928,7 @@ namespace gl
//Notification of a draw command
virtual void notify()
{
//Insert fence about 25% into the buffer
if (m_fence.is_empty() && (m_data_loc > (m_size >> 2)))
if (m_fence.is_empty())
m_fence.reset();
}
};
@@ -1056,69 +1046,6 @@ namespace gl
void notify() override {}
};
class buffer_view
{
buffer* m_buffer = nullptr;
u32 m_offset = 0;
u32 m_range = 0;
GLenum m_format = GL_R8UI;
public:
buffer_view(buffer *_buffer, u32 offset, u32 range, GLenum format = GL_R8UI)
: m_buffer(_buffer), m_offset(offset), m_range(range), m_format(format)
{}
buffer_view()
{}
void update(buffer *_buffer, u32 offset, u32 range, GLenum format = GL_R8UI)
{
m_buffer = _buffer;
m_offset = offset;
m_range = range;
m_format = format;
}
u32 offset() const
{
return m_offset;
}
u32 range() const
{
return m_range;
}
u32 format() const
{
return m_format;
}
buffer* buffer() const
{
return m_buffer;
}
bool in_range(u32 address, u32 size, u32& new_offset) const
{
if (address < m_offset)
return false;
const u32 _offset = address - m_offset;
if (m_range < _offset)
return false;
const auto remaining = m_range - _offset;
if (size <= remaining)
{
new_offset = _offset;
return true;
}
return false;
}
};
class vao
{
template<buffer::target BindId, uint GetStateId>
@@ -1754,11 +1681,6 @@ namespace gl
__glcheck glTextureBufferRange(id(), gl_format_type, buf.id(), offset, length);
}
void copy_from(buffer_view &view)
{
copy_from(*view.buffer(), view.format(), view.offset(), view.range());
}
void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings)
{
buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf);
@@ -2843,4 +2765,17 @@ namespace gl
set_id(0);
}
};
class buffer_view : public buffer
{
public:
buffer_view(GLuint id) : buffer(id)
{
}
~buffer_view()
{
set_id(0);
}
};
}
-5
View File
@@ -24,11 +24,6 @@ struct GLTraits
vertexProgramData.Compile();
}
static
void validate_pipeline_properties(const vertex_program_type&, const fragment_program_type&, pipeline_properties&)
{
}
static
pipeline_storage_type build_pipeline(const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData, const pipeline_properties&)
{
-29
View File
@@ -947,35 +947,6 @@ namespace gl
glTextureBarrierNV();
}
bool render_target_format_is_compatible(gl::texture* tex, u32 gcm_format) override
{
if (auto as_rtt = dynamic_cast<gl::render_target*>(tex))
{
auto ifmt = as_rtt->get_compatible_internal_format();
switch (gcm_format)
{
default:
//TODO
LOG_TRACE(RSX, "Format incompatibility detected, reporting failure to force data copy (GL_INTERNAL_FORMAT=0x%X, GCM_FORMAT=0x%X)", (u32)ifmt, gcm_format);
return false;
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
return (ifmt == gl::texture::internal_format::rgba16f);
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return (ifmt == gl::texture::internal_format::rgba32f);
case CELL_GCM_TEXTURE_X32_FLOAT:
return (ifmt == gl::texture::internal_format::r32f);
case CELL_GCM_TEXTURE_R5G6B5:
return (ifmt == gl::texture::internal_format::r5g6b5);
case CELL_GCM_TEXTURE_DEPTH24_D8:
return (ifmt == gl::texture::internal_format::depth24_stencil8 || ifmt == gl::texture::internal_format::depth32f_stencil8);
case CELL_GCM_TEXTURE_A8R8G8B8:
return (ifmt == gl::texture::internal_format::rgba8 || ifmt == gl::texture::internal_format::depth24_stencil8 || ifmt == gl::texture::internal_format::depth32f_stencil8);
}
}
fmt::throw_exception("Format comparison for non-rendertargets is not implemented" HERE);
}
public:
texture_cache() {}
+2 -22
View File
@@ -180,7 +180,7 @@ namespace
};
}
gl::vertex_upload_info GLGSRender::set_vertex_buffer()
vertex_upload_info GLGSRender::set_vertex_buffer()
{
std::chrono::time_point<steady_clock> then = steady_clock::now();
@@ -196,7 +196,7 @@ gl::vertex_upload_info GLGSRender::set_vertex_buffer()
auto required = calculate_memory_requirements(m_vertex_layout, vertex_count);
std::pair<void*, u32> persistent_mapping = {}, volatile_mapping = {};
gl::vertex_upload_info upload_info = { result.vertex_draw_count, result.allocated_vertex_count, result.vertex_index_base, 0u, 0u, result.index_info };
vertex_upload_info upload_info = { result.vertex_draw_count, result.allocated_vertex_count, result.vertex_index_base, 0u, 0u, result.index_info };
if (required.first > 0)
{
@@ -233,32 +233,12 @@ gl::vertex_upload_info GLGSRender::set_vertex_buffer()
m_vertex_cache->store_range(storage_address, GL_R8UI, required.first, persistent_mapping.second);
}
}
if (!m_persistent_stream_view.in_range(upload_info.persistent_mapping_offset, required.first, upload_info.persistent_mapping_offset))
{
const size_t view_size = ((upload_info.persistent_mapping_offset + m_max_texbuffer_size) > m_attrib_ring_buffer->size()) ?
(m_attrib_ring_buffer->size() - upload_info.persistent_mapping_offset) : m_max_texbuffer_size;
m_persistent_stream_view.update(m_attrib_ring_buffer.get(), upload_info.persistent_mapping_offset, (u32)view_size);
m_gl_persistent_stream_buffer.copy_from(m_persistent_stream_view);
upload_info.persistent_mapping_offset = 0;
}
}
if (required.second > 0)
{
volatile_mapping = m_attrib_ring_buffer->alloc_from_heap(required.second, m_min_texbuffer_alignment);
upload_info.volatile_mapping_offset = volatile_mapping.second;
if (!m_volatile_stream_view.in_range(upload_info.volatile_mapping_offset, required.second, upload_info.volatile_mapping_offset))
{
const size_t view_size = ((upload_info.volatile_mapping_offset + m_max_texbuffer_size) > m_attrib_ring_buffer->size()) ?
(m_attrib_ring_buffer->size() - upload_info.volatile_mapping_offset) : m_max_texbuffer_size;
m_volatile_stream_view.update(m_attrib_ring_buffer.get(), upload_info.volatile_mapping_offset, (u32)view_size);
m_gl_volatile_stream_buffer.copy_from(m_volatile_stream_view);
upload_info.volatile_mapping_offset = 0;
}
}
//Write all the data
-3
View File
@@ -1257,7 +1257,6 @@ namespace rsx
if (state.current_draw_clause.command == rsx::draw_command::inlined_array)
{
vertex_input_layout result = {};
result.interleaved_blocks.reserve(8);
interleaved_range_info info = {};
info.interleaved = true;
@@ -1282,8 +1281,6 @@ namespace rsx
const u32 frequency_divider_mask = rsx::method_registers.frequency_divider_operation_mask();
vertex_input_layout result = {};
result.interleaved_blocks.reserve(8);
result.referenced_registers.reserve(4);
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
{
-3
View File
@@ -96,10 +96,7 @@ void VKFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
for (int i = 0; i < sizeof(table) / sizeof(*table); ++i)
{
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", table[i].second))
{
OS << "layout(location=" << std::to_string(output_index++) << ") " << "out vec4 " << table[i].first << ";\n";
vk_prog->output_color_masks[i] = UINT32_MAX;
}
}
}
-2
View File
@@ -52,8 +52,6 @@ public:
std::string shader;
std::vector<size_t> FragmentConstantOffsetCache;
std::array<u32, 4> output_color_masks{ {} };
std::vector<vk::glsl::program_input> uniforms;
void SetInputs(std::vector<vk::glsl::program_input>& uniforms);
/**
+31 -23
View File
@@ -666,9 +666,6 @@ VKGSRender::~VKGSRender()
vk::finalize_compiler_context();
m_prog_buffer->clear();
m_persistent_attribute_storage.reset();
m_volatile_attribute_storage.reset();
//Global resources
vk::destroy_global_resources();
@@ -1129,8 +1126,22 @@ void VKGSRender::end()
if (replace)
{
fs_sampler_handles[i] = std::make_unique<vk::sampler>(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode);
for (auto &sampler : m_current_frame->samplers_to_clean)
{
if (sampler->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode))
{
fs_sampler_handles[i] = std::move(sampler);
replace = false;
break;
}
}
if (replace)
{
fs_sampler_handles[i] = std::make_unique<vk::sampler>(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode);
}
}
}
else
@@ -1174,6 +1185,7 @@ void VKGSRender::end()
if (replace)
{
//This is unlikely, there is no need to check the dirty pool
vs_sampler_handles[i] = std::make_unique<vk::sampler>(
*m_device,
VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
@@ -1197,12 +1209,10 @@ void VKGSRender::end()
//Load program
std::chrono::time_point<steady_clock> program_start = textures_end;
load_program(upload_info);
load_program(std::get<2>(upload_info), std::get<3>(upload_info));
VkBufferView persistent_buffer = m_persistent_attribute_storage ? m_persistent_attribute_storage->value : null_buffer_view->value;
VkBufferView volatile_buffer = m_volatile_attribute_storage ? m_volatile_attribute_storage->value : null_buffer_view->value;
m_program->bind_uniform(persistent_buffer, "persistent_input_stream", m_current_frame->descriptor_set);
m_program->bind_uniform(volatile_buffer, "volatile_input_stream", m_current_frame->descriptor_set);
m_program->bind_uniform(m_persistent_attribute_storage, "persistent_input_stream", m_current_frame->descriptor_set);
m_program->bind_uniform(m_volatile_attribute_storage, "volatile_input_stream", m_current_frame->descriptor_set);
std::chrono::time_point<steady_clock> program_stop = steady_clock::now();
m_setup_time += std::chrono::duration_cast<std::chrono::microseconds>(program_stop - program_start).count();
@@ -1435,6 +1445,8 @@ void VKGSRender::end()
vkCmdClearAttachments(*m_current_command_buffer, static_cast<u32>(buffers_to_clear.size()), buffers_to_clear.data(), 1, &clear_rect);
}
std::optional<std::tuple<VkDeviceSize, VkIndexType> > index_info = std::get<4>(upload_info);
bool primitive_emulated = false;
vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, primitive_emulated);
@@ -1449,11 +1461,12 @@ void VKGSRender::end()
m_occlusion_map[m_active_query_info->driver_handle].command_buffer_to_wait = m_current_command_buffer;
}
if (!upload_info.index_info)
if (!index_info)
{
if (single_draw)
{
vkCmdDraw(*m_current_command_buffer, upload_info.vertex_draw_count, 1, 0, 0);
const auto vertex_count = std::get<1>(upload_info);
vkCmdDraw(*m_current_command_buffer, vertex_count, 1, 0, 0);
}
else
{
@@ -1467,10 +1480,10 @@ void VKGSRender::end()
else
{
VkIndexType index_type;
const u32 index_count = upload_info.vertex_draw_count;
u32 index_count = std::get<1>(upload_info);
VkDeviceSize offset;
std::tie(offset, index_type) = upload_info.index_info.value();
std::tie(offset, index_type) = index_info.value();
vkCmdBindIndexBuffer(*m_current_command_buffer, m_index_buffer_ring_info.heap->value, offset, index_type);
if (single_draw)
@@ -2147,7 +2160,7 @@ bool VKGSRender::check_program_status()
return (rsx::method_registers.shader_program_address() != 0);
}
void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
void VKGSRender::load_program(u32 vertex_count, u32 vertex_base)
{
get_current_fragment_program(fs_sampler_state);
verify(HERE), current_fragment_program.valid;
@@ -2330,13 +2343,11 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
fill_scale_offset_data(buf, false);
fill_user_clip_data(buf + 64);
*(reinterpret_cast<u32*>(buf + 128)) = rsx::method_registers.transform_branch_bits();
*(reinterpret_cast<u32*>(buf + 132)) = vertex_info.vertex_index_base;
*(reinterpret_cast<u32*>(buf + 132)) = vertex_base;
*(reinterpret_cast<f32*>(buf + 136)) = rsx::method_registers.point_size();
*(reinterpret_cast<f32*>(buf + 140)) = rsx::method_registers.clip_min();
*(reinterpret_cast<f32*>(buf + 144)) = rsx::method_registers.clip_max();
fill_vertex_layout_state(m_vertex_layout, vertex_info.allocated_vertex_count, reinterpret_cast<s32*>(buf + 160),
vertex_info.persistent_window_offset, vertex_info.volatile_window_offset);
fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast<s32*>(buf + 160));
//Vertex constants
buf = buf + 512;
@@ -2346,10 +2357,7 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
//Fragment constants
buf = buf + 8192;
if (fragment_constants_sz)
{
m_prog_buffer->fill_fragment_constants_buffer({ reinterpret_cast<float*>(buf), ::narrow<int>(fragment_constants_sz) },
fragment_program, vk::sanitize_fp_values());
}
m_prog_buffer->fill_fragment_constants_buffer({ reinterpret_cast<float*>(buf), ::narrow<int>(fragment_constants_sz) }, fragment_program);
fill_fragment_state_buffer(buf + fragment_constants_sz, fragment_program);
+6 -17
View File
@@ -23,24 +23,13 @@ namespace vk
using null_vertex_cache = vertex_cache;
using shader_cache = rsx::shaders_cache<vk::pipeline_props, VKProgramBuffer>;
struct vertex_upload_info
{
VkPrimitiveTopology primitive;
u32 vertex_draw_count;
u32 allocated_vertex_count;
u32 vertex_index_base;
u32 persistent_window_offset;
u32 volatile_window_offset;
std::optional<std::tuple<VkDeviceSize, VkIndexType>> index_info;
};
}
//Heap allocation sizes in MB
//NOTE: Texture uploads can be huge, upto 16MB for a single texture (4096x4096px)
#define VK_ATTRIB_RING_BUFFER_SIZE_M 256
#define VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M 256
#define VK_UBO_RING_BUFFER_SIZE_M 128
#define VK_UBO_RING_BUFFER_SIZE_M 64
#define VK_INDEX_RING_BUFFER_SIZE_M 64
#define VK_MAX_ASYNC_CB_COUNT 64
@@ -273,8 +262,8 @@ private:
std::array<std::unique_ptr<vk::sampler>, rsx::limits::fragment_textures_count> fs_sampler_handles;
std::array<std::unique_ptr<vk::sampler>, rsx::limits::vertex_textures_count> vs_sampler_handles;
std::unique_ptr<vk::buffer_view> m_persistent_attribute_storage;
std::unique_ptr<vk::buffer_view> m_volatile_attribute_storage;
VkBufferView m_persistent_attribute_storage;
VkBufferView m_volatile_attribute_storage;
public:
//vk::fbo draw_fbo;
@@ -390,11 +379,11 @@ private:
void check_heap_status();
vk::vertex_upload_info upload_vertex_data();
/// returns primitive topology, index_count, allocated_verts, vertex_base_index, (offset in index buffer, index type)
std::tuple<VkPrimitiveTopology, u32, u32, u32, std::optional<std::tuple<VkDeviceSize, VkIndexType> > > upload_vertex_data();
public:
bool check_program_status();
void load_program(const vk::vertex_upload_info& vertex_info);
void load_program(u32 vertex_count, u32 vertex_base);
void init_buffers(rsx::framebuffer_creation_context context, bool skip_reading = false);
void read_buffers();
void write_buffers();
+2 -16
View File
@@ -14,11 +14,8 @@ namespace vk
VkSampler g_null_sampler = nullptr;
atomic_t<bool> g_cb_no_interrupt_flag { false };
//Driver compatibility workarounds
bool g_drv_no_primitive_restart_flag = false;
bool g_drv_force_32bit_indices = false;
bool g_drv_sanitize_fp_values = false;
atomic_t<bool> g_drv_no_primitive_restart_flag { false };
atomic_t<bool> g_drv_force_32bit_indices{ false };
u64 g_num_processed_frames = 0;
u64 g_num_total_frames = 0;
@@ -315,12 +312,6 @@ namespace vk
g_drv_force_32bit_indices = true;
}
#endif
//Nvidia cards are easily susceptible to NaN poisoning
if (gpu_name.find("NVIDIA") != std::string::npos || gpu_name.find("GeForce") != std::string::npos)
{
g_drv_sanitize_fp_values = true;
}
}
bool emulate_primitive_restart()
@@ -333,11 +324,6 @@ namespace vk
return g_drv_force_32bit_indices;
}
bool sanitize_fp_values()
{
return g_drv_sanitize_fp_values;
}
void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range)
{
//Prepare an image to match the new layout..
-20
View File
@@ -72,7 +72,6 @@ namespace vk
//Compatibility workarounds
bool emulate_primitive_restart();
bool force_32bit_index_buffer();
bool sanitize_fp_values();
VkComponentMapping default_component_map();
VkImageSubresource default_image_subresource();
@@ -617,25 +616,6 @@ namespace vk
buffer_view(const buffer_view&) = delete;
buffer_view(buffer_view&&) = delete;
bool in_range(u32 address, u32 size, u32& offset) const
{
if (address < info.offset)
return false;
const u32 _offset = address - (u32)info.offset;
if (info.range < _offset)
return false;
const auto remaining = info.range - _offset;
if (size <= remaining)
{
offset = _offset;
return true;
}
return false;
}
private:
VkDevice m_device;
};
-10
View File
@@ -95,16 +95,6 @@ struct VKTraits
vertexProgramData.Compile();
}
static
void validate_pipeline_properties(const VKVertexProgram&, const VKFragmentProgram &fp, vk::pipeline_props& properties)
{
//Explicitly disable writing to undefined registers
properties.att_state[0].colorWriteMask &= fp.output_color_masks[0];
properties.att_state[1].colorWriteMask &= fp.output_color_masks[1];
properties.att_state[2].colorWriteMask &= fp.output_color_masks[2];
properties.att_state[3].colorWriteMask &= fp.output_color_masks[3];
}
static
pipeline_storage_type build_pipeline(const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData,
const vk::pipeline_props &pipelineProperties, VkDevice dev, VkPipelineLayout common_pipeline_layout)
-24
View File
@@ -901,30 +901,6 @@ namespace vk
vk::insert_texture_barrier(cmd, tex);
}
bool render_target_format_is_compatible(vk::image* tex, u32 gcm_format) override
{
auto vk_format = tex->info.format;
switch (gcm_format)
{
default:
//TODO
LOG_TRACE(RSX, "Format incompatibility detected, reporting failure to force data copy (VK_FORMAT=0x%X, GCM_FORMAT=0x%X)", (u32)vk_format, gcm_format);
return false;
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
return (vk_format == VK_FORMAT_R16G16B16A16_SFLOAT);
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return (vk_format == VK_FORMAT_R32G32B32A32_SFLOAT);
case CELL_GCM_TEXTURE_X32_FLOAT:
return (vk_format == VK_FORMAT_R32_SFLOAT);
case CELL_GCM_TEXTURE_R5G6B5:
return (vk_format == VK_FORMAT_R5G6B5_UNORM_PACK16);
case CELL_GCM_TEXTURE_DEPTH24_D8:
return (vk_format == VK_FORMAT_D24_UNORM_S8_UINT || vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT);
case CELL_GCM_TEXTURE_A8R8G8B8:
return (vk_format == VK_FORMAT_B8G8R8A8_UNORM || vk_format == VK_FORMAT_D24_UNORM_S8_UINT || vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT);
}
}
public:
struct vk_blit_op_result : public blit_op_result
+24 -33
View File
@@ -253,7 +253,8 @@ namespace
};
}
vk::vertex_upload_info VKGSRender::upload_vertex_data()
std::tuple<VkPrimitiveTopology, u32, u32, u32, std::optional<std::tuple<VkDeviceSize, VkIndexType> > >
VKGSRender::upload_vertex_data()
{
m_vertex_layout = analyse_inputs_interleaved();
@@ -265,9 +266,11 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
//Do actual vertex upload
auto required = calculate_memory_requirements(m_vertex_layout, vertex_count);
u32 persistent_range_base = UINT32_MAX, volatile_range_base = UINT32_MAX;
size_t persistent_offset = UINT64_MAX, volatile_offset = UINT64_MAX;
m_persistent_attribute_storage = VK_NULL_HANDLE;
m_volatile_attribute_storage = VK_NULL_HANDLE;
if (required.first > 0)
{
//Check if cacheable
@@ -284,7 +287,8 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
if (auto cached = m_vertex_cache->find_vertex_range(storage_address, VK_FORMAT_R8_UINT, required.first))
{
in_cache = true;
persistent_range_base = cached->offset_in_heap;
m_current_frame->buffer_views_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device,
m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, cached->offset_in_heap, required.first));
}
else
{
@@ -295,7 +299,8 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
if (!in_cache)
{
persistent_offset = (u32)m_attrib_ring_info.alloc<256>(required.first);
persistent_range_base = (u32)persistent_offset;
m_current_frame->buffer_views_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device,
m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, persistent_offset, required.first));
if (to_store)
{
@@ -303,12 +308,25 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
m_vertex_cache->store_range(storage_address, VK_FORMAT_R8_UINT, required.first, (u32)persistent_offset);
}
}
m_persistent_attribute_storage = m_current_frame->buffer_views_to_clean.back()->value;
}
else
{
m_persistent_attribute_storage = null_buffer_view->value;
}
if (required.second > 0)
{
volatile_offset = (u32)m_attrib_ring_info.alloc<256>(required.second);
volatile_range_base = (u32)volatile_offset;
m_current_frame->buffer_views_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device,
m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, volatile_offset, required.second));
m_volatile_attribute_storage = m_current_frame->buffer_views_to_clean.back()->value;
}
else
{
m_volatile_attribute_storage = null_buffer_view->value;
}
//Write all the data once if possible
@@ -340,32 +358,5 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
}
}
if (persistent_range_base != UINT32_MAX)
{
if (!m_persistent_attribute_storage || !m_persistent_attribute_storage->in_range(persistent_range_base, required.first, persistent_range_base))
{
if (m_persistent_attribute_storage)
m_current_frame->buffer_views_to_clean.push_back(std::move(m_persistent_attribute_storage));
//View 64M blocks at a time (different drivers will only allow a fixed viewable heap size, 64M should be safe)
const size_t view_size = (persistent_range_base + 0x4000000) > m_attrib_ring_info.size() ? m_attrib_ring_info.size() - persistent_range_base : 0x4000000;
m_persistent_attribute_storage = std::make_unique<vk::buffer_view>(*m_device, m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, persistent_range_base, view_size);
persistent_range_base = 0;
}
}
if (volatile_range_base != UINT32_MAX)
{
if (!m_volatile_attribute_storage || !m_volatile_attribute_storage->in_range(volatile_range_base, required.second, volatile_range_base))
{
if (m_volatile_attribute_storage)
m_current_frame->buffer_views_to_clean.push_back(std::move(m_volatile_attribute_storage));
const size_t view_size = (volatile_range_base + 0x4000000) > m_attrib_ring_info.size() ? m_attrib_ring_info.size() - volatile_range_base : 0x4000000;
m_volatile_attribute_storage = std::make_unique<vk::buffer_view>(*m_device, m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, volatile_range_base, view_size);
volatile_range_base = 0;
}
}
return{ result.native_primitive_type, result.vertex_draw_count, result.allocated_vertex_count, result.vertex_index_base, persistent_range_base, volatile_range_base, result.index_info };
return std::make_tuple(result.native_primitive_type, result.vertex_draw_count, result.allocated_vertex_count, result.vertex_index_base, result.index_info);
}
+31 -24
View File
@@ -21,10 +21,10 @@ void fmt_class_string<frame_limit_type>::format(std::string& out, u64 arg)
switch (value)
{
case frame_limit_type::none: return "Off";
case frame_limit_type::_30: return "30";
case frame_limit_type::_50: return "50";
case frame_limit_type::_59_94: return "59.94";
case frame_limit_type::_50: return "50";
case frame_limit_type::_60: return "60";
case frame_limit_type::_30: return "30";
case frame_limit_type::_auto: return "Auto";
}
@@ -35,7 +35,7 @@ void fmt_class_string<frame_limit_type>::format(std::string& out, u64 arg)
namespace rsx
{
rsx_state method_registers;
std::array<rsx_method_t, 0x10000 / 4> methods{};
void invalid_method(thread* rsx, u32 _reg, u32 arg)
@@ -64,10 +64,10 @@ namespace rsx
{
rsx->sync_point_request = true;
const u32 addr = get_address(method_registers.semaphore_offset_406e(), method_registers.semaphore_context_dma_406e());
if (vm::ps3::read32(addr) == arg) return;
if (vm::read32(addr) == arg) return;
u64 start = get_system_time();
while (vm::ps3::read32(addr) != arg)
while (vm::read32(addr) != arg)
{
// todo: LLE: why does this one keep hanging? is it vsh system semaphore? whats actually pushing this to the command buffer?!
if (addr == 0x40000030)
@@ -116,11 +116,12 @@ namespace rsx
if (addr >> 28 == 0x4)
{
// TODO: check no reservation area instead
vm::ps3::write32(addr, arg);
vm::write32(addr, arg);
return;
}
vm::ps3::write32(addr, arg);
vm::reader_lock lock;
vm::write32(addr, arg);
vm::notify(addr, 4);
}
}
@@ -161,7 +162,7 @@ namespace rsx
{
//
}
auto& sema = vm::ps3::_ref<RsxReports>(rsx->label_addr);
auto& sema = vm::_ref<RsxReports>(rsx->label_addr);
sema.semaphore[index].val = arg;
sema.semaphore[index].pad = 0;
sema.semaphore[index].timestamp = rsx->timestamp();
@@ -176,7 +177,7 @@ namespace rsx
}
u32 val = (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff);
auto& sema = vm::ps3::_ref<RsxReports>(rsx->label_addr);
auto& sema = vm::_ref<RsxReports>(rsx->label_addr);
sema.semaphore[index].val = val;
sema.semaphore[index].pad = 0;
sema.semaphore[index].timestamp = rsx->timestamp();
@@ -351,7 +352,7 @@ namespace rsx
{
rsx::method_registers.current_draw_clause.first_count_commands.resize(0);
rsx::method_registers.current_draw_clause.command = draw_command::none;
rsx::method_registers.current_draw_clause.primitive = rsx::method_registers.primitive_mode();
rsx::method_registers.current_draw_clause.primitive = to_primitive_type(arg);
rsxthr->begin();
return;
}
@@ -415,7 +416,7 @@ namespace rsx
return;
}
vm::ps3::ptr<CellGcmReportData> result = address_ptr;
vm::ptr<CellGcmReportData> result = address_ptr;
switch (type)
{
@@ -483,7 +484,7 @@ namespace rsx
return;
}
vm::ps3::ptr<CellGcmReportData> result = address_ptr;
vm::ptr<CellGcmReportData> result = address_ptr;
rsx->conditional_render_test_failed = (result->value == 0);
}
@@ -552,7 +553,7 @@ namespace rsx
const u32 pixel_offset = (method_registers.blit_engine_output_pitch_nv3062() * y) + (x << 2);
u32 address = get_address(method_registers.blit_engine_output_offset_nv3062() + pixel_offset + index * 4, method_registers.blit_engine_output_location_nv3062());
vm::ps3::write32(address, arg);
vm::write32(address, arg);
}
};
}
@@ -661,7 +662,7 @@ namespace rsx
const tiled_region dst_region = rsx->get_tiled_address(dst_offset + out_offset, dst_dma & 0xf);
u8* pixels_src = src_region.tile ? src_region.ptr + src_region.base : src_region.ptr;
u8* pixels_dst = vm::ps3::_ptr<u8>(get_address(dst_offset + out_offset, dst_dma));
u8* pixels_dst = vm::_ptr<u8>(get_address(dst_offset + out_offset, dst_dma));
if (out_pitch == 0)
{
@@ -693,7 +694,8 @@ namespace rsx
if (convert_w == 0 || convert_h == 0)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN: Invalid dimensions or scaling factor. Request ignored");
LOG_ERROR(RSX, "NV3089_IMAGE_IN: Invalid dimensions or scaling factor. Request ignored (ds_dx=%d, dt_dy=%d)",
method_registers.blit_engine_ds_dx(), method_registers.blit_engine_dt_dy());
return;
}
@@ -788,7 +790,7 @@ namespace rsx
if (method_registers.blit_engine_context_surface() != blit_engine::context_surface::swizzle2d)
{
if (need_convert || need_clip)
{
{
if (need_clip)
{
if (need_convert)
@@ -854,7 +856,7 @@ namespace rsx
pixels_src = temp2.get();
}
// It looks like rsx may ignore the requested swizzle size and just always
// It looks like rsx may ignore the requested swizzle size and just always
// round up to nearest power of 2
/*u8 sw_width_log2 = method_registers.nv309e_sw_width_log2();
u8 sw_height_log2 = method_registers.nv309e_sw_height_log2();
@@ -932,7 +934,7 @@ namespace rsx
LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", in_format, out_format);
}
LOG_NOTICE(RSX, "NV0039_OFFSET_IN: pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x",
LOG_TRACE(RSX, "NV0039_OFFSET_IN: pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x",
in_pitch, out_pitch, line_length, line_count, in_format, out_format, notify);
if (!in_pitch)
@@ -995,10 +997,10 @@ namespace rsx
switch (g_cfg.video.frame_limit)
{
case frame_limit_type::none: limit = 0.; break;
case frame_limit_type::_30: limit = 30.; break;
case frame_limit_type::_50: limit = 50.; break;
case frame_limit_type::_59_94: limit = 59.94; break;
case frame_limit_type::_50: limit = 50.; break;
case frame_limit_type::_60: limit = 60.; break;
case frame_limit_type::_30: limit = 30.; break;
case frame_limit_type::_auto: limit = rsx->fps_limit; break; // TODO
}
@@ -1026,7 +1028,7 @@ namespace rsx
}
}
}
rsx->int_flip_index++;
rsx->current_display_buffer = arg;
rsx->flip(arg);
@@ -1188,6 +1190,11 @@ namespace rsx
registers[reg] = value;
}
bool rsx_state::test(u32 reg, u32 value) const
{
return registers[reg] == value;
}
namespace method_detail
{
template<int Id, int Step, int Count, template<u32> class T, int Index = 0>
@@ -1560,7 +1567,7 @@ namespace rsx
//Some custom GCM methods
methods[GCM_SET_DRIVER_OBJECT] = nullptr;
bind_array<GCM_FLIP_HEAD, 1, 2, nullptr>();
bind_array<GCM_DRIVER_QUEUE, 1, 8, nullptr>();
@@ -1677,8 +1684,8 @@ namespace rsx
// custom methods
bind<GCM_FLIP_COMMAND, flip_command>();
return true;
return true;
}();
}
+1 -1
View File
@@ -96,7 +96,7 @@ void fmt_class_string<video_renderer>::format(std::string& out, u64 arg)
case video_renderer::opengl: return "OpenGL";
case video_renderer::vulkan: return "Vulkan";
#ifdef _MSC_VER
case video_renderer::dx12: return "DirectX 12";
case video_renderer::dx12: return "D3D12";
#endif
}
+6 -6
View File
@@ -127,10 +127,10 @@ enum class video_aspect
enum class frame_limit_type
{
none,
_30,
_50,
_59_94,
_50,
_60,
_30,
_auto,
};
@@ -291,7 +291,7 @@ struct cfg_root : cfg::node
cfg::_int<0, 16> spu_delay_penalty{this, "SPU delay penalty", 3}; //Number of milliseconds to block a thread if a virtual 'core' isn't free
cfg::_bool spu_loop_detection{this, "SPU loop detection", true}; //Try to detect wait loops and trigger thread yield
cfg::_enum<lib_loading_type> lib_loading{this, "Lib loader", lib_loading_type::liblv2only};
cfg::_enum<lib_loading_type> lib_loading{this, "Lib Loader", lib_loading_type::liblv2only};
cfg::_bool hook_functions{this, "Hook static functions"};
cfg::set_entry load_libraries{this, "Load libraries"};
@@ -350,7 +350,7 @@ struct cfg_root : cfg::node
struct node_d3d12 : cfg::node
{
node_d3d12(cfg::node* _this) : cfg::node(_this, "DirectX 12") {}
node_d3d12(cfg::node* _this) : cfg::node(_this, "D3D12") {}
cfg::string adapter{this, "Adapter"};
@@ -375,7 +375,7 @@ struct cfg_root : cfg::node
cfg::_enum<audio_renderer> renderer{this, "Renderer", static_cast<audio_renderer>(1)};
cfg::_bool dump_to_file{this, "Dump to file"};
cfg::_bool convert_to_u16{this, "Convert to 16-bit"};
cfg::_bool convert_to_u16{this, "Convert to 16 bit"};
cfg::_bool downmix_to_2ch{this, "Downmix to Stereo", true};
cfg::_int<2, 128> frames{this, "Buffer Count", 32};
cfg::_int<1, 128> startt{this, "Start Threshold", 1};
@@ -388,7 +388,7 @@ struct cfg_root : cfg::node
cfg::_enum<keyboard_handler> keyboard{this, "Keyboard", keyboard_handler::null};
cfg::_enum<mouse_handler> mouse{this, "Mouse", mouse_handler::basic};
cfg::_enum<pad_handler> pad{this, "Controller", pad_handler::keyboard};
cfg::_enum<pad_handler> pad{this, "Pad", pad_handler::keyboard};
cfg::_enum<camera_handler> camera{this, "Camera", camera_handler::null};
cfg::_enum<fake_camera_type> camera_type{this, "Camera type", fake_camera_type::unknown};
+1 -1
View File
@@ -31,7 +31,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+1 -1
View File
@@ -31,7 +31,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+1 -1
View File
@@ -62,7 +62,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+1 -1
View File
@@ -31,7 +31,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+2 -2
View File
@@ -30,7 +30,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -61,7 +61,7 @@
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>..\3rdparty\zlib;..\llvm\include;..\polly\include;..\llvm_build\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\3rdparty\zlib;..\llvm\include;..\llvm_build\include;</AdditionalIncludeDirectories>
</ClCompile>
<PreBuildEvent>
<Command>%windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd"</Command>
+4 -4
View File
@@ -26,7 +26,7 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<PlatformToolSet>v141</PlatformToolSet>
<PlatformToolSet>v140</PlatformToolSet>
<OutputDirectory>release\</OutputDirectory>
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
<CharacterSet>Unicode</CharacterSet>
@@ -35,7 +35,7 @@
<PrimaryOutput>rpcs3</PrimaryOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'" Label="Configuration">
<PlatformToolSet>v141</PlatformToolSet>
<PlatformToolSet>v140</PlatformToolSet>
<OutputDirectory>release\</OutputDirectory>
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
<CharacterSet>Unicode</CharacterSet>
@@ -44,7 +44,7 @@
<PrimaryOutput>rpcs3</PrimaryOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<PlatformToolSet>v141</PlatformToolSet>
<PlatformToolSet>v140</PlatformToolSet>
<OutputDirectory>debug\</OutputDirectory>
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
<CharacterSet>Unicode</CharacterSet>
@@ -53,7 +53,7 @@
<PrimaryOutput>rpcs3</PrimaryOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'" Label="Configuration">
<PlatformToolSet>v141</PlatformToolSet>
<PlatformToolSet>v140</PlatformToolSet>
<OutputDirectory>debug\</OutputDirectory>
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
<CharacterSet>Unicode</CharacterSet>
+7 -7
View File
@@ -5,7 +5,7 @@ constexpr auto qstr = QString::fromStdString;
auto_pause_settings_dialog::auto_pause_settings_dialog(QWidget *parent) : QDialog(parent)
{
QLabel *description = new QLabel(tr("To use automatic pause: enter the ID(s) of a function or a system call. You must restart your emulated game or application for changed settings to take effect. You can enable/disable this in the settings."), this);
QLabel *description = new QLabel(tr("To use auto pause: enter the ID(s) of a function or a system call.\nRestart of the game is required to apply. You can enable/disable this in the settings."), this);
pauseList = new QTableWidget(this);
pauseList->setColumnCount(2);
@@ -36,7 +36,7 @@ auto_pause_settings_dialog::auto_pause_settings_dialog(QWidget *parent) : QDialo
setLayout(mainLayout);
setMinimumSize(QSize(400, 360));
setWindowTitle(tr("Automatic pause settings"));
setWindowTitle(tr("Auto Pause Manager"));
//Events
connect(pauseList, &QTableWidget::customContextMenuRequested, this, &auto_pause_settings_dialog::ShowContextMenu);
@@ -45,7 +45,7 @@ auto_pause_settings_dialog::auto_pause_settings_dialog(QWidget *parent) : QDialo
connect(saveButton, &QAbstractButton::clicked, [=]
{
SaveEntries();
LOG_SUCCESS(HLE, "Automatic pause: file pause.bin was updated.");
LOG_SUCCESS(HLE, "Auto Pause: File pause.bin was updated.");
});
connect(cancelButton, &QAbstractButton::clicked, this, &QWidget::close);
@@ -124,11 +124,11 @@ void auto_pause_settings_dialog::UpdateList(void)
if (m_entries[i] < 1024)
{
typeItem->setData(Qt::DisplayRole, tr("System call"));
typeItem->setData(Qt::DisplayRole, tr("System Call"));
}
else
{
typeItem->setData(Qt::DisplayRole, tr("Function call"));
typeItem->setData(Qt::DisplayRole, tr("Function Call"));
}
pauseList->setItem(i, 0, callItem);
@@ -206,7 +206,7 @@ AutoPauseConfigDialog::AutoPauseConfigDialog(QWidget* parent, auto_pause_setting
button_ok->setFixedWidth(50);
button_cancel->setFixedWidth(50);
QLabel* description = new QLabel(tr("Specify ID of system call or function call below. You need to use a hexadecimal ID."), this);
QLabel* description = new QLabel(tr("Specify ID of System Call or Function Call below. You need to use a Hexadecimal ID."), this);
description->setWordWrap(true);
m_current_converted = new QLabel(tr("Currently it gets an id of \"Unset\"."), this);
@@ -218,7 +218,7 @@ AutoPauseConfigDialog::AutoPauseConfigDialog(QWidget* parent, auto_pause_setting
m_id->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
m_id->setMaxLength(8);
m_id->setFixedWidth(65);
setWindowTitle("Automatic pause setting: " + m_id->text());
setWindowTitle("Auto Pause Setting: " + m_id->text());
connect(button_cancel, &QAbstractButton::clicked, this, &AutoPauseConfigDialog::OnCancel);
connect(button_ok, &QAbstractButton::clicked, this, &AutoPauseConfigDialog::OnOk);
+1 -1
View File
@@ -22,7 +22,7 @@ inline std::string sstr(const QString& _in) { return _in.toStdString(); }
cg_disasm_window::cg_disasm_window(std::shared_ptr<gui_settings> xSettings): xgui_settings(xSettings)
{
setWindowTitle(tr("Cg disassembler"));
setWindowTitle(tr("Cg Disasm"));
setAttribute(Qt::WA_DeleteOnClose);
setAcceptDrops(true);
setMinimumSize(QSize(200, 150)); // seems fine on win 10
+2 -2
View File
@@ -43,8 +43,8 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> settings, QWidget *
m_breakpoints_list_delete->setShortcutContext(Qt::WidgetShortcut);
m_breakpoints_list->addAction(m_breakpoints_list_delete);
m_go_to_addr = new QPushButton(tr("Go to address"), this);
m_go_to_pc = new QPushButton(tr("Go to PC"), this);
m_go_to_addr = new QPushButton(tr("Go To Address"), this);
m_go_to_pc = new QPushButton(tr("Go To PC"), this);
m_btn_capture = new QPushButton(tr("Capture"), this);
m_btn_step = new QPushButton(tr("Step"), this);
m_btn_run = new QPushButton(Run, this);
+4 -4
View File
@@ -126,7 +126,7 @@ public:
QStringList vulkanAdapters;
QString name_Null = tr("Null");
QString name_Vulkan = tr("Vulkan");
QString name_D3D12 = tr("DirectX 12");
QString name_D3D12 = tr("D3D12[DO NOT USE]");
QString name_OpenGL = tr("OpenGL");
Render_Info D3D12;
Render_Info Vulkan;
@@ -186,7 +186,7 @@ private:
// Core Tab
{ PPUDecoder, { "Core", "PPU Decoder"}},
{ SPUDecoder, { "Core", "SPU Decoder"}},
{ LibLoadOptions, { "Core", "Lib loader"}},
{ LibLoadOptions, { "Core", "Lib Loader"}},
{ HookStaticFuncs, { "Core", "Hook static functions"}},
{ EnableThreadScheduler, { "Core", "Enable thread scheduler"}},
{ LowerSPUThreadPrio, { "Core", "Lower SPU thread priority"}},
@@ -221,13 +221,13 @@ private:
{ AnisotropicFilterOverride,{ "Video", "Anisotropic Filter Override" }},
{ ResolutionScale, { "Video", "Resolution Scale" }},
{ MinimumScalableDimension, { "Video", "Minimum Scalable Dimension" }},
{ D3D12Adapter, { "Video", "DirectX 12", "Adapter"}},
{ D3D12Adapter, { "Video", "D3D12", "Adapter"}},
{ VulkanAdapter, { "Video", "Vulkan", "Adapter"}},
// Audio
{ AudioRenderer, { "Audio", "Renderer"}},
{ DumpToFile, { "Audio", "Dump to file"}},
{ ConvertTo16Bit, { "Audio", "Convert to 16-bit"}},
{ ConvertTo16Bit, { "Audio", "Convert to 16 bit"}},
{ DownmixStereo, { "Audio", "Downmix to Stereo"}},
// Input / Output
+23 -23
View File
@@ -24,7 +24,7 @@ inline std::string sstr(const QString& _in) { return _in.toStdString(); }
inline QSize sizeFromSlider(const int& pos) { return gui::gl_icon_size_min + (gui::gl_icon_size_max - gui::gl_icon_size_min) * (pos / (float)gui::gl_max_slider_pos); }
game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std::shared_ptr<emu_settings> emuSettings, QWidget *parent)
: QDockWidget(tr("Game list"), parent), xgui_settings(guiSettings), xemu_settings(emuSettings)
: QDockWidget(tr("Game List"), parent), xgui_settings(guiSettings), xemu_settings(emuSettings)
{
m_isListLayout = xgui_settings->GetValue(gui::gl_listMode).toBool();
m_icon_size_index = xgui_settings->GetValue(gui::gl_iconSize).toInt();
@@ -87,10 +87,10 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
m_categoryActs->setEnabled(m_isListLayout);
m_modeActList = { new QAction(""), QIcon(":/Icons/list_blue.png"), QIcon(":/Icons/list_gray.png") };
m_modeActList.action->setToolTip(tr("Enable list mode"));
m_modeActList.action->setToolTip(tr("Enable List Mode"));
m_modeActGrid = { new QAction(""), QIcon(":/Icons/grid_blue.png"), QIcon(":/Icons/grid_gray.png") };
m_modeActGrid.action->setToolTip(tr("Enable grid mode"));
m_modeActGrid.action->setToolTip(tr("Enable Grid Mode"));
m_modeActs = new QActionGroup(m_Tool_Bar);
m_modeActs->addAction(m_modeActList.action);
@@ -186,17 +186,17 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
m_Game_Dock->setCentralWidget(m_Central_Widget);
// Actions regarding showing/hiding columns
QAction* showIconColAct = new QAction(tr("Show icons"), this);
QAction* showNameColAct = new QAction(tr("Show names"), this);
QAction* showSerialColAct = new QAction(tr("Show serials"), this);
QAction* showFWColAct = new QAction(tr("Show firmwares"), this);
QAction* showAppVersionColAct = new QAction(tr("Show versions"), this);
QAction* showCategoryColAct = new QAction(tr("Show categories"), this);
QAction* showPathColAct = new QAction(tr("Show paths"), this);
QAction* showResolutionColAct = new QAction(tr("Show supported resolutions"), this);
QAction* showSoundFormatColAct = new QAction(tr("Show sound formats"), this);
QAction* showParentalLevelColAct = new QAction(tr("Show parental levels"), this);
QAction* showCompatibilityAct = new QAction(tr("Show compatibilities"), this);
QAction* showIconColAct = new QAction(tr("Show Icons"), this);
QAction* showNameColAct = new QAction(tr("Show Names"), this);
QAction* showSerialColAct = new QAction(tr("Show Serials"), this);
QAction* showFWColAct = new QAction(tr("Show Firmwares"), this);
QAction* showAppVersionColAct = new QAction(tr("Show Versions"), this);
QAction* showCategoryColAct = new QAction(tr("Show Categories"), this);
QAction* showPathColAct = new QAction(tr("Show Paths"), this);
QAction* showResolutionColAct = new QAction(tr("Show Supported Resolutions"), this);
QAction* showSoundFormatColAct = new QAction(tr("Show Sound Formats"), this);
QAction* showParentalLevelColAct = new QAction(tr("Show Parental Levels"), this);
QAction* showCompatibilityAct = new QAction(tr("Show Compatibilities"), this);
m_columnActs = { showIconColAct, showNameColAct, showSerialColAct, showFWColAct, showAppVersionColAct, showCategoryColAct, showPathColAct,
showResolutionColAct, showSoundFormatColAct, showParentalLevelColAct, showCompatibilityAct };
@@ -670,15 +670,15 @@ void game_list_frame::ShowSpecifiedContextMenu(const QPoint &pos, int row)
QAction* configure = myMenu.addAction(tr("&Configure"));
myMenu.addSeparator();
QAction* removeGame = myMenu.addAction(tr("&Remove"));
QAction* removeConfig = myMenu.addAction(tr("&Remove custom configuration"));
QAction* deleteShadersCache = myMenu.addAction(tr("&Delete shaders cache"));
QAction* deleteLLVMCache = myMenu.addAction(tr("&Delete LLVM cache"));
QAction* removeConfig = myMenu.addAction(tr("&Remove Custom Configuration"));
QAction* deleteShadersCache = myMenu.addAction(tr("&Delete Shaders Cache"));
QAction* deleteLLVMCache = myMenu.addAction(tr("&Delete LLVM Cache"));
myMenu.addSeparator();
QAction* openGameFolder = myMenu.addAction(tr("&Open install folder"));
QAction* openConfig = myMenu.addAction(tr("&Open config folder"));
QAction* openGameFolder = myMenu.addAction(tr("&Open Install Folder"));
QAction* openConfig = myMenu.addAction(tr("&Open Config Folder"));
myMenu.addSeparator();
QAction* checkCompat = myMenu.addAction(tr("&Check game compatibility"));
QAction* downloadCompat = myMenu.addAction(tr("&Download compatibility database"));
QAction* checkCompat = myMenu.addAction(tr("&Check Game Compatibility"));
QAction* downloadCompat = myMenu.addAction(tr("&Download Compatibility Database"));
connect(boot, &QAction::triggered, [=]
{
@@ -717,7 +717,7 @@ void game_list_frame::ShowSpecifiedContextMenu(const QPoint &pos, int row)
connect(deleteLLVMCache, &QAction::triggered, [=]()
{
if (QMessageBox::question(this, tr("Confirm delete"), tr("Delete LLVM cache?")) == QMessageBox::Yes)
if (QMessageBox::question(this, tr("Confirm Delete"), tr("Delete LLVM cache?")) == QMessageBox::Yes)
{
const std::string config_base_dir = fs::get_config_dir() + "data/" + m_game_data[row].info.serial;
@@ -832,7 +832,7 @@ void game_list_frame::RemoveCustomConfiguration(int row)
void game_list_frame::DeleteShadersCache(int row)
{
if (QMessageBox::question(this, tr("Confirm delete"), tr("Delete shaders cache?")) != QMessageBox::Yes)
if (QMessageBox::question(this, tr("Confirm Delete"), tr("Delete shaders cache?")) != QMessageBox::Yes)
return;
const std::string config_base_dir = fs::get_config_dir() + "data/" + m_game_data[row].info.serial;
+1
View File
@@ -69,5 +69,6 @@ void gl_gs_frame::flip(draw_context_t context, bool skip_frame)
//Do not swap buffers if frame skip is active
if (skip_frame) return;
((QOpenGLContext*)context)->makeCurrent(this);
((QOpenGLContext*)context)->swapBuffers(this);
}
+1 -1
View File
@@ -105,7 +105,7 @@ void gs_frame::keyPressEvent(QKeyEvent *keyEvent)
case Qt::Key_R:
if (keyEvent->modifiers() == Qt::ControlModifier && (!Emu.GetBoot().empty())) { Emu.Restart(); return; }
break;
case Qt::Key_F:
case Qt::Key_E:
if (keyEvent->modifiers() == Qt::ControlModifier)
{
if (Emu.IsReady()) { Emu.Run(); return; }
+20 -20
View File
@@ -27,7 +27,7 @@
kernel_explorer::kernel_explorer(QWidget* parent) : QDialog(parent)
{
setWindowTitle(tr("Kernel explorer"));
setWindowTitle(tr("Kernel Explorer"));
setObjectName("kernel_explorer");
setAttribute(Qt::WA_DeleteOnClose);
setMinimumSize(QSize(700, 450));
@@ -74,7 +74,7 @@ void kernel_explorer::Update()
const u32 total_memory_usage = vm_block->used();
QTreeWidgetItem* root = new QTreeWidgetItem();
root->setText(0, qstr(fmt::format("Process, ID = 0x00000001, Total memory usage = 0x%x (%0.2f MB)", total_memory_usage, (float)total_memory_usage / (1024 * 1024))));
root->setText(0, qstr(fmt::format("Process, ID = 0x00000001, Total Memory Usage = 0x%x (%0.2f MB)", total_memory_usage, (float)total_memory_usage / (1024 * 1024))));
m_tree->addTopLevelItem(root);
union name64
@@ -118,21 +118,21 @@ void kernel_explorer::Update()
std::vector<lv2_obj_rec> lv2_types(256);
lv2_types[SYS_MEM_OBJECT] = l_addTreeChild(root, "Memory");
lv2_types[SYS_MUTEX_OBJECT] = l_addTreeChild(root, "Mutexes");
lv2_types[SYS_COND_OBJECT] = l_addTreeChild(root, "Condition variables");
lv2_types[SYS_RWLOCK_OBJECT] = l_addTreeChild(root, "Reader writer locks");
lv2_types[SYS_INTR_TAG_OBJECT] = l_addTreeChild(root, "Interrupt tags");
lv2_types[SYS_INTR_SERVICE_HANDLE_OBJECT] = l_addTreeChild(root, "Interrupt service handles");
lv2_types[SYS_EVENT_QUEUE_OBJECT] = l_addTreeChild(root, "Event queues");
lv2_types[SYS_EVENT_PORT_OBJECT] = l_addTreeChild(root, "Event ports");
lv2_types[SYS_COND_OBJECT] = l_addTreeChild(root, "Condition Variables");
lv2_types[SYS_RWLOCK_OBJECT] = l_addTreeChild(root, "Reader Writer Locks");
lv2_types[SYS_INTR_TAG_OBJECT] = l_addTreeChild(root, "Interrupt Tags");
lv2_types[SYS_INTR_SERVICE_HANDLE_OBJECT] = l_addTreeChild(root, "Interrupt Service Handles");
lv2_types[SYS_EVENT_QUEUE_OBJECT] = l_addTreeChild(root, "Event Queues");
lv2_types[SYS_EVENT_PORT_OBJECT] = l_addTreeChild(root, "Event Ports");
lv2_types[SYS_TRACE_OBJECT] = l_addTreeChild(root, "Traces");
lv2_types[SYS_SPUIMAGE_OBJECT] = l_addTreeChild(root, "SPU Images");
lv2_types[SYS_PRX_OBJECT] = l_addTreeChild(root, "Modules");
lv2_types[SYS_SPUPORT_OBJECT] = l_addTreeChild(root, "SPU Ports");
lv2_types[SYS_LWMUTEX_OBJECT] = l_addTreeChild(root, "Light weight mutexes");
lv2_types[SYS_LWMUTEX_OBJECT] = l_addTreeChild(root, "Light Weight Mutexes");
lv2_types[SYS_TIMER_OBJECT] = l_addTreeChild(root, "Timers");
lv2_types[SYS_SEMAPHORE_OBJECT] = l_addTreeChild(root, "Semaphores");
lv2_types[SYS_LWCOND_OBJECT] = l_addTreeChild(root, "Light weight condition variables");
lv2_types[SYS_EVENT_FLAG_OBJECT] = l_addTreeChild(root, "Event flags");
lv2_types[SYS_LWCOND_OBJECT] = l_addTreeChild(root, "Light Weight Condition Variables");
lv2_types[SYS_EVENT_FLAG_OBJECT] = l_addTreeChild(root, "Event Flags");
idm::select<lv2_obj>([&](u32 id, lv2_obj& obj)
{
@@ -170,26 +170,26 @@ void kernel_explorer::Update()
case SYS_INTR_TAG_OBJECT:
{
// auto& tag = static_cast<lv2_int_tag&>(obj);
l_addTreeChild(node, qstr(fmt::format("Intr tag: ID = 0x%08x", id)));
l_addTreeChild(node, qstr(fmt::format("Intr Tag: ID = 0x%08x", id)));
break;
}
case SYS_INTR_SERVICE_HANDLE_OBJECT:
{
// auto& serv = static_cast<lv2_int_serv&>(obj);
l_addTreeChild(node, qstr(fmt::format("Intr svc: ID = 0x%08x", id)));
l_addTreeChild(node, qstr(fmt::format("Intr Svc: ID = 0x%08x", id)));
break;
}
case SYS_EVENT_QUEUE_OBJECT:
{
auto& eq = static_cast<lv2_event_queue&>(obj);
l_addTreeChild(node, qstr(fmt::format("Event queue: ID = 0x%08x \"%s\", %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", id, +name64(eq.name),
l_addTreeChild(node, qstr(fmt::format("Event Queue: ID = 0x%08x \"%s\", %s, Key = %#llx, Events = %zu/%d, Waiters = %zu", id, +name64(eq.name),
eq.type == SYS_SPU_QUEUE ? "SPU" : "PPU", eq.key, eq.events.size(), eq.size, eq.sq.size())));
break;
}
case SYS_EVENT_PORT_OBJECT:
{
auto& ep = static_cast<lv2_event_port&>(obj);
l_addTreeChild(node, qstr(fmt::format("Event port: ID = 0x%08x, Name = %#llx", id, ep.name)));
l_addTreeChild(node, qstr(fmt::format("Event Port: ID = 0x%08x, Name = %#llx", id, ep.name)));
break;
}
case SYS_TRACE_OBJECT:
@@ -252,12 +252,12 @@ void kernel_explorer::Update()
}
});
lv2_types.emplace_back(l_addTreeChild(root, "Memory containers"));
lv2_types.emplace_back(l_addTreeChild(root, "Memory Containers"));
idm::select<lv2_memory_container>([&](u32 id, lv2_memory_container&)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("Memory container: ID = 0x%08x", id)));
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("Memory Container: ID = 0x%08x", id)));
});
lv2_types.emplace_back(l_addTreeChild(root, "PPU Threads"));
@@ -276,15 +276,15 @@ void kernel_explorer::Update()
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread: ID = 0x%08x '%s'", id, spu.get_name())));
});
lv2_types.emplace_back(l_addTreeChild(root, "SPU Thread groups"));
lv2_types.emplace_back(l_addTreeChild(root, "SPU Thread Groups"));
idm::select<lv2_spu_group>([&](u32 id, lv2_spu_group& tg)
{
lv2_types.back().count++;
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread group: ID = 0x%08x '%s'", id, tg.name)));
l_addTreeChild(lv2_types.back().node, qstr(fmt::format("SPU Thread Group: ID = 0x%08x '%s'", id, tg.name)));
});
lv2_types.emplace_back(l_addTreeChild(root, "File descriptors"));
lv2_types.emplace_back(l_addTreeChild(root, "File Descriptors"));
idm::select<lv2_fs_object>([&](u32 id, lv2_fs_object& fo)
{
+4 -4
View File
@@ -290,7 +290,7 @@ void main_window::BootGame()
}
QString path_last_Game = guiSettings->GetValue(gui::fd_boot_game).toString();
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Select game folder"), path_last_Game, QFileDialog::ShowDirsOnly);
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Select Game Folder"), path_last_Game, QFileDialog::ShowDirsOnly);
if (dirPath == NULL)
{
@@ -727,7 +727,7 @@ void main_window::OnEmuPause()
m_thumb_playPause->setToolTip(tr("Resume emulation"));
m_thumb_playPause->setIcon(m_icon_thumb_play);
#endif
ui->sysPauseAct->setText(tr("&Resume\tCtrl+F"));
ui->sysPauseAct->setText(tr("&Resume\tCtrl+E"));
ui->sysPauseAct->setIcon(m_icon_play);
ui->toolbar_start->setIcon(m_icon_play);
ui->toolbar_start->setToolTip(tr("Resume emulation"));
@@ -1099,7 +1099,7 @@ void main_window::CreateConnects()
{
sysutil_send_system_cmd(m_sys_menu_opened ? 0x0132 /* CELL_SYSUTIL_SYSTEM_MENU_CLOSE */ : 0x0131 /* CELL_SYSUTIL_SYSTEM_MENU_OPEN */, 0);
m_sys_menu_opened = !m_sys_menu_opened;
ui->sysSendOpenMenuAct->setText(tr("Press &%0 PS button").arg(m_sys_menu_opened ? tr("close") : tr("open")));
ui->sysSendOpenMenuAct->setText(tr("Send &%0 system menu cmd").arg(m_sys_menu_opened ? tr("close") : tr("open")));
});
connect(ui->sysSendExitAct, &QAction::triggered, [=]
@@ -1512,7 +1512,7 @@ void main_window::keyPressEvent(QKeyEvent *keyEvent)
{
switch (keyEvent->key())
{
case Qt::Key_F: if (Emu.IsPaused()) Emu.Resume(); else if (Emu.IsReady()) Emu.Run(); return;
case Qt::Key_E: if (Emu.IsPaused()) Emu.Resume(); else if (Emu.IsReady()) Emu.Run(); return;
case Qt::Key_P: if (Emu.IsRunning()) Emu.Pause(); return;
case Qt::Key_S: if (!Emu.IsStopped()) Emu.Stop(); return;
case Qt::Key_R: if (!Emu.GetBoot().empty()) Emu.Restart(); return;
+1 -1
View File
@@ -6,7 +6,7 @@
memory_string_searcher::memory_string_searcher(QWidget* parent)
: QDialog(parent)
{
setWindowTitle(tr("String searcher"));
setWindowTitle(tr("String Searcher"));
setAttribute(Qt::WA_DeleteOnClose);
m_addr_line = new QLineEdit(this);
+4 -4
View File
@@ -8,7 +8,7 @@ constexpr auto qstr = QString::fromStdString;
memory_viewer_panel::memory_viewer_panel(QWidget* parent)
: QDialog(parent)
{
setWindowTitle(tr("Memory viewer"));
setWindowTitle(tr("Memory Viewer"));
setObjectName("memory_viewer");
setAttribute(Qt::WA_DeleteOnClose);
exit = false;
@@ -29,7 +29,7 @@ memory_viewer_panel::memory_viewer_panel(QWidget* parent)
QHBoxLayout* hbox_tools = new QHBoxLayout();
//Tools: Memory Viewer Options
QGroupBox* tools_mem = new QGroupBox(tr("Memory viewer options"));
QGroupBox* tools_mem = new QGroupBox(tr("Memory Viewer Options"));
QHBoxLayout* hbox_tools_mem = new QHBoxLayout();
//Tools: Memory Viewer Options: Address
@@ -81,7 +81,7 @@ memory_viewer_panel::memory_viewer_panel(QWidget* parent)
tools_mem->setLayout(hbox_tools_mem);
//Tools: Raw Image Preview Options
QGroupBox* tools_img = new QGroupBox(tr("Raw image preview options"));
QGroupBox* tools_img = new QGroupBox(tr("Raw Image Preview Options"));
QHBoxLayout* hbox_tools_img = new QHBoxLayout();;
//Tools: Raw Image Preview Options : Size
@@ -389,7 +389,7 @@ void memory_viewer_panel::ShowImage(QWidget* parent, u32 addr, int mode, u32 wid
layout->addWidget(canvas);
QDialog* f_image_viewer = new QDialog(parent);
f_image_viewer->setWindowTitle(qstr(fmt::format("Raw image @ 0x%x", addr)));
f_image_viewer->setWindowTitle(qstr(fmt::format("Raw Image @ 0x%x", addr)));
f_image_viewer->setFixedSize(QSize(width, height));
f_image_viewer->setLayout(layout);
f_image_viewer->show();
+13 -13
View File
@@ -29,7 +29,7 @@ rsx_debugger::rsx_debugger(QWidget* parent)
QVBoxLayout* vbox_tools = new QVBoxLayout();
// Controls
QGroupBox* gb_controls = new QGroupBox(tr("RSX Debugger controls"), this);
QGroupBox* gb_controls = new QGroupBox(tr("RSX Debugger Controls"), this);
QHBoxLayout* hbox_controls = new QHBoxLayout();
// Controls: Address
@@ -110,8 +110,8 @@ rsx_debugger::rsx_debugger(QWidget* parent)
};
m_list_commands = l_addRSXTab(m_list_commands, tr("RSX Commands"), 4);
m_list_captured_frame = l_addRSXTab(m_list_captured_frame, tr("Captured frame"), 1);
m_list_captured_draw_calls = l_addRSXTab(m_list_captured_draw_calls, tr("Captured draw calls"), 1);
m_list_captured_frame = l_addRSXTab(m_list_captured_frame, tr("Captured Frame"), 1);
m_list_captured_draw_calls = l_addRSXTab(m_list_captured_draw_calls, tr("Captured Draw Calls"), 1);
m_list_flags = l_addRSXTab(m_list_flags, tr("Flags"), 2);
m_list_lightning = l_addRSXTab(m_list_lightning, tr("Lightning"), 2);
m_list_texture = l_addRSXTab(m_list_texture, tr("Texture"), 9);
@@ -193,12 +193,12 @@ rsx_debugger::rsx_debugger(QWidget* parent)
//Buffers
QVBoxLayout* vbox_buffers1 = new QVBoxLayout();
QVBoxLayout* vbox_buffers2 = new QVBoxLayout();
QGroupBox* gb_buffers_colorA = new QGroupBox(tr("Color buffer A"), p_buffers);
QGroupBox* gb_buffers_colorB = new QGroupBox(tr("Color buffer B"), p_buffers);
QGroupBox* gb_buffers_colorC = new QGroupBox(tr("Color buffer C"), p_buffers);
QGroupBox* gb_buffers_colorD = new QGroupBox(tr("Color buffer D"), p_buffers);
QGroupBox* gb_buffers_depth = new QGroupBox(tr("Depth buffer"), p_buffers);
QGroupBox* gb_buffers_stencil = new QGroupBox(tr("Stencil buffer"), p_buffers);
QGroupBox* gb_buffers_colorA = new QGroupBox(tr("Color Buffer A"), p_buffers);
QGroupBox* gb_buffers_colorB = new QGroupBox(tr("Color Buffer B"), p_buffers);
QGroupBox* gb_buffers_colorC = new QGroupBox(tr("Color Buffer C"), p_buffers);
QGroupBox* gb_buffers_colorD = new QGroupBox(tr("Color Buffer D"), p_buffers);
QGroupBox* gb_buffers_depth = new QGroupBox(tr("Depth Buffer"), p_buffers);
QGroupBox* gb_buffers_stencil = new QGroupBox(tr("Stencil Buffer"), p_buffers);
QGroupBox* gb_buffers_text = new QGroupBox(tr("Texture"), p_buffers);
QHBoxLayout* hbox_buffers_colorA = new QHBoxLayout();
QHBoxLayout* hbox_buffers_colorB = new QHBoxLayout();
@@ -1062,7 +1062,7 @@ const char* rsx_debugger::ParseGCMEnum(u32 value, u32 type)
case 0xF006: return "Add Signed";
case 0xF007: return "Reverse Add Signed";
default: return "Wrong value!";
default: return "Wrong Value!";
}
}
case CELL_GCM_PRIMITIVE_ENUM:
@@ -1080,7 +1080,7 @@ const char* rsx_debugger::ParseGCMEnum(u32 value, u32 type)
case 9: return "QUAD_STRIP";
case 10: return "POLYGON";
default: return "Wrong value!";
default: return "Wrong Value!";
}
}
default: return "Unknown!";
@@ -1150,7 +1150,7 @@ QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA
break;
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
DISASM("Texture offset[%d]: %08x", index, (u32)args[0]);
DISASM("Texture Offset[%d]: %08x", index, (u32)args[0]);
switch ((args[1] & 0x3) - 1)
{
case CELL_GCM_LOCATION_LOCAL: DISASM("(Local memory);"); break;
@@ -1176,7 +1176,7 @@ QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA
if((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD)
{
DISASM("Non increment cmd");
DISASM("Non Increment cmd");
}
DISASM("[0x%08x(", cmd);
+1 -1
View File
@@ -9,7 +9,7 @@ constexpr auto qstr = QString::fromStdString;
save_data_info_dialog::save_data_info_dialog(const SaveDataEntry& save, QWidget* parent)
: QDialog(parent), m_entry(save)
{
setWindowTitle(tr("Save data information"));
setWindowTitle(tr("Save Data Information"));
// Table
m_list = new QTableWidget(this);
+7 -7
View File
@@ -18,15 +18,15 @@ save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& e
{
if (op >= 8)
{
setWindowTitle(tr("Save data interface (Delete)"));
setWindowTitle(tr("Save Data Interface (Delete)"));
}
else if (op & 1)
{
setWindowTitle(tr("Save data interface (Load)"));
setWindowTitle(tr("Save Data Interface (Load)"));
}
else
{
setWindowTitle(tr("Save data interface (Save)"));
setWindowTitle(tr("Save Data Interface (Save)"));
}
setMinimumSize(QSize(400, 400));
@@ -48,7 +48,7 @@ save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& e
if (entries.size() > 0)
{ // If there are no entries, don't add the selection widget or the selection label to the UI.
QPushButton *push_select = new QPushButton(tr("&Select entry"), this);
QPushButton *push_select = new QPushButton(tr("&Select Entry"), this);
connect(push_select, &QAbstractButton::clicked, this, &save_data_list_dialog::accept);
push_select->setAutoDefault(true);
push_select->setDefault(true);
@@ -60,7 +60,7 @@ save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& e
if (listSet->newData)
{
QPushButton *saveNewEntry = new QPushButton(tr("Save new entry"), this);
QPushButton *saveNewEntry = new QPushButton(tr("Save New Entry"), this);
connect(saveNewEntry, &QAbstractButton::clicked, this, [&]()
{
m_entry = selection_code::new_save;
@@ -119,12 +119,12 @@ void save_data_list_dialog::UpdateSelectionLabel()
{
if (m_list->currentRow() == -1)
{
m_entry_label->setText(tr("Currently selected: None"));
m_entry_label->setText(tr("Currently Selected: None"));
}
else
{
int entry = m_list->item(m_list->currentRow(), 0)->data(Qt::UserRole).toInt();
m_entry_label->setText(tr("Currently selected: ") + qstr(m_save_entries[entry].dirName));
m_entry_label->setText(tr("Currently Selected: ") + qstr(m_save_entries[entry].dirName));
}
}
}
+5 -5
View File
@@ -5,13 +5,13 @@
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>POLLY_AVAILABLE;LLVM_AVAILABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>LLVM_AVAILABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Lib>
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Debug - LLVM'">..\llvm_build\Debug\lib;..\llvm_build\lib\Debug</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Release - LLVM'">..\llvm_build\Release\lib;..\llvm_build\lib\Release</AdditionalLibraryDirectories>
<AdditionalDependencies>LLVMProfileData.lib;LLVMDebugInfoCodeView.lib;LLVMDebugInfoMSF.lib;LLVMInstrumentation.lib;LLVMMCJIT.lib;LLVMRuntimeDyld.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMGlobalISel.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMX86AsmPrinter.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib;LLVMMCDisassembler.lib;LLVMipo.lib;LLVMBinaryFormat.lib;LLVMPasses.lib;LLVMIRReader.lib;LLVMLinker.lib;LLVMAsmParser.lib;Polly.lib;PollyISL.lib;PollyPPCG.lib</AdditionalDependencies>
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Debug - LLVM'">..\llvm_build\Debug\lib</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Release - LLVM'">..\llvm_build\Release\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>LLVMProfileData.lib;LLVMDebugInfoCodeView.lib;LLVMDebugInfoMSF.lib;LLVMInstrumentation.lib;LLVMMCJIT.lib;LLVMRuntimeDyld.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMGlobalISel.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMX86AsmPrinter.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib;LLVMMCDisassembler.lib;LLVMipo.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
</Project>