Compare commits

...
145 Commits
Author SHA1 Message Date
RedDevilus 38ff521851 GameDB: Megaman + Nicktoons
Megaman X - Command Mission flickering FMV fix and fix for the lighting in the game Nicktoons Unite!
2022-03-22 22:02:30 +00:00
RedDevilus 34de1bffc6 GameDB: Remove outdated comments
The gameDB still had some leftover comments that aren't true anymore. In the past before 1.7.2002 / https://github.com/PCSX2/pcsx2/pull/3936 you needed to use full boot to correctly pass your chosen BIOS language to be piped to the game. Basically fast boot defaulted to the first entry in the available language list.
Full boot:
If you want to see BIOS logo - Good
Region check - Bad

Fast boot:
Immediately jump into the game - Good
Skips region check - Good
Now acts like full boot for languages - Good
2022-03-22 20:58:02 +00:00
Connor McLaughlin 8dc1592278 GSDumpReplayer: Fix ReadFIFO2 packet executing on wrong thread 2022-03-22 16:50:31 +00:00
Mrlinkwii 5b86205349 Gamedb: add 'VUSyncHack' to Totally Spies! Totally Party 2022-03-22 14:45:35 +00:00
Mrlinkwii 0d4fbd540e Gamedb: Fix 'SLES-54453' title 2022-03-22 14:27:39 +00:00
Connor McLaughlin b9edabc236 Qt: Fix incorrect setting binding for display linear 2022-03-22 13:38:26 +00:00
Connor McLaughlin 180d9ae9c9 Qt: Correct EE/IOP console defaults 2022-03-22 13:38:26 +00:00
Connor McLaughlin 80cc2f0cb7 Qt: Log machine caps on startup 2022-03-22 13:38:26 +00:00
Connor McLaughlin 1927896442 GS: Fix some edge cases with fbfetch
Second alpha pass with A masked, DATE enabled, etc.
2022-03-21 20:24:09 +00:00
RedDevilus bf9c1176b6 GameDB: Fix Midnightclub 3 + Add Evangelion Jo
Special texture to:
Midnight club 3
Evangelion - Jo
2022-03-21 20:23:54 +00:00
Tzerinas 166156519a GameDB: Fixes to TeamICO games.
Adds the Software Renderer FMV hack to ICO and Half-Pixel Offset (Vertex) to both games.
2022-03-21 20:16:46 +00:00
lightningterror d89daa1b25 misc: A few more 32bit cleanups. 2022-03-21 20:56:03 +01:00
lightningterror efc17f265c readme: Update to reflect recent drop of 32bit. 2022-03-21 20:28:33 +01:00
lightningterror 8427e6fd3e emitter test: Cleanup 32bit code. 2022-03-21 20:21:36 +01:00
lightningterror f1ac712eba build: Remove _M_X86_64, __M_X86_64, _M_X86_32 defines.
32bit cleanup.
2022-03-21 20:21:36 +01:00
lightningterror 0d4394a749 core: Clean up 32bit code. 2022-03-21 20:21:36 +01:00
lightningterror 9dac598113 common: Clean up 32bit code. 2022-03-21 20:21:36 +01:00
lightningterror 6db573d255 emitter: Clean up 32bit code. 2022-03-21 20:21:36 +01:00
Connor McLaughlin 9b21f31b0d GS/Vulkan: Fix crash is vertex/index buffer causes exec 2022-03-21 18:36:31 +00:00
lightningterror 2fedecb809 GS-hw: Purge Evangelion crc hack.
It's broken, HPO special does the job.
Someone should add it to the hw gamefixes.
2022-03-21 17:25:25 +01:00
PCSX2 Bot b24a8c70e3 PAD: Update to latest controller database. 2022-03-21 17:14:41 +01:00
RedDevilus d6684efd26 GameDB: GS HW Batch X
Relevant:
Bully
Colosseum - Road to Freedom
Dark Chronicle (Dark Cloud 2)
Killzone
God of War
Gun
Midnight Club 3
Mortal Kombat - Deadly Alliance
Need for Speed Carbon / Most Wanted / Undercover
Prince of Persia - Sand of Time / The Two Thrones / Warrior Within
Resident Evil 4 (BioHazard 4)
Thrillville / Off the Rails
2022-03-21 15:04:45 +00:00
TellowKrinkle 644241959a GS: Fix inverted DSB check 2022-03-21 02:33:38 +00:00
TellowKrinkle 273c1b1922 GS: Clean up leftover definitions
Accidentally leftover during the blend op refactor
2022-03-21 02:33:38 +00:00
Connor McLaughlin 45682c382f GS: Add NO_COLOR flag to PS (depth-only) 2022-03-20 23:41:33 +00:00
Connor McLaughlin 4e6b86f8f4 GS/Vulkan: Use VK_ARM_rasterization_order_attachment_access if available 2022-03-20 23:41:33 +00:00
Connor McLaughlin a6b4ca69db GS/Vulkan: Support rendering without D32S8 2022-03-20 23:41:33 +00:00
Connor McLaughlin 6b32e00097 GS: Make factors part of blend state
Instead of using the blend map indices.
2022-03-20 23:41:33 +00:00
Connor McLaughlin 19d310475b GS: Draw alpha pass when dual source blend is missing 2022-03-20 23:41:33 +00:00
Connor McLaughlin a8b9df3952 GS: Utilize GL_EXT_framebuffer_fetch where available 2022-03-20 23:41:33 +00:00
Connor McLaughlin bb75c78c1a GS: Add option to disable texture barriers/geometry shaders 2022-03-20 23:41:33 +00:00
Mrlinkwii 57ea137982 Gamedb: add missing serials 2022-03-20 23:25:42 +00:00
refractionpcsx2 9721ed0fb3 GS: Use pixel format mask for FBMSK checks 2022-03-20 23:24:42 +00:00
Mrlinkwii 224863fbd5 GameDB: adds 'VUSyncHack' to Panzer Elite Action - Fields of Glory 2022-03-20 17:40:43 +00:00
Mrlinkwii 1d459d8fab Gamedb: Remove VU rounding form 'Hitman - Contracts' 2022-03-20 15:30:00 +00:00
arcum42@gmail.com 33e0ac729e Core: Remove memcmp_mmx. 2022-03-20 12:54:58 +00:00
Connor McLaughlin 268ecf42c3 Build: Remove 32bit configs from vsprops 2022-03-20 12:53:42 +00:00
refractionpcsx2 708281f00b GS: Properly detect 16bit format on Texture Shuffle + Convert 2022-03-20 06:49:16 +00:00
RedDevilus 56b68a50e9 GameDB: Even more GS HW Fixes
Affects:
Ape Escape 3
Armored Core Last Raven
Berserk
Forever Kingdom
Front Mission 4 / 5
Need For Speed Underground 1 / 2
Kings Field 4 - The Ancient City
Test Drive Unlimited
Jak 2 / 3 / X
2022-03-20 05:57:18 +00:00
RedDevilus e4048dc2dd CI: Update labeler to expand WX 2022-03-20 04:50:29 +00:00
TheLastRar 5949c772d1 Qt: Fix bugs relating to per-game settings 2022-03-20 04:13:45 +00:00
RafaelTrepaUnCarballo 63998b64cc fix comment format 2022-03-20 04:10:11 +00:00
RafaelTrepaUnCarballo fbb3ea142a Add files via upload
Added gshack (wild arms hack) for all releases of Wild Arms Alter Code F
2022-03-20 04:10:11 +00:00
Tyler Wilding 435f760b5d GameDB: remove duplicate YAML keys 2022-03-20 04:03:03 +00:00
Tyler Wilding f47129bd72 deps: update rapid-yaml to v0.4.1 2022-03-20 04:03:03 +00:00
Tyler Wilding aa42acfe22 common: fix method name and clarify some behaviour 2022-03-20 04:03:03 +00:00
Tyler Wilding ddfe6ac5c1 memcard: update ryml parsing for folder memory cards
also make the file handling safer
2022-03-20 04:03:03 +00:00
Tyler Wilding 624dff1b96 gamedb: move away from deprecated ryml::parse func 2022-03-20 04:03:03 +00:00
Tyler Wilding 8d498b564d deps: update rapid-yaml to latest commit
has a bug fix that we hit in folder memory cards
2022-03-20 04:03:03 +00:00
Christian Kenny 26561261bc Core: Remove unused code 2022-03-20 04:00:27 +00:00
Connor McLaughlin 44728be719 Misc: Fix incorrect printf of std::string_view 2022-03-20 04:00:13 +00:00
Tzerinas 678bb1218b GameDB: Add fixes for Tak Games
SoftwareRendererFMVHack for Tak 1&2, Half-Pixel Offset (Texture) for Guardians of Gross.
2022-03-20 04:00:04 +00:00
RedDevilus c496e80eac PCSX2-GUI: Rename skipdraw and IDC for Partial Invalidation
Skipdraw and SkipDrawOffset isn't obvious to what it is. SkipDrawStart and SkipDrawEnd makes it obvious it's a range of values.
Also forgot to change the IDC for Disabling Partial Invalidation.
2022-03-20 03:59:38 +00:00
refractionpcsx2 269db188d0 Build: Remove 32bit from CMake. 2022-03-20 00:39:39 +00:00
refractionpcsx2 f5afbfd4f5 GS: Remove 32bit code from SW renderer 2022-03-20 00:39:39 +00:00
refractionpcsx2 ccd86a242c EE/VU JIT: Remove 32bit code 2022-03-20 00:39:39 +00:00
refractionpcsx2 42a5cb7ad2 Build: Remove 32bit targets from VS solution 2022-03-20 00:39:39 +00:00
Tyler Wilding 6977323d88 ci: remove redundant words from job names
its always 64bit now!
2022-03-19 21:19:48 +00:00
Tyler Wilding 7b1d03d45a ci: add link to previous release page in discord announcement 2022-03-19 21:19:48 +00:00
Tyler Wilding 8a4f1ef51a ci: stop building 32-bit
At this point -- not cleaning up the solution files / etc, only our actions.

