mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-08-28 00:24:35 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38ff521851 | ||
|
|
34de1bffc6 | ||
|
|
8dc1592278 | ||
|
|
5b86205349 | ||
|
|
0d4fbd540e | ||
|
|
b9edabc236 | ||
|
|
180d9ae9c9 | ||
|
|
80cc2f0cb7 | ||
|
|
1927896442 | ||
|
|
bf9c1176b6 | ||
|
|
166156519a | ||
|
|
d89daa1b25 | ||
|
|
efc17f265c | ||
|
|
8427e6fd3e | ||
|
|
f1ac712eba | ||
|
|
0d4394a749 | ||
|
|
9dac598113 | ||
|
|
6db573d255 | ||
|
|
9b21f31b0d | ||
|
|
2fedecb809 | ||
|
|
b24a8c70e3 | ||
|
|
d6684efd26 | ||
|
|
644241959a | ||
|
|
273c1b1922 | ||
|
|
45682c382f | ||
|
|
4e6b86f8f4 | ||
|
|
a6b4ca69db | ||
|
|
6b32e00097 | ||
|
|
19d310475b | ||
|
|
a8b9df3952 | ||
|
|
bb75c78c1a | ||
|
|
57ea137982 | ||
|
|
9721ed0fb3 | ||
|
|
224863fbd5 | ||
|
|
1d459d8fab | ||
|
|
33e0ac729e | ||
|
|
268ecf42c3 | ||
|
|
708281f00b | ||
|
|
56b68a50e9 | ||
|
|
e4048dc2dd | ||
|
|
5949c772d1 | ||
|
|
63998b64cc | ||
|
|
fbb3ea142a | ||
|
|
435f760b5d | ||
|
|
f47129bd72 | ||
|
|
aa42acfe22 | ||
|
|
ddfe6ac5c1 | ||
|
|
624dff1b96 | ||
|
|
8d498b564d | ||
|
|
26561261bc | ||
|
|
44728be719 | ||
|
|
678bb1218b | ||
|
|
c496e80eac | ||
|
|
269db188d0 | ||
|
|
f5afbfd4f5 | ||
|
|
ccd86a242c | ||
|
|
42a5cb7ad2 | ||
|
|
6977323d88 | ||
|
|
7b1d03d45a | ||
|
|
8a4f1ef51a | ||
|
|
9b50bb2e81 | ||
|
|
4f27d779a1 | ||
|
|
73c6353351 | ||
|
|
f571b66a43 | ||
|
|
901664ba44 | ||
|
|
02012b5491 | ||
|
|
4f57e40c91 | ||
|
|
832e536a9e | ||
|
|
c2316ca5bc | ||
|
|
3535edcfa1 | ||
|
|
a4932ed0f1 | ||
|
|
515d9040a1 | ||
|
|
fe3a743814 | ||
|
|
8e08cd772b | ||
|
|
206f80c5f4 | ||
|
|
c6ce380042 | ||
|
|
939d98d660 | ||
|
|
c9a3420f85 | ||
|
|
9a1a399bac | ||
|
|
c8aac1dca9 | ||
|
|
14c17916f5 | ||
|
|
7b0576d7cc | ||
|
|
ecb118d5af | ||
|
|
efbf187b35 | ||
|
|
2ea3feba90 | ||
|
|
f265257efb | ||
|
|
13cc0caed7 | ||
|
|
2068240e1a | ||
|
|
7f5901f022 | ||
|
|
a022de6225 | ||
|
|
f5570b7f40 | ||
|
|
7e1c48694a | ||
|
|
a546f61ea8 | ||
|
|
7ecac10eee | ||
|
|
ee2e10e86b | ||
|
|
7752f44a90 | ||
|
|
e01fc3eb47 | ||
|
|
910c8190e0 | ||
|
|
a62ccc0d69 | ||
|
|
4f47041108 | ||
|
|
16cfde0538 | ||
|
|
6a15d46461 | ||
|
|
4331ae1925 | ||
|
|
4d85d916b7 | ||
|
|
4f4b14dd4d | ||
|
|
444e650711 | ||
|
|
c65ccaa153 | ||
|
|
6b54db9b75 | ||
|
|
3bab470db6 | ||
|
|
adf01cb56a | ||
|
|
bbe3af7f61 | ||
|
|
3e7d32c807 | ||
|
|
76e25cb738 | ||
|
|
8f0dc34847 | ||
|
|
fc6ec2cc02 | ||
|
|
34b7b07ff8 | ||
|
|
6c33b73cdd | ||
|
|
1e86ba4120 | ||
|
|
89c79aa6c3 | ||
|
|
4ed748fa30 | ||
|
|
5569e94f41 | ||
|
|
892eec79ed | ||
|
|
b248b4a8af | ||
|
|
39fe467b64 | ||
|
|
1c301ec889 | ||
|
|
de5690ddcb | ||
|
|
f376c8f7ae | ||
|
|
2e199d47a8 | ||
|
|
96269db93e | ||
|
|
d35db63d73 | ||
|
|
9d003486c2 | ||
|
|
0c4b85980c | ||
|
|
5961db6b9b | ||
|
|
d0039c2920 | ||
|
|
5bdec2f532 | ||
|
|
fd758bb307 | ||
|
|
a11d09ebdf | ||
|
|
d294064da6 | ||
|
|
fd4a5acc40 | ||
|
|
05a7a61257 | ||
|
|
90a4a11d49 | ||
|
|
d9f914eb7c | ||
|
|
134242973b | ||
|
|
92900d8dc8 | ||
|
|
7a970e1d00 |
@@ -27,6 +27,11 @@
|
||||
'GUI/WX':
|
||||
- 'pcsx2/gui/*'
|
||||
- 'pcsx2/gui/**/*'
|
||||
- 'pcsx2/SPU2/wx/*'
|
||||
- 'pcsx2/SPU2/wx/**/*'
|
||||
- 'pcsx2/PAD/Linux/wx_dialog/*'
|
||||
- 'pcsx2/PAD/Linux/wx_dialog/**/*'
|
||||
- 'pcsx2/GS/Window/GSwxDialog.h'
|
||||
'GUI/Qt':
|
||||
- 'pcsx2-qt/*'
|
||||
- 'pcsx2-qt/**/*'
|
||||
|
||||
@@ -44,12 +44,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
compiler: gcc
|
||||
cmakeflags: -DLTO_PCSX2_CORE=ON
|
||||
appimage: true
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x64
|
||||
compiler: gcc
|
||||
@@ -57,7 +51,7 @@ jobs:
|
||||
appimage: true
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
platform: x64
|
||||
compiler: clang
|
||||
# Need to disable PCH until cmake 3.17
|
||||
# (PCH conflicts with ccache, fixed by https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4400)
|
||||
@@ -66,21 +60,21 @@ jobs:
|
||||
appimage: false
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
platform: x64
|
||||
compiler: gcc
|
||||
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
|
||||
detail: " nopch"
|
||||
appimage: false
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
platform: x64
|
||||
compiler: gcc
|
||||
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -DARCH_FLAG=-march=haswell
|
||||
detail: " avx2 nopch"
|
||||
appimage: false
|
||||
experimental: false
|
||||
|
||||
name: ${{ matrix.platform }} | ${{ matrix.compiler }}${{ matrix.detail }}
|
||||
name: ${{ matrix.compiler }}${{ matrix.detail }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
|
||||
@@ -70,7 +70,6 @@ jobs:
|
||||
platform: [x64]
|
||||
experimental: [false]
|
||||
|
||||
name: ${{ matrix.platform }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
|
||||
@@ -44,7 +44,8 @@ const embed = new MessageEmbed()
|
||||
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
|
||||
{ name: 'Release Link', value: `[Github Release](${releaseInfo.html_url})`, inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
|
||||
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
|
||||
{ name: 'Included Changes', value: releaseInfo.body, inline: false },
|
||||
{ name: 'Previous Builds', value: "[See Here](https://pcsx2.github.io/downloads.html#nightly-anchor)", inline: false }
|
||||
);
|
||||
|
||||
if (windowsAssetLinks != "") {
|
||||
|
||||
@@ -111,11 +111,8 @@ const { data: releaseAssetsPost } = await octokit.rest.repos.listReleaseAssets({
|
||||
|
||||
// Expected Assets, if we have all of them, we will publish it
|
||||
let expectedAssets = {
|
||||
"windows-32bit-sse4": false,
|
||||
"windows-32bit-avx2": false,
|
||||
"windows-64bit-sse4": false,
|
||||
"windows-64bit-avx2": false,
|
||||
"linux-appimage-32bit": false,
|
||||
"linux-appimage-64bit": false
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ allowed_game_options = [
|
||||
"roundModes",
|
||||
"clampModes",
|
||||
"gameFixes",
|
||||
"gsHWFixes",
|
||||
"speedHacks",
|
||||
"memcardFilters",
|
||||
"patches",
|
||||
@@ -19,24 +20,54 @@ allowed_game_options = [
|
||||
allowed_round_modes = ["eeRoundMode", "vuRoundMode"]
|
||||
allowed_clamp_modes = ["eeClampMode", "vuClampMode"]
|
||||
allowed_game_fixes = [
|
||||
"VuAddSubHack",
|
||||
"FpuCompareHack",
|
||||
"FpuMulHack",
|
||||
"FpuNegDivHack",
|
||||
"XGKickHack",
|
||||
"EETimingHack",
|
||||
"GoemonTlbHack",
|
||||
"SoftwareRendererFMVHack",
|
||||
"SkipMPEGHack",
|
||||
"OPHFlagHack",
|
||||
"EETimingHack",
|
||||
"DMABusyHack",
|
||||
"GIFFIFOHack",
|
||||
"VIFFIFOHack",
|
||||
"VIF1StallHack",
|
||||
"GIFFIFOHack",
|
||||
"GoemonTlbHack",
|
||||
"VUSyncHack",
|
||||
"VuAddSubHack",
|
||||
"IbitHack",
|
||||
"VUSyncHack",
|
||||
"VUOverflowHack",
|
||||
"XGKickHack",
|
||||
]
|
||||
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack"]
|
||||
allowed_gs_hw_fixes = [
|
||||
"autoFlush",
|
||||
"conservativeFramebuffer",
|
||||
"cpuFramebufferConversion",
|
||||
"disableDepthSupport",
|
||||
"wrapGSMem",
|
||||
"preloadFrameData",
|
||||
"disablePartialInvalidation",
|
||||
"textureInsideRT",
|
||||
"alignSprite",
|
||||
"mergeSprite",
|
||||
"wildArmsHack",
|
||||
"pointListPalette",
|
||||
"mipmap",
|
||||
"trilinearFiltering",
|
||||
"skipDrawStart",
|
||||
"skipDrawEnd",
|
||||
"halfBottomOverride",
|
||||
"halfPixelOffset",
|
||||
"roundSprite",
|
||||
"texturePreloading",
|
||||
]
|
||||
gs_hw_fix_ranges = {
|
||||
"mipmap": (0, 2),
|
||||
"trilinearFiltering": (0, 2),
|
||||
"skipDrawStart": (0, 100000),
|
||||
"skipDrawEnd": (0, 100000),
|
||||
"halfPixelOffset": (0, 3),
|
||||
"roundSprite": (0, 2),
|
||||
}
|
||||
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack", "MTVUSpeedHack"]
|
||||
# Patches are allowed to have a 'default' key or a crc-32 key, followed by
|
||||
allowed_patch_options = ["author", "content"]
|
||||
|
||||
@@ -94,6 +125,29 @@ def validate_game_fixes(serial, key, value):
|
||||
validate_valid_options(serial, key, gamefix, allowed_game_fixes)
|
||||
|
||||
|
||||
def validate_gs_hw_fix_value(serial, key, value):
|
||||
low, high = 0, 1
|
||||
if key in gs_hw_fix_ranges:
|
||||
low, high = gs_hw_fix_ranges[key]
|
||||
validate_int_option(serial, key, value, low, high)
|
||||
|
||||
|
||||
def validate_gs_hw_fixes(serial, key, value):
|
||||
if not isinstance(value, dict):
|
||||
issue_list.append("[{}]: 'gsHWFixes' must be a valid object".format(serial))
|
||||
return
|
||||
for fix, fix_value in value.items():
|
||||
validate_valid_options(serial, key, fix, allowed_gs_hw_fixes)
|
||||
validate_gs_hw_fix_value(serial, fix, fix_value)
|
||||
|
||||
# skipdraw range must have end >= start
|
||||
skip_draw_start = value["skipDrawStart"] if "skipDrawStart" in value else 0
|
||||
skip_draw_end = value["skipDrawEnd"] if "skipDrawEnd" in value else 0
|
||||
if isinstance(skip_draw_start, int) and isinstance(skip_draw_end, int) and skip_draw_end < skip_draw_start:
|
||||
issue_list.append("[{}]: skipDrawStart({}) must be greater or equal to skipDrawEnd({})".format(
|
||||
serial, skip_draw_start, skip_draw_end))
|
||||
|
||||
|
||||
def validate_speed_hacks(serial, key, value):
|
||||
if not isinstance(value, dict):
|
||||
issue_list.append("[{}]: 'speedHacks' must be a valid object".format(serial))
|
||||
@@ -145,6 +199,7 @@ option_validation_handlers = {
|
||||
)
|
||||
),
|
||||
"gameFixes": (lambda serial, key, value: validate_game_fixes(serial, key, value)),
|
||||
"gsHWFixes": (lambda serial, key, value: validate_gs_hw_fixes(serial, key, value)),
|
||||
"speedHacks": (lambda serial, key, value: validate_speed_hacks(serial, key, value)),
|
||||
"memcardFilters": (
|
||||
lambda serial, key, value: validate_list_of_strings(serial, key, value)
|
||||
|
||||
@@ -41,14 +41,11 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019]
|
||||
platform: [Win32, x64]
|
||||
platform: [x64]
|
||||
configuration: [Release, Release AVX2, CMake, Qt]
|
||||
experimental: [false]
|
||||
exclude:
|
||||
- platform: win32
|
||||
configuration: Qt
|
||||
|
||||
name: ${{ matrix.platform }} | ${{ matrix.configuration }}
|
||||
name: ${{ matrix.configuration }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
@@ -70,18 +67,18 @@ jobs:
|
||||
run: git submodule update --init --recursive -j $env:NUMBER_OF_PROCESSORS
|
||||
|
||||
- name: Setup Buildcache
|
||||
if: matrix.configuration == 'CMake' # TODO: buildcache on VS
|
||||
uses: mikehardy/buildcache-action@v1.2.2
|
||||
with:
|
||||
cache_key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.configuration }}
|
||||
if: matrix.configuration == 'CMake' # TODO: buildcache on VS
|
||||
|
||||
- name: Verify VS Project Files
|
||||
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
|
||||
if: matrix.configuration != 'CMake'
|
||||
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
|
||||
|
||||
- name: Setup msbuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
if: matrix.configuration != 'CMake'
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Download Qt build files
|
||||
if: matrix.configuration == 'Qt'
|
||||
@@ -93,6 +90,7 @@ jobs:
|
||||
del qt-6.2.2-x64.7z
|
||||
|
||||
- name: Generate CMake
|
||||
if: matrix.configuration == 'CMake'
|
||||
id: cmake
|
||||
shell: cmd
|
||||
run: |
|
||||
@@ -102,7 +100,6 @@ jobs:
|
||||
echo ::set-output name=buildtype::%type%
|
||||
echo ::set-output name=vcvars::%vcvars%
|
||||
cmake . -B build -DCMAKE_BUILD_TYPE=%type% -DLTO_PCSX2_CORE=ON -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_CXX_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
|
||||
if: matrix.configuration == 'CMake'
|
||||
|
||||
- name: Build PCSX2
|
||||
shell: cmd
|
||||
@@ -123,11 +120,11 @@ jobs:
|
||||
)
|
||||
|
||||
- name: Run Tests
|
||||
if: matrix.configuration == 'CMake'
|
||||
shell: cmd
|
||||
run: |
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
|
||||
cmake --build build --config ${{ steps.cmake.outputs.buildtype }} --target unittests
|
||||
if: matrix.configuration == 'CMake'
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/rapidyaml/rapidyaml updated: cf902dc49c...213b201d26
Vendored
+10
-15
@@ -52,6 +52,7 @@
|
||||
<ClInclude Include="rapidyaml\src\ryml_std.hpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\detail\checks.hpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\detail\parser_dbg.hpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\detail\print.hpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\detail\stack.hpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\common.hpp" />
|
||||
<ClCompile Include="rapidyaml\src\c4\yml\common.cpp" />
|
||||
@@ -72,8 +73,7 @@
|
||||
<ClCompile Include="rapidyaml\src\c4\yml\tree.cpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\writer.hpp" />
|
||||
<ClInclude Include="rapidyaml\src\c4\yml\yml.hpp" />
|
||||
<Natvis Include="rapidyaml\src\ryml.natvis">
|
||||
</Natvis>
|
||||
<Natvis Include="rapidyaml\src\ryml.natvis"></Natvis>
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\allocator.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\base64.hpp" />
|
||||
<ClCompile Include="rapidyaml\ext\c4core\src\c4\base64.cpp" />
|
||||
@@ -89,6 +89,7 @@
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\config.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\cpu.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ctor_dtor.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\dump.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\enum.hpp" />
|
||||
<ClCompile Include="rapidyaml\ext\c4core\src\c4\error.cpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\error.hpp" />
|
||||
@@ -107,35 +108,29 @@
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\restrict.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\span.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\std.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\std_fwd.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\string.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\string_fwd.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\tuple.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\vector.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\std\vector_fwd.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\substr.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\substr_fwd.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\szconv.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\time.hpp" />
|
||||
<ClCompile Include="rapidyaml\ext\c4core\src\c4\time.cpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\type_name.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\types.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\unrestrict.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\utf.hpp" />
|
||||
<ClCompile Include="rapidyaml\ext\c4core\src\c4\utf.cpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\windows.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\windows_pop.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\windows_push.hpp" />
|
||||
<Natvis Include="rapidyaml\ext\c4core\src\c4\c4core.natvis">
|
||||
</Natvis>
|
||||
<Natvis Include="rapidyaml\ext\c4core\src\c4\c4core.natvis"></Natvis>
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\debugbreak\debugbreak.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\rng\rng.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\sg14\inplace_function.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float.hpp" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\ascii_number.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\bigint.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\decimal_to_binary.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\digit_comparison.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\fast_float.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\fast_table.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\float_common.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\parse_number.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float\include\fast_float\simple_decimal_conversion.h" />
|
||||
<ClInclude Include="rapidyaml\ext\c4core\src\c4\ext\fast_float_all.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
+1
-294
@@ -54,6 +54,7 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glad", "3rdparty\glad\glad.vcxproj", "{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ryml", "3rdparty\rapidyaml\ryml.vcxproj", "{DE9653B6-17DD-356A-9EE0-28A731772587}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cubeb", "3rdparty\cubeb\cubeb.vcxproj", "{BF74C473-DC04-44B3-92E8-4145F4E77342}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleini", "3rdparty\simpleini\simpleini.vcxproj", "{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}"
|
||||
@@ -64,594 +65,300 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang", "3rdparty\glslang
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug AVX2|Win32 = Debug AVX2|Win32
|
||||
Debug AVX2|x64 = Debug AVX2|x64
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Devel AVX2|Win32 = Devel AVX2|Win32
|
||||
Devel AVX2|x64 = Devel AVX2|x64
|
||||
Devel|Win32 = Devel|Win32
|
||||
Devel|x64 = Devel|x64
|
||||
Release AVX2|Win32 = Release AVX2|Win32
|
||||
Release AVX2|x64 = Release AVX2|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|Win32.ActiveCfg = Debug AVX2|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|Win32.Build.0 = Debug AVX2|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|x64.ActiveCfg = Debug AVX2|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug AVX2|x64.Build.0 = Debug AVX2|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|x64.Build.0 = Debug|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|Win32.ActiveCfg = Devel AVX2|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|Win32.Build.0 = Devel AVX2|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|x64.ActiveCfg = Devel AVX2|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel AVX2|x64.Build.0 = Devel AVX2|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel|x64.Build.0 = Devel|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|Win32.ActiveCfg = Release AVX2|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|Win32.Build.0 = Release AVX2|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|x64.ActiveCfg = Release AVX2|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release AVX2|x64.Build.0 = Release AVX2|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.Build.0 = Release|Win32
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|x64.ActiveCfg = Release|x64
|
||||
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|x64.Build.0 = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|x64.Build.0 = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|x64.Build.0 = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|Win32.Build.0 = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|x64.ActiveCfg = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|x64.Build.0 = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|x64.Build.0 = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|x64.Build.0 = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.Build.0 = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.ActiveCfg = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.Build.0 = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.Build.0 = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.Build.0 = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|Win32.Build.0 = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.ActiveCfg = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.Build.0 = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.Build.0 = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|x64.Build.0 = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.Build.0 = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.ActiveCfg = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.Build.0 = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.Build.0 = Debug|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.Build.0 = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|Win32.Build.0 = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.ActiveCfg = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.Build.0 = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.Build.0 = Debug|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.Build.0 = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.Build.0 = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Debug|x64.Build.0 = Debug|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Devel|x64.Build.0 = Devel|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|Win32.Build.0 = Release|Win32
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|x64.ActiveCfg = Release|x64
|
||||
{24C45343-FD20-5C92-81C1-35A2AE841E79}.Release|x64.Build.0 = Release|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.Build.0 = Debug|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Devel|x64.Build.0 = Devel|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.Build.0 = Release|Win32
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.ActiveCfg = Release|x64
|
||||
{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.Build.0 = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.Build.0 = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|x64.Build.0 = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.Build.0 = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.ActiveCfg = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.Build.0 = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|x64.Build.0 = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|x64.Build.0 = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.Build.0 = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.ActiveCfg = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.Build.0 = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|x64.Build.0 = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|x64.Build.0 = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|Win32.Build.0 = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|x64.ActiveCfg = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|x64.Build.0 = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.Build.0 = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|x64.Build.0 = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.Build.0 = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.ActiveCfg = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.Build.0 = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|x64.Build.0 = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|x64.Build.0 = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|Win32.Build.0 = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.ActiveCfg = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.Build.0 = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.Build.0 = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.Build.0 = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|Win32.Build.0 = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.ActiveCfg = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.Build.0 = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.Build.0 = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|x64.Build.0 = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|Win32.Build.0 = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|x64.ActiveCfg = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|x64.Build.0 = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|x64.Build.0 = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|x64.Build.0 = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|Win32.Build.0 = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|x64.ActiveCfg = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|x64.Build.0 = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.Build.0 = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.Build.0 = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.Build.0 = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.ActiveCfg = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.Build.0 = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|x64.Build.0 = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|x64.Build.0 = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|Win32.Build.0 = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|x64.ActiveCfg = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|x64.Build.0 = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|x64.Build.0 = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|x64.Build.0 = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|Win32.Build.0 = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.ActiveCfg = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.Build.0 = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|x64.Build.0 = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|x64.Build.0 = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|Win32.Build.0 = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|x64.ActiveCfg = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|x64.Build.0 = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|x64.Build.0 = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|x64.Build.0 = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|Win32.Build.0 = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|x64.ActiveCfg = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|x64.Build.0 = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|x64.Build.0 = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|x64.Build.0 = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|Win32.Build.0 = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|x64.ActiveCfg = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|x64.Build.0 = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.Build.0 = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.Build.0 = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|Win32.Build.0 = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.ActiveCfg = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
|
||||
@@ -23,7 +23,7 @@ Development builds are also available from [Github](https://github.com/PCSX2/pcs
|
||||
|
||||
| Operating System | CPU | GPU | RAM |
|
||||
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
|
||||
| - Windows 8.1 or newer (32 or 64 bit) <br/> - Ubuntu 18.04/Debian or newer, Arch Linux, or other distro (32 or 64 bit) | - Supports SSE4.1 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/singleThread.html) rating near or greater than 1600 <br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (GeForce GTX 750) <br/> - 2 GB Video Memory | 4 GB |
|
||||
| - Windows 8.1 or newer (64 bit) <br/> - Ubuntu 18.04/Debian or newer, Arch Linux, or other distro (64 bit) | - Supports SSE4.1 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/singleThread.html) rating near or greater than 1600 <br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (GeForce GTX 750) <br/> - 2 GB Video Memory | 4 GB |
|
||||
|
||||
_Note: Recommended Single Thread Performance is based on moderately complex games. Games that pushed the PS2 hardware to its limits will struggle on CPUs at this level. Some release titles and 2D games which underutilized the PS2 hardware may run on CPUs rated as low as 1200. A quick reference for CPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:CPU_intensive_games), [Forum](https://forums.pcsx2.net/Thread-LIST-The-Most-CPU-Intensive-Games) and CPU **light** games: [Forum](https://forums.pcsx2.net/Thread-LIST-Games-that-don-t-need-a-strong-CPU-to-emulate)_
|
||||
|
||||
@@ -40,6 +40,7 @@ _Note: Recommended GPU is based on 3x Internal, ~1080p resolution requirements.
|
||||
- You need the [Visual C++ 2019 x86 Redistributables](https://support.microsoft.com/en-us/help/2977003/) to run PCSX2.
|
||||
- Windows XP and Direct3D9 support was dropped after stable release 1.4.0.
|
||||
- Windows 7 and Windows 8 support was dropped after stable release 1.6.0.
|
||||
- 32 bit support was dropped after stable release 1.6.0.
|
||||
- Make sure to update your operating system and drivers to ensure you have the best experience possible. Having a newer GPU is also recommended so you have the latest supported drivers.
|
||||
- Because of copyright issues, and the complexity of trying to work around it, you need a BIOS dump extracted from a legitimately-owned PS2 console to use the emulator. For more information about the BIOS and how to get it from your console, visit [this page](pcsx2/Docs/PCSX2_FAQ.md#question-13-where-do-i-get-a-ps2-bios).
|
||||
- PCSX2 uses two CPU cores for emulation by default. A third core can be used via the MTVU speed hack, which is compatible with most games. This can be a significant speedup on CPUs with 3+ cores, but it may be a slowdown on GS-limited games (or on CPUs with fewer than 2 cores). Software renderers will then additionally use however many rendering threads it is set to and will need higher core counts to run efficiently.
|
||||
|
||||
Binary file not shown.
+2853
-144
File diff suppressed because it is too large
Load Diff
@@ -401,8 +401,8 @@
|
||||
03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,
|
||||
03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||
030000007e0500001920000000000000,Nintendo Switch N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,
|
||||
030000007e0500001720000000000000,Nintendo Switch Online Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
|
||||
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
030000007e0500001720000000000000,Nintendo Switch Online Controller,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b15,platform:Windows,
|
||||
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,misc1:b13,platform:Windows,
|
||||
030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,
|
||||
03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
|
||||
03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,
|
||||
@@ -833,6 +833,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000222c00000020000000010000,Qanba Drone Arcade Stick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,
|
||||
030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000321500000204000000010000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000321500000104000000010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
@@ -1112,6 +1113,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
030000005e040000ea02000008040000,Microsoft Xbox One S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
|
||||
030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
@@ -1137,7 +1139,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||
050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux,
|
||||
050000007e0500001920000001000000,Nintendo Switch N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
|
||||
050000007e0500001920000001000000,Nintendo Switch N64 Controller,+rightx:b8,-righty:b2,-rightx:b3,+righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
|
||||
050000007e0500001720000001000000,Nintendo Switch Online Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||
03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
#define PS_AUTOMATIC_LOD 0
|
||||
#define PS_MANUAL_LOD 0
|
||||
#define PS_TEX_IS_FB 0
|
||||
#define PS_NO_COLOR 0
|
||||
#define PS_NO_COLOR1 0
|
||||
#define PS_NO_ABLEND 0
|
||||
#define PS_ONLY_ALPHA 0
|
||||
#endif
|
||||
|
||||
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
|
||||
@@ -99,8 +103,12 @@ struct PS_INPUT
|
||||
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
#if !PS_NO_COLOR
|
||||
float4 c0 : SV_Target0;
|
||||
#if !PS_NO_COLOR1
|
||||
float4 c1 : SV_Target1;
|
||||
#endif
|
||||
#endif
|
||||
#if PS_ZCLAMP
|
||||
float depth : SV_Depth;
|
||||
#endif
|
||||
@@ -854,8 +862,21 @@ PS_OUTPUT ps_main(PS_INPUT input)
|
||||
|
||||
ps_fbmask(C, input.p.xy);
|
||||
|
||||
#if !PS_NO_COLOR
|
||||
output.c0 = C / 255.0f;
|
||||
#if !PS_NO_COLOR1
|
||||
output.c1 = (float4)(alpha_blend);
|
||||
#endif
|
||||
|
||||
#if PS_NO_ABLEND
|
||||
// write alpha blend factor into col0
|
||||
output.c0.a = alpha_blend;
|
||||
#endif
|
||||
#if PS_ONLY_ALPHA
|
||||
// rgb isn't used
|
||||
output.c0.rgb = float3(0.0f, 0.0f, 0.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PS_ZCLAMP
|
||||
output.depth = min(input.p.z, MaxDepthPS);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#endif
|
||||
|
||||
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
|
||||
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
|
||||
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
||||
@@ -38,12 +39,36 @@ in SHADER
|
||||
#endif
|
||||
} PSin;
|
||||
|
||||
// Same buffer but 2 colors for dual source blending
|
||||
layout(location = 0, index = 0) out vec4 SV_Target0;
|
||||
layout(location = 0, index = 1) out vec4 SV_Target1;
|
||||
#define TARGET_0_QUALIFIER out
|
||||
|
||||
// Only enable framebuffer fetch when we actually need it.
|
||||
#if HAS_FRAMEBUFFER_FETCH && (PS_TEX_IS_FB == 1 || PS_FBMASK || SW_BLEND_NEEDS_RT || PS_DATE != 0)
|
||||
// We need to force the colour to be defined here, to read from it.
|
||||
// Basically the only scenario where this'll happen is RGBA masked and DATE is active.
|
||||
#undef PS_NO_COLOR
|
||||
#define PS_NO_COLOR 0
|
||||
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||
#undef TARGET_0_QUALIFIER
|
||||
#define TARGET_0_QUALIFIER inout
|
||||
#define LAST_FRAG_COLOR SV_Target0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !PS_NO_COLOR
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
// Same buffer but 2 colors for dual source blending
|
||||
layout(location = 0, index = 0) TARGET_0_QUALIFIER vec4 SV_Target0;
|
||||
layout(location = 0, index = 1) out vec4 SV_Target1;
|
||||
#else
|
||||
layout(location = 0) TARGET_0_QUALIFIER vec4 SV_Target0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
layout(binding = 1) uniform sampler2D PaletteSampler;
|
||||
|
||||
#if !HAS_FRAMEBUFFER_FETCH
|
||||
layout(binding = 2) uniform sampler2D RtSampler; // note 2 already use by the image below
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_GL42_image
|
||||
#if PS_DATE > 0
|
||||
@@ -79,7 +104,11 @@ layout(early_fragment_tests) in;
|
||||
vec4 sample_c(vec2 uv)
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
return LAST_FRAG_COLOR;
|
||||
#else
|
||||
return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if PS_POINT_SAMPLER
|
||||
@@ -234,7 +263,11 @@ mat4 sample_4p(vec4 u)
|
||||
int fetch_raw_depth()
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
return int(LAST_FRAG_COLOR.r * exp2(32.0f));
|
||||
#else
|
||||
return int(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).r * exp2(32.0f));
|
||||
#endif
|
||||
#else
|
||||
return int(texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0).r * exp2(32.0f));
|
||||
#endif
|
||||
@@ -243,7 +276,11 @@ int fetch_raw_depth()
|
||||
vec4 fetch_raw_color()
|
||||
{
|
||||
#if PS_TEX_IS_FB == 1
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
return LAST_FRAG_COLOR;
|
||||
#else
|
||||
return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#endif
|
||||
#else
|
||||
return texelFetch(TextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#endif
|
||||
@@ -603,7 +640,11 @@ void ps_fbmask(inout vec4 C)
|
||||
{
|
||||
// FIXME do I need special case for 16 bits
|
||||
#if PS_FBMASK
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
vec4 RT = trunc(LAST_FRAG_COLOR * 255.0f + 0.1f);
|
||||
#else
|
||||
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
|
||||
#endif
|
||||
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
|
||||
#endif
|
||||
}
|
||||
@@ -659,7 +700,14 @@ void ps_blend(inout vec4 Color, float As)
|
||||
return;
|
||||
#endif
|
||||
|
||||
vec3 Cs = Color.rgb;
|
||||
|
||||
#if SW_BLEND_NEEDS_RT
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
vec4 RT = trunc(LAST_FRAG_COLOR * 255.0f + 0.1f);
|
||||
#else
|
||||
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
|
||||
#endif
|
||||
|
||||
#if PS_DFMT == FMT_24
|
||||
float Ad = 1.0f;
|
||||
@@ -671,7 +719,7 @@ void ps_blend(inout vec4 Color, float As)
|
||||
|
||||
// Let the compiler do its jobs !
|
||||
vec3 Cd = RT.rgb;
|
||||
vec3 Cs = Color.rgb;
|
||||
#endif
|
||||
|
||||
#if PS_BLEND_A == 0
|
||||
vec3 A = Cs;
|
||||
@@ -748,14 +796,24 @@ void ps_main()
|
||||
if ((int(gl_FragCoord.y) & 1) == (PS_SCANMSK & 1))
|
||||
discard;
|
||||
#endif
|
||||
|
||||
#if PS_DATE != 0
|
||||
#if ((PS_DATE & 3) == 1 || (PS_DATE & 3) == 2)
|
||||
|
||||
#if PS_WRITE_RG == 1
|
||||
// Pseudo 16 bits access.
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
float rt_a = LAST_FRAG_COLOR.g;
|
||||
#else
|
||||
float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).g;
|
||||
#endif
|
||||
#else
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
float rt_a = LAST_FRAG_COLOR.a;
|
||||
#else
|
||||
float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).a;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (PS_DATE & 3) == 1
|
||||
// DATM == 0: Pixel with alpha equal to 1 will failed
|
||||
@@ -784,6 +842,7 @@ void ps_main()
|
||||
if (gl_PrimitiveID > stencil_ceil) {
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec4 C = ps_color();
|
||||
@@ -845,7 +904,11 @@ void ps_main()
|
||||
|
||||
// Must be done before alpha correction
|
||||
#if (PS_BLEND_C == 1 && PS_CLR_HW > 3)
|
||||
#if HAS_FRAMEBUFFER_FETCH
|
||||
vec4 RT = trunc(LAST_FRAG_COLOR * 255.0f + 0.1f);
|
||||
#else
|
||||
vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f);
|
||||
#endif
|
||||
float alpha_blend = (PS_DFMT == FMT_24) ? 1.0f : RT.a / 128.0f;
|
||||
#else
|
||||
float alpha_blend = C.a / 128.0f;
|
||||
@@ -885,8 +948,21 @@ void ps_main()
|
||||
|
||||
ps_fbmask(C);
|
||||
|
||||
#if !PS_NO_COLOR
|
||||
SV_Target0 = C / 255.0f;
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
SV_Target1 = vec4(alpha_blend);
|
||||
#endif
|
||||
|
||||
#if PS_NO_ABLEND
|
||||
// write alpha blend factor into col0
|
||||
SV_Target0.a = alpha_blend;
|
||||
#endif
|
||||
#if PS_ONLY_ALPHA
|
||||
// rgb isn't used
|
||||
SV_Target0.rgb = vec3(0.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PS_ZCLAMP
|
||||
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
|
||||
|
||||
@@ -378,7 +378,7 @@ layout(location = 0) in VSOutput
|
||||
#endif
|
||||
} vsIn;
|
||||
|
||||
#ifndef DISABLE_DUAL_SOURCE
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
layout(location = 0, index = 0) out vec4 o_col0;
|
||||
layout(location = 0, index = 1) out vec4 o_col1;
|
||||
#else
|
||||
@@ -389,7 +389,13 @@ layout(set = 1, binding = 0) uniform sampler2D Texture;
|
||||
layout(set = 1, binding = 1) uniform sampler2D Palette;
|
||||
|
||||
#if PS_FEEDBACK_LOOP_IS_NEEDED
|
||||
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
|
||||
#ifndef DISABLE_TEXTURE_BARRIER
|
||||
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
|
||||
vec4 sample_from_rt() { return subpassLoad(RtSampler); }
|
||||
#else
|
||||
layout(set = 2, binding = 0) uniform texture2D RtSampler;
|
||||
vec4 sample_from_rt() { return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PS_DATE > 0
|
||||
@@ -399,7 +405,7 @@ layout(set = 2, binding = 1) uniform texture2D PrimMinTexture;
|
||||
vec4 sample_c(vec2 uv)
|
||||
{
|
||||
#if PS_TEX_IS_FB
|
||||
return subpassLoad(RtSampler);
|
||||
return sample_from_rt();
|
||||
#else
|
||||
#if PS_POINT_SAMPLER
|
||||
// Weird issue with ATI/AMD cards,
|
||||
@@ -549,7 +555,7 @@ mat4 sample_4p(vec4 u)
|
||||
int fetch_raw_depth(ivec2 xy)
|
||||
{
|
||||
#if PS_TEX_IS_FB
|
||||
vec4 col = subpassLoad(RtSampler);
|
||||
vec4 col = sample_from_rt();
|
||||
#else
|
||||
vec4 col = texelFetch(Texture, xy, 0);
|
||||
#endif
|
||||
@@ -559,7 +565,7 @@ int fetch_raw_depth(ivec2 xy)
|
||||
vec4 fetch_raw_color(ivec2 xy)
|
||||
{
|
||||
#if PS_TEX_IS_FB
|
||||
return subpassLoad(RtSampler);
|
||||
return sample_from_rt();
|
||||
#else
|
||||
return texelFetch(Texture, xy, 0);
|
||||
#endif
|
||||
@@ -935,7 +941,7 @@ vec4 ps_color()
|
||||
void ps_fbmask(inout vec4 C)
|
||||
{
|
||||
#if PS_FBMASK
|
||||
vec4 RT = trunc(subpassLoad(RtSampler) * 255.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
|
||||
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
|
||||
#endif
|
||||
}
|
||||
@@ -995,7 +1001,7 @@ void ps_blend(inout vec4 Color, float As)
|
||||
#endif
|
||||
|
||||
#if PS_FEEDBACK_LOOP_IS_NEEDED
|
||||
vec4 RT = trunc(subpassLoad(RtSampler) * 255.0f + 0.1f);
|
||||
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
|
||||
#else
|
||||
// Not used, but we define it to make the selection below simpler.
|
||||
vec4 RT = vec4(0.0f);
|
||||
@@ -1095,9 +1101,9 @@ void main()
|
||||
|
||||
#if PS_WRITE_RG == 1
|
||||
// Pseudo 16 bits access.
|
||||
float rt_a = subpassLoad(RtSampler).g;
|
||||
float rt_a = sample_from_rt().g;
|
||||
#else
|
||||
float rt_a = subpassLoad(RtSampler).a;
|
||||
float rt_a = sample_from_rt().a;
|
||||
#endif
|
||||
|
||||
#if (PS_DATE & 3) == 1
|
||||
@@ -1195,11 +1201,22 @@ void main()
|
||||
|
||||
ps_fbmask(C);
|
||||
|
||||
#if !PS_NO_COLOR
|
||||
o_col0 = C / 255.0f;
|
||||
#ifndef DISABLE_DUAL_SOURCE
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
o_col1 = vec4(alpha_blend);
|
||||
#endif
|
||||
|
||||
#if PS_NO_ABLEND
|
||||
// write alpha blend factor into col0
|
||||
o_col0.a = alpha_blend;
|
||||
#endif
|
||||
#if PS_ONLY_ALPHA
|
||||
// rgb isn't used
|
||||
o_col0.rgb = vec3(0.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PS_ZCLAMP
|
||||
gl_FragDepth = min(gl_FragCoord.z, MaxDepthPS);
|
||||
#endif
|
||||
|
||||
@@ -140,44 +140,13 @@ endif()
|
||||
# Architecture bitness detection
|
||||
include(TargetArch)
|
||||
target_architecture(PCSX2_TARGET_ARCHITECTURES)
|
||||
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64" OR ${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
|
||||
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
|
||||
message(STATUS "Compiling a ${PCSX2_TARGET_ARCHITECTURES} build on a ${CMAKE_HOST_SYSTEM_PROCESSOR} host.")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
|
||||
endif()
|
||||
|
||||
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
|
||||
# * -fPIC option was removed for multiple reasons.
|
||||
# - Code only supports the x86 architecture.
|
||||
# - code uses the ebx register so it's not compliant with PIC.
|
||||
# - Impacts the performance too much.
|
||||
# - Only plugins. No package will link to them.
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE OFF)
|
||||
|
||||
if(NOT DEFINED ARCH_FLAG)
|
||||
if (MSVC)
|
||||
set(ARCH_FLAG /arch:SSE2)
|
||||
else()
|
||||
if (DISABLE_ADVANCE_SIMD)
|
||||
if (USE_ICC)
|
||||
set(ARCH_FLAG "-msse2 -msse4.1")
|
||||
else()
|
||||
set(ARCH_FLAG "-msse -msse2 -msse4.1 -mfxsr -march=i686")
|
||||
endif()
|
||||
else()
|
||||
# AVX requires some fix of the ABI (mangling) (default 2)
|
||||
# Note: V6 requires GCC 4.7
|
||||
#set(ARCH_FLAG "-march=native -fabi-version=6")
|
||||
set(ARCH_FLAG "-mfxsr -march=native")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND PCSX2_DEFS _ARCH_32=1 _M_X86=1 _M_X86_32=1)
|
||||
set(_ARCH_32 1)
|
||||
set(_M_X86 1)
|
||||
set(_M_X86_32 1)
|
||||
elseif(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
|
||||
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
|
||||
# x86_64 requires -fPIC
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -193,10 +162,9 @@ elseif(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
|
||||
set(ARCH_FLAG "-march=native")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND PCSX2_DEFS _ARCH_64=1 _M_X86=1 _M_X86_64=1 __M_X86_64=1)
|
||||
list(APPEND PCSX2_DEFS _ARCH_64=1 _M_X86=1)
|
||||
set(_ARCH_64 1)
|
||||
set(_M_X86 1)
|
||||
set(_M_X86_64 1)
|
||||
else()
|
||||
# All but i386 requires -fPIC
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -53,7 +53,6 @@ target_sources(common PRIVATE
|
||||
emitter/LnxCpuDetect.cpp
|
||||
emitter/WinCpuDetect.cpp
|
||||
emitter/x86emitter.cpp
|
||||
x86/MemcpyFast.cpp
|
||||
Darwin/DarwinThreads.cpp
|
||||
Darwin/DarwinMisc.cpp
|
||||
Darwin/DarwinSemaphore.cpp
|
||||
|
||||
@@ -12,51 +12,6 @@
|
||||
; You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
; If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
IFDEF _M_X86_32
|
||||
|
||||
; -----------------------------------------
|
||||
; 32-bit X86
|
||||
; -----------------------------------------
|
||||
.386
|
||||
.model flat
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
PUBLIC @fastjmp_set@4
|
||||
PUBLIC @fastjmp_jmp@8
|
||||
|
||||
; void fastjmp_set(fastjmp_buf*)
|
||||
@fastjmp_set@4 PROC
|
||||
mov eax, dword ptr [esp]
|
||||
mov edx, esp ; fixup stack pointer, so it doesn't include the call to fastjmp_set
|
||||
add edx, 4
|
||||
mov dword ptr [ecx], eax ; actually eip
|
||||
mov dword ptr [ecx + 4], ebx
|
||||
mov dword ptr [ecx + 8], edx ; actually esp
|
||||
mov dword ptr [ecx + 12], ebp
|
||||
mov dword ptr [ecx + 16], esi
|
||||
mov dword ptr [ecx + 20], edi
|
||||
xor eax, eax
|
||||
ret
|
||||
@fastjmp_set@4 ENDP
|
||||
|
||||
; void __fastcall fastjmp_jmp(fastjmp_buf*, int)
|
||||
@fastjmp_jmp@8 PROC
|
||||
mov eax, edx ; return code
|
||||
mov edx, dword ptr [ecx + 0]
|
||||
mov ebx, dword ptr [ecx + 4]
|
||||
mov esp, dword ptr [ecx + 8]
|
||||
mov ebp, dword ptr [ecx + 12]
|
||||
mov esi, dword ptr [ecx + 16]
|
||||
mov edi, dword ptr [ecx + 20]
|
||||
jmp edx
|
||||
@fastjmp_jmp@8 ENDP
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
ENDIF ; _M_X86_32
|
||||
|
||||
IFDEF _M_X86_64
|
||||
; -----------------------------------------
|
||||
; 64-bit X86
|
||||
; -----------------------------------------
|
||||
@@ -124,6 +79,4 @@ fastjmp_jmp ENDP
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
ENDIF ; _M_X86_64
|
||||
|
||||
END
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#define PREFIX ""
|
||||
#endif
|
||||
|
||||
#if defined(_M_X86_64)
|
||||
|
||||
asm(
|
||||
"\t.global " PREFIX "fastjmp_set\n"
|
||||
"\t.global " PREFIX "fastjmp_jmp\n"
|
||||
@@ -57,36 +55,4 @@ asm(
|
||||
jmp *%rdx
|
||||
)");
|
||||
|
||||
#elif defined(_M_X86_32)
|
||||
|
||||
asm(
|
||||
"\t.global " PREFIX "fastjmp_set\n"
|
||||
"\t.global " PREFIX "fastjmp_jmp\n"
|
||||
"\t.text\n"
|
||||
"\t" PREFIX "fastjmp_set:" R"(
|
||||
movl 0(%esp), %eax
|
||||
movl %esp, %edx # fixup stack pointer, so it doesn't include the call to fastjmp_set
|
||||
addl $4, %edx
|
||||
movl %eax, 0(%ecx) # actually eip
|
||||
movl %ebx, 4(%ecx)
|
||||
movl %edx, 8(%ecx) # actually esp
|
||||
movl %ebp, 12(%ecx)
|
||||
movl %esi, 16(%ecx)
|
||||
movl %edi, 20(%ecx)
|
||||
xorl %eax, %eax
|
||||
ret
|
||||
)"
|
||||
"\t" PREFIX "fastjmp_jmp:" R"(
|
||||
movl %edx, %eax
|
||||
movl 0(%ecx), %edx # actually eip
|
||||
movl 4(%ecx), %ebx
|
||||
movl 8(%ecx), %esp # actually esp
|
||||
movl 12(%ecx), %ebp
|
||||
movl 16(%ecx), %esi
|
||||
movl 20(%ecx), %edi
|
||||
jmp *%edx
|
||||
)");
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __WIN32
|
||||
|
||||
+2
-6
@@ -20,14 +20,10 @@
|
||||
|
||||
struct fastjmp_buf
|
||||
{
|
||||
#if defined(_M_X86_64) && defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
static constexpr std::size_t BUF_SIZE = 240;
|
||||
#elif defined(_M_X86_64)
|
||||
static constexpr std::size_t BUF_SIZE = 64;
|
||||
#elif defined(_M_X86_32)
|
||||
static constexpr std::size_t BUF_SIZE = 24;
|
||||
#else
|
||||
#error Unknown architecture.
|
||||
static constexpr std::size_t BUF_SIZE = 64;
|
||||
#endif
|
||||
|
||||
alignas(16) std::uint8_t buf[BUF_SIZE];
|
||||
|
||||
@@ -504,7 +504,7 @@ std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(const char* filename)
|
||||
std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(std::FILE* fp)
|
||||
{
|
||||
std::fseek(fp, 0, SEEK_END);
|
||||
long size = std::ftell(fp);
|
||||
const long size = std::ftell(fp);
|
||||
std::fseek(fp, 0, SEEK_SET);
|
||||
if (size < 0)
|
||||
return std::nullopt;
|
||||
@@ -528,13 +528,14 @@ std::optional<std::string> FileSystem::ReadFileToString(const char* filename)
|
||||
std::optional<std::string> FileSystem::ReadFileToString(std::FILE* fp)
|
||||
{
|
||||
std::fseek(fp, 0, SEEK_END);
|
||||
long size = std::ftell(fp);
|
||||
const long size = std::ftell(fp);
|
||||
std::fseek(fp, 0, SEEK_SET);
|
||||
if (size < 0)
|
||||
return std::nullopt;
|
||||
|
||||
std::string res;
|
||||
res.resize(static_cast<size_t>(size));
|
||||
// NOTE - assumes mode 'rb', for example, this will fail over missing Windows carriage return bytes
|
||||
if (size > 0 && std::fread(res.data(), 1u, static_cast<size_t>(size), fp) != static_cast<size_t>(size))
|
||||
return std::nullopt;
|
||||
|
||||
@@ -553,7 +554,7 @@ bool FileSystem::WriteBinaryFile(const char* filename, const void* data, size_t
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileSystem::WriteFileToString(const char* filename, const std::string_view& sv)
|
||||
bool FileSystem::WriteStringToFile(const char* filename, const std::string_view& sv)
|
||||
{
|
||||
ManagedCFilePtr fp = OpenManagedCFile(filename, "wb");
|
||||
if (!fp)
|
||||
@@ -1269,7 +1270,7 @@ bool FileSystem::FindFiles(const char* Path, const char* Pattern, u32 Flags, Fin
|
||||
|
||||
bool FileSystem::StatFile(const char* path, struct stat* st)
|
||||
{
|
||||
return stat(path, st);
|
||||
return stat(path, st) == 0;
|
||||
}
|
||||
|
||||
bool FileSystem::StatFile(std::FILE* fp, struct stat* st)
|
||||
@@ -1278,7 +1279,7 @@ bool FileSystem::StatFile(std::FILE* fp, struct stat* st)
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
return fstat(fd, st);
|
||||
return fstat(fd, st) == 0;
|
||||
}
|
||||
|
||||
bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* sd)
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ namespace FileSystem
|
||||
std::optional<std::string> ReadFileToString(const char* filename);
|
||||
std::optional<std::string> ReadFileToString(std::FILE* fp);
|
||||
bool WriteBinaryFile(const char* filename, const void* data, size_t data_length);
|
||||
bool WriteFileToString(const char* filename, const std::string_view& sv);
|
||||
bool WriteStringToFile(const char* filename, const std::string_view& sv);
|
||||
|
||||
/// creates a directory in the local filesystem
|
||||
/// if the directory already exists, the return value will be true.
|
||||
|
||||
@@ -19,14 +19,6 @@
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include "common/Pcsx2Defs.h"
|
||||
|
||||
// For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and
|
||||
// other implementations. So for this combination only, prefer memcmp_mmx
|
||||
#if defined(_MSC_VER) && !defined(_M_X86_64)
|
||||
extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
|
||||
#else
|
||||
#define memcmp_mmx memcmp
|
||||
#endif
|
||||
|
||||
// This method can clear any object-like entity -- which is anything that is not a pointer.
|
||||
// Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically
|
||||
// for you!
|
||||
|
||||
+1
-5
@@ -110,11 +110,7 @@ static const int __pagesize = PCSX2_PAGESIZE;
|
||||
// happens *by design* like all the friggen time >_<)
|
||||
|
||||
#ifndef __fastcall
|
||||
#ifndef _M_X86_32
|
||||
#define __fastcall // Attribute not available, and x86_32 is pretty much the only cc that passes literally everything in registers
|
||||
#else
|
||||
#define __fastcall __attribute__((fastcall))
|
||||
#endif
|
||||
#define __fastcall
|
||||
#endif
|
||||
#define __vectorcall __fastcall
|
||||
#define _inline __inline__ __attribute__((unused))
|
||||
|
||||
@@ -225,12 +225,7 @@ extern bool pxParseAssignmentString(const wxString& src, wxString& ldest, wxStri
|
||||
|
||||
#define pxsFmt FastFormatUnicode().Write
|
||||
#define pxsFmtV FastFormatUnicode().WriteV
|
||||
|
||||
#ifdef _M_X86_64
|
||||
#define pxsPtr(ptr) pxsFmt("0x%016" PRIXPTR, (ptr)).c_str()
|
||||
#else
|
||||
#define pxsPtr(ptr) pxsFmt("0x%08" PRIXPTR, (ptr)).c_str()
|
||||
#endif
|
||||
|
||||
extern wxString& operator+=(wxString& str1, const FastFormatUnicode& str2);
|
||||
extern wxString operator+(const wxString& str1, const FastFormatUnicode& str2);
|
||||
|
||||
@@ -153,6 +153,17 @@ namespace StringUtil
|
||||
return (str.length() >= suffix_length && str.compare(str.length() - suffix_length, suffix_length, suffix) == 0);
|
||||
}
|
||||
|
||||
/// StartsWith/EndsWith variants which aren't case sensitive.
|
||||
static inline bool StartsWithNoCase(const std::string_view& str, const char* prefix)
|
||||
{
|
||||
return (Strncasecmp(str.data(), prefix, std::strlen(prefix)) == 0);
|
||||
}
|
||||
static inline bool EndsWithNoCase(const std::string_view& str, const char* suffix)
|
||||
{
|
||||
const std::size_t suffix_length = std::strlen(suffix);
|
||||
return (str.length() >= suffix_length && Strncasecmp(str.data() + (str.length() - suffix_length), suffix, suffix_length) == 0);
|
||||
}
|
||||
|
||||
/// Strip whitespace from the start/end of the string.
|
||||
std::string_view StripWhitespace(const std::string_view& str);
|
||||
|
||||
|
||||
@@ -352,6 +352,11 @@ namespace Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsPipelineBuilder::AddBlendFlags(u32 flags)
|
||||
{
|
||||
m_blend_state.flags |= flags;
|
||||
}
|
||||
|
||||
void GraphicsPipelineBuilder::ClearBlendAttachments()
|
||||
{
|
||||
m_blend_attachments = {};
|
||||
|
||||
@@ -112,6 +112,7 @@ namespace Vulkan
|
||||
VkBlendOp op, VkBlendFactor alpha_src_factor, VkBlendFactor alpha_dst_factor, VkBlendOp alpha_op,
|
||||
VkColorComponentFlags write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
|
||||
void AddBlendFlags(u32 flags);
|
||||
void ClearBlendAttachments();
|
||||
|
||||
void SetBlendConstants(float r, float g, float b, float a);
|
||||
|
||||
+97
-15
@@ -445,6 +445,8 @@ namespace Vulkan
|
||||
SupportsExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_khr_driver_properties =
|
||||
SupportsExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_arm_rasterization_order_attachment_access =
|
||||
SupportsExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -597,11 +599,19 @@ namespace Vulkan
|
||||
// provoking vertex
|
||||
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
|
||||
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
|
||||
|
||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||
{
|
||||
provoking_vertex_feature.provokingVertexLast = VK_TRUE;
|
||||
Util::AddPointerToChain(&device_info, &provoking_vertex_feature);
|
||||
}
|
||||
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
|
||||
{
|
||||
rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE;
|
||||
Util::AddPointerToChain(&device_info, &rasterization_order_access_feature);
|
||||
}
|
||||
|
||||
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
||||
if (res != VK_SUCCESS)
|
||||
@@ -621,6 +631,9 @@ namespace Vulkan
|
||||
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
|
||||
}
|
||||
|
||||
m_gpu_timing_supported = (queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0);
|
||||
DevCon.WriteLn("GPU timing is %s", m_gpu_timing_supported ? "supported" : "not supported");
|
||||
|
||||
ProcessDeviceExtensions();
|
||||
return true;
|
||||
}
|
||||
@@ -633,20 +646,21 @@ namespace Vulkan
|
||||
VkPhysicalDeviceFeatures2 features2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
|
||||
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_features = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
|
||||
void** pNext = &features2.pNext;
|
||||
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
|
||||
|
||||
// add in optional feature structs
|
||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||
{
|
||||
*pNext = &provoking_vertex_features;
|
||||
pNext = &provoking_vertex_features.pNext;
|
||||
}
|
||||
Util::AddPointerToChain(&features2, &provoking_vertex_features);
|
||||
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
|
||||
Util::AddPointerToChain(&features2, &rasterization_order_access_feature);
|
||||
|
||||
// query
|
||||
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
|
||||
|
||||
// confirm we actually support it
|
||||
m_optional_extensions.vk_ext_provoking_vertex &= (provoking_vertex_features.provokingVertexLast == VK_TRUE);
|
||||
m_optional_extensions.vk_arm_rasterization_order_attachment_access &= (rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess == VK_TRUE);
|
||||
}
|
||||
|
||||
if (vkGetPhysicalDeviceProperties2)
|
||||
@@ -667,6 +681,8 @@ namespace Vulkan
|
||||
|
||||
Console.WriteLn("VK_EXT_provoking_vertex is %s",
|
||||
m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_ARM_rasterization_order_attachment_access is %s",
|
||||
m_optional_extensions.vk_arm_rasterization_order_attachment_access ? "supported" : "NOT supported");
|
||||
}
|
||||
|
||||
bool Context::CreateAllocator()
|
||||
@@ -823,11 +839,30 @@ namespace Vulkan
|
||||
return false;
|
||||
}
|
||||
Vulkan::Util::SetObjectName(g_vulkan_context->GetDevice(), m_global_descriptor_pool, "Global Descriptor Pool");
|
||||
|
||||
if (m_gpu_timing_supported)
|
||||
{
|
||||
const VkQueryPoolCreateInfo query_create_info = {VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, nullptr,
|
||||
0, VK_QUERY_TYPE_TIMESTAMP, NUM_COMMAND_BUFFERS * 2, 0};
|
||||
res = vkCreateQueryPool(m_device, &query_create_info, nullptr, &m_timestamp_query_pool);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateQueryPool failed: ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Context::DestroyGlobalDescriptorPool()
|
||||
{
|
||||
if (m_timestamp_query_pool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyQueryPool(m_device, m_timestamp_query_pool, nullptr);
|
||||
m_timestamp_query_pool = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (m_global_descriptor_pool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyDescriptorPool(m_device, m_global_descriptor_pool, nullptr);
|
||||
@@ -920,6 +955,18 @@ namespace Vulkan
|
||||
vkDeviceWaitIdle(m_device);
|
||||
}
|
||||
|
||||
float Context::GetAndResetAccumulatedGPUTime()
|
||||
{
|
||||
const float time = m_accumulated_gpu_time;
|
||||
m_accumulated_gpu_time = 0.0f;
|
||||
return time;
|
||||
}
|
||||
|
||||
void Context::SetEnableGPUTiming(bool enabled)
|
||||
{
|
||||
m_gpu_timing_enabled = enabled && m_gpu_timing_supported;
|
||||
}
|
||||
|
||||
void Context::WaitForCommandBufferCompletion(u32 index)
|
||||
{
|
||||
// Wait for this command buffer to be completed.
|
||||
@@ -968,6 +1015,11 @@ namespace Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
{
|
||||
vkCmdWriteTimestamp(m_current_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, m_timestamp_query_pool, m_current_frame * 2 + 1);
|
||||
}
|
||||
|
||||
res = vkEndCommandBuffer(resources.command_buffers[1]);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
@@ -1145,6 +1197,29 @@ namespace Vulkan
|
||||
|
||||
// using the lower 32 bits of the fence index should be sufficient here, I hope...
|
||||
vmaSetCurrentFrameIndex(m_allocator, static_cast<u32>(m_next_fence_counter));
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
{
|
||||
std::array<u64, 2> timestamps;
|
||||
res = vkGetQueryPoolResults(m_device, m_timestamp_query_pool, index * 2, static_cast<u32>(timestamps.size()),
|
||||
sizeof(u64) * timestamps.size(), timestamps.data(), sizeof(u64), VK_QUERY_RESULT_64_BIT);
|
||||
if (res == VK_SUCCESS)
|
||||
{
|
||||
// if we didn't write the timestamp at the start of the cmdbuffer (just enabled timing), the first TS will be zero
|
||||
if (timestamps[0] > 0)
|
||||
{
|
||||
const u64 ns_diff = (timestamps[1] - timestamps[0]) * static_cast<u64>(m_device_properties.limits.timestampPeriod);
|
||||
m_accumulated_gpu_time += static_cast<double>(ns_diff) / 1000000.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkGetQueryPoolResults failed: ");
|
||||
}
|
||||
|
||||
vkCmdResetQueryPool(m_current_command_buffer, m_timestamp_query_pool, index * 2, 2);
|
||||
vkCmdWriteTimestamp(m_current_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, m_timestamp_query_pool, index * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void Context::ExecuteCommandBuffer(bool wait_for_completion)
|
||||
@@ -1326,15 +1401,19 @@ namespace Vulkan
|
||||
input_reference.layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
input_reference_ptr = &input_reference;
|
||||
|
||||
subpass_dependency.srcSubpass = 0;
|
||||
subpass_dependency.dstSubpass = 0;
|
||||
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
subpass_dependency.srcAccessMask =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
subpass_dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
|
||||
subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
subpass_dependency_ptr = &subpass_dependency;
|
||||
if (!g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
|
||||
{
|
||||
// don't need the framebuffer-local dependency when we have rasterization order attachment access
|
||||
subpass_dependency.srcSubpass = 0;
|
||||
subpass_dependency.dstSubpass = 0;
|
||||
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
subpass_dependency.srcAccessMask =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
subpass_dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
|
||||
subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
subpass_dependency_ptr = &subpass_dependency;
|
||||
}
|
||||
}
|
||||
|
||||
num_attachments++;
|
||||
@@ -1353,7 +1432,10 @@ namespace Vulkan
|
||||
num_attachments++;
|
||||
}
|
||||
|
||||
const VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
|
||||
const VkSubpassDescriptionFlags subpass_flags =
|
||||
(key.color_feedback_loop && g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
|
||||
? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM : 0;
|
||||
const VkSubpassDescription subpass = {subpass_flags, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
|
||||
input_reference_ptr ? input_reference_ptr : nullptr, color_reference_ptr ? 1u : 0u,
|
||||
color_reference_ptr ? color_reference_ptr : nullptr, nullptr, depth_reference_ptr, 0, nullptr};
|
||||
const VkRenderPassCreateInfo pass_info = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0u,
|
||||
|
||||
+11
-2
@@ -51,6 +51,7 @@ namespace Vulkan
|
||||
bool vk_ext_provoking_vertex : 1;
|
||||
bool vk_ext_memory_budget : 1;
|
||||
bool vk_khr_driver_properties : 1;
|
||||
bool vk_arm_rasterization_order_attachment_access : 1;
|
||||
};
|
||||
|
||||
~Context();
|
||||
@@ -208,6 +209,9 @@ namespace Vulkan
|
||||
|
||||
void WaitForGPUIdle();
|
||||
|
||||
float GetAndResetAccumulatedGPUTime();
|
||||
void SetEnableGPUTiming(bool enabled);
|
||||
|
||||
private:
|
||||
Context(VkInstance instance, VkPhysicalDevice physical_device);
|
||||
|
||||
@@ -284,14 +288,19 @@ namespace Vulkan
|
||||
VkDescriptorPool m_global_descriptor_pool = VK_NULL_HANDLE;
|
||||
|
||||
VkQueue m_graphics_queue = VK_NULL_HANDLE;
|
||||
u32 m_graphics_queue_family_index = 0;
|
||||
VkQueue m_present_queue = VK_NULL_HANDLE;
|
||||
u32 m_graphics_queue_family_index = 0;
|
||||
u32 m_present_queue_family_index = 0;
|
||||
|
||||
VkQueryPool m_timestamp_query_pool = VK_NULL_HANDLE;
|
||||
float m_accumulated_gpu_time = 0.0f;
|
||||
bool m_gpu_timing_enabled = false;
|
||||
bool m_gpu_timing_supported = false;
|
||||
|
||||
std::array<FrameResources, NUM_COMMAND_BUFFERS> m_frame_resources;
|
||||
u64 m_next_fence_counter = 1;
|
||||
u64 m_completed_fence_counter = 0;
|
||||
u32 m_current_frame;
|
||||
u32 m_current_frame = 0;
|
||||
|
||||
StreamBuffer m_texture_upload_buffer;
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@
|
||||
<ClCompile Include="Vulkan\Texture.cpp" />
|
||||
<ClCompile Include="Vulkan\Util.cpp" />
|
||||
<ClCompile Include="WindowInfo.cpp" />
|
||||
<ClCompile Include="x86\MemcpyFast.cpp" />
|
||||
<ClCompile Include="PathUtils.cpp" />
|
||||
<ClCompile Include="Perf.cpp" />
|
||||
<ClCompile Include="PrecompiledHeader.cpp">
|
||||
@@ -111,11 +110,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="EventSource.inl" />
|
||||
<MASM Include="FastJmp.asm">
|
||||
<FileType>Document</FileType>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">_M_X86_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_M_X86_64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</MASM>
|
||||
<MASM Include="FastJmp.asm" />
|
||||
<None Include="Vulkan\EntryPoints.inl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -49,9 +49,6 @@
|
||||
<ClCompile Include="Linux\LnxThreads.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="x86\MemcpyFast.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="emitter\movs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -230,9 +230,7 @@ void x86capabilities::Identify()
|
||||
Model = (regs[0] >> 4) & 0xf;
|
||||
FamilyID = (regs[0] >> 8) & 0xf;
|
||||
TypeID = (regs[0] >> 12) & 0x3;
|
||||
#ifdef __M_X86_64
|
||||
//u32 x86_64_8BITBRANDID = regs[1] & 0xff;
|
||||
#endif
|
||||
Flags = regs[3];
|
||||
Flags2 = regs[2];
|
||||
}
|
||||
@@ -251,9 +249,7 @@ void x86capabilities::Identify()
|
||||
{
|
||||
cpuid(regs, 0x80000001);
|
||||
|
||||
#ifdef __M_X86_64
|
||||
//u32 x86_64_12BITBRANDID = regs[1] & 0xfff;
|
||||
#endif
|
||||
EFlags2 = regs[2];
|
||||
EFlags = regs[3];
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace x86Emitter
|
||||
{
|
||||
if (sibdest.Is8BitOp())
|
||||
{
|
||||
xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest);
|
||||
xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest, 1);
|
||||
|
||||
xWrite<s8>(imm);
|
||||
}
|
||||
|
||||
@@ -65,10 +65,8 @@ namespace x86Emitter
|
||||
void operator()(void* f, u32 a1, u32 a2) const;
|
||||
void operator()(void* f, void* a1) const;
|
||||
|
||||
#ifdef __M_X86_64
|
||||
void operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2 = xEmptyReg) const;
|
||||
void operator()(void* f, u32 a1, const xRegisterLong& a2) const;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
__fi void operator()(T* func, u32 a1, const xRegisterLong& a2 = xEmptyReg) const
|
||||
|
||||
@@ -70,7 +70,6 @@ namespace x86Emitter
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __M_X86_64
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xImpl_MovImm64
|
||||
// --------------------------------------------------------------------------------------
|
||||
@@ -82,7 +81,6 @@ namespace x86Emitter
|
||||
|
||||
void operator()(const xRegister64& to, s64 imm, bool preserve_flags = false) const;
|
||||
};
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xImpl_CMov
|
||||
@@ -131,10 +129,8 @@ namespace x86Emitter
|
||||
void operator()(const xRegister16or32or64& to, const xIndirect8& sibsrc) const;
|
||||
void operator()(const xRegister32or64& to, const xRegister16& from) const;
|
||||
void operator()(const xRegister32or64& to, const xIndirect16& sibsrc) const;
|
||||
#ifdef __M_X86_64
|
||||
void operator()(const xRegister64& to, const xRegister32& from) const;
|
||||
void operator()(const xRegister64& to, const xIndirect32& sibsrc) const;
|
||||
#endif
|
||||
|
||||
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
|
||||
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
|
||||
|
||||
@@ -57,11 +57,8 @@ namespace x86Emitter
|
||||
// flags.
|
||||
|
||||
extern const xImpl_Mov xMOV;
|
||||
#ifdef __M_X86_64
|
||||
extern const xImpl_MovImm64 xMOV64;
|
||||
#endif
|
||||
extern const xImpl_Test xTEST;
|
||||
|
||||
extern const xImpl_Group2 xROL, xROR,
|
||||
xRCL, xRCR,
|
||||
xSHL, xSHR,
|
||||
@@ -222,7 +219,6 @@ namespace x86Emitter
|
||||
/// May use `tmp` on x86-64
|
||||
void xWriteImm64ToMem(u64* addr, const xAddressReg& tmp, u64 imm);
|
||||
|
||||
#ifdef __M_X86_64
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Helper function to run operations with large immediates
|
||||
/// If the immediate fits in 32 bits, runs op(target, imm)
|
||||
@@ -240,7 +236,6 @@ namespace x86Emitter
|
||||
op(dst, tmpRegister);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JMP / Jcc Instructions!
|
||||
|
||||
@@ -125,11 +125,7 @@ namespace x86Emitter
|
||||
|
||||
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
|
||||
|
||||
#ifdef __M_X86_64
|
||||
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
|
||||
#else
|
||||
u8 nR = 0x80;
|
||||
#endif
|
||||
u8 L = reg.IsWideSIMD() ? 4 : 0;
|
||||
|
||||
u8 nv = (~param2.GetId() & 0xF) << 3;
|
||||
@@ -155,15 +151,9 @@ namespace x86Emitter
|
||||
|
||||
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
|
||||
|
||||
#ifdef __M_X86_64
|
||||
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
|
||||
u8 nB = param3.IsExtended() ? 0x00 : 0x20;
|
||||
u8 nX = 0x40; // likely unused so hardwired to disabled
|
||||
#else
|
||||
u8 nR = 0x80;
|
||||
u8 nB = 0x20;
|
||||
u8 nX = 0x40;
|
||||
#endif
|
||||
u8 L = reg.IsWideSIMD() ? 4 : 0;
|
||||
u8 W = (w == -1) ? (reg.GetOperandSize() == 8 ? 0x80 : 0) : // autodetect the size
|
||||
0x80 * w; // take directly the W value
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace x86Emitter
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __M_X86_64
|
||||
void xImpl_FastCall::operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2) const
|
||||
{
|
||||
prepareRegsForFastcall(a1, a2);
|
||||
@@ -118,7 +117,6 @@ namespace x86Emitter
|
||||
xMOV(arg1reg, a1);
|
||||
(*this)(f, arg1reg, arg2reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
void xImpl_FastCall::operator()(void* f, void* a1) const
|
||||
{
|
||||
@@ -214,10 +212,8 @@ namespace x86Emitter
|
||||
s32* bah = xJcc32(comparison);
|
||||
sptr distance = (sptr)target - (sptr)xGetPtr();
|
||||
|
||||
#ifdef __M_X86_64
|
||||
// This assert won't physically happen on x86 targets
|
||||
pxAssertDev(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target is too far away, needs an indirect register");
|
||||
#endif
|
||||
|
||||
*bah = (s32)distance;
|
||||
}
|
||||
|
||||
+2
-28
@@ -55,18 +55,7 @@ namespace x86Emitter
|
||||
// mov eax has a special from when writing directly to a DISP32 address
|
||||
// (sans any register index/base registers).
|
||||
|
||||
#ifndef __M_X86_64
|
||||
// Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr
|
||||
if (from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty())
|
||||
{
|
||||
xOpAccWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from, dest);
|
||||
xWrite32(dest.Displacement);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest);
|
||||
}
|
||||
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest);
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()(const xRegisterInt& to, const xIndirectVoid& src) const
|
||||
@@ -74,18 +63,7 @@ namespace x86Emitter
|
||||
// mov eax has a special from when reading directly from a DISP32 address
|
||||
// (sans any register index/base registers).
|
||||
|
||||
#ifndef __M_X86_64
|
||||
// Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr
|
||||
if (to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty())
|
||||
{
|
||||
xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src);
|
||||
xWrite32(src.Displacement);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src);
|
||||
}
|
||||
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src);
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()(const xIndirect64orLess& dest, sptr imm) const
|
||||
@@ -153,7 +131,6 @@ namespace x86Emitter
|
||||
|
||||
const xImpl_Mov xMOV;
|
||||
|
||||
#ifdef __M_X86_64
|
||||
void xImpl_MovImm64::operator()(const xRegister64& to, s64 imm, bool preserve_flags) const
|
||||
{
|
||||
if (imm == (u32)imm || imm == (s32)imm)
|
||||
@@ -169,7 +146,6 @@ namespace x86Emitter
|
||||
}
|
||||
|
||||
const xImpl_MovImm64 xMOV64;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// CMOVcc
|
||||
@@ -241,7 +217,6 @@ namespace x86Emitter
|
||||
xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, sibsrc);
|
||||
}
|
||||
|
||||
#ifdef __M_X86_64
|
||||
void xImpl_MovExtend::operator()(const xRegister64& to, const xRegister32& from) const
|
||||
{
|
||||
EbpAssert();
|
||||
@@ -255,7 +230,6 @@ namespace x86Emitter
|
||||
pxAssertMsg(SignExtend, "Use mov for 64-bit movzx");
|
||||
xOpWrite(0, 0x63, to, sibsrc);
|
||||
}
|
||||
#endif
|
||||
|
||||
const xImpl_MovExtend xMOVSX = {true};
|
||||
const xImpl_MovExtend xMOVZX = {false};
|
||||
|
||||
@@ -93,9 +93,8 @@ namespace x86Emitter
|
||||
//
|
||||
__emitinline void SimdPrefix(u8 prefix, u16 opcode)
|
||||
{
|
||||
#ifdef __M_X86_64
|
||||
pxAssertMsg(prefix == 0, "REX prefix must be just before the opcode");
|
||||
#endif
|
||||
|
||||
const bool is16BitOpcode = ((opcode & 0xff) == 0x38) || ((opcode & 0xff) == 0x3a);
|
||||
|
||||
// If the lower byte is not a valid prefix and the upper byte is non-zero it
|
||||
|
||||
@@ -151,17 +151,12 @@ const xRegister8
|
||||
ah(4), ch(5),
|
||||
dh(6), bh(7);
|
||||
|
||||
#if defined(_WIN32) || !defined(__M_X86_64)
|
||||
#if defined(_WIN32)
|
||||
const xAddressReg
|
||||
arg1reg = rcx,
|
||||
arg2reg = rdx,
|
||||
#ifdef __M_X86_64
|
||||
arg3reg = r8,
|
||||
arg4reg = r9,
|
||||
#else
|
||||
arg3reg = xRegisterEmpty(),
|
||||
arg4reg = xRegisterEmpty(),
|
||||
#endif
|
||||
calleeSavedReg1 = rdi,
|
||||
calleeSavedReg2 = rsi;
|
||||
|
||||
@@ -214,7 +209,6 @@ const xRegister32
|
||||
"e12", "e13", "e14", "e15"
|
||||
};
|
||||
|
||||
#ifdef __M_X86_64
|
||||
const char* const x86_regnames_gpr64[] =
|
||||
{
|
||||
"rax", "rcx", "rdx", "rbx",
|
||||
@@ -222,7 +216,6 @@ const xRegister32
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15"
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* const x86_regnames_sse[] =
|
||||
{
|
||||
@@ -252,10 +245,8 @@ const xRegister32
|
||||
return x86_regnames_gpr16[Id];
|
||||
case 4:
|
||||
return x86_regnames_gpr32[Id];
|
||||
#ifdef __M_X86_64
|
||||
case 8:
|
||||
return x86_regnames_gpr64[Id];
|
||||
#endif
|
||||
case 16:
|
||||
return x86_regnames_sse[Id];
|
||||
}
|
||||
@@ -300,9 +291,6 @@ const xRegister32
|
||||
void EmitSibMagic(uint regfield, const void* address, int extraRIPOffset)
|
||||
{
|
||||
sptr displacement = (sptr)address;
|
||||
#ifndef __M_X86_64
|
||||
ModRM(0, regfield, ModRm_UseDisp32);
|
||||
#else
|
||||
sptr ripRelative = (sptr)address - ((sptr)x86Ptr + sizeof(s8) + sizeof(s32) + extraRIPOffset);
|
||||
// Can we use a rip-relative address? (Prefer this over eiz because it's a byte shorter)
|
||||
if (ripRelative == (s32)ripRelative)
|
||||
@@ -316,7 +304,6 @@ const xRegister32
|
||||
ModRM(0, regfield, ModRm_UseSib);
|
||||
SibSB(0, Sib_EIZ, Sib_UseDisp32);
|
||||
}
|
||||
#endif
|
||||
|
||||
xWrite<s32>((s32)displacement);
|
||||
}
|
||||
@@ -440,11 +427,9 @@ const xRegister32
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
__emitinline static void EmitRex(bool w, bool r, bool x, bool b)
|
||||
{
|
||||
#ifdef __M_X86_64
|
||||
const u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | (u8)b;
|
||||
if (rex != 0x40)
|
||||
xWrite8(rex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void EmitRex(uint regfield, const void* address)
|
||||
@@ -989,12 +974,8 @@ const xRegister32
|
||||
|
||||
__emitinline u32* xLEA_Writeback(xAddressReg to)
|
||||
{
|
||||
#ifdef __M_X86_64
|
||||
xOpWrite(0, 0x8d, to, ptr[(void*)(0xdcdcdcd + (uptr)xGetPtr() + 7)]);
|
||||
#else
|
||||
xOpAccWrite(0, 0xb8 | to.Id, 0, to);
|
||||
xWrite32(0xcdcdcdcd);
|
||||
#endif
|
||||
|
||||
return (u32*)xGetPtr() - 1;
|
||||
}
|
||||
|
||||
@@ -1045,12 +1026,7 @@ const xRegister32
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __M_X86_64
|
||||
xOpWrite(to.GetPrefix16(), 0xff, isDec ? 1 : 0, to);
|
||||
#else
|
||||
to.prefix16();
|
||||
xWrite8((isDec ? 0x48 : 0x40) | to.Id);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1200,25 +1176,10 @@ const xRegister32
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper object to handle ABI frame
|
||||
#ifdef __M_X86_64
|
||||
|
||||
// All x86-64 calling conventions ensure/require stack to be 16 bytes aligned
|
||||
// I couldn't find documentation on when, but compilers would indicate it's before the call: https://gcc.godbolt.org/z/KzTfsz
|
||||
#define ALIGN_STACK(v) xADD(rsp, v)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// GCC ensures/requires stack to be 16 bytes aligned before the call
|
||||
// Call will store 4 bytes. EDI/ESI/EBX will take another 12 bytes.
|
||||
// EBP will take 4 bytes if m_base_frame is enabled
|
||||
#define ALIGN_STACK(v) xADD(esp, v)
|
||||
|
||||
#else
|
||||
|
||||
#define ALIGN_STACK(v)
|
||||
|
||||
#endif
|
||||
|
||||
static void stackAlign(int offset, bool moveDown)
|
||||
{
|
||||
int needed = (16 - (offset % 16)) % 16;
|
||||
@@ -1250,8 +1211,6 @@ const xRegister32
|
||||
m_offset += sizeof(void*);
|
||||
}
|
||||
|
||||
#ifdef __M_X86_64
|
||||
|
||||
xPUSH(rbx);
|
||||
xPUSH(r12);
|
||||
xPUSH(r13);
|
||||
@@ -1265,16 +1224,6 @@ const xRegister32
|
||||
m_offset += 48;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// Save the register context
|
||||
xPUSH(edi);
|
||||
xPUSH(esi);
|
||||
xPUSH(ebx);
|
||||
m_offset += 12;
|
||||
|
||||
#endif
|
||||
|
||||
stackAlign(m_offset, true);
|
||||
}
|
||||
|
||||
@@ -1282,8 +1231,6 @@ const xRegister32
|
||||
{
|
||||
stackAlign(m_offset, false);
|
||||
|
||||
#ifdef __M_X86_64
|
||||
|
||||
// Restore the register context
|
||||
#ifdef _WIN32
|
||||
xADD(rsp, 32);
|
||||
@@ -1296,15 +1243,6 @@ const xRegister32
|
||||
xPOP(r12);
|
||||
xPOP(rbx);
|
||||
|
||||
#else
|
||||
|
||||
// Restore the register context
|
||||
xPOP(ebx);
|
||||
xPOP(esi);
|
||||
xPOP(edi);
|
||||
|
||||
#endif
|
||||
|
||||
// Destroy the frame
|
||||
if (m_base_frame)
|
||||
{
|
||||
@@ -1352,7 +1290,6 @@ const xRegister32
|
||||
|
||||
void xLoadFarAddr(const xAddressReg& dst, void* addr)
|
||||
{
|
||||
#ifdef __M_X86_64
|
||||
sptr iaddr = (sptr)addr;
|
||||
sptr rip = (sptr)xGetPtr() + 7; // LEA will be 7 bytes
|
||||
sptr disp = iaddr - rip;
|
||||
@@ -1364,19 +1301,11 @@ const xRegister32
|
||||
{
|
||||
xMOV64(dst, iaddr);
|
||||
}
|
||||
#else
|
||||
xMOV(dst, (sptr)addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void xWriteImm64ToMem(u64* addr, const xAddressReg& tmp, u64 imm)
|
||||
{
|
||||
#ifdef __M_X86_64
|
||||
xImm64Op(xMOV, ptr64[addr], tmp, imm);
|
||||
#else
|
||||
xMOV(ptr32[(u32*)addr], (u32)(imm & 0xFFFFFFFF));
|
||||
xMOV(ptr32[(u32*)addr + 1], (u32)(imm >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // End namespace x86Emitter
|
||||
|
||||
@@ -17,14 +17,8 @@
|
||||
|
||||
#include "common/Threading.h"
|
||||
|
||||
#ifdef __M_X86_64
|
||||
static const uint iREGCNT_XMM = 16;
|
||||
static const uint iREGCNT_GPR = 16;
|
||||
#else
|
||||
// Register counts for x86/32 mode:
|
||||
static const uint iREGCNT_XMM = 8;
|
||||
static const uint iREGCNT_GPR = 8;
|
||||
#endif
|
||||
|
||||
enum XMMSSEType
|
||||
{
|
||||
@@ -313,17 +307,10 @@ namespace x86Emitter
|
||||
bool IsSIMD() const { return GetOperandSize() == 16; }
|
||||
|
||||
// IsWide: return true if the register is 64 bits (requires a wide op on the rex prefix)
|
||||
#ifdef __M_X86_64
|
||||
bool IsWide() const
|
||||
{
|
||||
return GetOperandSize() == 8;
|
||||
}
|
||||
#else
|
||||
bool IsWide() const
|
||||
{
|
||||
return false;
|
||||
} // no 64 bits GPR
|
||||
#endif
|
||||
// return true if the register is a valid YMM register
|
||||
bool IsWideSIMD() const { return GetOperandSize() == 32; }
|
||||
|
||||
@@ -498,11 +485,7 @@ namespace x86Emitter
|
||||
// more sense and allows the programmer a little more type protection if needed.
|
||||
//
|
||||
|
||||
#ifdef __M_X86_64
|
||||
#define xRegisterLong xRegister64
|
||||
#else
|
||||
#define xRegisterLong xRegister32
|
||||
#endif
|
||||
static const int wordsize = sizeof(sptr);
|
||||
|
||||
class xAddressReg : public xRegisterLong
|
||||
@@ -854,11 +837,7 @@ extern const xRegister32
|
||||
typedef xIndirect<u32> xIndirect32;
|
||||
typedef xIndirect<u16> xIndirect16;
|
||||
typedef xIndirect<u8> xIndirect8;
|
||||
#ifdef __M_X86_64
|
||||
typedef xIndirect<u64> xIndirectNative;
|
||||
#else
|
||||
typedef xIndirect<u32> xIndirectNative;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xIndirect64orLess - base class 64, 32, 16, and 8 bit operand types
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Devel|Win32">
|
||||
<Configuration>Devel</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Devel|x64">
|
||||
<Configuration>Devel</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\3rdparty\wxwidgets3.0\include;$(SolutionDir)\3rdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;_M_X86_64;__M_X86_64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">_ARCH_32=1;_M_X86_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StructMemberAlignment>16Bytes</StructMemberAlignment>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug AVX2|Win32">
|
||||
<Configuration>Debug AVX2</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug AVX2|x64">
|
||||
<Configuration>Debug AVX2</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Devel AVX2|Win32">
|
||||
<Configuration>Devel AVX2</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Devel AVX2|x64">
|
||||
<Configuration>Devel AVX2</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release AVX2|Win32">
|
||||
<Configuration>Release AVX2</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release AVX2|x64">
|
||||
<Configuration>Release AVX2</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pcsx2.pch</PrecompiledHeaderOutputFile>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;_M_X86_64;__M_X86_64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">_ARCH_32=1;_M_X86_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
// GH: AMD memcpy was removed. The remaining part (memcmp_mmx) is likely from Zerofrog.
|
||||
// Hopefully memcmp_mmx will be dropped in the future.
|
||||
|
||||
#if defined(_WIN32) && !defined(_M_AMD64)
|
||||
#include "common/MemcpyFast.h"
|
||||
#include "common/Assertions.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4414)
|
||||
#endif
|
||||
|
||||
// Inline assembly syntax for use with Visual C++
|
||||
|
||||
// mmx mem-compare implementation, size has to be a multiple of 8
|
||||
// returns 0 is equal, nonzero value if not equal
|
||||
// ~10 times faster than standard memcmp
|
||||
// (zerofrog)
|
||||
u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize)
|
||||
{
|
||||
pxAssert((cmpsize & 7) == 0);
|
||||
|
||||
__asm {
|
||||
mov ecx, cmpsize
|
||||
mov edx, src1
|
||||
mov esi, src2
|
||||
|
||||
cmp ecx, 32
|
||||
jl Done4
|
||||
|
||||
// custom test first 8 to make sure things are ok
|
||||
movq mm0, [esi]
|
||||
movq mm1, [esi+8]
|
||||
pcmpeqd mm0, [edx]
|
||||
pcmpeqd mm1, [edx+8]
|
||||
pand mm0, mm1
|
||||
movq mm2, [esi+16]
|
||||
pmovmskb eax, mm0
|
||||
movq mm3, [esi+24]
|
||||
|
||||
// check if eq
|
||||
cmp eax, 0xff
|
||||
je NextComp
|
||||
mov eax, 1
|
||||
jmp End
|
||||
|
||||
NextComp:
|
||||
pcmpeqd mm2, [edx+16]
|
||||
pcmpeqd mm3, [edx+24]
|
||||
pand mm2, mm3
|
||||
pmovmskb eax, mm2
|
||||
|
||||
sub ecx, 32
|
||||
add esi, 32
|
||||
add edx, 32
|
||||
|
||||
// check if eq
|
||||
cmp eax, 0xff
|
||||
je ContinueTest
|
||||
mov eax, 1
|
||||
jmp End
|
||||
|
||||
cmp ecx, 64
|
||||
jl Done8
|
||||
|
||||
Cmp8:
|
||||
movq mm0, [esi]
|
||||
movq mm1, [esi+8]
|
||||
movq mm2, [esi+16]
|
||||
movq mm3, [esi+24]
|
||||
movq mm4, [esi+32]
|
||||
movq mm5, [esi+40]
|
||||
movq mm6, [esi+48]
|
||||
movq mm7, [esi+56]
|
||||
pcmpeqd mm0, [edx]
|
||||
pcmpeqd mm1, [edx+8]
|
||||
pcmpeqd mm2, [edx+16]
|
||||
pcmpeqd mm3, [edx+24]
|
||||
pand mm0, mm1
|
||||
pcmpeqd mm4, [edx+32]
|
||||
pand mm0, mm2
|
||||
pcmpeqd mm5, [edx+40]
|
||||
pand mm0, mm3
|
||||
pcmpeqd mm6, [edx+48]
|
||||
pand mm0, mm4
|
||||
pcmpeqd mm7, [edx+56]
|
||||
pand mm0, mm5
|
||||
pand mm0, mm6
|
||||
pand mm0, mm7
|
||||
pmovmskb eax, mm0
|
||||
|
||||
// check if eq
|
||||
cmp eax, 0xff
|
||||
je Continue
|
||||
mov eax, 1
|
||||
jmp End
|
||||
|
||||
Continue:
|
||||
sub ecx, 64
|
||||
add esi, 64
|
||||
add edx, 64
|
||||
ContinueTest:
|
||||
cmp ecx, 64
|
||||
jge Cmp8
|
||||
|
||||
Done8:
|
||||
test ecx, 0x20
|
||||
jz Done4
|
||||
movq mm0, [esi]
|
||||
movq mm1, [esi+8]
|
||||
movq mm2, [esi+16]
|
||||
movq mm3, [esi+24]
|
||||
pcmpeqd mm0, [edx]
|
||||
pcmpeqd mm1, [edx+8]
|
||||
pcmpeqd mm2, [edx+16]
|
||||
pcmpeqd mm3, [edx+24]
|
||||
pand mm0, mm1
|
||||
pand mm0, mm2
|
||||
pand mm0, mm3
|
||||
pmovmskb eax, mm0
|
||||
sub ecx, 32
|
||||
add esi, 32
|
||||
add edx, 32
|
||||
|
||||
// check if eq
|
||||
cmp eax, 0xff
|
||||
je Done4
|
||||
mov eax, 1
|
||||
jmp End
|
||||
|
||||
Done4:
|
||||
cmp ecx, 24
|
||||
jne Done2
|
||||
movq mm0, [esi]
|
||||
movq mm1, [esi+8]
|
||||
movq mm2, [esi+16]
|
||||
pcmpeqd mm0, [edx]
|
||||
pcmpeqd mm1, [edx+8]
|
||||
pcmpeqd mm2, [edx+16]
|
||||
pand mm0, mm1
|
||||
pand mm0, mm2
|
||||
pmovmskb eax, mm0
|
||||
|
||||
// check if eq
|
||||
cmp eax, 0xff
|
||||
setne al
|
||||
jmp End
|
||||
|
||||
Done2:
|
||||
cmp ecx, 16
|
||||
jne Done1
|
||||
|
||||
movq mm0, [esi]
|
||||
movq mm1, [esi+8]
|
||||
pcmpeqd mm0, [edx]
|
||||
pcmpeqd mm1, [edx+8]
|
||||
pand mm0, mm1
|
||||
pmovmskb eax, mm0
|
||||
|
||||
// check if eq
|
||||
cmp eax, 0xff
|
||||
setne al
|
||||
jmp End
|
||||
|
||||
Done1:
|
||||
cmp ecx, 8
|
||||
jne Done
|
||||
|
||||
mov eax, [esi]
|
||||
mov esi, [esi+4]
|
||||
cmp eax, [edx]
|
||||
je Next
|
||||
mov eax, 1
|
||||
jmp End
|
||||
|
||||
Next:
|
||||
cmp esi, [edx+4]
|
||||
setne al
|
||||
jmp End
|
||||
|
||||
Done:
|
||||
xor eax, eax
|
||||
|
||||
End:
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/HostDisplay.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
@@ -235,7 +236,7 @@ void EmuThread::run()
|
||||
m_event_loop = new QEventLoop();
|
||||
m_started_semaphore.release();
|
||||
|
||||
if (!VMManager::InitializeMemory())
|
||||
if (!VMManager::Internal::InitializeMemory())
|
||||
pxFailRel("Failed to allocate memory map");
|
||||
|
||||
// we need input sources ready for binding
|
||||
@@ -257,7 +258,7 @@ void EmuThread::run()
|
||||
stopBackgroundControllerPollTimer();
|
||||
destroyBackgroundControllerPollTimer();
|
||||
InputManager::CloseSources();
|
||||
VMManager::ReleaseMemory();
|
||||
VMManager::Internal::ReleaseMemory();
|
||||
PerformanceMetrics::SetCPUThreadTimer(Common::ThreadCPUTimer());
|
||||
moveToThread(m_ui_thread);
|
||||
deleteLater();
|
||||
@@ -677,6 +678,9 @@ bool Host::BeginPresentFrame(bool frame_skip)
|
||||
|
||||
void Host::EndPresentFrame()
|
||||
{
|
||||
if (GSDumpReplayer::IsReplayingDump())
|
||||
GSDumpReplayer::RenderUI();
|
||||
|
||||
ImGuiManager::RenderOSD();
|
||||
s_host_display->EndPresent();
|
||||
ImGuiManager::NewFrame();
|
||||
|
||||
+13
-9
@@ -41,7 +41,9 @@ static void PrintCommandLineHelp(const char* progname)
|
||||
std::fprintf(stderr, "\n");
|
||||
std::fprintf(stderr, " -help: Displays this information and exits.\n");
|
||||
std::fprintf(stderr, " -version: Displays version information and exits.\n");
|
||||
std::fprintf(stderr, " -batch: Enables batch mode (exits after powering off).\n");
|
||||
std::fprintf(stderr, " -batch: Enables batch mode (exits after shutting down).\n");
|
||||
std::fprintf(stderr, " -elf <file>: Overrides the boot ELF with the specified filename.\n");
|
||||
std::fprintf(stderr, " -disc <path>: Uses the specified host DVD drive as a source.\n");
|
||||
std::fprintf(stderr, " -fastboot: Force fast boot for provided filename.\n");
|
||||
std::fprintf(stderr, " -slowboot: Force slow boot for provided filename.\n");
|
||||
std::fprintf(stderr, " -resume: Load resume save state. If a boot filename is provided,\n"
|
||||
@@ -64,10 +66,8 @@ static void PrintCommandLineHelp(const char* progname)
|
||||
static std::shared_ptr<VMBootParameters>& AutoBoot(std::shared_ptr<VMBootParameters>& autoboot)
|
||||
{
|
||||
if (!autoboot)
|
||||
{
|
||||
autoboot = std::make_shared<VMBootParameters>();
|
||||
autoboot->source_type = CDVD_SourceType::NoDisc;
|
||||
}
|
||||
|
||||
return autoboot;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,12 @@ static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMBo
|
||||
AutoBoot(autoboot)->elf_override = argv[++i];
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-disc"))
|
||||
{
|
||||
AutoBoot(autoboot)->source_type = CDVD_SourceType::Disc;
|
||||
AutoBoot(autoboot)->filename = argv[++i];
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-fullscreen"))
|
||||
{
|
||||
Console.WriteLn("Going fullscreen after booting.");
|
||||
@@ -172,12 +178,10 @@ static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMBo
|
||||
#undef CHECK_ARG_PARAM
|
||||
}
|
||||
|
||||
if (!AutoBoot(autoboot)->source.empty())
|
||||
AutoBoot(autoboot)->source += ' ';
|
||||
else
|
||||
AutoBoot(autoboot)->source_type = CDVD_SourceType::Iso;
|
||||
if (!AutoBoot(autoboot)->filename.empty())
|
||||
AutoBoot(autoboot)->filename += ' ';
|
||||
|
||||
AutoBoot(autoboot)->source += argv[i];
|
||||
AutoBoot(autoboot)->filename += argv[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+57
-19
@@ -44,9 +44,15 @@
|
||||
#include "svnrev.h"
|
||||
|
||||
static constexpr char DISC_IMAGE_FILTER[] =
|
||||
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.elf *.irx *.m3u);;Single-Track Raw Images (*.bin "
|
||||
"*.iso);;Cue Sheets (*.cue);;MAME CHD Images (*.chd);;CSO Images (*.cso);;"
|
||||
"ELF Executables (*.elf);;IRX Executables (*.irx);;Playlists (*.m3u)");
|
||||
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.elf *.irx *.m3u *.gs *.gs.xz);;"
|
||||
"Single-Track Raw Images (*.bin *.iso);;"
|
||||
"Cue Sheets (*.cue);;"
|
||||
"MAME CHD Images (*.chd);;"
|
||||
"CSO Images (*.cso);;"
|
||||
"ELF Executables (*.elf);;"
|
||||
"IRX Executables (*.irx);;"
|
||||
"Playlists (*.m3u);;"
|
||||
"GS Dumps (*.gs *.gs.xz)");
|
||||
|
||||
const char* MainWindow::DEFAULT_THEME_NAME = "darkfusion";
|
||||
|
||||
@@ -182,9 +188,9 @@ void MainWindow::connectSignals()
|
||||
m_ui.actionEnableVerboseLogging->setChecked(true);
|
||||
m_ui.actionEnableVerboseLogging->setEnabled(false);
|
||||
#endif
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", true);
|
||||
connect(m_ui.actionEnableEEConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", true);
|
||||
connect(m_ui.actionEnableIOPConsoleLogging, &QAction::triggered, this, &MainWindow::onLoggingOptionChanged);
|
||||
|
||||
// These need to be queued connections to stop crashing due to menus opening/closing and switching focus.
|
||||
@@ -602,7 +608,10 @@ void MainWindow::clearProgressBar()
|
||||
m_ui.statusBar->removeWidget(m_status_progress_widget);
|
||||
}
|
||||
|
||||
bool MainWindow::isShowingGameList() const { return m_ui.mainContainer->currentIndex() == 0; }
|
||||
bool MainWindow::isShowingGameList() const
|
||||
{
|
||||
return m_ui.mainContainer->currentIndex() == 0;
|
||||
}
|
||||
|
||||
void MainWindow::switchToGameListView()
|
||||
{
|
||||
@@ -635,11 +644,20 @@ void MainWindow::switchToEmulationView()
|
||||
m_display_widget->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::refreshGameList(bool invalidate_cache) { m_game_list_widget->refresh(invalidate_cache); }
|
||||
void MainWindow::refreshGameList(bool invalidate_cache)
|
||||
{
|
||||
m_game_list_widget->refresh(invalidate_cache);
|
||||
}
|
||||
|
||||
void MainWindow::invalidateSaveStateCache() { m_save_states_invalidated = true; }
|
||||
void MainWindow::invalidateSaveStateCache()
|
||||
{
|
||||
m_save_states_invalidated = true;
|
||||
}
|
||||
|
||||
void MainWindow::reportError(const QString& title, const QString& message) { QMessageBox::critical(this, title, message); }
|
||||
void MainWindow::reportError(const QString& title, const QString& message)
|
||||
{
|
||||
QMessageBox::critical(this, title, message);
|
||||
}
|
||||
|
||||
bool MainWindow::confirmShutdown()
|
||||
{
|
||||
@@ -660,7 +678,10 @@ void MainWindow::requestExit()
|
||||
close();
|
||||
}
|
||||
|
||||
void Host::InvalidateSaveStateCache() { QMetaObject::invokeMethod(g_main_window, &MainWindow::invalidateSaveStateCache, Qt::QueuedConnection); }
|
||||
void Host::InvalidateSaveStateCache()
|
||||
{
|
||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::invalidateSaveStateCache, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void MainWindow::onGameListRefreshProgress(const QString& status, int current, int total)
|
||||
{
|
||||
@@ -668,7 +689,10 @@ void MainWindow::onGameListRefreshProgress(const QString& status, int current, i
|
||||
setProgressBar(current, total);
|
||||
}
|
||||
|
||||
void MainWindow::onGameListRefreshComplete() { clearProgressBar(); }
|
||||
void MainWindow::onGameListRefreshComplete()
|
||||
{
|
||||
clearProgressBar();
|
||||
}
|
||||
|
||||
void MainWindow::onGameListSelectionChanged()
|
||||
{
|
||||
@@ -779,14 +803,13 @@ void MainWindow::onStartFileActionTriggered()
|
||||
return;
|
||||
|
||||
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
|
||||
VMManager::SetBootParametersForPath(filename.toStdString(), params.get());
|
||||
params->filename = filename.toStdString();
|
||||
g_emu_thread->startVM(std::move(params));
|
||||
}
|
||||
|
||||
void MainWindow::onStartBIOSActionTriggered()
|
||||
{
|
||||
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
|
||||
params->source_type = CDVD_SourceType::NoDisc;
|
||||
g_emu_thread->startVM(std::move(params));
|
||||
}
|
||||
|
||||
@@ -801,7 +824,10 @@ void MainWindow::onChangeDiscFromFileActionTriggered()
|
||||
g_emu_thread->changeDisc(filename);
|
||||
}
|
||||
|
||||
void MainWindow::onChangeDiscFromGameListActionTriggered() { switchToGameListView(); }
|
||||
void MainWindow::onChangeDiscFromGameListActionTriggered()
|
||||
{
|
||||
switchToGameListView();
|
||||
}
|
||||
|
||||
void MainWindow::onChangeDiscFromDeviceActionTriggered()
|
||||
{
|
||||
@@ -885,11 +911,20 @@ void MainWindow::onViewGamePropertiesActionTriggered()
|
||||
SettingsDialog::openGamePropertiesDialog(nullptr, m_current_game_crc);
|
||||
}
|
||||
|
||||
void MainWindow::onGitHubRepositoryActionTriggered() { QtUtils::OpenURL(this, AboutDialog::getGitHubRepositoryUrl()); }
|
||||
void MainWindow::onGitHubRepositoryActionTriggered()
|
||||
{
|
||||
QtUtils::OpenURL(this, AboutDialog::getGitHubRepositoryUrl());
|
||||
}
|
||||
|
||||
void MainWindow::onSupportForumsActionTriggered() { QtUtils::OpenURL(this, AboutDialog::getSupportForumsUrl()); }
|
||||
void MainWindow::onSupportForumsActionTriggered()
|
||||
{
|
||||
QtUtils::OpenURL(this, AboutDialog::getSupportForumsUrl());
|
||||
}
|
||||
|
||||
void MainWindow::onDiscordServerActionTriggered() { QtUtils::OpenURL(this, AboutDialog::getDiscordServerUrl()); }
|
||||
void MainWindow::onDiscordServerActionTriggered()
|
||||
{
|
||||
QtUtils::OpenURL(this, AboutDialog::getDiscordServerUrl());
|
||||
}
|
||||
|
||||
void MainWindow::onAboutActionTriggered()
|
||||
{
|
||||
@@ -1191,7 +1226,10 @@ void MainWindow::displayResizeRequested(qint32 width, qint32 height)
|
||||
resize(QSize(std::max<qint32>(width, 1), std::max<qint32>(height + extra_height, 1)));
|
||||
}
|
||||
|
||||
void MainWindow::destroyDisplay() { destroyDisplayWidget(); }
|
||||
void MainWindow::destroyDisplay()
|
||||
{
|
||||
destroyDisplayWidget();
|
||||
}
|
||||
|
||||
void MainWindow::focusDisplayWidget()
|
||||
{
|
||||
@@ -1398,7 +1436,7 @@ void MainWindow::loadSaveStateFile(const QString& filename, const QString& state
|
||||
else
|
||||
{
|
||||
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
|
||||
VMManager::SetBootParametersForPath(filename.toStdString(), params.get());
|
||||
params->filename = filename.toStdString();
|
||||
params->save_state = state_filename.toStdString();
|
||||
g_emu_thread->startVM(std::move(params));
|
||||
}
|
||||
|
||||
@@ -699,11 +699,17 @@
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableEEConsoleLogging">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable EE Console Logging</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableIOPConsoleLogging">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable IOP Console Logging</string>
|
||||
</property>
|
||||
|
||||
+5
-2
@@ -82,6 +82,9 @@ bool QtHost::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VMManager::Internal::InitializeGlobals())
|
||||
return false;
|
||||
|
||||
HookSignals();
|
||||
return true;
|
||||
}
|
||||
@@ -313,13 +316,13 @@ void Host::ReportErrorAsync(const std::string_view& title, const std::string_vie
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
{
|
||||
Console.Error("ReportErrorAsync: %*s: %*s",
|
||||
Console.Error("ReportErrorAsync: %.*s: %.*s",
|
||||
static_cast<int>(title.size()), title.data(),
|
||||
static_cast<int>(message.size()), message.data());
|
||||
}
|
||||
else if (!message.empty())
|
||||
{
|
||||
Console.Error("ReportErrorAsync: %*s",
|
||||
Console.Error("ReportErrorAsync: %.*s",
|
||||
static_cast<int>(message.size()), message.data());
|
||||
}
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ namespace SettingWidgetBinder
|
||||
|
||||
int sif_value;
|
||||
if (sif->GetIntValue(section.c_str(), key.c_str(), &sif_value))
|
||||
Accessor::setNullableIntValue(widget, sif_value);
|
||||
Accessor::setNullableIntValue(widget, sif_value - option_offset);
|
||||
else
|
||||
Accessor::setNullableIntValue(widget, std::nullopt);
|
||||
|
||||
@@ -735,7 +735,7 @@ namespace SettingWidgetBinder
|
||||
{
|
||||
for (int i = 0; enum_values[i] != nullptr; i++)
|
||||
{
|
||||
if (value == enum_values[i])
|
||||
if (sif_value == enum_values[i])
|
||||
{
|
||||
sif_int_value = i;
|
||||
break;
|
||||
@@ -744,9 +744,9 @@ namespace SettingWidgetBinder
|
||||
}
|
||||
Accessor::setNullableIntValue(widget, sif_int_value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), enum_names]() {
|
||||
Accessor::connectValueChanged(widget, [sif, widget, section = std::move(section), key = std::move(key), enum_values]() {
|
||||
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||
sif->SetStringValue(section.c_str(), key.c_str(), enum_names[new_value.value()]);
|
||||
sif->SetStringValue(section.c_str(), key.c_str(), enum_values[new_value.value()]);
|
||||
else
|
||||
sif->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
InputBindingWidget* widget = findChild<InputBindingWidget*>(QString::fromStdString(binding));
|
||||
if (!widget)
|
||||
{
|
||||
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%*s)",
|
||||
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%.*s)",
|
||||
binding.c_str(), static_cast<int>(type.size()), type.data());
|
||||
continue;
|
||||
}
|
||||
@@ -155,4 +155,4 @@ ControllerBindingWidget_Base* ControllerBindingWidget_DualShock2::createInstance
|
||||
return new ControllerBindingWidget_DualShock2(parent);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -83,7 +83,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.fmvAspectRatio, "EmuCore/GS", "FMVAspectRatioSwitch",
|
||||
Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames, FMVAspectRatioSwitchType::Off);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.interlacing, "EmuCore/GS", "interlace", DEFAULT_INTERLACE_MODE);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearFiltering, "EmuCore/GS", "LinearPresent", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearFiltering, "EmuCore/GS", "linear_present", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.integerScaling, "EmuCore/GS", "IntegerScaling", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.internalResolutionScreenshots, "EmuCore/GS", "InternalResolutionScreenshots", false);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.zoom, "EmuCore/GS", "Zoom", 100.0f);
|
||||
@@ -104,6 +104,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowSpeed, "EmuCore/GS", "OsdShowSpeed", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowFPS, "EmuCore/GS", "OsdShowFPS", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowCPU, "EmuCore/GS", "OsdShowCPU", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowGPU, "EmuCore/GS", "OsdShowGPU", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowResolution, "EmuCore/GS", "OsdShowResolution", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowGSStats, "EmuCore/GS", "OsdShowGSStats", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowIndicators, "EmuCore/GS", "OsdShowIndicators", true);
|
||||
@@ -141,22 +142,22 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
// HW Renderer Fixes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawRangeStart, "EmuCore/GS", "UserHacks_SkipDraw", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawRangeCount, "EmuCore/GS", "UserHacks_SkipDraw_Offset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawStart, "EmuCore/GS", "UserHacks_SkipDraw_Start", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.skipDrawEnd, "EmuCore/GS", "UserHacks_SkipDraw_End", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.hwAutoFlush, "EmuCore/GS", "UserHacks_AutoFlush", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.frameBufferConversion, "EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDepthEmulation, "EmuCore/GS", "UserHacks_DisableDepthSupport", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.memoryWrapping, "EmuCore/GS", "wrap_gs_mem", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableSafeFeatures, "EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadFrameData, "EmuCore/GS", "preload_frame_with_gs_data", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fastTextureInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Upscaling Fixes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_RoundSprite", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_round_sprite_offset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetX, "EmuCore/GS", "UserHacks_TCOffsetX", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetY, "EmuCore/GS", "UserHacks_TCOffsetY", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.alignSprite, "EmuCore/GS", "UserHacks_align_sprite_X", false);
|
||||
@@ -178,6 +179,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideTextureBarriers, "EmuCore/GS", "OverrideTextureBarriers", -1, -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideGeometryShader, "EmuCore/GS", "OverrideGeometryShaders", -1, -1);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "EmuCore/GS", "DisableFramebufferFetch", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "EmuCore/GS", "DisableDualSourceBlend", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SW Settings
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="enableHWFixes">
|
||||
<property name="text">
|
||||
<string>Enable Hardware Renderer Fixes</string>
|
||||
<string>Manual Hardware Renderer Fixes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -661,10 +661,18 @@
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawRangeStart"/>
|
||||
<widget class="QSpinBox" name="skipDrawStart">
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawRangeCount"/>
|
||||
<widget class="QSpinBox" name="skipDrawEnd">
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@@ -713,9 +721,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="fastTextureInvalidation">
|
||||
<widget class="QCheckBox" name="disablePartialInvalidation">
|
||||
<property name="text">
|
||||
<string>Fast Texture Invalidation</string>
|
||||
<string>Disable Partial Invalidation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -809,7 +817,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="textureOffsetX"/>
|
||||
<widget class="QSpinBox" name="textureOffsetX">
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
@@ -819,7 +831,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="textureOffsetY"/>
|
||||
<widget class="QSpinBox" name="textureOffsetY">
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@@ -913,13 +929,20 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="osdShowGPU">
|
||||
<property name="text">
|
||||
<string>Show GPU Usage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="osdShowGSStats">
|
||||
<property name="text">
|
||||
<string>Show Statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="osdShowIndicators">
|
||||
<property name="text">
|
||||
<string>Show Indicators</string>
|
||||
@@ -940,21 +963,91 @@
|
||||
<property name="title">
|
||||
<string>Debug Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<layout class="QFormLayout" name="formLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useBlitSwapChain">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Use Blit Swap Chain</string>
|
||||
<string>Override Texture Barriers:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<widget class="QComboBox" name="overrideTextureBarriers">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Enabled</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_30">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
<string>Override Geometry Shader:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="overrideGeometryShader">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Enabled</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useBlitSwapChain">
|
||||
<property name="text">
|
||||
<string>Use Blit Swap Chain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="disableDualSource">
|
||||
<property name="text">
|
||||
<string>Disable Dual Source Blending</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="disableFramebufferFetch">
|
||||
<property name="text">
|
||||
<string>Disable Framebuffer Fetch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -390,7 +390,7 @@ void SettingsDialog::setStringSettingValue(const char* section, const char* key,
|
||||
{
|
||||
if (m_sif)
|
||||
{
|
||||
value.has_value() ? m_sif->SetBoolValue(section, key, value.value()) : m_sif->DeleteValue(section, key);
|
||||
value.has_value() ? m_sif->SetStringValue(section, key, value.value()) : m_sif->DeleteValue(section, key);
|
||||
m_sif->Save();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -983,6 +983,7 @@ if(PCSX2_CORE)
|
||||
Frontend/InputManager.cpp
|
||||
Frontend/InputSource.cpp
|
||||
Frontend/LayeredSettingsInterface.cpp
|
||||
GSDumpReplayer.cpp
|
||||
HostSettings.cpp
|
||||
VMManager.cpp
|
||||
)
|
||||
@@ -992,6 +993,7 @@ if(PCSX2_CORE)
|
||||
Frontend/InputManager.h
|
||||
Frontend/InputSource.h
|
||||
Frontend/LayeredSettingsInterface.h
|
||||
GSDumpReplayer.h
|
||||
HostSettings.h
|
||||
VMManager.h)
|
||||
endif()
|
||||
|
||||
+14
-4
@@ -58,6 +58,7 @@ enum SpeedhackId
|
||||
|
||||
Speedhack_mvuFlag = SpeedhackId_FIRST,
|
||||
Speedhack_InstantVU1,
|
||||
Speedhack_MTVU,
|
||||
|
||||
SpeedhackId_COUNT
|
||||
};
|
||||
@@ -422,11 +423,14 @@ struct Pcsx2Config
|
||||
UseDebugDevice : 1,
|
||||
UseBlitSwapChain : 1,
|
||||
DisableShaderCache : 1,
|
||||
DisableDualSourceBlend : 1,
|
||||
DisableFramebufferFetch : 1,
|
||||
ThreadedPresentation : 1,
|
||||
OsdShowMessages : 1,
|
||||
OsdShowSpeed : 1,
|
||||
OsdShowFPS : 1,
|
||||
OsdShowCPU : 1,
|
||||
OsdShowGPU : 1,
|
||||
OsdShowResolution : 1,
|
||||
OsdShowGSStats : 1,
|
||||
OsdShowIndicators : 1;
|
||||
@@ -441,7 +445,8 @@ struct Pcsx2Config
|
||||
WrapGSMem : 1,
|
||||
Mipmap : 1,
|
||||
AA1 : 1,
|
||||
UserHacks : 1,
|
||||
PointListPalette : 1,
|
||||
ManualUserHacks : 1,
|
||||
UserHacks_AlignSpriteX : 1,
|
||||
UserHacks_AutoFlush : 1,
|
||||
UserHacks_CPUFBConversion : 1,
|
||||
@@ -509,8 +514,8 @@ struct Pcsx2Config
|
||||
int SWExtraThreads{2};
|
||||
int SWExtraThreadsHeight{4};
|
||||
int TVShader{0};
|
||||
int SkipDraw{0};
|
||||
int SkipDrawOffset{0};
|
||||
int SkipDrawStart{0};
|
||||
int SkipDrawEnd{0};
|
||||
|
||||
int UserHacks_HalfBottomOverride{-1};
|
||||
int UserHacks_HalfPixelOffset{0};
|
||||
@@ -518,6 +523,8 @@ struct Pcsx2Config
|
||||
int UserHacks_TCOffsetX{0};
|
||||
int UserHacks_TCOffsetY{0};
|
||||
TriFiltering UserHacks_TriFilter{TriFiltering::Off};
|
||||
int OverrideTextureBarriers{-1};
|
||||
int OverrideGeometryShaders{-1};
|
||||
|
||||
int ShadeBoost_Brightness{50};
|
||||
int ShadeBoost_Contrast{50};
|
||||
@@ -543,6 +550,9 @@ struct Pcsx2Config
|
||||
/// Sets user hack values to defaults when user hacks are not enabled.
|
||||
void MaskUserHacks();
|
||||
|
||||
/// Sets user hack values to defaults when upscaling is not enabled.
|
||||
void MaskUpscalingHacks();
|
||||
|
||||
/// Returns true if any of the hardware renderers are selected.
|
||||
bool UseHardwareRenderer() const;
|
||||
|
||||
@@ -668,7 +678,7 @@ struct Pcsx2Config
|
||||
* which is 2^32 * 512 byte sectors
|
||||
* Note that we don't yet support
|
||||
* 48bit LBA, so our limit is lower */
|
||||
uint HddSizeSectors{0};
|
||||
uint HddSizeSectors{40 * (1024 * 1024 * 1024 / 512)};
|
||||
|
||||
DEV9Options();
|
||||
|
||||
|
||||
+45
-7
@@ -48,7 +48,7 @@ SERIAL-12345: # !required! Serial number for the game, this is how games are loo
|
||||
memcardFilters:
|
||||
- "SERIAL-123"
|
||||
- "SERIAL-456"
|
||||
# You can define multple patches, but they are identified by the CRC.
|
||||
# You can define multiple patches, but they are identified by the CRC.
|
||||
patches:
|
||||
default: # Default CRC!
|
||||
author: "Some Person"
|
||||
@@ -124,6 +124,44 @@ The clamp modes are also numerically based.
|
||||
* `2` = Clamp **Extra** (clamp results as well as operands)
|
||||
* `3` = Clamp **Extra+Preserve Sign**
|
||||
|
||||
## GS Hardware Fixes
|
||||
|
||||
[ ] = GameDB values
|
||||
{ } = GUI options
|
||||
( ) = Default values
|
||||
|
||||
### GS Hardware Mipmap Fixes
|
||||
|
||||
* mipmap [`0` or `1` or `2`] {Off, Basic, Full} Default: Automatic (No value, looks up GameDB)
|
||||
* trilinearFiltering [`0` or `1` or `2`] {None, Trilinear, Trilinear Ultra} Default: None (`0`)
|
||||
|
||||
### GS Hardware General Fixes
|
||||
|
||||
* conservativeFramebuffer [`0` or `1`] {Off or On} Default: On (`1`)
|
||||
* texturePreloading [`0` or `1` or `2`] {None, Partial or Full Hash Cache} Default: None (`0`)
|
||||
|
||||
### GS Hardware Renderer Fixes
|
||||
|
||||
* autoFlush [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* disableDepthSupport [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* disablePartialInvalidation [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* cpuFramebufferConversion [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* wrapGSMem [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* preloadFrameData [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* textureInsideRT [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* halfBottomOverride [`0` or `1`] {Force-Disabled or Force-Enabled} Default: Automatic (No value, looks up GameDB)
|
||||
* pointListPalette [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
|
||||
### GS Hardware Upscaling Fixes
|
||||
|
||||
* alignSprite [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* mergeSprite [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* wildArmsHack [`0` or `1`] {Off or On} Default: Off (`0`)
|
||||
* skipDrawStart [Value between `0` to `100000`] {0-100000} Default: Off (`0`)
|
||||
* skipDrawEnd [Value between `0` to `100000`] {0-100000} Default: Off (`0`)
|
||||
* halfPixelOffset [`0` or `1` or `2` or `3`] {Off, Normal Vertex, Special Texture or Special Texture Aggressive} Default: Off (`0`)
|
||||
* roundSprite [`0` or `1` or `2`] {Off, Half or Full} Default: Off (`0`)
|
||||
|
||||
## Game Fixes
|
||||
|
||||
These values are case-sensitive so take care. If you incorrectly specify a GameFix, you will get a validation error on startup. Any invalid game-fixes will be dropped from the game's list of fixes.
|
||||
@@ -184,12 +222,12 @@ These values are in a key-value format, where the value is assumed to be an inte
|
||||
* `mvuFlagSpeedHack`
|
||||
* Accepted Values - `0` / `1`
|
||||
* Katamari Damacy have weird speed bug when this speed hack is enabled (and it is by default)
|
||||
|
||||
<!-- [list-item-spacing] Missing new line after list item->
|
||||
|
||||
- `InstantVU1SpeedHack`
|
||||
- Accepted Values - `0` / `1`
|
||||
- Games such as Parappa the Rapper 2 need VU1 to sync, so you can force disable the speedhack here
|
||||
* `MTVUSpeedHack`
|
||||
* Accepted Values - `0` / `1`
|
||||
* T-bit games dislike MTVU and some games are incompatible with MTVU.
|
||||
* `InstantVU1SpeedHack`
|
||||
* Accepted Values - `0` / `1`
|
||||
* Games such as Parappa the Rapper 2 need VU1 to sync, so you can force sync with this parameter.
|
||||
|
||||
## Memory Card Filter Override
|
||||
|
||||
|
||||
@@ -742,11 +742,122 @@ void D3D11HostDisplay::EndPresent()
|
||||
ImGui::Render();
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
PopTimestampQuery();
|
||||
|
||||
const UINT vsync_rate = static_cast<UINT>(m_vsync_mode != VsyncMode::Off);
|
||||
if (vsync_rate == 0 && m_using_allow_tearing)
|
||||
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
||||
else
|
||||
m_swap_chain->Present(vsync_rate, 0);
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
KickTimestampQuery();
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::CreateTimestampQueries()
|
||||
{
|
||||
for (u32 i = 0; i < NUM_TIMESTAMP_QUERIES; i++)
|
||||
{
|
||||
for (u32 j = 0; j < 3; j++)
|
||||
{
|
||||
const CD3D11_QUERY_DESC qdesc((j == 0) ? D3D11_QUERY_TIMESTAMP_DISJOINT : D3D11_QUERY_TIMESTAMP);
|
||||
const HRESULT hr = m_device->CreateQuery(&qdesc, m_timestamp_queries[i][j].ReleaseAndGetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
m_timestamp_queries = {};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KickTimestampQuery();
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::DestroyTimestampQueries()
|
||||
{
|
||||
if (!m_timestamp_queries[0][0])
|
||||
return;
|
||||
|
||||
if (m_timestamp_query_started)
|
||||
m_context->End(m_timestamp_queries[m_write_timestamp_query][1].Get());
|
||||
|
||||
m_timestamp_queries = {};
|
||||
m_read_timestamp_query = 0;
|
||||
m_write_timestamp_query = 0;
|
||||
m_waiting_timestamp_queries = 0;
|
||||
m_timestamp_query_started = 0;
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::PopTimestampQuery()
|
||||
{
|
||||
while (m_waiting_timestamp_queries > 0)
|
||||
{
|
||||
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint;
|
||||
const HRESULT disjoint_hr = m_context->GetData(m_timestamp_queries[m_read_timestamp_query][0].Get(), &disjoint, sizeof(disjoint), D3D11_ASYNC_GETDATA_DONOTFLUSH);
|
||||
if (disjoint_hr != S_OK)
|
||||
break;
|
||||
|
||||
if (disjoint.Disjoint)
|
||||
{
|
||||
DevCon.WriteLn("GPU timing disjoint, resetting.");
|
||||
m_read_timestamp_query = 0;
|
||||
m_write_timestamp_query = 0;
|
||||
m_waiting_timestamp_queries = 0;
|
||||
m_timestamp_query_started = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
u64 start = 0, end = 0;
|
||||
const HRESULT start_hr = m_context->GetData(m_timestamp_queries[m_read_timestamp_query][1].Get(), &start, sizeof(start), D3D11_ASYNC_GETDATA_DONOTFLUSH);
|
||||
const HRESULT end_hr = m_context->GetData(m_timestamp_queries[m_read_timestamp_query][2].Get(), &end, sizeof(end), D3D11_ASYNC_GETDATA_DONOTFLUSH);
|
||||
if (start_hr == S_OK && end_hr == S_OK)
|
||||
{
|
||||
m_accumulated_gpu_time += static_cast<float>(static_cast<double>(end - start) / (static_cast<double>(disjoint.Frequency) / 1000.0));
|
||||
m_read_timestamp_query = (m_read_timestamp_query + 1) % NUM_TIMESTAMP_QUERIES;
|
||||
m_waiting_timestamp_queries--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delay ending the current query until we've read back some
|
||||
if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1))
|
||||
{
|
||||
m_context->End(m_timestamp_queries[m_write_timestamp_query][2].Get());
|
||||
m_context->End(m_timestamp_queries[m_write_timestamp_query][0].Get());
|
||||
m_write_timestamp_query = (m_write_timestamp_query + 1) % NUM_TIMESTAMP_QUERIES;
|
||||
m_timestamp_query_started = false;
|
||||
m_waiting_timestamp_queries++;
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::KickTimestampQuery()
|
||||
{
|
||||
if (m_timestamp_query_started)
|
||||
return;
|
||||
|
||||
m_context->Begin(m_timestamp_queries[m_write_timestamp_query][0].Get());
|
||||
m_context->End(m_timestamp_queries[m_write_timestamp_query][1].Get());
|
||||
m_timestamp_query_started = true;
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::SetGPUTimingEnabled(bool enabled)
|
||||
{
|
||||
if (m_gpu_timing_enabled == enabled)
|
||||
return;
|
||||
|
||||
m_gpu_timing_enabled = enabled;
|
||||
if (m_gpu_timing_enabled)
|
||||
CreateTimestampQueries();
|
||||
else
|
||||
DestroyTimestampQueries();
|
||||
}
|
||||
|
||||
float D3D11HostDisplay::GetAndResetAccumulatedGPUTime()
|
||||
{
|
||||
const float value = m_accumulated_gpu_time;
|
||||
m_accumulated_gpu_time = 0.0f;
|
||||
return value;
|
||||
}
|
||||
|
||||
HostDisplay::AdapterAndModeList D3D11HostDisplay::StaticGetAdapterAndModeList()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "HostDisplay.h"
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include "common/WindowInfo.h"
|
||||
#include <array>
|
||||
#include <d3d11.h>
|
||||
#include <dxgi.h>
|
||||
#include <memory>
|
||||
@@ -68,10 +69,14 @@ public:
|
||||
bool BeginPresent(bool frame_skip) override;
|
||||
void EndPresent() override;
|
||||
|
||||
void SetGPUTimingEnabled(bool enabled) override;
|
||||
float GetAndResetAccumulatedGPUTime() override;
|
||||
|
||||
static AdapterAndModeList StaticGetAdapterAndModeList();
|
||||
|
||||
protected:
|
||||
static constexpr u32 DISPLAY_CONSTANT_BUFFER_SIZE = 16;
|
||||
static constexpr u8 NUM_TIMESTAMP_QUERIES = 3;
|
||||
|
||||
static AdapterAndModeList GetAdapterAndModeList(IDXGIFactory* dxgi_factory);
|
||||
|
||||
@@ -82,6 +87,11 @@ protected:
|
||||
bool CreateSwapChain(const DXGI_MODE_DESC* fullscreen_mode);
|
||||
bool CreateSwapChainRTV();
|
||||
|
||||
void CreateTimestampQueries();
|
||||
void DestroyTimestampQueries();
|
||||
void PopTimestampQuery();
|
||||
void KickTimestampQuery();
|
||||
|
||||
ComPtr<ID3D11Device> m_device;
|
||||
ComPtr<ID3D11DeviceContext> m_context;
|
||||
|
||||
@@ -92,5 +102,13 @@ protected:
|
||||
bool m_allow_tearing_supported = false;
|
||||
bool m_using_flip_model_swap_chain = true;
|
||||
bool m_using_allow_tearing = false;
|
||||
|
||||
std::array<std::array<ComPtr<ID3D11Query>, 3>, NUM_TIMESTAMP_QUERIES> m_timestamp_queries = {};
|
||||
u8 m_read_timestamp_query = 0;
|
||||
u8 m_write_timestamp_query = 0;
|
||||
u8 m_waiting_timestamp_queries = 0;
|
||||
bool m_timestamp_query_started = false;
|
||||
float m_accumulated_gpu_time = 0.0f;
|
||||
bool m_gpu_timing_enabled = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -123,19 +123,19 @@ void GameList::FillBootParametersForEntry(VMBootParameters* params, const Entry*
|
||||
{
|
||||
if (entry->type == GameList::EntryType::PS1Disc || entry->type == GameList::EntryType::PS2Disc)
|
||||
{
|
||||
params->source = entry->path;
|
||||
params->filename = entry->path;
|
||||
params->source_type = CDVD_SourceType::Iso;
|
||||
params->elf_override.clear();
|
||||
}
|
||||
else if (entry->type == GameList::EntryType::ELF)
|
||||
{
|
||||
params->source.clear();
|
||||
params->filename.clear();
|
||||
params->source_type = CDVD_SourceType::NoDisc;
|
||||
params->elf_override = entry->path;
|
||||
}
|
||||
else
|
||||
{
|
||||
params->source.clear();
|
||||
params->filename.clear();
|
||||
params->source_type = CDVD_SourceType::NoDisc;
|
||||
params->elf_override.clear();
|
||||
}
|
||||
@@ -568,6 +568,17 @@ const GameList::Entry* GameList::GetEntryForPath(const char* path)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GameList::Entry* GameList::GetEntryByCRC(u32 crc)
|
||||
{
|
||||
for (const Entry& entry : m_entries)
|
||||
{
|
||||
if (entry.crc == crc)
|
||||
return &entry;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GameList::Entry* GameList::GetEntryBySerialAndCRC(const std::string_view& serial, u32 crc)
|
||||
{
|
||||
for (const Entry& entry : m_entries)
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace GameList
|
||||
std::unique_lock<std::recursive_mutex> GetLock();
|
||||
const Entry* GetEntryByIndex(u32 index);
|
||||
const Entry* GetEntryForPath(const char* path);
|
||||
const Entry* GetEntryByCRC(u32 crc);
|
||||
const Entry* GetEntryBySerialAndCRC(const std::string_view& serial, u32 crc);
|
||||
u32 GetEntryCount();
|
||||
|
||||
|
||||
@@ -469,6 +469,17 @@ static void DrawOSDMessages()
|
||||
}
|
||||
}
|
||||
|
||||
static void FormatProcessorStat(FastFormatAscii& text, double usage, double time)
|
||||
{
|
||||
// Some values, such as GPU (and even CPU to some extent) can be out of phase with the wall clock,
|
||||
// which the processor time is divided by to get a utilization percentage. Let's clamp it at 100%,
|
||||
// so that people don't get confused, and remove the decimal places when it's there while we're at it.
|
||||
if (usage >= 99.95)
|
||||
text.Write("100%% (%.2fms)", time);
|
||||
else
|
||||
text.Write("%.1f%% (%.2fms)", usage, time);
|
||||
}
|
||||
|
||||
static void DrawPerformanceOverlay()
|
||||
{
|
||||
const float scale = s_global_scale;
|
||||
@@ -575,32 +586,43 @@ static void DrawPerformanceOverlay()
|
||||
|
||||
text.Clear();
|
||||
if (EmuConfig.Speedhacks.EECycleRate != 0 || EmuConfig.Speedhacks.EECycleSkip != 0)
|
||||
{
|
||||
text.Write("EE[%d/%d]: %.1f%% (%.2fms)", EmuConfig.Speedhacks.EECycleRate, EmuConfig.Speedhacks.EECycleSkip,
|
||||
PerformanceMetrics::GetCPUThreadUsage(),
|
||||
PerformanceMetrics::GetCPUThreadAverageTime());
|
||||
}
|
||||
text.Write("EE[%d/%d]: ", EmuConfig.Speedhacks.EECycleRate, EmuConfig.Speedhacks.EECycleSkip);
|
||||
else
|
||||
{
|
||||
text.Write("EE: %.1f%% (%.2fms)", PerformanceMetrics::GetCPUThreadUsage(),
|
||||
PerformanceMetrics::GetCPUThreadAverageTime());
|
||||
}
|
||||
text.Write("EE: ");
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetCPUThreadUsage(), PerformanceMetrics::GetCPUThreadAverageTime());
|
||||
DRAW_LINE(s_fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
|
||||
text.Clear();
|
||||
text.Write("GS: %.1f%% (%.2fms)", PerformanceMetrics::GetGSThreadUsage(),
|
||||
PerformanceMetrics::GetGSThreadAverageTime());
|
||||
text.Write("GS: ");
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetGSThreadUsage(), PerformanceMetrics::GetGSThreadAverageTime());
|
||||
DRAW_LINE(s_fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
|
||||
const u32 gs_sw_threads = PerformanceMetrics::GetGSSWThreadCount();
|
||||
for (u32 i = 0; i < gs_sw_threads; i++)
|
||||
{
|
||||
text.Clear();
|
||||
text.Write("SW-%u: ", i);
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetGSSWThreadUsage(i), PerformanceMetrics::GetGSSWThreadAverageTime(i));
|
||||
DRAW_LINE(s_fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
if (THREAD_VU1)
|
||||
{
|
||||
text.Clear();
|
||||
text.Write("VU: %.1f%% (%.2fms)", PerformanceMetrics::GetVUThreadUsage(),
|
||||
PerformanceMetrics::GetVUThreadAverageTime());
|
||||
text.Write("VU: ");
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetVUThreadUsage(), PerformanceMetrics::GetVUThreadAverageTime());
|
||||
DRAW_LINE(s_fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
|
||||
if (GSConfig.OsdShowGPU)
|
||||
{
|
||||
text.Clear();
|
||||
text.Write("GPU: ");
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetGPUUsage(), PerformanceMetrics::GetGPUAverageTime());
|
||||
DRAW_LINE(s_fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
if (GSConfig.OsdShowIndicators)
|
||||
{
|
||||
const bool is_normal_speed = (EmuConfig.GS.LimitScalar == EmuConfig.Framerate.NominalScalar);
|
||||
@@ -630,3 +652,17 @@ void ImGuiManager::RenderOSD()
|
||||
DrawOSDMessages();
|
||||
}
|
||||
|
||||
float ImGuiManager::GetGlobalScale()
|
||||
{
|
||||
return s_global_scale;
|
||||
}
|
||||
|
||||
ImFont* ImGuiManager::GetStandardFont()
|
||||
{
|
||||
return s_standard_font;
|
||||
}
|
||||
|
||||
ImFont* ImGuiManager::GetFixedFont()
|
||||
{
|
||||
return s_fixed_font;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
struct ImFont;
|
||||
|
||||
namespace ImGuiManager
|
||||
{
|
||||
/// Initializes ImGui, creates fonts, etc.
|
||||
@@ -34,5 +36,14 @@ namespace ImGuiManager
|
||||
|
||||
/// Renders any on-screen display elements.
|
||||
void RenderOSD();
|
||||
|
||||
/// Returns the scale of all on-screen elements.
|
||||
float GetGlobalScale();
|
||||
|
||||
/// Returns the standard font for external drawing.
|
||||
ImFont* GetStandardFont();
|
||||
|
||||
/// Returns the fixed-width font for external drawing.
|
||||
ImFont* GetFixedFont();
|
||||
} // namespace ImGuiManager
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ bool InputManager::SplitBinding(
|
||||
const std::string_view::size_type slash_pos = binding.find('/');
|
||||
if (slash_pos == std::string_view::npos)
|
||||
{
|
||||
Console.Warning("Malformed binding: '%*s'", static_cast<int>(binding.size()), binding.data());
|
||||
Console.Warning("Malformed binding: '%.*s'", static_cast<int>(binding.size()), binding.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -374,6 +374,128 @@ void OpenGLHostDisplay::EndPresent()
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
GL::Program::ResetLastProgram();
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
PopTimestampQuery();
|
||||
|
||||
m_gl_context->SwapBuffers();
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
KickTimestampQuery();
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::CreateTimestampQueries()
|
||||
{
|
||||
const bool gles = m_gl_context->IsGLES();
|
||||
const auto GenQueries = gles ? glGenQueriesEXT : glGenQueries;
|
||||
|
||||
GenQueries(static_cast<u32>(m_timestamp_queries.size()), m_timestamp_queries.data());
|
||||
KickTimestampQuery();
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::DestroyTimestampQueries()
|
||||
{
|
||||
if (m_timestamp_queries[0] == 0)
|
||||
return;
|
||||
|
||||
const bool gles = m_gl_context->IsGLES();
|
||||
const auto DeleteQueries = gles ? glDeleteQueriesEXT : glDeleteQueries;
|
||||
|
||||
if (m_timestamp_query_started)
|
||||
{
|
||||
const auto EndQuery = gles ? glEndQueryEXT : glEndQuery;
|
||||
EndQuery(m_timestamp_queries[m_write_timestamp_query]);
|
||||
}
|
||||
|
||||
DeleteQueries(static_cast<u32>(m_timestamp_queries.size()), m_timestamp_queries.data());
|
||||
m_timestamp_queries.fill(0);
|
||||
m_read_timestamp_query = 0;
|
||||
m_write_timestamp_query = 0;
|
||||
m_waiting_timestamp_queries = 0;
|
||||
m_timestamp_query_started = false;
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::PopTimestampQuery()
|
||||
{
|
||||
const bool gles = m_gl_context->IsGLES();
|
||||
|
||||
if (gles)
|
||||
{
|
||||
GLint disjoint = 0;
|
||||
glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint);
|
||||
if (disjoint)
|
||||
{
|
||||
DevCon.WriteLn("GPU timing disjoint, resetting.");
|
||||
if (m_timestamp_query_started)
|
||||
glEndQueryEXT(GL_TIME_ELAPSED);
|
||||
|
||||
m_read_timestamp_query = 0;
|
||||
m_write_timestamp_query = 0;
|
||||
m_waiting_timestamp_queries = 0;
|
||||
m_timestamp_query_started = false;
|
||||
}
|
||||
}
|
||||
|
||||
while (m_waiting_timestamp_queries > 0)
|
||||
{
|
||||
const auto GetQueryObjectiv = gles ? glGetQueryObjectivEXT : glGetQueryObjectiv;
|
||||
const auto GetQueryObjectui64v = gles ? glGetQueryObjectui64vEXT : glGetQueryObjectui64v;
|
||||
|
||||
GLint available = 0;
|
||||
GetQueryObjectiv(m_timestamp_queries[m_read_timestamp_query], GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
pxAssert(m_read_timestamp_query != m_write_timestamp_query);
|
||||
|
||||
if (!available)
|
||||
break;
|
||||
|
||||
u64 result = 0;
|
||||
GetQueryObjectui64v(m_timestamp_queries[m_read_timestamp_query], GL_QUERY_RESULT, &result);
|
||||
m_accumulated_gpu_time += static_cast<float>(static_cast<double>(result) / 1000000.0);
|
||||
m_read_timestamp_query = (m_read_timestamp_query + 1) % NUM_TIMESTAMP_QUERIES;
|
||||
m_waiting_timestamp_queries--;
|
||||
}
|
||||
|
||||
// delay ending the current query until we've read back some
|
||||
if (m_timestamp_query_started && m_waiting_timestamp_queries < (NUM_TIMESTAMP_QUERIES - 1))
|
||||
{
|
||||
const auto EndQuery = gles ? glEndQueryEXT : glEndQuery;
|
||||
EndQuery(GL_TIME_ELAPSED);
|
||||
|
||||
m_write_timestamp_query = (m_write_timestamp_query + 1) % NUM_TIMESTAMP_QUERIES;
|
||||
m_timestamp_query_started = false;
|
||||
m_waiting_timestamp_queries++;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::KickTimestampQuery()
|
||||
{
|
||||
if (m_timestamp_query_started)
|
||||
return;
|
||||
|
||||
const bool gles = m_gl_context->IsGLES();
|
||||
const auto BeginQuery = gles ? glBeginQueryEXT : glBeginQuery;
|
||||
|
||||
BeginQuery(GL_TIME_ELAPSED, m_timestamp_queries[m_write_timestamp_query]);
|
||||
m_timestamp_query_started = true;
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::SetGPUTimingEnabled(bool enabled)
|
||||
{
|
||||
enabled &= (!m_gl_context->IsGLES() || GLAD_GL_EXT_disjoint_timer_query);
|
||||
|
||||
if (m_gpu_timing_enabled == enabled)
|
||||
return;
|
||||
|
||||
m_gpu_timing_enabled = enabled;
|
||||
if (m_gpu_timing_enabled)
|
||||
CreateTimestampQueries();
|
||||
else
|
||||
DestroyTimestampQueries();
|
||||
}
|
||||
|
||||
float OpenGLHostDisplay::GetAndResetAccumulatedGPUTime()
|
||||
{
|
||||
const float value = m_accumulated_gpu_time;
|
||||
m_accumulated_gpu_time = 0.0f;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "HostDisplay.h"
|
||||
#include "common/GL/Context.h"
|
||||
#include "common/WindowInfo.h"
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <memory>
|
||||
|
||||
class OpenGLHostDisplay final : public HostDisplay
|
||||
@@ -60,7 +62,12 @@ public:
|
||||
bool BeginPresent(bool frame_skip) override;
|
||||
void EndPresent() override;
|
||||
|
||||
void SetGPUTimingEnabled(bool enabled) override;
|
||||
float GetAndResetAccumulatedGPUTime() override;
|
||||
|
||||
protected:
|
||||
static constexpr u8 NUM_TIMESTAMP_QUERIES = 3;
|
||||
|
||||
const char* GetGLSLVersionString() const;
|
||||
std::string GetGLSLVersionHeader() const;
|
||||
|
||||
@@ -70,6 +77,19 @@ protected:
|
||||
|
||||
void SetSwapInterval();
|
||||
|
||||
void CreateTimestampQueries();
|
||||
void DestroyTimestampQueries();
|
||||
void PopTimestampQuery();
|
||||
void KickTimestampQuery();
|
||||
|
||||
std::unique_ptr<GL::Context> m_gl_context;
|
||||
|
||||
std::array<GLuint, NUM_TIMESTAMP_QUERIES> m_timestamp_queries = {};
|
||||
u8 m_read_timestamp_query = 0;
|
||||
u8 m_write_timestamp_query = 0;
|
||||
u8 m_waiting_timestamp_queries = 0;
|
||||
bool m_timestamp_query_started = false;
|
||||
float m_accumulated_gpu_time = 0.0f;
|
||||
bool m_gpu_timing_enabled = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include <array>
|
||||
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 1;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 4;
|
||||
|
||||
class VulkanHostDisplayTexture : public HostDisplayTexture
|
||||
{
|
||||
@@ -396,6 +396,16 @@ void VulkanHostDisplay::EndPresent()
|
||||
g_vulkan_context->MoveToNextCommandBuffer();
|
||||
}
|
||||
|
||||
void VulkanHostDisplay::SetGPUTimingEnabled(bool enabled)
|
||||
{
|
||||
g_vulkan_context->SetEnableGPUTiming(enabled);
|
||||
}
|
||||
|
||||
float VulkanHostDisplay::GetAndResetAccumulatedGPUTime()
|
||||
{
|
||||
return g_vulkan_context->GetAndResetAccumulatedGPUTime();
|
||||
}
|
||||
|
||||
HostDisplay::AdapterAndModeList VulkanHostDisplay::StaticGetAdapterAndModeList(const WindowInfo* wi)
|
||||
{
|
||||
AdapterAndModeList ret;
|
||||
|
||||
@@ -51,6 +51,9 @@ public:
|
||||
bool BeginPresent(bool frame_skip) override;
|
||||
void EndPresent() override;
|
||||
|
||||
void SetGPUTimingEnabled(bool enabled) override;
|
||||
float GetAndResetAccumulatedGPUTime() override;
|
||||
|
||||
static AdapterAndModeList StaticGetAdapterAndModeList(const WindowInfo* wi);
|
||||
|
||||
protected:
|
||||
|
||||
+37
-38
@@ -147,6 +147,9 @@ void GSclose()
|
||||
g_gs_device.reset();
|
||||
}
|
||||
|
||||
if (HostDisplay* display = Host::GetHostDisplay(); display)
|
||||
display->SetGPUTimingEnabled(false);
|
||||
|
||||
Host::ReleaseHostDisplay();
|
||||
}
|
||||
|
||||
@@ -238,6 +241,7 @@ static bool DoGSOpen(GSRendererType renderer, u8* basemem)
|
||||
s_gs->SetRegsMem(basemem);
|
||||
|
||||
display->SetVSync(EmuConfig.GetEffectiveVsyncMode());
|
||||
display->SetGPUTimingEnabled(GSConfig.OsdShowGPU);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -310,7 +314,6 @@ bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* b
|
||||
|
||||
GSConfig = config;
|
||||
GSConfig.Renderer = renderer;
|
||||
GSConfig.MaskUserHacks();
|
||||
|
||||
if (!Host::AcquireHostDisplay(GetAPIForRenderer(renderer)))
|
||||
{
|
||||
@@ -658,21 +661,16 @@ void GSgetStats(std::string& info)
|
||||
|
||||
if (GSConfig.Renderer == GSRendererType::SW)
|
||||
{
|
||||
float sum = 0.0f;
|
||||
for (int i = GSPerfMon::WorkerDraw0; i < GSPerfMon::TimerLast; i++)
|
||||
sum += pm.GetTimer(static_cast<GSPerfMon::timer_t>(i));
|
||||
|
||||
const double fps = GetVerticalFrequency();
|
||||
const double fillrate = pm.Get(GSPerfMon::Fillrate);
|
||||
info = format("%s SW | %d S | %d P | %d D | %.2f U | %.2f D | %.2f mpps | %d%% WCPU",
|
||||
info = format("%s SW | %d S | %d P | %d D | %.2f U | %.2f D | %.2f mpps",
|
||||
api_name,
|
||||
(int)pm.Get(GSPerfMon::SyncPoint),
|
||||
(int)pm.Get(GSPerfMon::Prim),
|
||||
(int)pm.Get(GSPerfMon::Draw),
|
||||
pm.Get(GSPerfMon::Swizzle) / 1024,
|
||||
pm.Get(GSPerfMon::Unswizzle) / 1024,
|
||||
fps * fillrate / (1024 * 1024),
|
||||
static_cast<int>(std::lround(sum)));
|
||||
fps * fillrate / (1024 * 1024));
|
||||
}
|
||||
else if (GSConfig.Renderer == GSRendererType::Null)
|
||||
{
|
||||
@@ -723,7 +721,6 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
Pcsx2Config::GSOptions old_config(std::move(GSConfig));
|
||||
GSConfig = new_config;
|
||||
GSConfig.Renderer = (GSConfig.Renderer == GSRendererType::Auto) ? GSUtil::GetPreferredRenderer() : GSConfig.Renderer;
|
||||
GSConfig.MaskUserHacks();
|
||||
if (!s_gs)
|
||||
return;
|
||||
|
||||
@@ -758,21 +755,6 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
|
||||
// Options which aren't using the global struct yet, so we need to recreate all GS objects.
|
||||
if (
|
||||
GSConfig.ConservativeFramebuffer != old_config.ConservativeFramebuffer ||
|
||||
GSConfig.AutoFlushSW != old_config.AutoFlushSW ||
|
||||
GSConfig.PreloadFrameWithGSData != old_config.PreloadFrameWithGSData ||
|
||||
GSConfig.WrapGSMem != old_config.WrapGSMem ||
|
||||
GSConfig.Mipmap != old_config.Mipmap ||
|
||||
GSConfig.AA1 != old_config.AA1 ||
|
||||
GSConfig.UserHacks_AlignSpriteX != old_config.UserHacks_AlignSpriteX ||
|
||||
GSConfig.UserHacks_AutoFlush != old_config.UserHacks_AutoFlush ||
|
||||
GSConfig.UserHacks_CPUFBConversion != old_config.UserHacks_CPUFBConversion ||
|
||||
GSConfig.UserHacks_DisableDepthSupport != old_config.UserHacks_DisableDepthSupport ||
|
||||
GSConfig.UserHacks_DisablePartialInvalidation != old_config.UserHacks_DisablePartialInvalidation ||
|
||||
GSConfig.UserHacks_DisableSafeFeatures != old_config.UserHacks_DisableSafeFeatures ||
|
||||
GSConfig.UserHacks_MergePPSprite != old_config.UserHacks_MergePPSprite ||
|
||||
GSConfig.UserHacks_WildHack != old_config.UserHacks_WildHack ||
|
||||
GSConfig.UserHacks_TextureInsideRt != old_config.UserHacks_TextureInsideRt ||
|
||||
GSConfig.DumpGSData != old_config.DumpGSData ||
|
||||
GSConfig.SaveRT != old_config.SaveRT ||
|
||||
GSConfig.SaveFrame != old_config.SaveFrame ||
|
||||
@@ -784,12 +766,6 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
GSConfig.SWExtraThreads != old_config.SWExtraThreads ||
|
||||
GSConfig.SWExtraThreadsHeight != old_config.SWExtraThreadsHeight ||
|
||||
|
||||
GSConfig.UserHacks_HalfBottomOverride != old_config.UserHacks_HalfBottomOverride ||
|
||||
GSConfig.UserHacks_HalfPixelOffset != old_config.UserHacks_HalfPixelOffset ||
|
||||
GSConfig.UserHacks_RoundSprite != old_config.UserHacks_RoundSprite ||
|
||||
GSConfig.UserHacks_TCOffsetX != old_config.UserHacks_TCOffsetX ||
|
||||
GSConfig.UserHacks_TCOffsetY != old_config.UserHacks_TCOffsetY ||
|
||||
|
||||
GSConfig.ShadeBoost_Brightness != old_config.ShadeBoost_Brightness ||
|
||||
GSConfig.ShadeBoost_Contrast != old_config.ShadeBoost_Contrast ||
|
||||
GSConfig.ShadeBoost_Saturation != old_config.ShadeBoost_Saturation ||
|
||||
@@ -806,17 +782,29 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
// This is where we would do finer-grained checks in the future.
|
||||
// For example, flushing the texture cache when mipmap settings change.
|
||||
|
||||
if (GSConfig.HWMipmap != old_config.HWMipmap || GSConfig.CRCHack != old_config.CRCHack)
|
||||
if (GSConfig.CRCHack != old_config.CRCHack ||
|
||||
GSConfig.PointListPalette != old_config.PointListPalette)
|
||||
{
|
||||
// for automatic mipmaps, we need to reload the crc
|
||||
s_gs->SetGameCRC(s_gs->GetGameCRC(), s_gs->GetGameCRCOptions());
|
||||
}
|
||||
|
||||
// reload texture cache when trilinear filtering or mipmap options change
|
||||
if (GSConfig.HWMipmap != old_config.HWMipmap ||
|
||||
// renderer-specific options (e.g. auto flush, TC offset)
|
||||
s_gs->UpdateSettings(old_config);
|
||||
|
||||
// reload texture cache when trilinear filtering or TC options change
|
||||
if (
|
||||
(GSConfig.UseHardwareRenderer() && GSConfig.HWMipmap != old_config.HWMipmap) ||
|
||||
GSConfig.ConservativeFramebuffer != old_config.ConservativeFramebuffer ||
|
||||
GSConfig.TexturePreloading != old_config.TexturePreloading ||
|
||||
GSConfig.UserHacks_TriFilter != old_config.UserHacks_TriFilter ||
|
||||
GSConfig.GPUPaletteConversion != old_config.GPUPaletteConversion)
|
||||
GSConfig.GPUPaletteConversion != old_config.GPUPaletteConversion ||
|
||||
GSConfig.PreloadFrameWithGSData != old_config.PreloadFrameWithGSData ||
|
||||
GSConfig.WrapGSMem != old_config.WrapGSMem ||
|
||||
GSConfig.UserHacks_CPUFBConversion != old_config.UserHacks_CPUFBConversion ||
|
||||
GSConfig.UserHacks_DisableDepthSupport != old_config.UserHacks_DisableDepthSupport ||
|
||||
GSConfig.UserHacks_DisablePartialInvalidation != old_config.UserHacks_DisablePartialInvalidation ||
|
||||
GSConfig.UserHacks_TextureInsideRt != old_config.UserHacks_TextureInsideRt)
|
||||
{
|
||||
s_gs->PurgeTextureCache();
|
||||
s_gs->PurgePool();
|
||||
@@ -836,6 +824,12 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
|
||||
{
|
||||
s_gs->PurgeTextureCache();
|
||||
}
|
||||
|
||||
if (GSConfig.OsdShowGPU != old_config.OsdShowGPU)
|
||||
{
|
||||
if (HostDisplay* display = Host::GetHostDisplay(); display)
|
||||
display->SetGPUTimingEnabled(GSConfig.OsdShowGPU);
|
||||
}
|
||||
}
|
||||
|
||||
void GSSwitchRenderer(GSRendererType new_renderer)
|
||||
@@ -1314,6 +1308,8 @@ void GSApp::Init()
|
||||
m_default_configuration["CrcHacksExclusions"] = "";
|
||||
m_default_configuration["disable_hw_gl_draw"] = "0";
|
||||
m_default_configuration["disable_shader_cache"] = "0";
|
||||
m_default_configuration["DisableDualSourceBlend"] = "0";
|
||||
m_default_configuration["DisableFramebufferFetch"] = "0";
|
||||
m_default_configuration["dithering_ps2"] = "2";
|
||||
m_default_configuration["dump"] = "0";
|
||||
m_default_configuration["DumpReplaceableTextures"] = "0";
|
||||
@@ -1341,11 +1337,11 @@ void GSApp::Init()
|
||||
m_default_configuration["OsdShowSpeed"] = "0";
|
||||
m_default_configuration["OsdShowFPS"] = "0";
|
||||
m_default_configuration["OsdShowCPU"] = "0";
|
||||
m_default_configuration["OsdShowGPU"] = "0";
|
||||
m_default_configuration["OsdShowResolution"] = "0";
|
||||
m_default_configuration["OsdShowGSStats"] = "0";
|
||||
m_default_configuration["OsdShowIndicators"] = "1";
|
||||
m_default_configuration["OsdScale"] = "100";
|
||||
m_default_configuration["override_geometry_shader"] = "-1";
|
||||
m_default_configuration["override_GL_ARB_copy_image"] = "-1";
|
||||
m_default_configuration["override_GL_ARB_clear_texture"] = "-1";
|
||||
m_default_configuration["override_GL_ARB_clip_control"] = "-1";
|
||||
@@ -1356,8 +1352,11 @@ void GSApp::Init()
|
||||
m_default_configuration["override_GL_ARB_sparse_texture"] = "-1";
|
||||
m_default_configuration["override_GL_ARB_sparse_texture2"] = "-1";
|
||||
m_default_configuration["override_GL_ARB_texture_barrier"] = "-1";
|
||||
m_default_configuration["OverrideTextureBarriers"] = "-1";
|
||||
m_default_configuration["OverrideGeometryShaders"] = "-1";
|
||||
m_default_configuration["paltex"] = "0";
|
||||
m_default_configuration["png_compression_level"] = std::to_string(Z_BEST_SPEED);
|
||||
m_default_configuration["PointListPalette"] = "0";
|
||||
m_default_configuration["PrecacheTextureReplacements"] = "0";
|
||||
m_default_configuration["preload_frame_with_gs_data"] = "0";
|
||||
m_default_configuration["Renderer"] = std::to_string(static_cast<int>(GSRendererType::Auto));
|
||||
@@ -1395,8 +1394,8 @@ void GSApp::Init()
|
||||
m_default_configuration["UserHacks_HalfPixelOffset"] = "0";
|
||||
m_default_configuration["UserHacks_merge_pp_sprite"] = "0";
|
||||
m_default_configuration["UserHacks_round_sprite_offset"] = "0";
|
||||
m_default_configuration["UserHacks_SkipDraw"] = "0";
|
||||
m_default_configuration["UserHacks_SkipDraw_Offset"] = "0";
|
||||
m_default_configuration["UserHacks_SkipDraw_Start"] = "0";
|
||||
m_default_configuration["UserHacks_SkipDraw_End"] = "0";
|
||||
m_default_configuration["UserHacks_TCOffsetX"] = "0";
|
||||
m_default_configuration["UserHacks_TCOffsetY"] = "0";
|
||||
m_default_configuration["UserHacks_TextureInsideRt"] = "0";
|
||||
@@ -1644,4 +1643,4 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys){
|
||||
}},
|
||||
END_HOTKEY_LIST()
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -538,7 +538,7 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
|
||||
|
||||
for (int i = 0; i < m_threads; i++)
|
||||
{
|
||||
m_workers.push_back(std::unique_ptr<GSPng::Worker>(new GSPng::Worker(&GSPng::Process)));
|
||||
m_workers.push_back(std::unique_ptr<GSPng::Worker>(new GSPng::Worker({}, &GSPng::Process, {})));
|
||||
}
|
||||
|
||||
m_capturing = true;
|
||||
|
||||
+33
-186
@@ -26,14 +26,7 @@ const CRC::Game CRC::m_games[] =
|
||||
{0x68CE6801, ArTonelico2, JP, 0},
|
||||
{0xCE2C1DBF, ArTonelico2, EU, 0},
|
||||
{0x2113EA2E, MetalSlug6, JP, 0},
|
||||
{0x42E05BAF, TomoyoAfter, JP, PointListPalette},
|
||||
{0x7800DC84, Clannad, JP, PointListPalette},
|
||||
{0xA6167B59, Lamune, JP, PointListPalette},
|
||||
{0xDDB59F46, KyuuketsuKitanMoonties, JP, PointListPalette},
|
||||
{0xC8EE2562, PiaCarroteYoukosoGPGakuenPrincess, JP, PointListPalette},
|
||||
{0x6CF94A43, KazokuKeikakuKokoroNoKizuna, JP, PointListPalette},
|
||||
{0xEDAF602D, DuelSaviorDestiny, JP, PointListPalette},
|
||||
{0xBB63D785, OneTwentyYenStories, JP, PointListPalette}, // no Haru: 120 Yen Stories
|
||||
{0xA6167B59, Lamune, JP, 0},
|
||||
{0xA39517AB, FFX, EU, 0},
|
||||
{0x78D83FD5, FFX, EU, 0}, // Demo
|
||||
{0xA39517AE, FFX, FR, 0},
|
||||
@@ -94,12 +87,6 @@ const CRC::Game CRC::m_games[] =
|
||||
{0x71521863, SFEX3, US, 0},
|
||||
{0x63642E9F, SFEX3, JP, 0},
|
||||
{0xCA1F6E53, SFEX3, JP, 0}, // Taikenban Disc (Demo/Trial)
|
||||
{0xC19A374E, SoTC, US, 0},
|
||||
{0x7D8F539A, SoTC, EU, 0},
|
||||
{0x0F0C4A9C, SoTC, EU, 0},
|
||||
{0x877F3436, SoTC, JP, 0},
|
||||
{0xA17D6AAA, SoTC, KO, 0},
|
||||
{0x877B3D35, SoTC, CH, 0},
|
||||
{0x6F8545DB, ICO, US, 0},
|
||||
{0x48CDF317, ICO, US, 0}, // Demo
|
||||
{0xB01A4C95, ICO, JP, 0},
|
||||
@@ -163,9 +150,6 @@ const CRC::Game CRC::m_games[] =
|
||||
{0xA32F7CD0, AceCombat4, US, 0}, // Also needed for automatic mipmapping
|
||||
{0x5ED8FB53, AceCombat4, JP, 0},
|
||||
{0x1B9B7563, AceCombat4, EU, 0},
|
||||
{0x39B574F0, AceCombat5, US, 0}, // The Unsung War
|
||||
{0x86089F31, AceCombat5, JP, 0},
|
||||
{0x1D54FEA9, AceCombat5, EU, 0}, // Squadron Leader
|
||||
{0xFC46EA61, Tekken5, JP, 0},
|
||||
{0x1F88EE37, Tekken5, EU, 0},
|
||||
{0x1F88BECD, Tekken5, EU, 0}, // language selector...
|
||||
@@ -206,7 +190,6 @@ const CRC::Game CRC::m_games[] =
|
||||
{0xA3643EB1, GiTS, KO, 0},
|
||||
{0x28557423, GiTS, RU, 0},
|
||||
{0xBF6F101F, GiTS, EU, 0}, // same CRC as another US disc
|
||||
{0xF442260C, MajokkoALaMode2, JP, PointListPalette},
|
||||
{0xA616A6C2, TalesOfAbyss, US, 0},
|
||||
{0x14FE77F7, TalesOfAbyss, US, 0},
|
||||
{0xAA5EC3A3, TalesOfAbyss, JP, 0},
|
||||
@@ -239,14 +222,13 @@ const CRC::Game CRC::m_games[] =
|
||||
{0xDD93DA88, BigMuthaTruckers, JP, 0}, // Bakusou Convoy Densetsu - Otoko Hanamichi America Roman
|
||||
{0xE169BAF8, RedDeadRevolver, US, 0},
|
||||
{0xE2E67E23, RedDeadRevolver, EU, 0},
|
||||
{0xCBB87BF9, EvangelionJo, JP, 0},
|
||||
{0xC5B75C7C, Oneechanbara2Special, JP, 0},
|
||||
{0xC725CC6C, Oneechanbara2Special, JP, 0},
|
||||
{0x07608CA2, Oneechanbara2Special, EU, 0}, // Zombie Hunters 2
|
||||
{0xE0347841, XenosagaE3, JP, TextureInsideRt},
|
||||
{0xA707236E, XenosagaE3, JP, TextureInsideRt}, // Demo
|
||||
{0xA4E88698, XenosagaE3, CH, TextureInsideRt},
|
||||
{0x2088950A, XenosagaE3, US, TextureInsideRt},
|
||||
{0xE0347841, XenosagaE3, JP, 0},
|
||||
{0xA707236E, XenosagaE3, JP, 0}, // Demo
|
||||
{0xA4E88698, XenosagaE3, CH, 0},
|
||||
{0x2088950A, XenosagaE3, US, 0},
|
||||
{0xB1995E29, ShadowofRome, EU, 0},
|
||||
{0x958DCA28, ShadowofRome, EU, 0},
|
||||
{0x57818AF6, ShadowofRome, US, 0},
|
||||
@@ -315,14 +297,14 @@ const CRC::Game CRC::m_games[] =
|
||||
{0x812C5A96, ShinOnimusha, EU, 0},
|
||||
{0xFE44479E, ShinOnimusha, US, 0},
|
||||
{0xFFDE85E9, ShinOnimusha, US, 0},
|
||||
{0xE21404E2, GetawayGames, US, TextureInsideRt}, // Getaway
|
||||
{0xE8249852, GetawayGames, JP, TextureInsideRt}, // Getaway
|
||||
{0x458485EF, GetawayGames, EU, TextureInsideRt}, // Getaway
|
||||
{0x5DFBE144, GetawayGames, EU, TextureInsideRt}, // Getaway
|
||||
{0xE78971DF, GetawayGames, US, TextureInsideRt}, // GetawayBlackMonday
|
||||
{0x342D97FA, GetawayGames, US, TextureInsideRt}, // GetawayBlackMonday Demo
|
||||
{0xE8C0AD1A, GetawayGames, JP, TextureInsideRt}, // GetawayBlackMonday
|
||||
{0x09C3DF79, GetawayGames, EU, TextureInsideRt}, // GetawayBlackMonday
|
||||
{0xE21404E2, GetawayGames, US, 0}, // Getaway
|
||||
{0xE8249852, GetawayGames, JP, 0}, // Getaway
|
||||
{0x458485EF, GetawayGames, EU, 0}, // Getaway
|
||||
{0x5DFBE144, GetawayGames, EU, 0}, // Getaway
|
||||
{0xE78971DF, GetawayGames, US, 0}, // GetawayBlackMonday
|
||||
{0x342D97FA, GetawayGames, US, 0}, // GetawayBlackMonday Demo
|
||||
{0xE8C0AD1A, GetawayGames, JP, 0}, // GetawayBlackMonday
|
||||
{0x09C3DF79, GetawayGames, EU, 0}, // GetawayBlackMonday
|
||||
{0x1130BF23, SakuraTaisen, CH, 0},
|
||||
{0x4FAE8B83, SakuraTaisen, KO, 0},
|
||||
{0xEF06DBD6, SakuraWarsSoLongMyLove, JP, 0},
|
||||
@@ -350,161 +332,26 @@ const CRC::Game CRC::m_games[] =
|
||||
{0XE1BF5DCA, SuperManReturns, US, 0},
|
||||
{0XE8F7BAB6, SuperManReturns, EU, 0},
|
||||
{0x06A7506A, SacredBlaze, JP, 0},
|
||||
{0x9C712FF0, Jak1, EU, TextureInsideRt}, // Jak and Daxter: The Precursor Legacy
|
||||
{0x1B3976AB, Jak1, US, TextureInsideRt},
|
||||
{0x472E7699, Jak1, US, TextureInsideRt}, // Greatest Hits
|
||||
{0x96A608C5, Jak1, US, TextureInsideRt}, // Cingular Wireless Demo, PS Underground Demo
|
||||
{0xEDE4FE64, Jak1, JP, TextureInsideRt}, // Jak x Daxter: Kyuusekai no Isan
|
||||
{0x2A7FD3B4, Jak1, JP, TextureInsideRt}, // Demo
|
||||
{0x2479F4A9, Jak2, EU, TextureInsideRt},
|
||||
{0xF41C1B29, Jak2, EU, TextureInsideRt}, // Demo
|
||||
{0x9184AAF1, Jak2, US, TextureInsideRt},
|
||||
{0xA2034C69, Jak2, US, TextureInsideRt}, // Demo
|
||||
{0x25FE4D23, Jak2, KO, TextureInsideRt},
|
||||
{0xB4976DAF, Jak2, JP, TextureInsideRt}, // Jak II: Jak x Daxter 2
|
||||
{0x43D4FF3E, Jak2, JP, TextureInsideRt}, // Demo
|
||||
{0x12804727, Jak3, EU, TextureInsideRt},
|
||||
{0xE59E10BF, Jak3, EU, TextureInsideRt},
|
||||
{0xCA68E4D5, Jak3, EU, TextureInsideRt}, // Demo
|
||||
{0x644CFD03, Jak3, US, TextureInsideRt},
|
||||
{0xD401BC20, Jak3, US, TextureInsideRt}, // Demo
|
||||
{0xD1368EAE, Jak3, KO, TextureInsideRt},
|
||||
{0xDF659E77, JakX, EU, TextureInsideRt}, // Jak X: Combat Racing
|
||||
{0xC20596DB, JakX, EU, TextureInsideRt}, // Beta Trial Disc, v0.01
|
||||
{0x3091E6FB, JakX, US, TextureInsideRt},
|
||||
{0xC417D919, JakX, US, TextureInsideRt}, // Demo
|
||||
{0xDA366A53, JakX, US, TextureInsideRt}, // Public Beta v.1
|
||||
{0x7B564230, JakX, US, TextureInsideRt}, // Jak and Daxter Complete Trilogy Demo
|
||||
{0xDBA28C59, JakX, US, TextureInsideRt}, // Greatest Hits
|
||||
{0x4653CA3E, HarleyDavidson, US, 0},
|
||||
// Games list for Automatic Mipmapping
|
||||
// Basic mipmapping
|
||||
{0x194C9F38, AceCombatZero, EU, 0}, // Ace Combat: The Belkan War
|
||||
{0x65729657, AceCombatZero, US, 0},
|
||||
{0xA04B52DB, AceCombatZero, JP, 0},
|
||||
{0x2799A4E5, AceCombatZero, KO, 0},
|
||||
{0x09B3AD4D, ApeEscape2, EU, 0},
|
||||
{0xADCDCB88, ApeEscape2, EU, 0}, // Spanish version
|
||||
{0xBBB21612, ApeEscape2, DE, 0},
|
||||
{0xE2B8D3B2, ApeEscape2, IT, 0},
|
||||
{0x8B6FE2EA, ApeEscape2, FR, 0},
|
||||
{0xBDD9F5E1, ApeEscape2, US, 0},
|
||||
{0xFE0A6AB6, ApeEscape2, JP, 0}, // Saru! Get You! 2
|
||||
{0x64A9982B, ApeEscape2, CH, 0},
|
||||
{0xEC8EF2DE, Barnyard, US, 0}, // Nickelodeon: Barnyard
|
||||
{0x0B2F3DEE, Barnyard, KO, 0},
|
||||
{0x5267A845, Barnyard, EU, 0},
|
||||
{0x0940508D, BrianLaraInternationalCricket, EU, 0},
|
||||
{0x0BAA8DD8, DarkCloud, EU, 0},
|
||||
{0x1DF41F33, DarkCloud, US, 0},
|
||||
{0xA5C05C78, DarkCloud, US, 0},
|
||||
{0x60AA5049, DarkCloud, KO, 0},
|
||||
{0xECD8E386, DarkCloud, JP, 0},
|
||||
{0x67A29886, DestroyAllHumans, US, 0},
|
||||
{0xE3E8E893, DestroyAllHumans, EU, 0},
|
||||
{0x42DF8C8C, DestroyAllHumans2, US, 0},
|
||||
{0x743E10C2, DestroyAllHumans2, EU, 0},
|
||||
{0x67C38BAA, FIFA03, US, 0},
|
||||
{0x722BBD62, FIFA03, EU, 0},
|
||||
{0x2BCCF704, FIFA03, EU, 0},
|
||||
{0xCC6AA742, FIFA04, KO, 0},
|
||||
{0x2C6A4E2E, FIFA04, US, 0},
|
||||
{0x684ADFC6, FIFA04, EU, 0},
|
||||
{0x972611BB, FIFA05, US, 0},
|
||||
{0x972719A3, FIFA05, EU, 0},
|
||||
{0xC5473413, HarryPotterATCOS, NoRegion, 0}, // EU and US versions have the same CRC - Chamber Of Secrets
|
||||
{0xE1963055, HarryPotterATCOS, JP, 0}, // Harry Potter to Himitsu no Heya
|
||||
{0xE90BE9F8, HarryPotterATCOS, JP, 0}, // Coca Cola original Version
|
||||
{0xB38CC628, HarryPotterATGOF, US, 0},
|
||||
{0xCDE017A7, HarryPotterATGOF, KO, 0},
|
||||
{0xB18DC525, HarryPotterATGOF, EU, 0},
|
||||
{0x9C3A84F4, HarryPotterATHBP, US, 0}, // Half-Blood Prince
|
||||
{0xCB598BC2, HarryPotterATHBP, EU, 0},
|
||||
{0x51E019BC, HarryPotterATPOA, NoRegion, 0}, // EU and US versions have the same CRC - Prisoner of Azkaban
|
||||
{0x99A8B4FF, HarryPotterATPOA, KO, 0},
|
||||
{0xA8901AD6, HarryPotterATPOA, JP, 0}, // Harry Potter to Azkaban no Shuujin
|
||||
{0x51E417AA, HarryPotterATPOA, EU, 0},
|
||||
{0x4C01B1B0, HarryPotterOOTP, US, 0}, // Order Of The Phoenix
|
||||
{0x01A9BF0E, HarryPotterOOTP, EU, 0},
|
||||
{0x960FFA6A, JurassicPark, EU, 0},
|
||||
{0xA99B8FE7, JurassicPark, US, 0},
|
||||
{0x230CB71D, SoulReaver2, US, 0},
|
||||
{0x1771BFE4, SoulReaver2, US, 0},
|
||||
{0x6F991F52, SoulReaver2, JP, 0},
|
||||
{0x1B7FF35A, SoulReaver2, KO, 0},
|
||||
{0x6D8B4CD1, SoulReaver2, EU, 0},
|
||||
{0x728AB07C, LegacyOfKainDefiance, US, 0},
|
||||
{0xBCAD1E8A, LegacyOfKainDefiance, EU, 0},
|
||||
{0x28D09BF9, NicktoonsUnite, US, 0},
|
||||
{0xF25266C4, NicktoonsUnite, EU, 0}, // Nickelodeon SpongeBob SquarePants And Friends Unite
|
||||
{0x7AE1C04B, Persona3, US, 0}, // Regular Version
|
||||
{0x05C3D28F, Persona3, JP, 0},
|
||||
{0xBCD68B1E, Persona3, KO, 0},
|
||||
{0x8A557EE5, Persona3, EU, 0},
|
||||
{0x94A82AAA, Persona3, US, 0}, // FES
|
||||
{0x232C7D72, Persona3, JP, 0},
|
||||
{0x8897C208, Persona3, KO, 0},
|
||||
{0xF64A6AE5, Persona3, EU, 0},
|
||||
{0x2BDA8ADB, ProjectSnowblind, US, 0},
|
||||
{0xF00CA82B, ProjectSnowblind, EU, 0},
|
||||
{0xF1583665, ProjectSnowblind, EU, 0},
|
||||
{0xA56A0525, Quake3Revolution, US, 0},
|
||||
{0x2064ACE6, Quake3Revolution, EU, 0},
|
||||
{0xCE4933D0, RatchetAndClank, US, 0},
|
||||
{0x6F191506, RatchetAndClank, US, 0}, // E3 Demo
|
||||
{0x81CBFEA2, RatchetAndClank, US, 0}, // EB Games Demo
|
||||
{0x56A35F77, RatchetAndClank, JP, 0},
|
||||
{0x76F724A3, RatchetAndClank, EU, 0},
|
||||
{0x6A8F18B9, RatchetAndClank, EU, 0},
|
||||
{0x5C19F3B7, RatchetAndClank, EU, 0}, // Regular Demo
|
||||
{0xB3A71D10, RatchetAndClank2, US, 0}, // Going Commando
|
||||
{0x38996035, RatchetAndClank2, US, 0},
|
||||
{0xF700EE7E, RatchetAndClank2, US, 0}, // Regular Demo
|
||||
{0xF67ADF58, RatchetAndClank2, US, 0}, // Retail Employees Demo
|
||||
{0xDF6F94A1, RatchetAndClank2, US, 0}, // Demo - Going Commando & Jak II
|
||||
{0x89A26EC9, RatchetAndClank2, KO, 0},
|
||||
{0x8CAA5F16, RatchetAndClank2, JP, 0}, // Gagaga! Ginga no Commando-ssu
|
||||
{0x2F486E6F, RatchetAndClank2, EU, 0},
|
||||
{0x45FE0CC4, RatchetAndClank3, US, 0}, // Up Your Arsenal
|
||||
{0x2A12175A, RatchetAndClank3, US, 0}, // Regular Demo
|
||||
{0xCC53C3B4, RatchetAndClank3, US, 0}, // Public Beta v1.0
|
||||
{0x9FCC4BA4, RatchetAndClank3, KO, 0},
|
||||
{0x64DC6000, RatchetAndClank3, JP, 0}, // Totsugeki! Galactic Rangers
|
||||
{0x17125698, RatchetAndClank3, EU, 0},
|
||||
{0x4A85FC67, RatchetAndClank3, EU, 0}, // Beta Trial Disc
|
||||
{0x9BFBCD42, RatchetAndClank4, US, 0}, // Deadlocked
|
||||
{0xD301186D, RatchetAndClank4, US, 0}, // Regular Demo
|
||||
{0xBDF8A887, RatchetAndClank4, US, 0}, // Public Beta v.1
|
||||
{0x529BC7CC, RatchetAndClank4, KO, 0},
|
||||
{0x2EC9DA96, RatchetAndClank4, JP, 0}, // GiriGiri Ginga no Giga Battle
|
||||
{0x76975025, RatchetAndClank4, JP, 0}, // Regular Demo
|
||||
{0xD697D204, RatchetAndClank4, EU, 0}, // Ratchet Gladiator
|
||||
{0x8661F7BA, RatchetAndClank5, US, 0}, // Size Matters
|
||||
{0x7029DCE6, RatchetAndClank5, KO, 0},
|
||||
{0x9ADCF7AF, RatchetAndClank5, JP, 0}, // Gekitotsu! Dodeka Ginga no Miri Miri Gundan
|
||||
{0xFCB981D5, RatchetAndClank5, EU, 0},
|
||||
{0x8634861F, RickyPontingInternationalCricket, EU, 0},
|
||||
{0xDDAC3815, Shox, US, 0},
|
||||
{0xF84FE9DE, Shox, KO, 0},
|
||||
{0x09F4038B, Shox, EU, 0},
|
||||
{0x78FFA39F, Shox, EU, 0},
|
||||
{0x3DF10389, Shox, EU, 0},
|
||||
{0x43CC009B, SlamTennis, EU, 0},
|
||||
{0xF17AF8BD, TheIncredibleHulkUD, US, 0},
|
||||
{0xEA8D4BDF, TheIncredibleHulkUD, US, 0},
|
||||
{0x6B3D50A5, TheIncredibleHulkUD, EU, 0},
|
||||
{0x2B58234D, TribesAerialAssault, US, 0},
|
||||
{0x4D22DB95, Whiplash, US, 0},
|
||||
{0xE8A97250, Whiplash, EU, 0},
|
||||
{0xB1BE3E51, Whiplash, EU, 0},
|
||||
{0x4C33FA2A, IndianaJonesAndTheEmperorsTomb, US, TextureInsideRt}, // TODO Add more CRCs (https://pcsx2.net/compatibility-list.html).
|
||||
{0xAE0E098F, IndianaJonesAndTheEmperorsTomb, DE, TextureInsideRt},
|
||||
{0xBBC3EFFA, WildArms4, US, TextureInsideRt}, // TODO Add more CRCs (https://pcsx2.net/compatibility-list.html).
|
||||
{0x36802E57, BeyondGoodAndEvil, US, TextureInsideRt}, // TODO Add more CRCs (https://pcsx2.net/compatibility-list.html).
|
||||
{0x08FFF00D, SSX3, US, TextureInsideRt},
|
||||
{0xCE942B2A, SSX3, EU, TextureInsideRt}, // TODO Add more CRCs (https://pcsx2.net/compatibility-list.html).
|
||||
{0x1FCC0CFB, DrivingEmotionTypeS, US, TextureInsideRt},
|
||||
{0x034836F8, DrivingEmotionTypeS, JP, TextureInsideRt}, // TODO Add more CRCs (https://pcsx2.net/compatibility-list.html).
|
||||
{0x2479F4A9, Jak2, EU, 0},
|
||||
{0xF41C1B29, Jak2, EU, 0}, // Demo
|
||||
{0x9184AAF1, Jak2, US, 0},
|
||||
{0xA2034C69, Jak2, US, 0}, // Demo
|
||||
{0x25FE4D23, Jak2, KO, 0},
|
||||
{0xB4976DAF, Jak2, JP, 0}, // Jak II: Jak x Daxter 2
|
||||
{0x43D4FF3E, Jak2, JP, 0}, // Demo
|
||||
{0x12804727, Jak3, EU, 0},
|
||||
{0xE59E10BF, Jak3, EU, 0},
|
||||
{0xCA68E4D5, Jak3, EU, 0}, // Demo
|
||||
{0x644CFD03, Jak3, US, 0},
|
||||
{0xD401BC20, Jak3, US, 0}, // Demo
|
||||
{0xD1368EAE, Jak3, KO, 0},
|
||||
{0xDF659E77, JakX, EU, 0}, // Jak X: Combat Racing
|
||||
{0xC20596DB, JakX, EU, 0}, // Beta Trial Disc, v0.01
|
||||
{0x3091E6FB, JakX, US, 0},
|
||||
{0xC417D919, JakX, US, 0}, // Demo
|
||||
{0xDA366A53, JakX, US, 0}, // Public Beta v.1
|
||||
{0x7B564230, JakX, US, 0}, // Jak and Daxter Complete Trilogy Demo
|
||||
{0xDBA28C59, JakX, US, 0}, // Greatest Hits
|
||||
};
|
||||
|
||||
std::map<u32, const CRC::Game*> CRC::m_map;
|
||||
|
||||
@@ -23,116 +23,64 @@ public:
|
||||
enum Title
|
||||
{
|
||||
NoTitle,
|
||||
AceCombatZero,
|
||||
AceCombat4,
|
||||
AceCombat5,
|
||||
ApeEscape2,
|
||||
ArTonelico2,
|
||||
Barnyard,
|
||||
BeyondGoodAndEvil,
|
||||
BigMuthaTruckers,
|
||||
BrianLaraInternationalCricket,
|
||||
BurnoutGames,
|
||||
Clannad,
|
||||
CrashBandicootWoC,
|
||||
DarkCloud,
|
||||
DBZBT2,
|
||||
DBZBT3,
|
||||
DeathByDegreesTekkenNinaWilliams,
|
||||
DestroyAllHumans,
|
||||
DestroyAllHumans2,
|
||||
DrivingEmotionTypeS,
|
||||
DuelSaviorDestiny,
|
||||
EvangelionJo,
|
||||
FFX,
|
||||
FFX2,
|
||||
FFXII,
|
||||
FIFA03,
|
||||
FIFA04,
|
||||
FIFA05,
|
||||
FightingBeautyWulong,
|
||||
GetawayGames,
|
||||
GiTS,
|
||||
GodHand,
|
||||
GodOfWar,
|
||||
GodOfWar2,
|
||||
HarleyDavidson,
|
||||
HarryPotterATCOS,
|
||||
HarryPotterATGOF,
|
||||
HarryPotterATHBP,
|
||||
HarryPotterATPOA,
|
||||
HarryPotterOOTP,
|
||||
HauntingGround,
|
||||
ICO,
|
||||
IkkiTousen,
|
||||
IndianaJonesAndTheEmperorsTomb,
|
||||
Jak1,
|
||||
Jak2,
|
||||
Jak3,
|
||||
JakX,
|
||||
JurassicPark,
|
||||
KazokuKeikakuKokoroNoKizuna,
|
||||
KnightsOfTheTemple2,
|
||||
Kunoichi,
|
||||
KyuuketsuKitanMoonties,
|
||||
Lamune,
|
||||
LegacyOfKainDefiance,
|
||||
MajokkoALaMode2,
|
||||
Manhunt2,
|
||||
MetalSlug6,
|
||||
MidnightClub3,
|
||||
NicktoonsUnite,
|
||||
Okami,
|
||||
Oneechanbara2Special,
|
||||
OneTwentyYenStories,
|
||||
Persona3,
|
||||
PiaCarroteYoukosoGPGakuenPrincess,
|
||||
PolyphonyDigitalGames,
|
||||
ProjectSnowblind,
|
||||
Quake3Revolution,
|
||||
RatchetAndClank,
|
||||
RatchetAndClank2,
|
||||
RatchetAndClank3,
|
||||
RatchetAndClank4,
|
||||
RatchetAndClank5,
|
||||
RedDeadRevolver,
|
||||
RickyPontingInternationalCricket,
|
||||
RozenMaidenGebetGarden,
|
||||
SacredBlaze,
|
||||
SakuraTaisen,
|
||||
SakuraWarsSoLongMyLove,
|
||||
SFEX3,
|
||||
ShadowHearts,
|
||||
ShadowofRome,
|
||||
ShinOnimusha,
|
||||
Shox,
|
||||
Simple2000Vol114,
|
||||
SkyGunner,
|
||||
SlamTennis,
|
||||
SMTNocturne,
|
||||
SonicUnleashed,
|
||||
SoTC,
|
||||
SoulReaver2,
|
||||
Spartan,
|
||||
SteambotChronicles,
|
||||
SSX3,
|
||||
SuperManReturns,
|
||||
SVCChaos,
|
||||
TalesOfAbyss,
|
||||
TalesOfLegendia,
|
||||
TalesofSymphonia,
|
||||
Tekken5,
|
||||
TheIncredibleHulkUD,
|
||||
TombRaiderAnniversary,
|
||||
TombRaiderLegend,
|
||||
TombRaiderUnderworld,
|
||||
TriAceGames,
|
||||
TribesAerialAssault,
|
||||
TomoyoAfter,
|
||||
UltramanFightingEvolution,
|
||||
UrbanReign,
|
||||
Whiplash,
|
||||
WildArms4,
|
||||
XenosagaE3,
|
||||
YakuzaGames,
|
||||
ZettaiZetsumeiToshi2,
|
||||
@@ -156,12 +104,6 @@ public:
|
||||
RegionCount,
|
||||
};
|
||||
|
||||
enum Flags
|
||||
{
|
||||
PointListPalette = 1,
|
||||
TextureInsideRt = 2,
|
||||
};
|
||||
|
||||
struct Game
|
||||
{
|
||||
u32 crc;
|
||||
|
||||
+42
-9
@@ -16,6 +16,7 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSDump.h"
|
||||
#include "GSExtra.h"
|
||||
#include "GSState.h"
|
||||
|
||||
GSDumpBase::GSDumpBase(const std::string& fn)
|
||||
: m_frames(0)
|
||||
@@ -32,10 +33,38 @@ GSDumpBase::~GSDumpBase()
|
||||
fclose(m_gs);
|
||||
}
|
||||
|
||||
void GSDumpBase::AddHeader(u32 crc, const freezeData& fd, const GSPrivRegSet* regs)
|
||||
void GSDumpBase::AddHeader(const std::string& serial, u32 crc,
|
||||
u32 screenshot_width, u32 screenshot_height, const u32* screenshot_pixels,
|
||||
const freezeData& fd, const GSPrivRegSet* regs)
|
||||
{
|
||||
AppendRawData(&crc, 4);
|
||||
AppendRawData(&fd.size, 4);
|
||||
// New header: CRC of FFFFFFFF, secondary header, full header follows.
|
||||
const u32 fake_crc = 0xFFFFFFFFu;
|
||||
AppendRawData(&fake_crc, 4);
|
||||
|
||||
// Compute full header size (with serial).
|
||||
// This acts as the state size for loading older dumps.
|
||||
const u32 screenshot_size = screenshot_width * screenshot_height * sizeof(screenshot_pixels[0]);
|
||||
const u32 header_size = sizeof(GSDumpHeader) + static_cast<u32>(serial.size()) + screenshot_size;
|
||||
AppendRawData(&header_size, 4);
|
||||
|
||||
// Write hader.
|
||||
GSDumpHeader header = {};
|
||||
header.state_version = GSState::STATE_VERSION;
|
||||
header.state_size = fd.size;
|
||||
header.crc = crc;
|
||||
header.serial_offset = sizeof(header);
|
||||
header.serial_size = static_cast<u32>(serial.size());
|
||||
header.screenshot_width = screenshot_width;
|
||||
header.screenshot_height = screenshot_height;
|
||||
header.screenshot_offset = header.serial_offset + header.serial_size;
|
||||
header.screenshot_size = screenshot_size;
|
||||
AppendRawData(&header, sizeof(header));
|
||||
if (!serial.empty())
|
||||
AppendRawData(serial.data(), serial.size());
|
||||
if (screenshot_pixels)
|
||||
AppendRawData(screenshot_pixels, screenshot_size);
|
||||
|
||||
// Then the real state data.
|
||||
AppendRawData(fd.data, fd.size);
|
||||
AppendRawData(regs, sizeof(*regs));
|
||||
}
|
||||
@@ -92,18 +121,20 @@ void GSDumpBase::Write(const void* data, size_t size)
|
||||
// GSDump implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
GSDump::GSDump(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs)
|
||||
GSDumpUncompressed::GSDumpUncompressed(const std::string& fn, const std::string& serial, u32 crc,
|
||||
u32 screenshot_width, u32 screenshot_height, const u32* screenshot_pixels,
|
||||
const freezeData& fd, const GSPrivRegSet* regs)
|
||||
: GSDumpBase(fn + ".gs")
|
||||
{
|
||||
AddHeader(crc, fd, regs);
|
||||
AddHeader(serial, crc, screenshot_width, screenshot_height, screenshot_pixels, fd, regs);
|
||||
}
|
||||
|
||||
void GSDump::AppendRawData(const void* data, size_t size)
|
||||
void GSDumpUncompressed::AppendRawData(const void* data, size_t size)
|
||||
{
|
||||
Write(data, size);
|
||||
}
|
||||
|
||||
void GSDump::AppendRawData(u8 c)
|
||||
void GSDumpUncompressed::AppendRawData(u8 c)
|
||||
{
|
||||
Write(&c, 1);
|
||||
}
|
||||
@@ -112,7 +143,9 @@ void GSDump::AppendRawData(u8 c)
|
||||
// GSDumpXz implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
GSDumpXz::GSDumpXz(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs)
|
||||
GSDumpXz::GSDumpXz(const std::string& fn, const std::string& serial, u32 crc,
|
||||
u32 screenshot_width, u32 screenshot_height, const u32* screenshot_pixels,
|
||||
const freezeData& fd, const GSPrivRegSet* regs)
|
||||
: GSDumpBase(fn + ".gs.xz")
|
||||
{
|
||||
m_strm = LZMA_STREAM_INIT;
|
||||
@@ -123,7 +156,7 @@ GSDumpXz::GSDumpXz(const std::string& fn, u32 crc, const freezeData& fd, const G
|
||||
return;
|
||||
}
|
||||
|
||||
AddHeader(crc, fd, regs);
|
||||
AddHeader(serial, crc, screenshot_width, screenshot_height, screenshot_pixels, fd, regs);
|
||||
}
|
||||
|
||||
GSDumpXz::~GSDumpXz()
|
||||
|
||||
+27
-6
@@ -23,7 +23,7 @@
|
||||
/*
|
||||
|
||||
Dump file format:
|
||||
- [crc/4] [state size/4] [state data/size] [PMODE/0x2000] [id/1] [data/?] .. [id/1] [data/?]
|
||||
- [0xFFFFFFFF] [Header] [state size/4] [state data/size] [PMODE/0x2000] [id/1] [data/?] .. [id/1] [data/?]
|
||||
|
||||
Transfer data (id == 0)
|
||||
- [0/1] [path index/1] [size/4] [data/size]
|
||||
@@ -39,6 +39,21 @@ Regs data (id == 3)
|
||||
|
||||
*/
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct GSDumpHeader
|
||||
{
|
||||
u32 state_version; ///< Must always be first in struct to safely prevent old PCSX2 versions from crashing.
|
||||
u32 state_size;
|
||||
u32 serial_offset;
|
||||
u32 serial_size;
|
||||
u32 crc;
|
||||
u32 screenshot_width;
|
||||
u32 screenshot_height;
|
||||
u32 screenshot_offset;
|
||||
u32 screenshot_size;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class GSDumpBase
|
||||
{
|
||||
int m_frames;
|
||||
@@ -46,7 +61,9 @@ class GSDumpBase
|
||||
FILE* m_gs;
|
||||
|
||||
protected:
|
||||
void AddHeader(u32 crc, const freezeData& fd, const GSPrivRegSet* regs);
|
||||
void AddHeader(const std::string& serial, u32 crc,
|
||||
u32 screenshot_width, u32 screenshot_height, const u32* screenshot_pixels,
|
||||
const freezeData& fd, const GSPrivRegSet* regs);
|
||||
void Write(const void* data, size_t size);
|
||||
|
||||
virtual void AppendRawData(const void* data, size_t size) = 0;
|
||||
@@ -61,14 +78,16 @@ public:
|
||||
bool VSync(int field, bool last, const GSPrivRegSet* regs);
|
||||
};
|
||||
|
||||
class GSDump final : public GSDumpBase
|
||||
class GSDumpUncompressed final : public GSDumpBase
|
||||
{
|
||||
void AppendRawData(const void* data, size_t size) final;
|
||||
void AppendRawData(u8 c) final;
|
||||
|
||||
public:
|
||||
GSDump(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs);
|
||||
virtual ~GSDump() = default;
|
||||
GSDumpUncompressed(const std::string& fn, const std::string& serial, u32 crc,
|
||||
u32 screenshot_width, u32 screenshot_height, const u32* screenshot_pixels,
|
||||
const freezeData& fd, const GSPrivRegSet* regs);
|
||||
virtual ~GSDumpUncompressed() = default;
|
||||
};
|
||||
|
||||
class GSDumpXz final : public GSDumpBase
|
||||
@@ -83,6 +102,8 @@ class GSDumpXz final : public GSDumpBase
|
||||
void AppendRawData(u8 c);
|
||||
|
||||
public:
|
||||
GSDumpXz(const std::string& fn, u32 crc, const freezeData& fd, const GSPrivRegSet* regs);
|
||||
GSDumpXz(const std::string& fn, const std::string& serial, u32 crc,
|
||||
u32 screenshot_width, u32 screenshot_height, const u32* screenshot_pixels,
|
||||
const freezeData& fd, const GSPrivRegSet* regs);
|
||||
virtual ~GSDumpXz();
|
||||
};
|
||||
|
||||
@@ -106,6 +106,7 @@ GSLocalMemory::GSLocalMemory()
|
||||
psm.pgs = GSVector2i(64, 32);
|
||||
psm.msk = 0xff;
|
||||
psm.depth = 0;
|
||||
psm.fmsk = 0xffffffff;
|
||||
}
|
||||
|
||||
m_psm[PSM_PSGPU24].info = GSLocalMemory::swizzle16;
|
||||
@@ -346,6 +347,17 @@ GSLocalMemory::GSLocalMemory()
|
||||
m_psm[PSM_PSMZ24].depth = 1;
|
||||
m_psm[PSM_PSMZ16].depth = 1;
|
||||
m_psm[PSM_PSMZ16S].depth = 1;
|
||||
|
||||
m_psm[PSM_PSMCT24].fmsk = 0x00FFFFFF;
|
||||
m_psm[PSM_PSGPU24].fmsk = 0x00FFFFFF;
|
||||
m_psm[PSM_PSMCT16].fmsk = 0x80F8F8F8;
|
||||
m_psm[PSM_PSMCT16S].fmsk = 0x80F8F8F8;
|
||||
m_psm[PSM_PSMT8H].fmsk = 0xFF000000;
|
||||
m_psm[PSM_PSMT4HL].fmsk = 0x0F000000;
|
||||
m_psm[PSM_PSMT4HH].fmsk = 0xF0000000;
|
||||
m_psm[PSM_PSMZ24].fmsk = 0x00FFFFFF;
|
||||
m_psm[PSM_PSMZ16].fmsk = 0x80F8F8F8;
|
||||
m_psm[PSM_PSMZ16S].fmsk = 0x80F8F8F8;
|
||||
}
|
||||
|
||||
GSLocalMemory::~GSLocalMemory()
|
||||
|
||||
@@ -468,6 +468,7 @@ public:
|
||||
u16 bpp, trbpp, pal, fmt;
|
||||
GSVector2i bs, pgs;
|
||||
u8 msk, depth;
|
||||
u32 fmsk;
|
||||
};
|
||||
|
||||
static psm_t m_psm[64];
|
||||
|
||||
+211
-43
@@ -14,28 +14,18 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "GSDump.h"
|
||||
#include "GSLzma.h"
|
||||
|
||||
GSDumpFile::GSDumpFile(char* filename, const char* repack_filename)
|
||||
{
|
||||
m_fp = fopen(filename, "rb");
|
||||
if (m_fp == nullptr)
|
||||
{
|
||||
fprintf(stderr, "failed to open %s\n", filename);
|
||||
throw "BAD"; // Just exit the program
|
||||
}
|
||||
|
||||
m_repack_fp = nullptr;
|
||||
if (repack_filename)
|
||||
{
|
||||
m_repack_fp = fopen(repack_filename, "wb");
|
||||
if (m_repack_fp == nullptr)
|
||||
fprintf(stderr, "failed to open %s for repack\n", repack_filename);
|
||||
}
|
||||
}
|
||||
using namespace GSDumpTypes;
|
||||
|
||||
GSDumpFile::GSDumpFile(FILE* file, FILE* repack_file)
|
||||
: m_repack_fp(repack_file), m_fp(file)
|
||||
: m_repack_fp(repack_file)
|
||||
, m_fp(file)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -57,13 +47,203 @@ GSDumpFile::~GSDumpFile()
|
||||
fclose(m_repack_fp);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
GSDumpLzma::GSDumpLzma(char* filename, const char* repack_filename)
|
||||
: GSDumpFile(filename, repack_filename)
|
||||
std::unique_ptr<GSDumpFile> GSDumpFile::OpenGSDump(const char* filename, const char* repack_filename /*= nullptr*/)
|
||||
{
|
||||
Initialize();
|
||||
std::FILE* fp = FileSystem::OpenCFile(filename, "rb");
|
||||
if (!fp)
|
||||
return nullptr;
|
||||
|
||||
std::FILE* repack_fp = nullptr;
|
||||
if (repack_filename && std::strlen(repack_filename) > 0)
|
||||
{
|
||||
repack_fp = FileSystem::OpenCFile(repack_filename, "wb");
|
||||
if (!repack_fp)
|
||||
{
|
||||
std::fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil::EndsWithNoCase(filename, ".xz"))
|
||||
return std::make_unique<GSDumpLzma>(fp, nullptr);
|
||||
else
|
||||
return std::make_unique<GSDumpRaw>(fp, nullptr);
|
||||
}
|
||||
|
||||
bool GSDumpFile::GetPreviewImageFromDump(const char* filename, u32* width, u32* height, std::vector<u32>* pixels)
|
||||
{
|
||||
std::unique_ptr<GSDumpFile> dump = OpenGSDump(filename);
|
||||
if (!dump)
|
||||
return false;
|
||||
|
||||
u32 crc;
|
||||
if (!dump->Read(&crc, sizeof(crc)) || crc != 0xFFFFFFFFu)
|
||||
{
|
||||
// not new header dump, so no preview
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 header_size;
|
||||
if (!dump->Read(&header_size, sizeof(header_size)) || header_size < sizeof(GSDumpHeader))
|
||||
{
|
||||
// doesn't have the screenshot fields
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<u8[]> header_bits = std::make_unique<u8[]>(header_size);
|
||||
if (!dump->Read(header_bits.get(), header_size))
|
||||
return false;
|
||||
|
||||
GSDumpHeader header;
|
||||
std::memcpy(&header, header_bits.get(), sizeof(header));
|
||||
if (header.screenshot_size == 0 ||
|
||||
header.screenshot_size < (header.screenshot_width * header.screenshot_height * sizeof(u32)) ||
|
||||
(static_cast<u64>(header.screenshot_offset) + header.screenshot_size) > header_size)
|
||||
{
|
||||
// doesn't have a screenshot
|
||||
return false;
|
||||
}
|
||||
|
||||
*width = header.screenshot_width;
|
||||
*height = header.screenshot_height;
|
||||
pixels->resize(header.screenshot_width * header.screenshot_height);
|
||||
std::memcpy(pixels->data(), header_bits.get() + header.screenshot_offset, header.screenshot_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDumpFile::ReadFile()
|
||||
{
|
||||
u32 ss;
|
||||
if (Read(&m_crc, sizeof(m_crc)) != sizeof(m_crc) || Read(&ss, sizeof(ss)) != sizeof(ss))
|
||||
return false;
|
||||
|
||||
m_state_data.resize(ss);
|
||||
if (Read(m_state_data.data(), ss) != ss)
|
||||
return false;
|
||||
|
||||
// Pull serial out of new header, if present.
|
||||
if (m_crc == 0xFFFFFFFFu)
|
||||
{
|
||||
GSDumpHeader header;
|
||||
if (m_state_data.size() < sizeof(header))
|
||||
{
|
||||
Console.Error("GSDump header is corrupted.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(&header, m_state_data.data(), sizeof(header));
|
||||
|
||||
m_crc = header.crc;
|
||||
|
||||
if (header.serial_size > 0)
|
||||
{
|
||||
if (header.serial_offset > ss || (static_cast<u64>(header.serial_offset) + header.serial_size) > ss)
|
||||
{
|
||||
Console.Error("GSDump header is corrupted.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.serial_size > 0)
|
||||
m_serial.assign(reinterpret_cast<const char*>(m_state_data.data()) + header.serial_offset, header.serial_size);
|
||||
}
|
||||
|
||||
// Read the real state data
|
||||
m_state_data.resize(header.state_size);
|
||||
if (Read(m_state_data.data(), header.state_size) != header.state_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_regs_data.resize(8192);
|
||||
if (Read(m_regs_data.data(), m_regs_data.size()) != m_regs_data.size())
|
||||
return false;
|
||||
|
||||
// read all the packet data in
|
||||
// TODO: make this suck less by getting the full/extracted size and preallocating
|
||||
for (;;)
|
||||
{
|
||||
const size_t packet_data_size = m_packet_data.size();
|
||||
m_packet_data.resize(std::max<size_t>(packet_data_size * 2, 8 * _1mb));
|
||||
|
||||
const size_t read_size = m_packet_data.size() - packet_data_size;
|
||||
const size_t read = Read(m_packet_data.data() + packet_data_size, read_size);
|
||||
if (read != read_size)
|
||||
{
|
||||
if (!IsEof())
|
||||
return false;
|
||||
|
||||
m_packet_data.resize(packet_data_size + read);
|
||||
m_packet_data.shrink_to_fit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8* data = m_packet_data.data();
|
||||
size_t remaining = m_packet_data.size();
|
||||
|
||||
#define GET_BYTE(dst) \
|
||||
do \
|
||||
{ \
|
||||
if (remaining < sizeof(u8)) \
|
||||
return false; \
|
||||
std::memcpy(dst, data, sizeof(u8)); \
|
||||
data++; \
|
||||
remaining--; \
|
||||
} while (0)
|
||||
#define GET_WORD(dst) \
|
||||
do \
|
||||
{ \
|
||||
if (remaining < sizeof(u32)) \
|
||||
return false; \
|
||||
std::memcpy(dst, data, sizeof(u32)); \
|
||||
data += sizeof(u32); \
|
||||
remaining -= sizeof(u32); \
|
||||
} while (0)
|
||||
|
||||
while (remaining > 0)
|
||||
{
|
||||
GSData packet = {};
|
||||
packet.path = GSTransferPath::Dummy;
|
||||
GET_BYTE(&packet.id);
|
||||
|
||||
switch (packet.id)
|
||||
{
|
||||
case GSType::Transfer:
|
||||
GET_BYTE(&packet.path);
|
||||
GET_WORD(&packet.length);
|
||||
break;
|
||||
case GSType::VSync:
|
||||
packet.length = 1;
|
||||
break;
|
||||
case GSType::ReadFIFO2:
|
||||
packet.length = 4;
|
||||
break;
|
||||
case GSType::Registers:
|
||||
packet.length = 8192;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (packet.length > 0)
|
||||
{
|
||||
if (remaining < packet.length)
|
||||
return false;
|
||||
|
||||
packet.data = data;
|
||||
data += packet.length;
|
||||
remaining -= packet.length;
|
||||
}
|
||||
|
||||
m_dump_packets.push_back(std::move(packet));
|
||||
}
|
||||
|
||||
#undef GET_WORD
|
||||
#undef GET_BYTE
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
GSDumpLzma::GSDumpLzma(FILE* file, FILE* repack_file)
|
||||
: GSDumpFile(file, repack_file)
|
||||
{
|
||||
@@ -137,11 +317,10 @@ bool GSDumpLzma::IsEof()
|
||||
return feof(m_fp) && m_avail == 0 && m_strm.avail_in == 0;
|
||||
}
|
||||
|
||||
bool GSDumpLzma::Read(void* ptr, size_t size)
|
||||
size_t GSDumpLzma::Read(void* ptr, size_t size)
|
||||
{
|
||||
size_t off = 0;
|
||||
uint8_t* dst = (uint8_t*)ptr;
|
||||
size_t full_size = size;
|
||||
while (size && !IsEof())
|
||||
{
|
||||
if (m_avail == 0)
|
||||
@@ -157,13 +336,10 @@ bool GSDumpLzma::Read(void* ptr, size_t size)
|
||||
off += l;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
Repack(ptr, full_size);
|
||||
return true;
|
||||
}
|
||||
if (off > 0)
|
||||
Repack(ptr, off);
|
||||
|
||||
return false;
|
||||
return off;
|
||||
}
|
||||
|
||||
GSDumpLzma::~GSDumpLzma()
|
||||
@@ -178,11 +354,6 @@ GSDumpLzma::~GSDumpLzma()
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
GSDumpRaw::GSDumpRaw(char* filename, const char* repack_filename)
|
||||
: GSDumpFile(filename, repack_filename)
|
||||
{
|
||||
}
|
||||
|
||||
GSDumpRaw::GSDumpRaw(FILE* file, FILE* repack_file)
|
||||
: GSDumpFile(file, repack_file)
|
||||
{
|
||||
@@ -193,20 +364,17 @@ bool GSDumpRaw::IsEof()
|
||||
return !!feof(m_fp);
|
||||
}
|
||||
|
||||
bool GSDumpRaw::Read(void* ptr, size_t size)
|
||||
size_t GSDumpRaw::Read(void* ptr, size_t size)
|
||||
{
|
||||
size_t ret = fread(ptr, 1, size, m_fp);
|
||||
if (ret != size && ferror(m_fp))
|
||||
{
|
||||
fprintf(stderr, "GSDumpRaw:: Read error (%zu/%zu)\n", ret, size);
|
||||
throw "BAD"; // Just exit the program
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret == size)
|
||||
{
|
||||
Repack(ptr, size);
|
||||
return true;
|
||||
}
|
||||
if (ret > 0)
|
||||
Repack(ptr, ret);
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
+313
-12
@@ -13,24 +13,327 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lzma.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define GEN_REG_ENUM_CLASS_CONTENT(ClassName, EntryName, Value) \
|
||||
EntryName = Value,
|
||||
|
||||
#define GEN_REG_GETNAME_CONTENT(ClassName, EntryName, Value) \
|
||||
case ClassName::EntryName: \
|
||||
return #EntryName;
|
||||
|
||||
#define GEN_REG_ENUM_CLASS_AND_GETNAME(Macro, ClassName, Type, DefaultString) \
|
||||
enum class ClassName : Type \
|
||||
{ \
|
||||
Macro(GEN_REG_ENUM_CLASS_CONTENT) \
|
||||
}; \
|
||||
static constexpr const char* GetName(ClassName reg) \
|
||||
{ \
|
||||
switch (reg) \
|
||||
{ \
|
||||
Macro(GEN_REG_GETNAME_CONTENT) default : return DefaultString; \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace GSDumpTypes
|
||||
{
|
||||
// clang-format off
|
||||
#define DEF_GSType(X) \
|
||||
X(GSType, Transfer, 0) \
|
||||
X(GSType, VSync, 1) \
|
||||
X(GSType, ReadFIFO2, 2) \
|
||||
X(GSType, Registers, 3)
|
||||
GEN_REG_ENUM_CLASS_AND_GETNAME(DEF_GSType, GSType, u8, "UnknownType")
|
||||
#undef DEF_GSType
|
||||
|
||||
#define DEF_GSTransferPath(X) \
|
||||
X(GSTransferPath, Path1Old, 0) \
|
||||
X(GSTransferPath, Path2, 1) \
|
||||
X(GSTransferPath, Path3, 2) \
|
||||
X(GSTransferPath, Path1New, 3) \
|
||||
X(GSTransferPath, Dummy, 4)
|
||||
GEN_REG_ENUM_CLASS_AND_GETNAME(DEF_GSTransferPath, GSTransferPath, u8, "UnknownPath")
|
||||
#undef DEF_GSTransferPath
|
||||
|
||||
#define DEF_GIFFlag(X) \
|
||||
X(GIFFlag, PACKED, 0) \
|
||||
X(GIFFlag, REGLIST, 1) \
|
||||
X(GIFFlag, IMAGE, 2) \
|
||||
X(GIFFlag, IMAGE2, 3)
|
||||
GEN_REG_ENUM_CLASS_AND_GETNAME(DEF_GIFFlag, GIFFlag, u8, "UnknownFlag")
|
||||
#undef DEF_GifFlag
|
||||
|
||||
#define DEF_GIFReg(X) \
|
||||
X(GIFReg, PRIM, 0x00) \
|
||||
X(GIFReg, RGBAQ, 0x01) \
|
||||
X(GIFReg, ST, 0x02) \
|
||||
X(GIFReg, UV, 0x03) \
|
||||
X(GIFReg, XYZF2, 0x04) \
|
||||
X(GIFReg, XYZ2, 0x05) \
|
||||
X(GIFReg, TEX0_1, 0x06) \
|
||||
X(GIFReg, TEX0_2, 0x07) \
|
||||
X(GIFReg, CLAMP_1, 0x08) \
|
||||
X(GIFReg, CLAMP_2, 0x09) \
|
||||
X(GIFReg, FOG, 0x0a) \
|
||||
X(GIFReg, XYZF3, 0x0c) \
|
||||
X(GIFReg, XYZ3, 0x0d) \
|
||||
X(GIFReg, AD, 0x0e) \
|
||||
X(GIFReg, NOP, 0x0f) \
|
||||
X(GIFReg, TEX1_1, 0x14) \
|
||||
X(GIFReg, TEX1_2, 0x15) \
|
||||
X(GIFReg, TEX2_1, 0x16) \
|
||||
X(GIFReg, TEX2_2, 0x17) \
|
||||
X(GIFReg, XYOFFSET_1, 0x18) \
|
||||
X(GIFReg, XYOFFSET_2, 0x19) \
|
||||
X(GIFReg, PRMODECONT, 0x1a) \
|
||||
X(GIFReg, PRMODE, 0x1b) \
|
||||
X(GIFReg, TEXCLUT, 0x1c) \
|
||||
X(GIFReg, SCANMSK, 0x22) \
|
||||
X(GIFReg, MIPTBP1_1, 0x34) \
|
||||
X(GIFReg, MIPTBP1_2, 0x35) \
|
||||
X(GIFReg, MIPTBP2_1, 0x36) \
|
||||
X(GIFReg, MIPTBP2_2, 0x37) \
|
||||
X(GIFReg, TEXA, 0x3b) \
|
||||
X(GIFReg, FOGCOL, 0x3d) \
|
||||
X(GIFReg, TEXFLUSH, 0x3f) \
|
||||
X(GIFReg, SCISSOR_1, 0x40) \
|
||||
X(GIFReg, SCISSOR_2, 0x41) \
|
||||
X(GIFReg, ALPHA_1, 0x42) \
|
||||
X(GIFReg, ALPHA_2, 0x43) \
|
||||
X(GIFReg, DIMX, 0x44) \
|
||||
X(GIFReg, DTHE, 0x45) \
|
||||
X(GIFReg, COLCLAMP, 0x46) \
|
||||
X(GIFReg, TEST_1, 0x47) \
|
||||
X(GIFReg, TEST_2, 0x48) \
|
||||
X(GIFReg, PABE, 0x49) \
|
||||
X(GIFReg, FBA_1, 0x4a) \
|
||||
X(GIFReg, FBA_2, 0x4b) \
|
||||
X(GIFReg, FRAME_1, 0x4c) \
|
||||
X(GIFReg, FRAME_2, 0x4d) \
|
||||
X(GIFReg, ZBUF_1, 0x4e) \
|
||||
X(GIFReg, ZBUF_2, 0x4f) \
|
||||
X(GIFReg, BITBLTBUF, 0x50) \
|
||||
X(GIFReg, TRXPOS, 0x51) \
|
||||
X(GIFReg, TRXREG, 0x52) \
|
||||
X(GIFReg, TRXDIR, 0x53) \
|
||||
X(GIFReg, HWREG, 0x54) \
|
||||
X(GIFReg, SIGNAL, 0x60) \
|
||||
X(GIFReg, FINISH, 0x61) \
|
||||
X(GIFReg, LABEL, 0x62)
|
||||
GEN_REG_ENUM_CLASS_AND_GETNAME(DEF_GIFReg, GIFReg, u8, "UnknownReg")
|
||||
#undef DEF_GIFReg
|
||||
// clang-format on
|
||||
|
||||
template <typename Output, typename Input, typename std::enable_if<sizeof(Input) == sizeof(Output), bool>::type = true>
|
||||
static constexpr Output BitCast(Input input)
|
||||
{
|
||||
Output output;
|
||||
memcpy(&output, &input, sizeof(input));
|
||||
return output;
|
||||
}
|
||||
template <typename Output = u32>
|
||||
static constexpr Output GetBits(u64 value, u32 shift, u32 numbits)
|
||||
{
|
||||
return static_cast<Output>((value >> shift) & ((1ull << numbits) - 1));
|
||||
}
|
||||
|
||||
template <typename Output = u32>
|
||||
static constexpr Output GetBits(u128 value, u32 shift, u32 numbits)
|
||||
{
|
||||
u64 outval = 0;
|
||||
if (shift == 0)
|
||||
outval = value.lo;
|
||||
else if (shift < 64)
|
||||
outval = (value.lo >> shift) | (value.hi << (64 - shift));
|
||||
else
|
||||
outval = value.hi >> (shift - 64);
|
||||
return static_cast<Output>(outval & ((1ull << numbits) - 1));
|
||||
}
|
||||
static constexpr const char* GetNameOneBit(u8 value, const char* zero, const char* one)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
return zero;
|
||||
case 1:
|
||||
return one;
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
static constexpr const char* GetNameBool(bool value)
|
||||
{
|
||||
return value ? "True" : "False";
|
||||
}
|
||||
|
||||
static constexpr const char* GetNamePRIMPRIM(u8 prim)
|
||||
{
|
||||
switch (prim)
|
||||
{
|
||||
case 0:
|
||||
return "Point";
|
||||
case 1:
|
||||
return "Line";
|
||||
case 2:
|
||||
return "Line Strip";
|
||||
case 3:
|
||||
return "Triangle";
|
||||
case 4:
|
||||
return "Triangle Strip";
|
||||
case 5:
|
||||
return "Triangle Fan";
|
||||
case 6:
|
||||
return "Sprite";
|
||||
case 7:
|
||||
return "Invalid";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
static constexpr const char* GetNamePRIMIIP(u8 iip)
|
||||
{
|
||||
return GetNameOneBit(iip, "Flat Shading", "Gouraud Shading");
|
||||
}
|
||||
static constexpr const char* GetNamePRIMFST(u8 fst)
|
||||
{
|
||||
return GetNameOneBit(fst, "STQ Value", "UV Value");
|
||||
}
|
||||
static constexpr const char* GetNamePRIMCTXT(u8 ctxt)
|
||||
{
|
||||
return GetNameOneBit(ctxt, "Context 1", "Context 2");
|
||||
}
|
||||
static constexpr const char* GetNamePRIMFIX(u8 fix)
|
||||
{
|
||||
return GetNameOneBit(fix, "Unfixed", "Fixed");
|
||||
}
|
||||
static constexpr const char* GetNameTEXTCC(u8 tcc)
|
||||
{
|
||||
return GetNameOneBit(tcc, "RGB", "RGBA");
|
||||
}
|
||||
static constexpr const char* GetNameTEXTFX(u8 tfx)
|
||||
{
|
||||
switch (tfx)
|
||||
{
|
||||
case 0:
|
||||
return "Modulate";
|
||||
case 1:
|
||||
return "Decal";
|
||||
case 2:
|
||||
return "Highlight";
|
||||
case 3:
|
||||
return "Highlight2";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
static constexpr const char* GetNameTEXCSM(u8 csm)
|
||||
{
|
||||
return GetNameOneBit(csm, "CSM1", "CSM2");
|
||||
}
|
||||
static constexpr const char* GetNameTEXPSM(u8 psm)
|
||||
{
|
||||
switch (psm)
|
||||
{
|
||||
case 000:
|
||||
return "PSMCT32";
|
||||
case 001:
|
||||
return "PSMCT24";
|
||||
case 002:
|
||||
return "PSMCT16";
|
||||
case 012:
|
||||
return "PSMCT16S";
|
||||
case 023:
|
||||
return "PSMT8";
|
||||
case 024:
|
||||
return "PSMT4";
|
||||
case 033:
|
||||
return "PSMT8H";
|
||||
case 044:
|
||||
return "PSMT4HL";
|
||||
case 054:
|
||||
return "PSMT4HH";
|
||||
case 060:
|
||||
return "PSMZ32";
|
||||
case 061:
|
||||
return "PSMZ24";
|
||||
case 062:
|
||||
return "PSMZ16";
|
||||
case 072:
|
||||
return "PSMZ16S";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
static constexpr const char* GetNameTEXCPSM(u8 psm)
|
||||
{
|
||||
switch (psm)
|
||||
{
|
||||
case 000:
|
||||
return "PSMCT32";
|
||||
case 002:
|
||||
return "PSMCT16";
|
||||
case 012:
|
||||
return "PSMCT16S";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
} // namespace GSDumpTypes
|
||||
|
||||
class GSDumpFile
|
||||
{
|
||||
FILE* m_repack_fp;
|
||||
public:
|
||||
struct GSData
|
||||
{
|
||||
GSDumpTypes::GSType id;
|
||||
const u8* data;
|
||||
s32 length;
|
||||
GSDumpTypes::GSTransferPath path;
|
||||
};
|
||||
|
||||
using ByteArray = std::vector<u8>;
|
||||
using GSDataArray = std::vector<GSData>;
|
||||
|
||||
virtual ~GSDumpFile();
|
||||
|
||||
static std::unique_ptr<GSDumpFile> OpenGSDump(const char* filename, const char* repack_filename = nullptr);
|
||||
static bool GetPreviewImageFromDump(const char* filename, u32* width, u32* height, std::vector<u32>* pixels);
|
||||
|
||||
__fi const std::string& GetSerial() const { return m_serial; }
|
||||
__fi u32 GetCRC() const { return m_crc; }
|
||||
|
||||
__fi const ByteArray& GetRegsData() const { return m_regs_data; }
|
||||
__fi const ByteArray& GetStateData() const { return m_state_data; }
|
||||
__fi const GSDataArray& GetPackets() const { return m_dump_packets; }
|
||||
|
||||
bool ReadFile();
|
||||
|
||||
protected:
|
||||
FILE* m_fp;
|
||||
GSDumpFile(FILE* file, FILE* repack_file);
|
||||
|
||||
virtual bool IsEof() = 0;
|
||||
virtual size_t Read(void* ptr, size_t size) = 0;
|
||||
|
||||
void Repack(void* ptr, size_t size);
|
||||
|
||||
public:
|
||||
virtual bool IsEof() = 0;
|
||||
virtual bool Read(void* ptr, size_t size) = 0;
|
||||
FILE* m_fp = nullptr;
|
||||
|
||||
GSDumpFile(char* filename, const char* repack_filename);
|
||||
GSDumpFile(FILE* file, FILE* repack_file);
|
||||
virtual ~GSDumpFile();
|
||||
private:
|
||||
FILE* m_repack_fp = nullptr;
|
||||
|
||||
std::string m_serial;
|
||||
u32 m_crc = 0;
|
||||
|
||||
std::vector<u8> m_regs_data;
|
||||
std::vector<u8> m_state_data;
|
||||
std::vector<u8> m_packet_data;
|
||||
|
||||
GSDataArray m_dump_packets;
|
||||
};
|
||||
|
||||
class GSDumpLzma : public GSDumpFile
|
||||
@@ -48,21 +351,19 @@ class GSDumpLzma : public GSDumpFile
|
||||
void Initialize();
|
||||
|
||||
public:
|
||||
GSDumpLzma(char* filename, const char* repack_filename);
|
||||
GSDumpLzma(FILE* file, FILE* repack_file);
|
||||
virtual ~GSDumpLzma();
|
||||
|
||||
bool IsEof() final;
|
||||
bool Read(void* ptr, size_t size) final;
|
||||
size_t Read(void* ptr, size_t size) final;
|
||||
};
|
||||
|
||||
class GSDumpRaw : public GSDumpFile
|
||||
{
|
||||
public:
|
||||
GSDumpRaw(char* filename, const char* repack_filename);
|
||||
GSDumpRaw(FILE* file, FILE* repack_file);
|
||||
virtual ~GSDumpRaw() = default;
|
||||
|
||||
bool IsEof() final;
|
||||
bool Read(void* ptr, size_t size) final;
|
||||
size_t Read(void* ptr, size_t size) final;
|
||||
};
|
||||
|
||||
@@ -26,9 +26,6 @@ GSPerfMon::GSPerfMon()
|
||||
{
|
||||
memset(m_counters, 0, sizeof(m_counters));
|
||||
memset(m_stats, 0, sizeof(m_stats));
|
||||
memset(m_timer_stats, 0, sizeof(m_timer_stats));
|
||||
memset(m_total, 0, sizeof(m_total));
|
||||
memset(m_begin, 0, sizeof(m_begin));
|
||||
}
|
||||
|
||||
void GSPerfMon::EndFrame()
|
||||
@@ -39,7 +36,6 @@ void GSPerfMon::EndFrame()
|
||||
|
||||
void GSPerfMon::Update()
|
||||
{
|
||||
#ifndef DISABLE_PERF_MON
|
||||
if (m_count > 0)
|
||||
{
|
||||
for (size_t i = 0; i < std::size(m_counters); i++)
|
||||
@@ -48,55 +44,7 @@ void GSPerfMon::Update()
|
||||
}
|
||||
|
||||
m_count = 0;
|
||||
|
||||
// Update CPU usage for SW renderer.
|
||||
if (GSConfig.Renderer == GSRendererType::SW)
|
||||
{
|
||||
const u64 current = __rdtsc();
|
||||
|
||||
for (size_t i = WorkerDraw0; i < TimerLast; i++)
|
||||
{
|
||||
if (m_begin[i] == 0)
|
||||
{
|
||||
m_timer_stats[i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_timer_stats[i] =
|
||||
static_cast<float>(static_cast<double>(m_total[i]) / static_cast<double>(current - m_begin[i])
|
||||
* 100.0);
|
||||
|
||||
m_begin[i] = 0;
|
||||
m_start[i] = 0;
|
||||
m_total[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
memset(m_counters, 0, sizeof(m_counters));
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSPerfMon::Start(int timer)
|
||||
{
|
||||
#ifndef DISABLE_PERF_MON
|
||||
m_start[timer] = __rdtsc();
|
||||
|
||||
if (m_begin[timer] == 0)
|
||||
{
|
||||
m_begin[timer] = m_start[timer];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GSPerfMon::Stop(int timer)
|
||||
{
|
||||
#ifndef DISABLE_PERF_MON
|
||||
if (m_start[timer] > 0)
|
||||
{
|
||||
m_total[timer] += __rdtsc() - m_start[timer];
|
||||
m_start[timer] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -18,14 +18,6 @@
|
||||
class GSPerfMon
|
||||
{
|
||||
public:
|
||||
enum timer_t
|
||||
{
|
||||
Main,
|
||||
Sync,
|
||||
WorkerDraw0,
|
||||
TimerLast = WorkerDraw0 + 32, // Enough space for 32 GS worker threads
|
||||
};
|
||||
|
||||
enum counter_t
|
||||
{
|
||||
Prim,
|
||||
@@ -47,15 +39,11 @@ public:
|
||||
protected:
|
||||
double m_counters[CounterLast];
|
||||
double m_stats[CounterLast];
|
||||
float m_timer_stats[TimerLast];
|
||||
u64 m_begin[TimerLast], m_total[TimerLast], m_start[TimerLast];
|
||||
u64 m_frame;
|
||||
clock_t m_lastframe;
|
||||
int m_count;
|
||||
int m_disp_fb_sprite_blits;
|
||||
|
||||
friend class GSPerfMonAutoTimer;
|
||||
|
||||
public:
|
||||
GSPerfMon();
|
||||
|
||||
@@ -65,12 +53,8 @@ public:
|
||||
|
||||
void Put(counter_t c, double val = 0) { m_counters[c] += val; }
|
||||
double Get(counter_t c) { return m_stats[c]; }
|
||||
float GetTimer(timer_t t) { return m_timer_stats[t]; }
|
||||
void Update();
|
||||
|
||||
void Start(int timer = Main);
|
||||
void Stop(int timer = Main);
|
||||
|
||||
__fi void AddDisplayFramebufferSpriteBlit() { m_disp_fb_sprite_blits++; }
|
||||
__fi int GetDisplayFramebufferSpriteBlits()
|
||||
{
|
||||
@@ -80,18 +64,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class GSPerfMonAutoTimer
|
||||
{
|
||||
GSPerfMon* m_pm;
|
||||
int m_timer;
|
||||
|
||||
public:
|
||||
GSPerfMonAutoTimer(GSPerfMon* pm, int timer = GSPerfMon::Main)
|
||||
{
|
||||
m_timer = timer;
|
||||
(m_pm = pm)->Start(m_timer);
|
||||
}
|
||||
~GSPerfMonAutoTimer() { m_pm->Stop(m_timer); }
|
||||
};
|
||||
|
||||
extern GSPerfMon g_perfmon;
|
||||
+277
-106
@@ -20,17 +20,29 @@
|
||||
|
||||
#include <algorithm> // clamp
|
||||
#include <cfloat> // FLT_MAX
|
||||
#include <iomanip> // Dump Verticles
|
||||
|
||||
int GSState::s_n = 0;
|
||||
|
||||
static __fi bool IsAutoFlushEnabled()
|
||||
{
|
||||
return (GSConfig.Renderer == GSRendererType::SW) ? GSConfig.AutoFlushSW : GSConfig.UserHacks_AutoFlush;
|
||||
}
|
||||
|
||||
static __fi bool IsFirstProvokingVertex()
|
||||
{
|
||||
return (GSConfig.Renderer != GSRendererType::SW && !g_gs_device->Features().provoking_vertex_last);
|
||||
}
|
||||
|
||||
GSState::GSState()
|
||||
: m_version(7)
|
||||
: m_version(STATE_VERSION)
|
||||
, m_gsc(NULL)
|
||||
, m_skip(0)
|
||||
, m_skip_offset(0)
|
||||
, m_q(1.0f)
|
||||
, m_scanmask_used(false)
|
||||
, m_vt(this)
|
||||
, tex_flushed(true)
|
||||
, m_vt(this, IsFirstProvokingVertex())
|
||||
, m_regs(NULL)
|
||||
, m_crc(0)
|
||||
, m_options(0)
|
||||
@@ -39,18 +51,8 @@ GSState::GSState()
|
||||
// m_nativeres seems to be a hack. Unfortunately it impacts draw call number which make debug painful in the replayer.
|
||||
// Let's keep it disabled to ease debug.
|
||||
m_nativeres = GSConfig.UpscaleMultiplier == 1;
|
||||
m_mipmap = theApp.GetConfigB("mipmap");
|
||||
m_mipmap = GSConfig.Mipmap;
|
||||
m_NTSC_Saturation = theApp.GetConfigB("NTSC_Saturation");
|
||||
if (theApp.GetConfigB("UserHacks"))
|
||||
{
|
||||
m_userhacks_auto_flush = theApp.GetConfigB("UserHacks_AutoFlush");
|
||||
m_userhacks_wildhack = theApp.GetConfigB("UserHacks_WildHack");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userhacks_auto_flush = false;
|
||||
m_userhacks_wildhack = false;
|
||||
}
|
||||
|
||||
s_n = 0;
|
||||
s_dump = theApp.GetConfigB("dump");
|
||||
@@ -132,7 +134,6 @@ GSState::GSState()
|
||||
PRIM = &m_env.PRIM;
|
||||
//CSR->rREV = 0x20;
|
||||
m_env.PRMODECONT.AC = 1;
|
||||
tex_flushed = true;
|
||||
|
||||
Reset();
|
||||
|
||||
@@ -246,7 +247,7 @@ void GSState::ResetHandlers()
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_PRIM] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerPRIM;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_RGBA] = &GSState::GIFPackedRegHandlerRGBA;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_STQ] = &GSState::GIFPackedRegHandlerSTQ;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_UV] = m_userhacks_wildhack ? &GSState::GIFPackedRegHandlerUV_Hack : &GSState::GIFPackedRegHandlerUV;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_UV] = GSConfig.UserHacks_WildHack ? &GSState::GIFPackedRegHandlerUV_Hack : &GSState::GIFPackedRegHandlerUV;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_TEX0_1] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerTEX0<0>;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_TEX0_2] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerTEX0<1>;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_CLAMP_1] = (GIFPackedRegHandler)(GIFRegHandler)&GSState::GIFRegHandlerCLAMP<0>;
|
||||
@@ -256,11 +257,10 @@ void GSState::ResetHandlers()
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
|
||||
|
||||
// swap first/last indices when the provoking vertex is the first (D3D/Vulkan)
|
||||
const bool index_swap = GSConfig.UseHardwareRenderer() && !g_gs_device->Features().provoking_vertex_last;
|
||||
if (m_userhacks_auto_flush)
|
||||
index_swap ? SetPrimHandlers<true, true>() : SetPrimHandlers<true, false>();
|
||||
if (IsAutoFlushEnabled())
|
||||
IsFirstProvokingVertex() ? SetPrimHandlers<true, true>() : SetPrimHandlers<true, false>();
|
||||
else
|
||||
index_swap ? SetPrimHandlers<false, true>() : SetPrimHandlers<false, false>();
|
||||
IsFirstProvokingVertex() ? SetPrimHandlers<false, true>() : SetPrimHandlers<false, false>();
|
||||
|
||||
std::fill(std::begin(m_fpGIFRegHandlers), std::end(m_fpGIFRegHandlers), &GSState::GIFRegHandlerNull);
|
||||
|
||||
@@ -268,7 +268,7 @@ void GSState::ResetHandlers()
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_RGBAQ] = &GSState::GIFRegHandlerRGBAQ;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_RGBAQ + 0x10] = &GSState::GIFRegHandlerRGBAQ;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_ST] = &GSState::GIFRegHandlerST;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_UV] = m_userhacks_wildhack ? &GSState::GIFRegHandlerUV_Hack : &GSState::GIFRegHandlerUV;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_UV] = GSConfig.UserHacks_WildHack ? &GSState::GIFRegHandlerUV_Hack : &GSState::GIFRegHandlerUV;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_1] = &GSState::GIFRegHandlerTEX0<0>;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_2] = &GSState::GIFRegHandlerTEX0<1>;
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_CLAMP_1] = &GSState::GIFRegHandlerCLAMP<0>;
|
||||
@@ -319,6 +319,19 @@ void GSState::ResetHandlers()
|
||||
m_fpGIFRegHandlers[GIF_A_D_REG_LABEL] = &GSState::GIFRegHandlerNull;
|
||||
}
|
||||
|
||||
void GSState::UpdateSettings(const Pcsx2Config::GSOptions& old_config)
|
||||
{
|
||||
m_mipmap = GSConfig.Mipmap;
|
||||
|
||||
if (
|
||||
GSConfig.AutoFlushSW != old_config.AutoFlushSW ||
|
||||
GSConfig.UserHacks_AutoFlush != old_config.UserHacks_AutoFlush ||
|
||||
GSConfig.UserHacks_WildHack != old_config.UserHacks_WildHack)
|
||||
{
|
||||
ResetHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
bool GSState::isinterlaced()
|
||||
{
|
||||
return !!m_regs->SMODE2.INT;
|
||||
@@ -543,6 +556,100 @@ float GSState::GetTvRefreshRate()
|
||||
__assume(0); // unreachable
|
||||
}
|
||||
|
||||
void GSState::DumpVertices(const std::string& filename)
|
||||
{
|
||||
std::ofstream file(filename);
|
||||
|
||||
if (!file.is_open())
|
||||
return;
|
||||
|
||||
size_t count = m_index.tail;
|
||||
GSVertex* buffer = &m_vertex.buff[0];
|
||||
|
||||
const char* DEL = ", ";
|
||||
|
||||
file << "VERTEX COORDS (XYZ)" << std::endl;
|
||||
file << std::fixed << std::setprecision(4);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
file << "\t" << "v" << i << ": ";
|
||||
GSVertex v = buffer[m_index.buff[i]];
|
||||
|
||||
float x = (v.XYZ.X - (int)m_context->XYOFFSET.OFX) / 16.0f;
|
||||
float y = (v.XYZ.Y - (int)m_context->XYOFFSET.OFY) / 16.0f;
|
||||
|
||||
file << x << DEL;
|
||||
file << y << DEL;
|
||||
file << v.XYZ.Z;
|
||||
file << std::endl;
|
||||
}
|
||||
|
||||
file << std::endl;
|
||||
|
||||
file << "VERTEX COLOR (RGBA)" << std::endl;
|
||||
file << std::fixed << std::setprecision(6);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
file << "\t" << "v" << i << ": ";
|
||||
GSVertex v = buffer[m_index.buff[i]];
|
||||
|
||||
file << std::setfill('0') << std::setw(3) << unsigned(v.RGBAQ.R) << DEL;
|
||||
file << std::setfill('0') << std::setw(3) << unsigned(v.RGBAQ.G) << DEL;
|
||||
file << std::setfill('0') << std::setw(3) << unsigned(v.RGBAQ.B) << DEL;
|
||||
file << std::setfill('0') << std::setw(3) << unsigned(v.RGBAQ.A);
|
||||
file << std::endl;
|
||||
}
|
||||
|
||||
file << std::endl;
|
||||
|
||||
bool use_uv = PRIM->FST;
|
||||
std::string qualifier = use_uv ? "UV" : "STQ";
|
||||
|
||||
file << "TEXTURE COORDS (" << qualifier << ")" << std::endl;;
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
file << "\t" << "v" << i << ": ";
|
||||
GSVertex v = buffer[m_index.buff[i]];
|
||||
|
||||
// note
|
||||
// Yes, technically as far as the GS is concerned Q belongs
|
||||
// to RGBAQ. However, the purpose of this dump is to print
|
||||
// our data in a more human readable format and typically Q
|
||||
// is associated with STQ.
|
||||
if (use_uv)
|
||||
{
|
||||
float uv_U = v.U / 16.0f;
|
||||
float uv_V = v.V / 16.0f;
|
||||
|
||||
file << uv_U << DEL << uv_V;
|
||||
}
|
||||
else
|
||||
file << v.ST.S << DEL << v.ST.T << DEL << v.RGBAQ.Q;
|
||||
|
||||
file << std::endl;
|
||||
}
|
||||
|
||||
file << std::endl;
|
||||
|
||||
file << "TRACER" << std::endl;
|
||||
|
||||
GSVector4i v = m_vt.m_min.c;
|
||||
file << "\tmin c (x,y,z,w): " << v.x << DEL << v.y << DEL << v.z << DEL << v.w << std::endl;
|
||||
v = m_vt.m_max.c;
|
||||
file << "\tmax c (x,y,z,w): " << v.x << DEL << v.y << DEL << v.z << DEL << v.w << std::endl;
|
||||
|
||||
GSVector4 v2 = m_vt.m_min.p;
|
||||
file << "\tmin p (x,y,z,w): " << v2.x << DEL << v2.y << DEL << v2.z << DEL << v2.w << std::endl;
|
||||
v2 = m_vt.m_max.p;
|
||||
file << "\tmax p (x,y,z,w): " << v2.x << DEL << v2.y << DEL << v2.z << DEL << v2.w << std::endl;
|
||||
v2 = m_vt.m_min.t;
|
||||
file << "\tmin t (x,y,z,w): " << v2.x << DEL << v2.y << DEL << v2.z << DEL << v2.w << std::endl;
|
||||
v2 = m_vt.m_max.t;
|
||||
file << "\tmax t (x,y,z,w): " << v2.x << DEL << v2.y << DEL << v2.z << DEL << v2.w << std::endl;
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void GSState::GIFPackedRegHandlerNull(const GIFPackedReg* RESTRICT r)
|
||||
{
|
||||
}
|
||||
@@ -894,7 +1001,10 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||
GL_REG("TEX0_%d = 0x%x_%x", i, r->U32[1], r->U32[0]);
|
||||
|
||||
GIFRegTEX0 TEX0 = r->TEX0;
|
||||
const bool MTBAreload = ((tex_flushed && (i == m_env.PRIM.CTXT)) || (r->TEX0.TBP0 != m_env.CTXT[i].TEX0.TBP0)) ? true : false;
|
||||
GIFRegMIPTBP1 temp_MIPTBP1;
|
||||
bool MTBAReloaded = false;
|
||||
// Max allowed MTBA size for 32bit swizzled textures (including 8H 4HL etc) is 512, 16bit and normal 8/4bit formats can be 1024
|
||||
const u32 maxTex = (GSLocalMemory::m_psm[TEX0.PSM].bpp < 32) ? 10 : 9;
|
||||
|
||||
// Spec max is 10
|
||||
//
|
||||
@@ -910,61 +1020,53 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||
TEX0.TW = std::clamp<u32>(TEX0.TW, 0, 10);
|
||||
TEX0.TH = std::clamp<u32>(TEX0.TH, 0, 10);
|
||||
|
||||
ApplyTEX0<i>(TEX0);
|
||||
|
||||
// When the texture cache reloads any MIPS need to update too, so let's do that here.
|
||||
// This is essentially triggered by the texture page change, so if TEXFLUSH is called and a draw doesn't proceed it, or TBP changes.
|
||||
// Textures must be of equal width/height and a minimum of 32x32
|
||||
if (MTBAreload && m_env.CTXT[i].TEX1.MTBA && m_env.CTXT[i].TEX0.TW == m_env.CTXT[i].TEX0.TH && m_env.CTXT[i].TEX0.TW >= 5)
|
||||
// MTBA loads are triggered by writes to TEX0 (but not TEX2!)
|
||||
// Textures MUST be a minimum width of 32 pixels
|
||||
// Format must be a color, Z formats do not trigger MTBA (but are valid for Mipmapping)
|
||||
if (m_env.CTXT[i].TEX1.MTBA && TEX0.TW >= 5 && TEX0.TW <= maxTex && (TEX0.PSM & 0x30) != 0x30)
|
||||
{
|
||||
// NOTE 1: TEX1.MXL must not be automatically set to 3 here.
|
||||
// NOTE 2: Mipmap levels are tightly packed, if (tbw << 6) > (1 << tw) then the left-over space to the right is used. (common for PSM_PSMT4)
|
||||
// NOTE 3: Non-rectangular textures are treated as rectangular when calculating the occupied space (height is extended, not sure about width)
|
||||
// NOTE 1: TEX1.MXL must not be automatically set to 3 here and it has no effect on MTBA.
|
||||
// NOTE 2: Mipmap levels are packed with a minimum distance between them of 1 block, even down at 4bit textures under 16x16.
|
||||
// NOTE 3: Everything is derrived from the width of the texture, TBW and TH are completely ignored (useful for handling non-rectangular ones)
|
||||
// NOTE 4: Cartoon Network Racing's menu is VERY sensitive to this as it uses 4bit sized textures for the sky.
|
||||
u32 bp = TEX0.TBP0;
|
||||
u32 bw = std::max(1u, (1u << TEX0.TW) >> 6);
|
||||
|
||||
u32 bp = m_env.CTXT[i].TEX0.TBP0;
|
||||
u32 bw = m_env.CTXT[i]. TEX0.TBW;
|
||||
u32 w = 1u << m_env.CTXT[i].TEX0.TW;
|
||||
u32 h = 1u << m_env.CTXT[i].TEX0.TH;
|
||||
u32 minwidth = m_env.CTXT[i].TEX1.MMIN >= 4 ? 8 : 1;
|
||||
// Address is calculated as a 4bit address space, then converted (/8) to 32bit address space
|
||||
// ((w * w * bpp) / 8) / 64. No the 'w' is not a typo ;)
|
||||
const u32 bpp = GSLocalMemory::m_psm[TEX0.PSM].bpp >> 2;
|
||||
u32 tex_size = ((1u << TEX0.TW) * (1u << TEX0.TW) * bpp) >> 9;
|
||||
|
||||
const u32 bpp = GSLocalMemory::m_psm[m_env.CTXT[i].TEX0.PSM].bpp;
|
||||
bp += tex_size;
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
tex_size = std::max<u32>(tex_size >> 2, 1);
|
||||
|
||||
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
|
||||
temp_MIPTBP1.TBP1 = bp;
|
||||
temp_MIPTBP1.TBW1 = bw;
|
||||
|
||||
if (w > minwidth)
|
||||
{
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
w = std::max<u32>(w >> 1, 1);
|
||||
h = std::max<u32>(h >> 1, 1);
|
||||
}
|
||||
bp += tex_size;
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
tex_size = std::max<u32>(tex_size >> 2, 1);
|
||||
|
||||
m_env.CTXT[i].MIPTBP1.TBP1 = bp;
|
||||
m_env.CTXT[i].MIPTBP1.TBW1 = bw;
|
||||
temp_MIPTBP1.TBP2 = bp;
|
||||
temp_MIPTBP1.TBW2 = bw;
|
||||
|
||||
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
|
||||
bp += tex_size;
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
|
||||
if (w > minwidth)
|
||||
{
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
w = std::max<u32>(w >> 1, 1);
|
||||
h = std::max<u32>(h >> 1, 1);
|
||||
}
|
||||
temp_MIPTBP1.TBP3 = bp;
|
||||
temp_MIPTBP1.TBW3 = bw;
|
||||
|
||||
m_env.CTXT[i].MIPTBP1.TBP2 = bp;
|
||||
m_env.CTXT[i].MIPTBP1.TBW2 = bw;
|
||||
if (temp_MIPTBP1 != m_env.CTXT[i].MIPTBP1)
|
||||
Flush();
|
||||
|
||||
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
|
||||
|
||||
if (w > minwidth)
|
||||
{
|
||||
bw = std::max<u32>(bw >> 1, 1);
|
||||
}
|
||||
|
||||
m_env.CTXT[i].MIPTBP1.TBP3 = bp;
|
||||
m_env.CTXT[i].MIPTBP1.TBW3 = bw;
|
||||
MTBAReloaded = true;
|
||||
}
|
||||
|
||||
tex_flushed = false;
|
||||
ApplyTEX0<i>(TEX0);
|
||||
|
||||
if (MTBAReloaded)
|
||||
m_env.CTXT[i].MIPTBP1 = temp_MIPTBP1;
|
||||
}
|
||||
|
||||
template <int i>
|
||||
@@ -1132,11 +1234,10 @@ void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r)
|
||||
{
|
||||
GL_REG("TEXFLUSH = 0x%x_%x PRIM TME %x", r->U32[1], r->U32[0], PRIM->TME);
|
||||
|
||||
tex_flushed = true;
|
||||
// Some games do a single sprite draw to itself, then flush the texture cache, then use that texture again.
|
||||
// This won't get picked up by the new autoflush logic (which checks for page crossings for the PS2 Texture Cache flush)
|
||||
// so we need to do it here.
|
||||
if(m_userhacks_auto_flush)
|
||||
if (IsAutoFlushEnabled())
|
||||
Flush();
|
||||
}
|
||||
|
||||
@@ -1705,14 +1806,59 @@ void GSState::Move()
|
||||
int _sy = sy, _dy = dy; // Faster with local copied variables, compiler optimizations are dumb
|
||||
if (xinc > 0)
|
||||
{
|
||||
for (int y = 0; y < h; y++, _sy += yinc, _dy += yinc)
|
||||
const int page_width = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].pgs.x;
|
||||
const int page_height = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].pgs.y;
|
||||
const int xpage = sx & ~(page_width - 1);
|
||||
const int ypage = _sy & ~(page_height - 1);
|
||||
// Copying from itself to itself (rotating textures) used in Gitaroo Man stage 8
|
||||
// What probably happens is because the copy is buffered, the source stays just ahead of the destination.
|
||||
if (sbp == dbp && (((_sy < _dy) && ((ypage + page_height) > _dy)) || ((sx < dx) && ((xpage + page_width) > dx))))
|
||||
{
|
||||
auto s = getPAHelper(spo, sx, _sy);
|
||||
auto d = getPAHelper(dpo, dx, _dy);
|
||||
int starty = 0;
|
||||
int endy = h;
|
||||
int y_inc = yinc;
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
if (((_sy < _dy) && ((ypage + page_height) > _dy)))
|
||||
{
|
||||
pxCopyFn(d, s, x);
|
||||
_sy += h;
|
||||
_dy += h;
|
||||
starty = h-1;
|
||||
endy = -1;
|
||||
y_inc = -y_inc;
|
||||
}
|
||||
|
||||
for (int y = starty; y != endy; y+= y_inc, _sy += y_inc, _dy += y_inc)
|
||||
{
|
||||
auto s = getPAHelper(spo, sx, _sy);
|
||||
auto d = getPAHelper(dpo, dx, _dy);
|
||||
|
||||
if (((sx < dx) && ((xpage + page_width) > dx)))
|
||||
{
|
||||
for (int x = w - 1; x >= 0; x--)
|
||||
{
|
||||
pxCopyFn(d, s, x);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
pxCopyFn(d, s, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int y = 0; y < h; y++, _sy += yinc, _dy += yinc)
|
||||
{
|
||||
auto s = getPAHelper(spo, sx, _sy);
|
||||
auto d = getPAHelper(dpo, dx, _dy);
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
pxCopyFn(d, s, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1819,8 +1965,6 @@ void GSState::SoftReset(u32 mask)
|
||||
|
||||
void GSState::ReadFIFO(u8* mem, int size)
|
||||
{
|
||||
GSPerfMonAutoTimer pmat(&g_perfmon);
|
||||
|
||||
Flush();
|
||||
|
||||
size *= 16;
|
||||
@@ -1839,8 +1983,6 @@ template void GSState::Transfer<3>(const u8* mem, u32 size);
|
||||
template <int index>
|
||||
void GSState::Transfer(const u8* mem, u32 size)
|
||||
{
|
||||
GSPerfMonAutoTimer pmat(&g_perfmon);
|
||||
|
||||
const u8* start = mem;
|
||||
|
||||
GIFPath& path = m_path[index];
|
||||
@@ -2127,7 +2269,7 @@ int GSState::Defrost(const freezeData* fd)
|
||||
|
||||
u8* data = fd->data;
|
||||
|
||||
int version;
|
||||
u32 version;
|
||||
|
||||
ReadState(&version, data);
|
||||
|
||||
@@ -2433,10 +2575,17 @@ GSState::PRIM_OVERLAP GSState::PrimitiveOverlap()
|
||||
|
||||
__forceinline void GSState::HandleAutoFlush()
|
||||
{
|
||||
const u32 frame_mask = GSLocalMemory::m_psm[m_context->TEX0.PSM].fmsk;
|
||||
const bool frame_hit = (m_context->FRAME.Block() == m_context->TEX0.TBP0) && !(m_context->TEST.ATE && m_context->TEST.ATST == 0 && m_context->TEST.AFAIL == 2) && ((m_context->FRAME.FBMSK & frame_mask) != frame_mask);
|
||||
// There's a strange behaviour we need to test on a PS2 here, if the FRAME is a Z format, like Powerdrome something swaps over, and it seems Alpha Fail of "FB Only" writes to the Z.. it's odd.
|
||||
const bool zbuf_hit = (m_context->ZBUF.Block() == m_context->TEX0.TBP0) && !(m_context->TEST.ATE && m_context->TEST.ATST == 0 && m_context->TEST.AFAIL != 2) && !m_context->ZBUF.ZMSK;
|
||||
const u32 frame_z_psm = frame_hit ? m_context->FRAME.PSM : m_context->ZBUF.PSM;
|
||||
const u32 frame_z_bp = frame_hit ? m_context->FRAME.Block() : m_context->ZBUF.Block();
|
||||
|
||||
// To briefly explain what's going on here, what we are checking for is draws over a texture when the source and destination are themselves.
|
||||
// Because one page of the texture gets buffered in the Texture Cache (the PS2's one) if any of those pixels are overwritten, you still read the old data.
|
||||
// So we need to calculate if a page boundary is being crossed for the format it is in and if the same part of the texture being written and read inside the draw.
|
||||
if ((m_context->FRAME.Block() == m_context->TEX0.TBP0) && (m_context->TEX0.PSM == m_context->FRAME.PSM) && PRIM->TME && (m_context->FRAME.FBMSK != 0xFFFFFFFF))
|
||||
if (PRIM->TME && (frame_hit || zbuf_hit) && GSUtil::HasSharedBits(frame_z_bp, frame_z_psm, m_context->TEX0.TBP0, m_context->TEX0.PSM))
|
||||
{
|
||||
const int page_mask_x = ~(GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x - 1);
|
||||
const int page_mask_y = ~(GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.y - 1);
|
||||
@@ -2513,14 +2662,46 @@ __forceinline void GSState::HandleAutoFlush()
|
||||
|
||||
if(page_crossed)
|
||||
{
|
||||
// Update the vertex trace, scissor it (important for Jak 3!) and intersect with the current texture.
|
||||
if((m_index.tail - 1) == current_tex_end)
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
if (!area_out.rintersect(tex_rect).rempty())
|
||||
// Make sure the format matches, otherwise the coordinates aren't gonna match, so the draws won't intersect.
|
||||
if (GSUtil::HasCompatibleBits(m_context->TEX0.PSM, frame_z_psm) && (m_context->FRAME.FBW == m_context->TEX0.TBW))
|
||||
{
|
||||
Flush();
|
||||
// Update the vertex trace, scissor it (important for Jak 3!) and intersect with the current texture.
|
||||
if ((m_index.tail - 1) == current_tex_end)
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
|
||||
// Intersect goes on space inside the rect
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)) + GSVector4i(0, 0, 1, 1);
|
||||
// Scissor output
|
||||
area_out = area_out.rintersect(GSVector4i(m_context->scissor.in));
|
||||
// Intersect with texture
|
||||
if (!area_out.rintersect(tex_rect).rempty())
|
||||
Flush();
|
||||
}
|
||||
else // Storage of the TEX and FRAME/Z is different, so uhh, just fall back to flushing each page. It's slower, sorry.
|
||||
{
|
||||
|
||||
if (m_context->FRAME.FBW == m_context->TEX0.TBW)
|
||||
{
|
||||
//We know we've changed page, so let's set the dimension to cover the page they're in (for different pixel orders)
|
||||
tex_rect = tex_rect & page_mask;
|
||||
tex_rect += GSVector4i(0, 0, 1, 1); // Intersect goes on space inside the rect
|
||||
tex_rect.z += GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x;
|
||||
tex_rect.w += GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.y;
|
||||
|
||||
if ((m_index.tail - 1) == current_tex_end)
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
area_out = area_out & page_mask;
|
||||
area_out += GSVector4i(0, 0, 1, 1); // Intersect goes on space inside the rect
|
||||
area_out.z += GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x;
|
||||
area_out.w += GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.y;
|
||||
|
||||
if (!area_out.rintersect(tex_rect).rempty())
|
||||
Flush();
|
||||
}
|
||||
else // Page width is different, so it's much more difficult to calculate where it's modifying.
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2534,32 +2715,22 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
switch (prim)
|
||||
{
|
||||
case GS_POINTLIST:
|
||||
case GS_INVALID:
|
||||
n = 1;
|
||||
break;
|
||||
case GS_LINELIST:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_SPRITE:
|
||||
case GS_LINESTRIP:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_TRIANGLELIST:
|
||||
n = 3;
|
||||
break;
|
||||
case GS_TRIANGLESTRIP:
|
||||
n = 3;
|
||||
break;
|
||||
case GS_TRIANGLEFAN:
|
||||
n = 3;
|
||||
break;
|
||||
case GS_SPRITE:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_INVALID:
|
||||
n = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_context->FRAME.FBMSK != 0xFFFFFFFF)
|
||||
if ((m_context->FRAME.FBMSK & GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk) != GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk)
|
||||
m_mem.m_clut.Invalidate(m_context->FRAME.Block());
|
||||
|
||||
if (auto_flush && m_index.tail >= n)
|
||||
@@ -2768,9 +2939,6 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
if (PRIM->TME)
|
||||
tex_flushed = false;
|
||||
}
|
||||
|
||||
/// Checks if region repeat is used (applying it does something to at least one of the values in min...max)
|
||||
@@ -3038,12 +3206,14 @@ void GSState::CalcAlphaMinMax()
|
||||
m_vt.m_alpha.valid = true;
|
||||
}
|
||||
|
||||
bool GSState::TryAlphaTest(u32& fm, u32& zm)
|
||||
bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
||||
{
|
||||
// Shortcut for the easy case
|
||||
if (m_context->TEST.ATST == ATST_ALWAYS)
|
||||
return true;
|
||||
|
||||
const u32 framemask = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk;
|
||||
const u32 framemaskalpha = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk & 0xFF000000;
|
||||
// Alpha test can only control the write of some channels. If channels are already masked
|
||||
// the alpha test is therefore a nop.
|
||||
switch (m_context->TEST.AFAIL)
|
||||
@@ -3055,11 +3225,11 @@ bool GSState::TryAlphaTest(u32& fm, u32& zm)
|
||||
return true;
|
||||
break;
|
||||
case AFAIL_ZB_ONLY:
|
||||
if (fm == 0xFFFFFFFF)
|
||||
if ((fm & framemask) == framemask)
|
||||
return true;
|
||||
break;
|
||||
case AFAIL_RGB_ONLY:
|
||||
if (zm == 0xFFFFFFFF && ((fm & 0xFF000000) == 0xFF000000 || GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 1))
|
||||
if (zm == 0xFFFFFFFF && ((fm & framemaskalpha) == framemaskalpha || GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 1))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
@@ -3074,8 +3244,9 @@ bool GSState::TryAlphaTest(u32& fm, u32& zm)
|
||||
}
|
||||
else
|
||||
{
|
||||
const int amin = GetAlphaMinMax().min;
|
||||
const int amax = GetAlphaMinMax().max;
|
||||
const GSVertexTrace::VertexAlpha& aminmax = GetAlphaMinMax();
|
||||
const int amin = aminmax.min;
|
||||
const int amax = aminmax.max;
|
||||
|
||||
const int aref = m_context->TEST.AREF;
|
||||
|
||||
@@ -3201,7 +3372,7 @@ bool GSState::IsOpaque()
|
||||
|
||||
bool GSState::IsMipMapDraw()
|
||||
{
|
||||
return m_context->TEX1.MXL > 0 && m_context->TEX1.MMIN >= 2 && m_context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0 && (!m_context->TEX1.MTBA || m_context->TEX0.TH == m_context->TEX0.TW);
|
||||
return m_context->TEX1.MXL > 0 && m_context->TEX1.MMIN >= 2 && m_context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0;
|
||||
}
|
||||
|
||||
bool GSState::IsMipMapActive()
|
||||
|
||||
+8
-5
@@ -123,7 +123,7 @@ class GSState : public GSAlignedClass<32>
|
||||
template<bool auto_flush, bool index_swap>
|
||||
void SetPrimHandlers();
|
||||
|
||||
int m_version;
|
||||
u32 m_version;
|
||||
int m_sssize;
|
||||
|
||||
struct GSTransferBuffer
|
||||
@@ -149,14 +149,11 @@ protected:
|
||||
bool IsBadFrame();
|
||||
void SetupCrcHack();
|
||||
|
||||
bool m_userhacks_wildhack;
|
||||
bool m_isPackedUV_HackFlag;
|
||||
CRCHackLevel m_crc_hack_level;
|
||||
GetSkipCount m_gsc;
|
||||
int m_skip;
|
||||
int m_skip_offset;
|
||||
bool m_userhacks_auto_flush;
|
||||
bool tex_flushed;
|
||||
|
||||
GSVertex m_v;
|
||||
float m_q;
|
||||
@@ -164,6 +161,7 @@ protected:
|
||||
GSVector4i m_ofxy;
|
||||
|
||||
bool m_scanmask_used;
|
||||
bool tex_flushed;
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -214,7 +212,7 @@ protected:
|
||||
u8 uses_boundary; ///< Whether or not the usage touches the left, top, right, or bottom edge (and therefore needs wrap modes preserved)
|
||||
};
|
||||
TextureMinMaxResult GetTextureMinMax(const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear);
|
||||
bool TryAlphaTest(u32& fm, u32& zm);
|
||||
bool TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm);
|
||||
bool IsOpaque();
|
||||
bool IsMipMapDraw();
|
||||
bool IsMipMapActive();
|
||||
@@ -245,6 +243,8 @@ public:
|
||||
int s_savel;
|
||||
std::string m_dump_root;
|
||||
|
||||
static constexpr u32 STATE_VERSION = 8;
|
||||
|
||||
enum PRIM_OVERLAP
|
||||
{
|
||||
PRIM_OVERLAP_UNKNOW,
|
||||
@@ -273,6 +273,8 @@ public:
|
||||
float GetTvRefreshRate();
|
||||
|
||||
virtual void Reset();
|
||||
virtual void UpdateSettings(const Pcsx2Config::GSOptions& old_config);
|
||||
|
||||
void Flush();
|
||||
void FlushPrim();
|
||||
void FlushWrite();
|
||||
@@ -301,6 +303,7 @@ public:
|
||||
void SetRegsMem(u8* basemem) { m_regs = reinterpret_cast<GSPrivRegSet*>(basemem); }
|
||||
|
||||
void SetFrameSkip(int skip);
|
||||
void DumpVertices(const std::string& filename);
|
||||
|
||||
PRIM_OVERLAP PrimitiveOverlap();
|
||||
GIFRegTEX0 GetTex0Layer(u32 lod);
|
||||
|
||||
@@ -27,7 +27,9 @@ class GSJobQueue final
|
||||
{
|
||||
private:
|
||||
std::thread m_thread;
|
||||
std::function<void()> m_startup;
|
||||
std::function<void(T&)> m_func;
|
||||
std::function<void()> m_shutdown;
|
||||
bool m_exit;
|
||||
ringbuffer_base<T, CAPACITY> m_queue;
|
||||
|
||||
@@ -38,6 +40,9 @@ private:
|
||||
|
||||
void ThreadProc()
|
||||
{
|
||||
if (m_startup)
|
||||
m_startup();
|
||||
|
||||
std::unique_lock<std::mutex> l(m_lock);
|
||||
|
||||
while (true)
|
||||
@@ -74,11 +79,16 @@ private:
|
||||
|
||||
l.lock();
|
||||
}
|
||||
|
||||
if (m_shutdown)
|
||||
m_shutdown();
|
||||
}
|
||||
|
||||
public:
|
||||
GSJobQueue(std::function<void(T&)> func)
|
||||
: m_func(func)
|
||||
GSJobQueue(std::function<void()> startup, std::function<void(T&)> func, std::function<void()> shutdown)
|
||||
: m_startup(std::move(startup))
|
||||
, m_func(std::move(func))
|
||||
, m_shutdown(std::move(shutdown))
|
||||
, m_exit(false)
|
||||
{
|
||||
m_thread = std::thread(&GSJobQueue::ThreadProc, this);
|
||||
|
||||
@@ -498,20 +498,29 @@ GSAdapter::GSAdapter(const DXGI_ADAPTER_DESC1& desc_dxgi)
|
||||
// TODO
|
||||
#endif
|
||||
|
||||
HWBlend GSDevice::GetBlend(size_t index)
|
||||
{
|
||||
HWBlend blend = m_blendMap[index];
|
||||
blend.op = ConvertBlendEnum(blend.op);
|
||||
blend.src = ConvertBlendEnum(blend.src);
|
||||
blend.dst = ConvertBlendEnum(blend.dst);
|
||||
return blend;
|
||||
}
|
||||
|
||||
u16 GSDevice::GetBlendFlags(size_t index) { return m_blendMap[index].flags; }
|
||||
|
||||
// clang-format off
|
||||
|
||||
std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap =
|
||||
const std::array<u8, 16> GSDevice::m_replaceDualSrcBlendMap =
|
||||
{{
|
||||
SRC_COLOR, // SRC_COLOR
|
||||
INV_SRC_COLOR, // INV_SRC_COLOR
|
||||
DST_COLOR, // DST_COLOR
|
||||
INV_DST_COLOR, // INV_DST_COLOR
|
||||
SRC_COLOR, // SRC1_COLOR
|
||||
INV_SRC_COLOR, // INV_SRC1_COLOR
|
||||
SRC_ALPHA, // SRC_ALPHA
|
||||
INV_SRC_ALPHA, // INV_SRC_ALPHA
|
||||
DST_ALPHA, // DST_ALPHA
|
||||
INV_DST_ALPHA, // INV_DST_ALPHA
|
||||
SRC_ALPHA, // SRC1_ALPHA
|
||||
INV_SRC_ALPHA, // INV_SRC1_ALPHA
|
||||
CONST_COLOR, // CONST_COLOR
|
||||
INV_CONST_COLOR, // INV_CONST_COLOR
|
||||
CONST_ONE, // CONST_ONE
|
||||
CONST_ZERO // CONST_ZERO
|
||||
}};
|
||||
|
||||
const std::array<HWBlend, 3*3*3*3> GSDevice::m_blendMap =
|
||||
{{
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs
|
||||
{ BLEND_CD , OP_ADD , CONST_ZERO , CONST_ONE} , // 0001: (Cs - Cs)*As + Cd ==> Cd
|
||||
@@ -594,5 +603,4 @@ std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap =
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 2220: (0 - 0)*F + Cs ==> Cs
|
||||
{ BLEND_CD , OP_ADD , CONST_ZERO , CONST_ONE} , // 2221: (0 - 0)*F + Cd ==> Cd
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 2222: (0 - 0)*F + 0 ==> 0
|
||||
{ 0 , OP_ADD , SRC_ALPHA , INV_SRC_ALPHA} , // extra for merge operation
|
||||
}};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/HashCombine.h"
|
||||
#include "common/WindowInfo.h"
|
||||
#include "GSFastList.h"
|
||||
#include "GSTexture.h"
|
||||
@@ -132,7 +133,8 @@ enum HWBlendFlags
|
||||
// Determines the HW blend function for DX11/OGL
|
||||
struct HWBlend
|
||||
{
|
||||
u16 flags, op, src, dst;
|
||||
u16 flags;
|
||||
u8 op, src, dst;
|
||||
};
|
||||
|
||||
struct alignas(16) GSHWDrawConfig
|
||||
@@ -150,6 +152,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
Triangle,
|
||||
Sprite,
|
||||
};
|
||||
#pragma pack(push, 1)
|
||||
struct GSSelector
|
||||
{
|
||||
union
|
||||
@@ -182,6 +185,8 @@ struct alignas(16) GSHWDrawConfig
|
||||
VSSelector(): key(0) {}
|
||||
VSSelector(u8 k): key(k) {}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#pragma pack(push, 4)
|
||||
struct PSSelector
|
||||
{
|
||||
// Performance note: there are too many shader combinations
|
||||
@@ -233,6 +238,10 @@ struct alignas(16) GSHWDrawConfig
|
||||
u32 colclip : 1;
|
||||
u32 blend_mix : 1;
|
||||
u32 pabe : 1;
|
||||
u32 no_color : 1; // disables color output entirely (depth only)
|
||||
u32 no_color1 : 1; // disables second color output (when unnecessary)
|
||||
u32 no_ablend : 1; // output alpha blend in col0 (for no-DSB)
|
||||
u32 only_alpha : 1; // don't bother computing RGB
|
||||
|
||||
// Others ways to fetch the texture
|
||||
u32 channel : 3;
|
||||
@@ -255,19 +264,52 @@ struct alignas(16) GSHWDrawConfig
|
||||
|
||||
// Scan mask
|
||||
u32 scanmsk : 2;
|
||||
|
||||
//u32 _free2 : 0;
|
||||
};
|
||||
|
||||
u64 key;
|
||||
struct
|
||||
{
|
||||
u64 key_lo;
|
||||
u32 key_hi;
|
||||
};
|
||||
};
|
||||
PSSelector(): key(0) {}
|
||||
__fi PSSelector() : key_lo(0), key_hi(0) {}
|
||||
|
||||
__fi bool operator==(const PSSelector& rhs) const { return (key_lo == rhs.key_lo && key_hi == rhs.key_hi); }
|
||||
__fi bool operator!=(const PSSelector& rhs) const { return (key_lo != rhs.key_lo || key_hi != rhs.key_hi); }
|
||||
__fi bool operator<(const PSSelector& rhs) const { return (key_lo < rhs.key_lo || key_hi < rhs.key_hi); }
|
||||
|
||||
__fi bool IsFeedbackLoop() const
|
||||
{
|
||||
return tex_is_fb || fbmask || date > 0 || blend_a == 1 || blend_b == 1 || blend_c == 1 || blend_d == 1;
|
||||
}
|
||||
|
||||
/// Disables color output from the pixel shader, this is done when all channels are masked.
|
||||
__fi void DisableColorOutput()
|
||||
{
|
||||
// remove software blending, since this will cause the color to be declared inout with fbfetch.
|
||||
blend_a = blend_b = blend_c = blend_d = 0;
|
||||
|
||||
// TEX_IS_FB relies on us having a color output to begin with.
|
||||
tex_is_fb = 0;
|
||||
|
||||
// no point having fbmask, since we're not writing. DATE has to stay.
|
||||
fbmask = 0;
|
||||
|
||||
// disable both outputs.
|
||||
no_color = no_color1 = 1;
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
struct PSSelectorHash
|
||||
{
|
||||
std::size_t operator()(const PSSelector& p) const
|
||||
{
|
||||
std::size_t h = 0;
|
||||
HashCombine(h, p.key_lo, p.key_hi);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
#pragma pack(push, 1)
|
||||
struct SamplerSelector
|
||||
{
|
||||
union
|
||||
@@ -284,7 +326,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
u8 key;
|
||||
};
|
||||
SamplerSelector(): key(0) {}
|
||||
SamplerSelector(u32 k): key(k) {}
|
||||
SamplerSelector(u8 k): key(k) {}
|
||||
static SamplerSelector Point() { return SamplerSelector(); }
|
||||
static SamplerSelector Linear()
|
||||
{
|
||||
@@ -338,7 +380,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
u8 key;
|
||||
};
|
||||
DepthStencilSelector(): key(0) {}
|
||||
DepthStencilSelector(u32 k): key(k) {}
|
||||
DepthStencilSelector(u8 k): key(k) {}
|
||||
static DepthStencilSelector NoDepth()
|
||||
{
|
||||
DepthStencilSelector out;
|
||||
@@ -366,8 +408,9 @@ struct alignas(16) GSHWDrawConfig
|
||||
u8 key;
|
||||
};
|
||||
ColorMaskSelector(): key(0xF) {}
|
||||
ColorMaskSelector(u32 c): key(0) { wrgba = c; }
|
||||
ColorMaskSelector(u8 c): key(0) { wrgba = c; }
|
||||
};
|
||||
#pragma pack(pop)
|
||||
struct alignas(16) VSConstantBuffer
|
||||
{
|
||||
GSVector2 vertex_scale;
|
||||
@@ -458,23 +501,25 @@ struct alignas(16) GSHWDrawConfig
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 index;
|
||||
u8 factor;
|
||||
bool is_constant : 1;
|
||||
bool is_accumulation : 1;
|
||||
bool is_mixed_hw_sw : 1;
|
||||
u8 enable : 1;
|
||||
u8 constant_enable : 1;
|
||||
u8 op : 6;
|
||||
u8 src_factor;
|
||||
u8 dst_factor;
|
||||
u8 constant;
|
||||
};
|
||||
u32 key;
|
||||
};
|
||||
BlendState(): key(0) {}
|
||||
BlendState(u8 index, u8 factor, bool is_constant, bool is_accumulation, bool is_mixed_hw_sw)
|
||||
BlendState(bool enable_, u8 src_factor_, u8 dst_factor_, u8 op_, bool constant_enable_, u8 constant_)
|
||||
: key(0)
|
||||
{
|
||||
this->index = index;
|
||||
this->factor = factor;
|
||||
this->is_constant = is_constant;
|
||||
this->is_accumulation = is_accumulation;
|
||||
this->is_mixed_hw_sw = is_mixed_hw_sw;
|
||||
enable = enable_;
|
||||
constant_enable = constant_enable_;
|
||||
src_factor = src_factor_;
|
||||
dst_factor = dst_factor_;
|
||||
op = op_;
|
||||
constant = constant_;
|
||||
}
|
||||
};
|
||||
enum class DestinationAlphaMode : u8
|
||||
@@ -500,9 +545,9 @@ struct alignas(16) GSHWDrawConfig
|
||||
GSVector4i drawarea; ///< Area in the framebuffer which will be modified.
|
||||
Topology topology; ///< Draw topology
|
||||
|
||||
alignas(8) PSSelector ps;
|
||||
GSSelector gs;
|
||||
VSSelector vs;
|
||||
PSSelector ps;
|
||||
|
||||
BlendState blend;
|
||||
SamplerSelector sampler;
|
||||
@@ -516,14 +561,18 @@ struct alignas(16) GSHWDrawConfig
|
||||
bool datm : 1;
|
||||
bool line_expand : 1;
|
||||
|
||||
struct AlphaSecondPass
|
||||
struct AlphaPass
|
||||
{
|
||||
alignas(8) PSSelector ps;
|
||||
bool enable;
|
||||
ColorMaskSelector colormask;
|
||||
DepthStencilSelector depth;
|
||||
PSSelector ps;
|
||||
float ps_aref;
|
||||
} alpha_second_pass;
|
||||
};
|
||||
static_assert(sizeof(AlphaPass) == 24, "alpha pass is 24 bytes");
|
||||
|
||||
AlphaPass alpha_second_pass;
|
||||
AlphaPass alpha_third_pass;
|
||||
|
||||
VSConstantBuffer cb_vs;
|
||||
PSConstantBuffer cb_ps;
|
||||
@@ -532,6 +581,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
class GSDevice : public GSAlignedClass<32>
|
||||
{
|
||||
public:
|
||||
// clang-format off
|
||||
struct FeatureSupport
|
||||
{
|
||||
bool broken_point_sampler : 1; ///< Issue with AMD cards, see tfx shader for details
|
||||
@@ -544,32 +594,38 @@ public:
|
||||
bool prefer_new_textures : 1; ///< Allocate textures up to the pool size before reusing them, to avoid render pass restarts.
|
||||
bool dxt_textures : 1; ///< Supports DXTn texture compression, i.e. S3TC and BC1-3.
|
||||
bool bptc_textures : 1; ///< Supports BC6/7 texture compression.
|
||||
bool framebuffer_fetch : 1; ///< Can sample from the framebuffer without texture barriers.
|
||||
bool dual_source_blend : 1; ///< Can use alpha output as a blend factor.
|
||||
bool stencil_buffer : 1; ///< Supports stencil buffer, and can use for DATE.
|
||||
FeatureSupport()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
FastList<GSTexture*> m_pool;
|
||||
static std::array<HWBlend, 3*3*3*3 + 1> m_blendMap;
|
||||
|
||||
protected:
|
||||
enum : u16
|
||||
// clang-format off
|
||||
enum : u8
|
||||
{
|
||||
// HW blend factors
|
||||
SRC_COLOR, INV_SRC_COLOR, DST_COLOR, INV_DST_COLOR,
|
||||
SRC1_COLOR, INV_SRC1_COLOR, SRC_ALPHA, INV_SRC_ALPHA,
|
||||
DST_ALPHA, INV_DST_ALPHA, SRC1_ALPHA, INV_SRC1_ALPHA,
|
||||
CONST_COLOR, INV_CONST_COLOR, CONST_ONE, CONST_ZERO,
|
||||
|
||||
SRC_COLOR, INV_SRC_COLOR, DST_COLOR, INV_DST_COLOR,
|
||||
SRC1_COLOR, INV_SRC1_COLOR, SRC_ALPHA, INV_SRC_ALPHA,
|
||||
DST_ALPHA, INV_DST_ALPHA, SRC1_ALPHA, INV_SRC1_ALPHA,
|
||||
CONST_COLOR, INV_CONST_COLOR, CONST_ONE, CONST_ZERO,
|
||||
};
|
||||
enum : u8
|
||||
{
|
||||
// HW blend operations
|
||||
OP_ADD, OP_SUBTRACT, OP_REV_SUBTRACT
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static const int m_NO_BLEND = 0;
|
||||
static const int m_MERGE_BLEND = m_blendMap.size() - 1;
|
||||
private:
|
||||
FastList<GSTexture*> m_pool;
|
||||
static const std::array<HWBlend, 3*3*3*3> m_blendMap;
|
||||
static const std::array<u8, 16> m_replaceDualSrcBlendMap;
|
||||
|
||||
protected:
|
||||
static constexpr u32 MAX_POOLED_TEXTURES = 300;
|
||||
|
||||
HostDisplay* m_display;
|
||||
@@ -598,7 +654,6 @@ protected:
|
||||
virtual void DoFXAA(GSTexture* sTex, GSTexture* dTex) {}
|
||||
virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex) {}
|
||||
virtual void DoExternalFX(GSTexture* sTex, GSTexture* dTex) {}
|
||||
virtual u16 ConvertBlendEnum(u16 generic) = 0; // Convert blend factors/ops from the generic enum to DX11/OGl specific.
|
||||
|
||||
public:
|
||||
GSDevice();
|
||||
@@ -697,10 +752,34 @@ public:
|
||||
|
||||
virtual void PrintMemoryUsage();
|
||||
|
||||
// Convert the GS blend equations to HW specific blend factors/ops
|
||||
__fi static constexpr bool IsDualSourceBlendFactor(u8 factor)
|
||||
{
|
||||
return (factor == SRC1_ALPHA || factor == INV_SRC1_ALPHA
|
||||
/*|| factor == SRC1_COLOR || factor == INV_SRC1_COLOR*/); // not used
|
||||
}
|
||||
__fi static constexpr bool IsConstantBlendFactor(u16 factor)
|
||||
{
|
||||
return (factor == CONST_COLOR || factor == INV_CONST_COLOR);
|
||||
}
|
||||
|
||||
// Convert the GS blend equations to HW blend factors/ops
|
||||
// Index is computed as ((((A * 3 + B) * 3) + C) * 3) + D. A, B, C, D taken from ALPHA register.
|
||||
HWBlend GetBlend(size_t index);
|
||||
u16 GetBlendFlags(size_t index);
|
||||
__ri static HWBlend GetBlend(u32 index, bool replace_dual_src)
|
||||
{
|
||||
HWBlend ret = m_blendMap[index];
|
||||
if (replace_dual_src)
|
||||
{
|
||||
ret.src = m_replaceDualSrcBlendMap[ret.src];
|
||||
ret.dst = m_replaceDualSrcBlendMap[ret.dst];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
__ri static u16 GetBlendFlags(u32 index) { return m_blendMap[index].flags; }
|
||||
__fi static bool IsDualSourceBlend(u32 index)
|
||||
{
|
||||
return (IsDualSourceBlendFactor(m_blendMap[index].src) ||
|
||||
IsDualSourceBlendFactor(m_blendMap[index].dst));
|
||||
}
|
||||
};
|
||||
|
||||
struct GSAdapter
|
||||
|
||||
@@ -20,11 +20,36 @@
|
||||
#include "HostDisplay.h"
|
||||
#include "PerformanceMetrics.h"
|
||||
#include "pcsx2/Config.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
#include "gui/AppCoreThread.h"
|
||||
#if defined(__unix__)
|
||||
#include <X11/keysym.h>
|
||||
#endif
|
||||
|
||||
static std::string GetDumpName()
|
||||
{
|
||||
return StringUtil::wxStringToUTF8String(GameInfo::gameName);
|
||||
}
|
||||
static std::string GetDumpSerial()
|
||||
{
|
||||
return StringUtil::wxStringToUTF8String(GameInfo::gameSerial);
|
||||
}
|
||||
#else
|
||||
#include "VMManager.h"
|
||||
|
||||
static std::string GetDumpName()
|
||||
{
|
||||
return VMManager::GetGameName();
|
||||
}
|
||||
static std::string GetDumpSerial()
|
||||
{
|
||||
return VMManager::GetGameSerial();
|
||||
}
|
||||
#endif
|
||||
|
||||
GSRenderer::GSRenderer()
|
||||
: m_shift_key(false)
|
||||
, m_control_key(false)
|
||||
@@ -391,8 +416,6 @@ static GSVector4 CalculateDrawRect(s32 window_width, s32 window_height, s32 text
|
||||
|
||||
void GSRenderer::VSync(u32 field, bool registers_written)
|
||||
{
|
||||
GSPerfMonAutoTimer pmat(&g_perfmon);
|
||||
|
||||
Flush();
|
||||
|
||||
if (s_dump && s_n >= s_saven)
|
||||
@@ -440,6 +463,9 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||
}
|
||||
|
||||
Host::EndPresentFrame();
|
||||
|
||||
if (GSConfig.OsdShowGPU)
|
||||
PerformanceMetrics::OnGPUPresent(Host::GetHostDisplay()->GetAndResetAccumulatedGPUTime());
|
||||
}
|
||||
g_gs_device->RestoreAPIState();
|
||||
|
||||
@@ -454,10 +480,26 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||
fd.data = new u8[fd.size];
|
||||
Freeze(&fd, false);
|
||||
|
||||
// keep the screenshot relatively small so we don't bloat the dump
|
||||
static constexpr u32 DUMP_SCREENSHOT_WIDTH = 640;
|
||||
static constexpr u32 DUMP_SCREENSHOT_HEIGHT = 480;
|
||||
std::vector<u32> screenshot_pixels;
|
||||
SaveSnapshotToMemory(DUMP_SCREENSHOT_WIDTH, DUMP_SCREENSHOT_HEIGHT, &screenshot_pixels);
|
||||
|
||||
if (m_control_key)
|
||||
m_dump = std::unique_ptr<GSDumpBase>(new GSDump(m_snapshot, m_crc, fd, m_regs));
|
||||
{
|
||||
m_dump = std::unique_ptr<GSDumpBase>(new GSDumpUncompressed(m_snapshot, GetDumpSerial(), m_crc,
|
||||
DUMP_SCREENSHOT_WIDTH, DUMP_SCREENSHOT_HEIGHT,
|
||||
screenshot_pixels.empty() ? nullptr : screenshot_pixels.data(),
|
||||
fd, m_regs));
|
||||
}
|
||||
else
|
||||
m_dump = std::unique_ptr<GSDumpBase>(new GSDumpXz(m_snapshot, m_crc, fd, m_regs));
|
||||
{
|
||||
m_dump = std::unique_ptr<GSDumpBase>(new GSDumpXz(m_snapshot, GetDumpSerial(), m_crc,
|
||||
DUMP_SCREENSHOT_WIDTH, DUMP_SCREENSHOT_HEIGHT,
|
||||
screenshot_pixels.empty() ? nullptr : screenshot_pixels.data(),
|
||||
fd, m_regs));
|
||||
}
|
||||
|
||||
delete[] fd.data;
|
||||
}
|
||||
@@ -528,6 +570,18 @@ bool GSRenderer::MakeSnapshot(const std::string& path)
|
||||
}
|
||||
prev_snap = cur_time;
|
||||
}
|
||||
|
||||
// append the game serial and title
|
||||
if (std::string name(GetDumpName()); !name.empty())
|
||||
{
|
||||
FileSystem::SanitizeFileName(name);
|
||||
m_snapshot += format("_%s", name.c_str());
|
||||
}
|
||||
if (std::string serial(GetDumpSerial()); !serial.empty())
|
||||
{
|
||||
FileSystem::SanitizeFileName(serial);
|
||||
m_snapshot += format("_%s", serial.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +600,7 @@ void GSRenderer::EndCapture()
|
||||
|
||||
void GSRenderer::KeyEvent(const HostKeyEvent& e)
|
||||
{
|
||||
#ifndef __APPLE__ // TODO: Add hotkey support on macOS
|
||||
#if !defined(PCSX2_CORE) && !defined(__APPLE__) // TODO: Add hotkey support on macOS
|
||||
#ifdef _WIN32
|
||||
m_shift_key = !!(::GetAsyncKeyState(VK_SHIFT) & 0x8000);
|
||||
m_control_key = !!(::GetAsyncKeyState(VK_CONTROL) & 0x8000);
|
||||
|
||||
@@ -21,13 +21,15 @@
|
||||
|
||||
CONSTINIT const GSVector4 GSVertexTrace::s_minmax = GSVector4::cxpr(FLT_MAX, -FLT_MAX, 0.f, 0.f);
|
||||
|
||||
GSVertexTrace::GSVertexTrace(const GSState* state)
|
||||
GSVertexTrace::GSVertexTrace(const GSState* state, bool provoking_vertex_first)
|
||||
: m_accurate_stq(false), m_state(state), m_primclass(GS_INVALID_CLASS)
|
||||
{
|
||||
memset(&m_alpha, 0, sizeof(m_alpha));
|
||||
|
||||
#define InitUpdate3(P, IIP, TME, FST, COLOR) \
|
||||
m_fmm[COLOR][FST][TME][IIP][P] = &GSVertexTrace::FindMinMax<P, IIP, TME, FST, COLOR>;
|
||||
m_fmm[COLOR][FST][TME][IIP][P] = \
|
||||
provoking_vertex_first ? &GSVertexTrace::FindMinMax<P, IIP, TME, FST, COLOR, true> : \
|
||||
&GSVertexTrace::FindMinMax<P, IIP, TME, FST, COLOR, false>;
|
||||
|
||||
#define InitUpdate2(P, IIP, TME) \
|
||||
InitUpdate3(P, IIP, TME, 0, 0) \
|
||||
@@ -151,7 +153,7 @@ void GSVertexTrace::Update(const void* vertex, const u32* index, int v_count, in
|
||||
}
|
||||
}
|
||||
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool flat_swapped>
|
||||
void GSVertexTrace::FindMinMax(const void* vertex, const u32* index, int count)
|
||||
{
|
||||
const GSDrawingContext* context = m_state->m_context;
|
||||
@@ -283,16 +285,16 @@ void GSVertexTrace::FindMinMax(const void* vertex, const u32* index, int count)
|
||||
int i = 0;
|
||||
for (; i < (count - 3); i += 6)
|
||||
{
|
||||
processVertices(v[index[i + 0]], v[index[i + 3]], false);
|
||||
processVertices(v[index[i + 0]], v[index[i + 3]], flat_swapped);
|
||||
processVertices(v[index[i + 1]], v[index[i + 4]], false);
|
||||
processVertices(v[index[i + 2]], v[index[i + 5]], true);
|
||||
processVertices(v[index[i + 2]], v[index[i + 5]], !flat_swapped);
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
processVertices(v[index[i + 0]], v[index[i + 1]], false);
|
||||
processVertices(v[index[i + 0]], v[index[i + 1]], flat_swapped);
|
||||
// Compiler optimizations go!
|
||||
// (And if they don't, it's only one vertex out of many)
|
||||
processVertices(v[index[i + 2]], v[index[i + 2]], true);
|
||||
processVertices(v[index[i + 2]], v[index[i + 2]], !flat_swapped);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -48,7 +48,7 @@ protected:
|
||||
|
||||
FindMinMaxPtr m_fmm[2][2][2][2][4];
|
||||
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool provoking_vertex_first>
|
||||
void FindMinMax(const void* vertex, const u32* index, int count);
|
||||
|
||||
public:
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
GSVector2 m_lod; // x = min, y = max
|
||||
|
||||
public:
|
||||
GSVertexTrace(const GSState* state);
|
||||
GSVertexTrace(const GSState* state, bool provoking_vertex_first);
|
||||
virtual ~GSVertexTrace() {}
|
||||
|
||||
void Update(const void* vertex, const u32* index, int v_count, int i_count, GS_PRIM_CLASS primclass);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
static bool SupportsTextureFormat(ID3D11Device* dev, DXGI_FORMAT format)
|
||||
{
|
||||
UINT support;
|
||||
if (FAILED(dev->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &support)))
|
||||
if (FAILED(dev->CheckFormatSupport(format, &support)))
|
||||
return false;
|
||||
|
||||
return (support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
||||
@@ -53,6 +53,9 @@ GSDevice11::GSDevice11()
|
||||
m_features.prefer_new_textures = false;
|
||||
m_features.dxt_textures = false;
|
||||
m_features.bptc_textures = false;
|
||||
m_features.framebuffer_fetch = false;
|
||||
m_features.dual_source_blend = true;
|
||||
m_features.stencil_buffer = true;
|
||||
}
|
||||
|
||||
bool GSDevice11::Create(HostDisplay* display)
|
||||
@@ -1249,10 +1252,14 @@ static GSDevice11::OMBlendSelector convertSel(GSHWDrawConfig::ColorMaskSelector
|
||||
{
|
||||
GSDevice11::OMBlendSelector out;
|
||||
out.wrgba = cm.wrgba;
|
||||
out.abe = blend.index != 0;
|
||||
out.blend_index = blend.index;
|
||||
out.accu_blend = blend.is_accumulation;
|
||||
out.blend_mix = blend.is_mixed_hw_sw;
|
||||
if (blend.enable)
|
||||
{
|
||||
out.blend_enable = true;
|
||||
out.blend_src_factor = blend.src_factor;
|
||||
out.blend_dst_factor = blend.dst_factor;
|
||||
out.blend_op = blend.op;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1346,7 +1353,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
PSSetShaderResource(0, rt_copy);
|
||||
}
|
||||
|
||||
SetupOM(config.depth, convertSel(config.colormask, config.blend), config.blend.factor);
|
||||
SetupOM(config.depth, convertSel(config.colormask, config.blend), config.blend.constant);
|
||||
SetupVS(config.vs, &config.cb_vs);
|
||||
SetupGS(config.gs);
|
||||
SetupPS(config.ps, &config.cb_ps, config.sampler);
|
||||
@@ -1367,7 +1374,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
SetupPS(config.alpha_second_pass.ps, nullptr, config.sampler);
|
||||
}
|
||||
|
||||
SetupOM(config.alpha_second_pass.depth, convertSel(config.alpha_second_pass.colormask, config.blend), config.blend.factor);
|
||||
SetupOM(config.alpha_second_pass.depth, convertSel(config.alpha_second_pass.colormask, config.blend), config.blend.constant);
|
||||
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
@@ -1386,30 +1393,3 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
Recycle(hdr_rt);
|
||||
}
|
||||
}
|
||||
|
||||
u16 GSDevice11::ConvertBlendEnum(u16 generic)
|
||||
{
|
||||
switch (generic)
|
||||
{
|
||||
case SRC_COLOR: return D3D11_BLEND_SRC_COLOR;
|
||||
case INV_SRC_COLOR: return D3D11_BLEND_INV_SRC_COLOR;
|
||||
case DST_COLOR: return D3D11_BLEND_DEST_COLOR;
|
||||
case INV_DST_COLOR: return D3D11_BLEND_INV_DEST_COLOR;
|
||||
case SRC1_COLOR: return D3D11_BLEND_SRC1_COLOR;
|
||||
case INV_SRC1_COLOR: return D3D11_BLEND_INV_SRC1_COLOR;
|
||||
case SRC_ALPHA: return D3D11_BLEND_SRC_ALPHA;
|
||||
case INV_SRC_ALPHA: return D3D11_BLEND_INV_SRC_ALPHA;
|
||||
case DST_ALPHA: return D3D11_BLEND_DEST_ALPHA;
|
||||
case INV_DST_ALPHA: return D3D11_BLEND_INV_DEST_ALPHA;
|
||||
case SRC1_ALPHA: return D3D11_BLEND_SRC1_ALPHA;
|
||||
case INV_SRC1_ALPHA: return D3D11_BLEND_INV_SRC1_ALPHA;
|
||||
case CONST_COLOR: return D3D11_BLEND_BLEND_FACTOR;
|
||||
case INV_CONST_COLOR: return D3D11_BLEND_INV_BLEND_FACTOR;
|
||||
case CONST_ONE: return D3D11_BLEND_ONE;
|
||||
case CONST_ZERO: return D3D11_BLEND_ZERO;
|
||||
case OP_ADD: return D3D11_BLEND_OP_ADD;
|
||||
case OP_SUBTRACT: return D3D11_BLEND_OP_SUBTRACT;
|
||||
case OP_REV_SUBTRACT: return D3D11_BLEND_OP_REV_SUBTRACT;
|
||||
default: ASSERT(0); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ public:
|
||||
u32 wb : 1;
|
||||
u32 wa : 1;
|
||||
// Alpha blending
|
||||
u32 blend_index : 7;
|
||||
u32 abe : 1;
|
||||
u32 accu_blend : 1;
|
||||
u32 blend_mix : 1;
|
||||
u32 blend_enable : 1;
|
||||
u32 blend_op : 2;
|
||||
u32 blend_src_factor : 4;
|
||||
u32 blend_dst_factor : 4;
|
||||
};
|
||||
|
||||
struct
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
u32 key;
|
||||
};
|
||||
|
||||
operator u32() { return key & 0x3fff; }
|
||||
operator u32() { return key & 0x7fff; }
|
||||
|
||||
OMBlendSelector()
|
||||
: key(0)
|
||||
@@ -127,8 +127,6 @@ private:
|
||||
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex) final;
|
||||
void DoExternalFX(GSTexture* sTex, GSTexture* dTex) final;
|
||||
|
||||
u16 ConvertBlendEnum(u16 generic) final;
|
||||
|
||||
wil::com_ptr_nothrow<ID3D11Device> m_dev;
|
||||
wil::com_ptr_nothrow<ID3D11DeviceContext> m_ctx;
|
||||
wil::com_ptr_nothrow<IDXGISwapChain1> m_swapchain;
|
||||
@@ -213,7 +211,7 @@ private:
|
||||
std::unordered_map<u32, GSVertexShader11> m_vs;
|
||||
wil::com_ptr_nothrow<ID3D11Buffer> m_vs_cb;
|
||||
std::unordered_map<u32, wil::com_ptr_nothrow<ID3D11GeometryShader>> m_gs;
|
||||
std::unordered_map<u64, wil::com_ptr_nothrow<ID3D11PixelShader>> m_ps;
|
||||
std::unordered_map<PSSelector, wil::com_ptr_nothrow<ID3D11PixelShader>, GSHWDrawConfig::PSSelectorHash> m_ps;
|
||||
wil::com_ptr_nothrow<ID3D11Buffer> m_ps_cb;
|
||||
std::unordered_map<u32, wil::com_ptr_nothrow<ID3D11SamplerState>> m_ps_ss;
|
||||
wil::com_ptr_nothrow<ID3D11SamplerState> m_palette_ss;
|
||||
@@ -291,7 +289,7 @@ public:
|
||||
bool CreateTextureFX();
|
||||
void SetupVS(VSSelector sel, const GSHWDrawConfig::VSConstantBuffer* cb);
|
||||
void SetupGS(GSSelector sel);
|
||||
void SetupPS(PSSelector sel, const GSHWDrawConfig::PSConstantBuffer* cb, PSSamplerSelector ssel);
|
||||
void SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstantBuffer* cb, PSSamplerSelector ssel);
|
||||
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, u8 afix);
|
||||
|
||||
void RenderHW(GSHWDrawConfig& config) final;
|
||||
|
||||
@@ -147,9 +147,9 @@ void GSDevice11::SetupGS(GSSelector sel)
|
||||
GSSetShader(gs.get(), m_vs_cb.get());
|
||||
}
|
||||
|
||||
void GSDevice11::SetupPS(PSSelector sel, const GSHWDrawConfig::PSConstantBuffer* cb, PSSamplerSelector ssel)
|
||||
void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstantBuffer* cb, PSSamplerSelector ssel)
|
||||
{
|
||||
auto i = std::as_const(m_ps).find(sel.key);
|
||||
auto i = std::as_const(m_ps).find(sel);
|
||||
|
||||
if (i == m_ps.end())
|
||||
{
|
||||
@@ -195,9 +195,13 @@ void GSDevice11::SetupPS(PSSelector sel, const GSHWDrawConfig::PSConstantBuffer*
|
||||
sm.AddMacro("PS_AUTOMATIC_LOD", sel.automatic_lod);
|
||||
sm.AddMacro("PS_MANUAL_LOD", sel.manual_lod);
|
||||
sm.AddMacro("PS_TEX_IS_FB", sel.tex_is_fb);
|
||||
sm.AddMacro("PS_NO_COLOR", sel.no_color);
|
||||
sm.AddMacro("PS_NO_COLOR1", sel.no_color1);
|
||||
sm.AddMacro("PS_NO_ABLEND", sel.no_ablend);
|
||||
sm.AddMacro("PS_ONLY_ALPHA", sel.only_alpha);
|
||||
|
||||
wil::com_ptr_nothrow<ID3D11PixelShader> ps = m_shader_cache.GetPixelShader(m_dev.get(), m_tfx_source, sm.GetPtr(), "ps_main");
|
||||
i = m_ps.try_emplace(sel.key, std::move(ps)).first;
|
||||
i = m_ps.try_emplace(sel, std::move(ps)).first;
|
||||
}
|
||||
|
||||
if (cb && m_ps_cb_cache.Update(*cb))
|
||||
@@ -277,6 +281,18 @@ void GSDevice11::ClearSamplerCache()
|
||||
m_ps_ss.clear();
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static constexpr std::array<D3D11_BLEND, 16> s_d3d11_blend_factors = { {
|
||||
D3D11_BLEND_SRC_COLOR, D3D11_BLEND_INV_SRC_COLOR, D3D11_BLEND_DEST_COLOR, D3D11_BLEND_INV_DEST_COLOR,
|
||||
D3D11_BLEND_SRC1_COLOR, D3D11_BLEND_INV_SRC1_COLOR, D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA,
|
||||
D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_INV_SRC1_ALPHA,
|
||||
D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_ONE, D3D11_BLEND_ZERO
|
||||
} };
|
||||
static constexpr std::array<D3D11_BLEND_OP, 3> s_d3d11_blend_ops = { {
|
||||
D3D11_BLEND_OP_ADD, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_OP_REV_SUBTRACT
|
||||
} };
|
||||
// clang-format on
|
||||
|
||||
void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, u8 afix)
|
||||
{
|
||||
auto i = std::as_const(m_om_dss).find(dssel.key);
|
||||
@@ -333,24 +349,15 @@ void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, u8
|
||||
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
|
||||
if (bsel.abe)
|
||||
if (bsel.blend_enable)
|
||||
{
|
||||
const HWBlend blend = GetBlend(bsel.blend_index);
|
||||
bd.RenderTarget[0].BlendEnable = TRUE;
|
||||
bd.RenderTarget[0].BlendOp = (D3D11_BLEND_OP)blend.op;
|
||||
bd.RenderTarget[0].SrcBlend = (D3D11_BLEND)blend.src;
|
||||
bd.RenderTarget[0].DestBlend = (D3D11_BLEND)blend.dst;
|
||||
bd.RenderTarget[0].BlendOp = s_d3d11_blend_ops[bsel.blend_op];
|
||||
bd.RenderTarget[0].SrcBlend = s_d3d11_blend_factors[bsel.blend_src_factor];
|
||||
bd.RenderTarget[0].DestBlend = s_d3d11_blend_factors[bsel.blend_dst_factor];
|
||||
bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
|
||||
if (bsel.accu_blend)
|
||||
{
|
||||
bd.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||
bd.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
|
||||
}
|
||||
else if (bsel.blend_mix)
|
||||
bd.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||
}
|
||||
|
||||
if (bsel.wr) bd.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_RED;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
bool s_nativeres;
|
||||
static CRCHackLevel s_crc_hack_level = CRCHackLevel::Full;
|
||||
|
||||
// hacks
|
||||
#define CRC_Partial (s_crc_hack_level >= CRCHackLevel::Partial)
|
||||
#define CRC_Full (s_crc_hack_level >= CRCHackLevel::Full)
|
||||
@@ -238,21 +237,6 @@ bool GSC_IkkiTousen(const GSFrameInfo& fi, int& skip)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_EvangelionJo(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if (skip == 0)
|
||||
{
|
||||
if ((CRC_Aggressive || !s_nativeres) && fi.TME && fi.TBP0 == 0x2BC0 || (fi.FBP == 0 || fi.FBP == 0x1180) && (fi.FPSM | fi.TPSM) == 0)
|
||||
{
|
||||
// Don't enable hack on native res if crc is below aggressive.
|
||||
// Removes blur/glow. Fixes ghosting when resolution is upscaled.
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_Oneechanbara2Special(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if (skip == 0)
|
||||
@@ -419,7 +403,7 @@ bool GSC_BurnoutGames(const GSFrameInfo& fi, int& skip)
|
||||
// 0x01dc0 01c00(MP) ntsc, 0x01f00 0x01d40(MP) ntsc progressive, 0x02200(MP) pal.
|
||||
// Yellow stripes.
|
||||
// Multiplayer tested only on Takedown.
|
||||
skip = 4;
|
||||
skip = GSConfig.UserHacks_AutoFlush ? 2 : 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -993,7 +977,6 @@ void GSState::SetupCrcHack()
|
||||
|
||||
// Upscaling hacks
|
||||
lut[CRC::DBZBT3] = GSC_DBZBT3;
|
||||
lut[CRC::EvangelionJo] = GSC_EvangelionJo;
|
||||
lut[CRC::FightingBeautyWulong] = GSC_FightingBeautyWulong;
|
||||
lut[CRC::GodOfWar2] = GSC_GodOfWar2;
|
||||
lut[CRC::IkkiTousen] = GSC_IkkiTousen;
|
||||
@@ -1054,7 +1037,7 @@ bool GSState::IsBadFrame()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_skip == 0 && GSConfig.UserHacks && (GSConfig.SkipDraw > 0))
|
||||
if (m_skip == 0 && GSConfig.SkipDrawEnd > 0)
|
||||
{
|
||||
if (fi.TME)
|
||||
{
|
||||
@@ -1062,8 +1045,8 @@ bool GSState::IsBadFrame()
|
||||
// General, often problematic post processing
|
||||
if (GSLocalMemory::m_psm[fi.TPSM].depth || GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))
|
||||
{
|
||||
m_skip_offset = GSConfig.SkipDrawOffset;
|
||||
m_skip = std::max(GSConfig.SkipDraw, m_skip_offset);
|
||||
m_skip_offset = GSConfig.SkipDrawStart;
|
||||
m_skip = GSConfig.SkipDrawEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,8 @@ GSRendererHW::GSRendererHW()
|
||||
, m_height(default_rt_size.y)
|
||||
, m_custom_width(1024)
|
||||
, m_custom_height(1024)
|
||||
, m_userhacks_ts_half_bottom(-1)
|
||||
, m_tc(new GSTextureCache(this))
|
||||
, m_src(nullptr)
|
||||
, m_hw_mipmap(GSConfig.HWMipmap)
|
||||
, m_userhacks_tcoffset(false)
|
||||
, m_userhacks_tcoffset_x(0)
|
||||
, m_userhacks_tcoffset_y(0)
|
||||
@@ -36,30 +34,8 @@ GSRendererHW::GSRendererHW()
|
||||
, m_reset(false)
|
||||
, m_lod(GSVector2i(0, 0))
|
||||
{
|
||||
m_mipmap = (m_hw_mipmap >= HWMipmapLevel::Basic);
|
||||
m_conservative_framebuffer = theApp.GetConfigB("conservative_framebuffer");
|
||||
|
||||
if (theApp.GetConfigB("UserHacks"))
|
||||
{
|
||||
m_userhacks_enabled_gs_mem_clear = !theApp.GetConfigB("UserHacks_Disable_Safe_Features");
|
||||
m_userHacks_enabled_unscale_ptln = !theApp.GetConfigB("UserHacks_Disable_Safe_Features");
|
||||
m_userhacks_align_sprite_X = theApp.GetConfigB("UserHacks_align_sprite_X");
|
||||
m_userHacks_merge_sprite = theApp.GetConfigB("UserHacks_merge_pp_sprite");
|
||||
m_userhacks_ts_half_bottom = theApp.GetConfigI("UserHacks_Half_Bottom_Override");
|
||||
m_userhacks_round_sprite_offset = theApp.GetConfigI("UserHacks_round_sprite_offset");
|
||||
m_userhacks_tcoffset_x = theApp.GetConfigI("UserHacks_TCOffsetX") / -1000.0f;
|
||||
m_userhacks_tcoffset_y = theApp.GetConfigI("UserHacks_TCOffsetY") / -1000.0f;
|
||||
m_userhacks_tcoffset = m_userhacks_tcoffset_x < 0.0f || m_userhacks_tcoffset_y < 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userhacks_enabled_gs_mem_clear = true;
|
||||
m_userHacks_enabled_unscale_ptln = true;
|
||||
m_userhacks_align_sprite_X = false;
|
||||
m_userHacks_merge_sprite = false;
|
||||
m_userhacks_ts_half_bottom = -1;
|
||||
m_userhacks_round_sprite_offset = 0;
|
||||
}
|
||||
m_mipmap = (GSConfig.HWMipmap >= HWMipmapLevel::Basic);
|
||||
SetTCOffset();
|
||||
|
||||
if (!GSConfig.UpscaleMultiplier) // Custom Resolution
|
||||
{
|
||||
@@ -67,13 +43,6 @@ GSRendererHW::GSRendererHW()
|
||||
m_custom_height = m_height = theApp.GetConfigI("resy");
|
||||
}
|
||||
|
||||
if (GSConfig.UpscaleMultiplier == 1) // hacks are only needed for upscaling issues.
|
||||
{
|
||||
m_userhacks_round_sprite_offset = 0;
|
||||
m_userhacks_align_sprite_X = false;
|
||||
m_userHacks_merge_sprite = false;
|
||||
}
|
||||
|
||||
m_dump_root = root_hw;
|
||||
GSTextureReplacements::Initialize(m_tc);
|
||||
}
|
||||
@@ -127,7 +96,7 @@ void GSRendererHW::SetScaling()
|
||||
//
|
||||
// m_large_framebuffer has been inverted to m_conservative_framebuffer, it isn't an option that benefits being enabled all the time for everyone.
|
||||
int fb_height = 1280;
|
||||
if (m_conservative_framebuffer)
|
||||
if (GSConfig.ConservativeFramebuffer)
|
||||
{
|
||||
fb_height = fb_width < 1024 ? std::max(512, crtc_size.y) : 1024;
|
||||
}
|
||||
@@ -183,6 +152,13 @@ void GSRendererHW::CustomResolutionScaling()
|
||||
printf("Frame buffer size set to %dx%d (%dx%d)\n", scissored_buffer_size.x, scissored_buffer_size.y, m_width, m_height);
|
||||
}
|
||||
|
||||
void GSRendererHW::SetTCOffset()
|
||||
{
|
||||
m_userhacks_tcoffset_x = std::max<s32>(GSConfig.UserHacks_TCOffsetX, 0) / -1000.0f;
|
||||
m_userhacks_tcoffset_y = std::max<s32>(GSConfig.UserHacks_TCOffsetY, 0) / -1000.0f;
|
||||
m_userhacks_tcoffset = m_userhacks_tcoffset_x < 0.0f || m_userhacks_tcoffset_y < 0.0f;
|
||||
}
|
||||
|
||||
GSRendererHW::~GSRendererHW()
|
||||
{
|
||||
delete m_tc;
|
||||
@@ -207,63 +183,6 @@ void GSRendererHW::SetGameCRC(u32 crc, int options)
|
||||
|
||||
m_hacks.SetGameCRC(m_game);
|
||||
|
||||
// Code for Automatic Mipmapping. Relies on game CRCs.
|
||||
m_hw_mipmap = GSConfig.HWMipmap;
|
||||
m_mipmap = (m_hw_mipmap >= HWMipmapLevel::Basic);
|
||||
if (m_hw_mipmap == HWMipmapLevel::Automatic)
|
||||
{
|
||||
switch (CRC::Lookup(crc).title)
|
||||
{
|
||||
case CRC::AceCombatZero:
|
||||
case CRC::AceCombat4:
|
||||
case CRC::AceCombat5:
|
||||
case CRC::ApeEscape2:
|
||||
case CRC::Barnyard:
|
||||
case CRC::BrianLaraInternationalCricket:
|
||||
case CRC::DarkCloud:
|
||||
case CRC::DestroyAllHumans:
|
||||
case CRC::DestroyAllHumans2:
|
||||
case CRC::FIFA03:
|
||||
case CRC::FIFA04:
|
||||
case CRC::FIFA05:
|
||||
case CRC::HarryPotterATCOS:
|
||||
case CRC::HarryPotterATGOF:
|
||||
case CRC::HarryPotterATHBP:
|
||||
case CRC::HarryPotterATPOA:
|
||||
case CRC::HarryPotterOOTP:
|
||||
case CRC::ICO:
|
||||
case CRC::Jak1:
|
||||
case CRC::Jak3:
|
||||
case CRC::JurassicPark:
|
||||
case CRC::LegacyOfKainDefiance:
|
||||
case CRC::NicktoonsUnite:
|
||||
case CRC::Persona3:
|
||||
case CRC::ProjectSnowblind:
|
||||
case CRC::Quake3Revolution:
|
||||
case CRC::RatchetAndClank:
|
||||
case CRC::RatchetAndClank2:
|
||||
case CRC::RatchetAndClank3:
|
||||
case CRC::RatchetAndClank4:
|
||||
case CRC::RatchetAndClank5:
|
||||
case CRC::RickyPontingInternationalCricket:
|
||||
case CRC::Shox:
|
||||
case CRC::SlamTennis:
|
||||
case CRC::SoTC:
|
||||
case CRC::SoulReaver2:
|
||||
case CRC::TheIncredibleHulkUD:
|
||||
case CRC::TombRaiderAnniversary:
|
||||
case CRC::TribesAerialAssault:
|
||||
case CRC::Whiplash:
|
||||
m_hw_mipmap = HWMipmapLevel::Basic;
|
||||
m_mipmap = true;
|
||||
break;
|
||||
default:
|
||||
m_hw_mipmap = HWMipmapLevel::Off;
|
||||
m_mipmap = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GSTextureReplacements::GameChanged();
|
||||
}
|
||||
|
||||
@@ -297,6 +216,13 @@ void GSRendererHW::Reset()
|
||||
GSRenderer::Reset();
|
||||
}
|
||||
|
||||
void GSRendererHW::UpdateSettings(const Pcsx2Config::GSOptions& old_config)
|
||||
{
|
||||
GSRenderer::UpdateSettings(old_config);
|
||||
m_mipmap = (GSConfig.HWMipmap >= HWMipmapLevel::Basic);
|
||||
SetTCOffset();
|
||||
}
|
||||
|
||||
void GSRendererHW::VSync(u32 field, bool registers_written)
|
||||
{
|
||||
if (m_reset)
|
||||
@@ -544,7 +470,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba)
|
||||
read_ba = (tex_pos > 112 && tex_pos < 144);
|
||||
|
||||
bool half_bottom = false;
|
||||
switch (m_userhacks_ts_half_bottom)
|
||||
switch (GSConfig.UserHacks_HalfBottomOverride)
|
||||
{
|
||||
case 0:
|
||||
// Force Disabled.
|
||||
@@ -572,9 +498,30 @@ void GSRendererHW::ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba)
|
||||
//
|
||||
// 32bits emulation means we can do the effect once but double the size.
|
||||
// Test cases: Crash Twinsantiy and DBZ BT3
|
||||
const int height_delta = m_src->m_valid_rect.height() - m_r.height();
|
||||
// Test Case: NFS: HP2 splits the effect h:256 and h:192 so 64
|
||||
half_bottom = abs(height_delta) <= 64;
|
||||
// Other games: Midnight Club 3 headlights, black bar in Xenosaga 3 dialogue,
|
||||
// Firefighter FD18 fire occlusion, PSI Ops half screen green overlay, Lord of the Rings - Two Towers,
|
||||
// Demon Stone , Sonic Unleashed, Lord of the Rings Two Towers,
|
||||
// Superman Shadow of Apokolips, Matrix Path of Neo, Big Mutha Truckers
|
||||
|
||||
int maxvert = 0;
|
||||
int minvert = 4096;
|
||||
for (size_t i = 0; i < count; i ++)
|
||||
{
|
||||
int YCord = 0;
|
||||
|
||||
if (!PRIM->FST)
|
||||
YCord = (int)((1 << m_context->TEX0.TH) * (v[i].ST.T / v[i].RGBAQ.Q));
|
||||
else
|
||||
YCord = (v[i].V >> 4);
|
||||
|
||||
if (maxvert < YCord)
|
||||
maxvert = YCord;
|
||||
if (minvert > YCord)
|
||||
minvert = YCord;
|
||||
}
|
||||
|
||||
half_bottom = minvert == 0 && m_r.height() <= maxvert;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -753,7 +700,7 @@ GSVector4i GSRendererHW::ComputeBoundingBox(const GSVector2& rtscale, const GSVe
|
||||
void GSRendererHW::MergeSprite(GSTextureCache::Source* tex)
|
||||
{
|
||||
// Upscaling hack to avoid various line/grid issues
|
||||
if (m_userHacks_merge_sprite && tex && tex->m_target && (m_vt.m_primclass == GS_SPRITE_CLASS))
|
||||
if (GSConfig.UserHacks_MergePPSprite && tex && tex->m_target && (m_vt.m_primclass == GS_SPRITE_CLASS))
|
||||
{
|
||||
if (PRIM->FST && GSLocalMemory::m_psm[tex->m_TEX0.PSM].fmt < 2 && ((m_vt.m_eq.value & 0xCFFFF) == 0xCFFFF))
|
||||
{
|
||||
@@ -1249,6 +1196,20 @@ void GSRendererHW::RoundSpriteOffset()
|
||||
|
||||
void GSRendererHW::Draw()
|
||||
{
|
||||
if (s_dump && (s_n >= s_saven))
|
||||
{
|
||||
std::string s;
|
||||
|
||||
// Dump Register state
|
||||
s = format("%05d_context.txt", s_n);
|
||||
|
||||
m_env.Dump(m_dump_root + s);
|
||||
m_context->Dump(m_dump_root + s);
|
||||
|
||||
// Dump vertices
|
||||
s = format("%05d_vertex.txt", s_n);
|
||||
DumpVertices(m_dump_root + s);
|
||||
}
|
||||
if (IsBadFrame())
|
||||
{
|
||||
GL_INS("Warning skipping a draw call (%d)", s_n);
|
||||
@@ -1288,13 +1249,14 @@ void GSRendererHW::Draw()
|
||||
|
||||
u32 fm = context->FRAME.FBMSK;
|
||||
u32 zm = context->ZBUF.ZMSK || context->TEST.ZTE == 0 ? 0xffffffff : 0;
|
||||
const u32 fm_mask = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk;
|
||||
|
||||
// Note required to compute TryAlphaTest below. So do it now.
|
||||
if (PRIM->TME && tex_psm.pal > 0)
|
||||
m_mem.m_clut.Read32(context->TEX0, env.TEXA);
|
||||
|
||||
// Test if we can optimize Alpha Test as a NOP
|
||||
context->TEST.ATE = context->TEST.ATE && !GSRenderer::TryAlphaTest(fm, zm);
|
||||
context->TEST.ATE = context->TEST.ATE && !GSRenderer::TryAlphaTest(fm, fm_mask, zm);
|
||||
|
||||
context->FRAME.FBMSK = fm;
|
||||
context->ZBUF.ZMSK = zm != 0;
|
||||
@@ -1310,7 +1272,7 @@ void GSRendererHW::Draw()
|
||||
// Depth is always pass/fail (no read) and write are discarded (tekken 5). (Note: DATE is currently implemented with a stencil buffer => a depth/stencil buffer)
|
||||
(zm != 0 && m_context->TEST.ZTST <= ZTST_ALWAYS && !m_context->TEST.DATE) ||
|
||||
// Depth will be written through the RT
|
||||
(context->FRAME.FBP == context->ZBUF.ZBP && !PRIM->TME && zm == 0 && fm == 0 && context->TEST.ZTE)
|
||||
(context->FRAME.FBP == context->ZBUF.ZBP && !PRIM->TME && zm == 0 && (fm & fm_mask) == 0 && context->TEST.ZTE)
|
||||
);
|
||||
|
||||
if (no_rt && no_ds)
|
||||
@@ -1424,7 +1386,7 @@ void GSRendererHW::Draw()
|
||||
|
||||
// upload the full chain (with offset) for the hash cache, in case some other texture uses more levels
|
||||
// for basic mipmapping, we can get away with just doing the base image, since all the mips get generated anyway.
|
||||
hash_lod_range = GSVector2i(m_lod.x, (m_hw_mipmap == HWMipmapLevel::Full) ? mxl : m_lod.x);
|
||||
hash_lod_range = GSVector2i(m_lod.x, (GSConfig.HWMipmap == HWMipmapLevel::Full) ? mxl : m_lod.x);
|
||||
|
||||
MIP_CLAMP.MINU >>= m_lod.x;
|
||||
MIP_CLAMP.MINV >>= m_lod.x;
|
||||
@@ -1449,7 +1411,7 @@ void GSRendererHW::Draw()
|
||||
TextureMinMaxResult tmm = GetTextureMinMax(TEX0, MIP_CLAMP, m_vt.IsLinear());
|
||||
|
||||
m_src = tex_psm.depth ? m_tc->LookupDepthSource(TEX0, env.TEXA, tmm.coverage) :
|
||||
m_tc->LookupSource(TEX0, env.TEXA, tmm.coverage, (m_hw_mipmap >= HWMipmapLevel::Basic ||
|
||||
m_tc->LookupSource(TEX0, env.TEXA, tmm.coverage, (GSConfig.HWMipmap >= HWMipmapLevel::Basic ||
|
||||
GSConfig.UserHacks_TriFilter == TriFiltering::Forced) ? &hash_lod_range : nullptr);
|
||||
|
||||
int tw = 1 << TEX0.TW;
|
||||
@@ -1504,7 +1466,7 @@ void GSRendererHW::Draw()
|
||||
}
|
||||
|
||||
// Round 2
|
||||
if (IsMipMapActive() && m_hw_mipmap == HWMipmapLevel::Full && !tex_psm.depth && !m_src->m_from_hash_cache)
|
||||
if (IsMipMapActive() && GSConfig.HWMipmap == HWMipmapLevel::Full && !tex_psm.depth && !m_src->m_from_hash_cache)
|
||||
{
|
||||
// Upload remaining texture layers
|
||||
const GSVector4 tmin = m_vt.m_min.t;
|
||||
@@ -1543,7 +1505,7 @@ void GSRendererHW::Draw()
|
||||
&& draw_sprite_tex && m_src->m_32_bits_fmt;
|
||||
|
||||
// Okami mustn't call this code
|
||||
if (m_texture_shuffle && m_vertex.next < 3 && PRIM->FST && (m_context->FRAME.FBMSK == 0))
|
||||
if (m_texture_shuffle && m_vertex.next < 3 && PRIM->FST && ((m_context->FRAME.FBMSK & fm_mask) == 0))
|
||||
{
|
||||
// Avious dubious call to m_texture_shuffle on 16 bits games
|
||||
// The pattern is severals column of 8 pixels. A single sprite
|
||||
@@ -1655,15 +1617,6 @@ void GSRendererHW::Draw()
|
||||
|
||||
std::string s;
|
||||
|
||||
if (s_n >= s_saven)
|
||||
{
|
||||
// Dump Register state
|
||||
s = format("%05d_context.txt", s_n);
|
||||
|
||||
m_env.Dump(m_dump_root + s);
|
||||
m_context->Dump(m_dump_root + s);
|
||||
}
|
||||
|
||||
if (s_savet && s_n >= s_saven && m_src)
|
||||
{
|
||||
s = format("%05d_f%lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
|
||||
@@ -1711,7 +1664,7 @@ void GSRendererHW::Draw()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_userhacks_enabled_gs_mem_clear)
|
||||
if (!GSConfig.UserHacks_DisableSafeFeatures)
|
||||
{
|
||||
// Constant Direct Write without texture/test/blending (aka a GS mem clear)
|
||||
if ((m_vt.m_primclass == GS_SPRITE_CLASS) && !PRIM->TME // Direct write
|
||||
@@ -1737,7 +1690,7 @@ void GSRendererHW::Draw()
|
||||
GSVertex* v = &m_vertex.buff[0];
|
||||
|
||||
// Hack to avoid vertical black line in various games (ace combat/tekken)
|
||||
if (m_userhacks_align_sprite_X)
|
||||
if (GSConfig.UserHacks_AlignSpriteX)
|
||||
{
|
||||
// Note for performance reason I do the check only once on the first
|
||||
// primitive
|
||||
@@ -1763,7 +1716,7 @@ void GSRendererHW::Draw()
|
||||
// Noting to do if no texture is sampled
|
||||
if (PRIM->FST && draw_sprite_tex)
|
||||
{
|
||||
if ((m_userhacks_round_sprite_offset > 1) || (m_userhacks_round_sprite_offset == 1 && !m_vt.IsLinear()))
|
||||
if ((GSConfig.UserHacks_RoundSprite > 1) || (GSConfig.UserHacks_RoundSprite == 1 && !m_vt.IsLinear()))
|
||||
{
|
||||
if (m_vt.IsLinear())
|
||||
RoundSpriteOffset<true>();
|
||||
@@ -1789,7 +1742,7 @@ void GSRendererHW::Draw()
|
||||
|
||||
//
|
||||
|
||||
if (fm != 0xffffffff && rt)
|
||||
if ((fm & fm_mask) != fm_mask && rt)
|
||||
{
|
||||
//rt->m_valid = rt->m_valid.runion(r);
|
||||
rt->UpdateValidity(m_r);
|
||||
@@ -1888,9 +1841,10 @@ void GSRendererHW::Hacks::SetGameCRC(const CRC::Game& game)
|
||||
m_oo = m_oo_map[hash];
|
||||
m_cu = m_cu_map[hash];
|
||||
|
||||
if (game.flags & CRC::PointListPalette)
|
||||
if (GSConfig.PointListPalette)
|
||||
{
|
||||
ASSERT(m_oi == NULL);
|
||||
if (m_oi)
|
||||
Console.Warning("Overriding m_oi with PointListPalette");
|
||||
|
||||
m_oi = &GSRendererHW::OI_PointListPalette;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,6 @@ private:
|
||||
int m_height;
|
||||
int m_custom_width;
|
||||
int m_custom_height;
|
||||
int m_userhacks_ts_half_bottom;
|
||||
|
||||
bool m_conservative_framebuffer;
|
||||
bool m_userhacks_align_sprite_X;
|
||||
bool m_userhacks_enabled_gs_mem_clear;
|
||||
bool m_userHacks_merge_sprite;
|
||||
|
||||
static constexpr float SSR_UV_TOLERANCE = 1.0f;
|
||||
|
||||
@@ -144,12 +138,10 @@ protected:
|
||||
GSTextureCache* m_tc;
|
||||
GSVector4i m_r;
|
||||
GSTextureCache::Source* m_src;
|
||||
HWMipmapLevel m_hw_mipmap;
|
||||
|
||||
virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0;
|
||||
|
||||
int m_userhacks_round_sprite_offset;
|
||||
bool m_userHacks_enabled_unscale_ptln;
|
||||
void SetTCOffset();
|
||||
|
||||
bool m_userhacks_tcoffset;
|
||||
float m_userhacks_tcoffset_x;
|
||||
@@ -185,6 +177,7 @@ public:
|
||||
GSVector2i GetTargetSize();
|
||||
|
||||
void Reset() override;
|
||||
void UpdateSettings(const Pcsx2Config::GSOptions& old_config) override;
|
||||
void VSync(u32 field, bool registers_written) override;
|
||||
|
||||
GSTexture* GetOutput(int i, int& y_offset) override;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user