Until the 32bit code itself is removed, we should still have an easy way to flip these back on.
2022-03-19 21:19:48 +00:00
Mrlinkwii 9b50bb2e81 Gamedb: remove no longer needed comments 2022-03-19 15:56:06 +00:00
Connor McLaughlin 4f27d779a1 GS/DX11: Fix incorrect format check for compressed textures 2022-03-19 03:57:20 +00:00
RedDevilus 73c6353351 Qt: Partial Invalidation
Some missing strings from the renaming.
2022-03-18 23:47:21 +00:00
Immersion95 f571b66a43 GameDB: HW fixes for Mega Man/Rockman X7 + Clamping mode fix (#5694) 2022-03-18 20:53:48 +00:00
BuildTools 901664ba44 GameDB: Rename fastTextureInvalidation
Attempt 2 renames fastTextureInvalidation to disablePartialInvalidation for more consistency with the new GUI name.
2022-03-18 13:52:36 +00:00
Immersion95 02012b5491 GameDB: HW fixes for Rockman X8
SoftwareRendererFMVHack for the NTSC-J & NTSC-K version of Megaman X8
2022-03-18 10:24:58 +00:00
TellowKrinkle 4f57e40c91 GS:SW: Fix lod on x64 2022-03-18 03:59:51 -05:00
RedDevilus 832e536a9e GameDB: Haunting Ground + 50 Cent and Level 5
Ranging from blurriness to font artifacts.
2022-03-18 08:44:33 +00:00
BuildTools c2316ca5bc GUI: Rename Fast Texture Invalidation
Renames Fast Texture Invalidation to Disable Partial Invalidation.

Update GraphicsSettingsWidget.ui
2022-03-18 02:11:12 +00:00
refractionpcsx2 3535edcfa1 GameDB: Add partial preloading to Stolen 2022-03-17 18:40:11 +00:00
KrossX a4932ed0f1 GameDB: Add DMABusy fix to Shining Wind 2022-03-17 14:33:07 +00:00
seta-sanandRedDevilus 515d9040a1 GameDB: Add gsHWFixes for Tales of Symphonia
Co-Authored-By: RedDevilus <martensregis@gmail.com>
2022-03-17 09:16:20 +00:00
Connor McLaughlin fe3a743814 ImGuiManager: Cap usage percents to 100% 2022-03-17 09:10:12 +00:00
Connor McLaughlin 8e08cd772b PerformanceMetrics: Add GPU time 2022-03-17 09:10:12 +00:00
Connor McLaughlin 206f80c5f4 GS: Compute SW CPU per-thread not per-draw 2022-03-17 09:10:12 +00:00
RedDevilus c6ce380042 GameDB: More GS HW Fixes
Some extra comments for Monster Lab and SSX Tricky.

New entries:

- Alter Echo
- Beyond Good and Evil
- Dragon Ball Z - Budokai Tenkaichi 2
- Fatal Frame 1 / 3
- Ghost in the Shell - Stand Alone Complex
- Global Defence Force
- Xenosaga 1 / 2 / 3
2022-03-17 08:57:58 +00:00
lightningterror 939d98d660 Qt: Allow skipdraw up to 10k max. 2022-03-17 02:44:14 +01:00
lightningterror c9a3420f85 GS: Fix Wunused-variable warnings. 2022-03-17 00:50:28 +01:00
refractionpcsx2 9a1a399bac GameDB: Add a bunch of hw fixes and upscaling fixes 2022-03-16 23:40:53 +00:00
RedDevilus c8aac1dca9 GameDB: Ace Combat + Soul Calibur + Metal Gear Solid Series
Missing mipmap from the Europese Ace Combat Zero/4/5, Align Sprite for them and Round Sprite. Align Sprite for SoulCalibur series.
Metal Gear 2 substance gets round sprite for font and Metal Gear 3 Subsistence gets Special (Texture) for blurriness.
2022-03-16 22:38:39 +00:00
lightningterror 14c17916f5 GS-hw: Optimize blending equations based on alpha value.
It will allow us to use free sw blending without texture barriers.

Will be especially helpful for opengl/vulkan.
2022-03-16 15:17:00 +01:00
RedDevilus 7b0576d7cc GameDB: Dog Island and COD Final Fronts (#5671) 2022-03-16 07:24:05 +00:00
Blackbird88 ecb118d5af GameDB: Add gsHWFixes for GTA LCS/VCS (#5662)
Co authored by @Blackbird88
2022-03-15 20:22:19 +00:00
RedDevilus efbf187b35 GameDB: Upscaling GS Batch 2
Adds second batch of upscaling fixes.
2022-03-15 20:21:15 +00:00
Tzerinas 2ea3feba90 GameDB: Add Upscaling Fixes to Onimusha 3
Adds Half-Pixel Offset: Special (Texture) and Round Sprite (Full) to Onimusha 3: Demon Siege
2022-03-15 20:19:06 +00:00
Tzerinas f265257efb GameDB: Add Software FMV to Grandia 2 and Xtreme
Adds the SoftwareRendererFMV hack to Grandia 2 and Xtreme. Also adjusted titles.
2022-03-15 20:18:43 +00:00
lightningterror 13cc0caed7 GS Debugger: Fix hw hacks behavior not properly disabling. 2022-03-15 15:46:24 +01:00
refractionpcsx2 2068240e1a GS: Adjust Auto Flush to catch edge cases
Affected Beyond Good and Evil water
2022-03-15 10:15:21 +00:00
Tzerinas 7f5901f022 GameDB: GS HW renderer fixes for Tales of the Abyss
Description of Changes
Add Half-Pixel Offset: Special (Texture) to Tales of the Abyss.
2022-03-15 09:38:24 +00:00
Tokman5andTokman5 a022de6225 GameDB: Add gsHWFixes for Shutokou Battle 01. (#5659)
Co-authored-by: Tokman5 <isozin_1210@yahoo.co.jp>
2022-03-15 08:12:52 +00:00
RedDevilus f5570b7f40 GameDB: Rogue Galaxy
Adds half roundsprite to make upscaled HW more like software mode such as minimap while fighting.
2022-03-15 08:11:17 +00:00
RedDevilus 7e1c48694a GameDB: Upscaling GS Batch 1
Fixes the lint and adds a bunch of upscaling fixes.
2022-03-15 00:54:38 +00:00
lightningterror a546f61ea8 Qt: Fix Round sprite hack not applying. 2022-03-14 23:43:25 +01:00
PCSX2 Bot 7ecac10eee PAD: Update to latest controller database. 2022-03-14 22:20:49 +01:00
Mrlinkwii ee2e10e86b GameDB: correct and update serials 2022-03-14 19:15:50 +00:00
RedDevilus 7752f44a90 GameDB: Documentation
Add values for GameDB, GUI options and the default to easier make GameDB changes
2022-03-14 19:14:40 +00:00
refractionpcsx2 e01fc3eb47 GS: Loosen requirement for half bottom 2022-03-14 19:14:26 +00:00
SaltyBet 910c8190e0 GameDB: Added missing variants of NAMCO games 2022-03-14 15:47:02 +00:00
SaltyBet a62ccc0d69 GameDB: Auto GS HW renderer fixes for some NAMCO games
- Tekken 4
- Tekken 5
- Tekken Tag Tournament
2022-03-14 15:47:02 +00:00
Dreadmoth 4f47041108 GameDB: Metal Arms - Glitch in the System (PAL)
Force disable mVU Flag Hack to prevent SPS
2022-03-14 15:33:39 +00:00
Connor McLaughlin 16cfde0538 GS: Use single array for dump packets 2022-03-14 15:26:19 +00:00
Connor McLaughlin 6a15d46461 Qt: Improve boot filename autodetection 2022-03-14 15:26:19 +00:00
Connor McLaughlin 4331ae1925 VMManager: Support playing back GS dumps 2022-03-14 15:26:19 +00:00
Connor McLaughlin 4d85d916b7 GS: Move dump file loading to core 2022-03-14 15:26:19 +00:00
Connor McLaughlin 4f4b14dd4d GameList: Add GetEntryByCRC() 2022-03-14 15:26:19 +00:00
Connor McLaughlin 444e650711 StringUtil: Add StartsWithNoCase/EndsWithNoCase 2022-03-14 15:26:19 +00:00
refractionpcsx2 c65ccaa153 GS-Config: Clear missing manual GS fixes 2022-03-14 11:08:39 +00:00
Connor McLaughlin 6b54db9b75 GS/VertexTrace: Fix min/max when last provoking vertex unsupported
This was causing incorrect min/max alpha values due to the index swap,
which caused the sides of text boxes in KH to disappear (because the
alpha test optimized to always failing).

Closes #5639.
2022-03-14 08:47:32 +00:00
Mrlinkwii 3bab470db6 Docs : Add GS hardware fixes and MTVUSpeedHack 2022-03-13 18:33:37 +00:00
refractionpcsx2 adf01cb56a GS-Build: Fix Dump Verticles for linux 2022-03-13 05:01:51 +00:00
refractionpcsx2 bbe3af7f61 GS-Debug: Dump verticles with draws
- Move context dumping to the top so we see it as the game set, not after we've messed with it.
Thanks to tadanokojin for these changes
2022-03-13 03:46:16 +00:00
refractionpcsx2 3e7d32c807 GameDB: Give slightly clearer message for GS Fix override 2022-03-13 03:18:44 +00:00
refractionpcsx2 76e25cb738 GameDB: Add mipmapping/trilinear for Hot Shots/Everybody's Golf games 2022-03-13 02:34:29 +00:00
refractionpcsx2 8f0dc34847 GS: Improvements to MTBA address calculation 2022-03-13 01:55:08 +00:00
RedDevilus fc6ec2cc02 GameDB: Transformers Armada: Prelude to Energon
Adds missing VIFFIFO + force disabling MTVU for not getting black screen
2022-03-13 01:53:48 +00:00
refractionpcsx2 34b7b07ff8 GameDB: Added a whole host of auto GS HW renderer fixes 2022-03-13 01:53:15 +00:00
Connor McLaughlin 6c33b73cdd GS: Make TC offset changable without recreating 2022-03-12 20:48:51 +00:00
Connor McLaughlin 1e86ba4120 GS: Append game serial/name to dump filename 2022-03-12 20:48:51 +00:00
Connor McLaughlin 89c79aa6c3 GSDump: Add embedded screenshot 2022-03-12 20:48:51 +00:00
Connor McLaughlin 4ed748fa30 GSDump: Add extensible header and serial
Serial is used to apply hw fixes.
2022-03-12 20:48:51 +00:00
Connor McLaughlin 5569e94f41 GS: Make setting change detection more fine grained
Avoids the slower full restart when it's not needed.
2022-03-12 20:48:51 +00:00
Connor McLaughlin 892eec79ed Workflows: Fix lint-gamedb for gsHWFixes 2022-03-12 20:48:51 +00:00
Connor McLaughlin b248b4a8af GameDB: Add HW fixes for GTASA/GOW/GOW2 2022-03-12 20:48:51 +00:00
Connor McLaughlin 39fe467b64 GS: Purge CRCs of unused titles 2022-03-12 20:48:51 +00:00
Connor McLaughlin 1c301ec889 GS: Move point list palette to gamedb 2022-03-12 20:48:51 +00:00
Connor McLaughlin de5690ddcb GS: Move texture-inside-rt flag to gamedb 2022-03-12 20:48:51 +00:00
Connor McLaughlin f376c8f7ae GS: Remove second source of truth for HWMipmap 2022-03-12 20:48:51 +00:00
Connor McLaughlin 2e199d47a8 GS: Move automatic mipmapping override to gamedb 2022-03-12 20:48:51 +00:00
Connor McLaughlin 96269db93e GameDatabase: Add ability to override GS fixes 2022-03-12 20:48:51 +00:00
Connor McLaughlin d35db63d73 GS: Reference GSConfig instead of using theApp
Removes multiple sources of truth, enables overrides.
2022-03-12 20:48:51 +00:00
refractionpcsx2 9d003486c2 GS-hw: Attempt to improve half screen detection 2022-03-12 12:28:18 +00:00
refractionpcsx2 0c4b85980c GS: Support local to local transfers that overwrite themselves 2022-03-12 12:27:43 +00:00
Connor McLaughlin 5961db6b9b GS/Vulkan: Elide render pass restarts on depth buffer toggle 2022-03-12 12:22:51 +00:00
Connor McLaughlin d0039c2920 Gif_Unit: Vectorize analyzeTag() 2022-03-12 12:10:32 +00:00
TellowKrinkle 5bdec2f532 x86emitter: Fix x64 8-bit rmw codegen 2022-03-11 12:59:57 +00:00
refractionpcsx2 fd758bb307 GameDB: Added MTVU disable to InstantVU off games 2022-03-11 10:25:15 +00:00
refractionpcsx2 a11d09ebdf Git: Update GameDB Validation script 2022-03-11 10:25:15 +00:00
refractionpcsx2 d294064da6 GameDB: Disable MTVU on T-Bit games 2022-03-11 10:25:15 +00:00
refractionpcsx2 fd4a5acc40 MTVU: Try to make T-Bit more reliable.
Add MTVUSpeedHack option to GameDB so it can be forcefully disabled
2022-03-11 10:25:15 +00:00
refractionpcsx2 05a7a61257 GS/Autoflush: Handle different page widths/arrangements 2022-03-11 10:24:26 +00:00
refractionpcsx2 90a4a11d49 GS: Add Auto Flush for Z buffer draws
Adjust Burnout CRC hack
2022-03-11 10:24:26 +00:00
lightningterror d9f914eb7c GS-hw: Move the Ad to As equation swap when alpha is masked to Basic level and higher on gl/vk.
Safer this way, otherwise need to take in to account when accumulation, non recursive, and blend mix is enabled, or manually enable them on Minimum level.

Everything that we need is enabled on Basic level.

Change is done for clamp 1 only.
2022-03-09 23:24:44 +01:00
TheLastRar 134242973b Config: Set a sane default value for HddSizeSectors 2022-03-09 10:07:54 +00:00
TheLastRar 92900d8dc8 Config: Fix manual subnet mask save/load 2022-03-09 10:07:54 +00:00
Ziemas 7a970e1d00 Filesystem: Properly convert stat return to bool.
Two of the overloads where wrong.
2022-03-09 09:33:51 +00:00
187 changed files with 7338 additions and 4347 deletions
+5
View File
@@ -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/**/*'
+4 -10
View File
@@ -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.
-1
View File
@@ -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)
+7 -10
View File
@@ -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
+10 -15
View File
@@ -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
View File
@@ -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
+2 -1
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -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,
+21
View File
@@ -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);
+80 -4
View File
@@ -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);
+27 -10
View File
@@ -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
+3 -35
View File
@@ -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)
-1
View File
@@ -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
-47
View File
@@ -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
-34
View File
@@ -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
View File
@@ -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];
+6 -5
View File
@@ -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
View File
@@ -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.
-8
View File
@@ -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
View File
@@ -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))
-5
View File
@@ -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);
+11
View File
@@ -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);
+5
View File
@@ -352,6 +352,11 @@ namespace Vulkan
}
}
void GraphicsPipelineBuilder::AddBlendFlags(u32 flags)
{
m_blend_state.flags |= flags;
}
void GraphicsPipelineBuilder::ClearBlendAttachments()
{
m_blend_attachments = {};
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+1 -6
View File
@@ -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>
-3
View File
@@ -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>
-4
View File
@@ -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];
}
+1 -1
View File
@@ -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);
}
-2
View File
@@ -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
-4
View File
@@ -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;
-5
View File
@@ -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!
-10
View File
@@ -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
-4
View File
@@ -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
View File
@@ -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};
+1 -2
View File
@@ -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
+2 -73
View File
@@ -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
-21
View File
@@ -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
-12
View File
@@ -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>
+1 -2
View File
@@ -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>
-12
View File
@@ -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>
+1 -2
View File
@@ -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>
-188
View File
@@ -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
+6 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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));
}
+6
View File
@@ -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
View File
@@ -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());
}
+4 -4
View File
@@ -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);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+10 -5
View File
@@ -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
+106 -13
View File
@@ -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>
+1 -1
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+111
View File
@@ -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()
+18
View File
@@ -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;
};
+14 -3
View File
@@ -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)
+1
View File
@@ -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();
+49 -13
View File
@@ -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;
}
+11
View File
@@ -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
+1 -1
View File
@@ -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;
}
+122
View File
@@ -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
View File
@@ -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;
};
+11 -1
View File
@@ -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;
+3
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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;
-58
View File
@@ -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
View File
@@ -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
View File
@@ -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();
};
+12
View File
@@ -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()
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
};
-52
View File
@@ -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
}
-30
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+12 -2
View File
@@ -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);
+21 -13
View File
@@ -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
}};
+119 -40
View File
@@ -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
+59 -5
View File
@@ -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);
+9 -7
View File
@@ -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
+2 -2
View File
@@ -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);
+14 -34
View File
@@ -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;
}
}
+7 -9
View File
@@ -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;
+23 -16
View File
@@ -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;
+4 -21
View File
@@ -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;
}
}
}
+70 -116
View File
@@ -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;
}
+2 -9
View File
@@ -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