Compare commits

...
106 Commits
Author SHA1 Message Date
Stenzekandrefractionpcsx2 bfc3d2e1d4 Patch: Rename le{short,word,double} to be{short,word,double}
MIPS is little endian, not big endian. Having little endian commands
suggests to the reader that the "normal" format is big endian, which is
obviously incorrect.
2023-05-25 16:47:36 +01:00
Stenzekandrefractionpcsx2 680affd1fe Common: Add ByteSwap.h
Provides a C++23-like std::byteswap implementation.
2023-05-25 16:47:36 +01:00
TellowKrinkleandrefractionpcsx2 ab1d2009a0 Core: Use 2MB stacks for µVU 2023-05-25 16:16:14 +01:00
lightningterror 8196f46721 GS-Metal: Fix Wunused-variable warnings. 2023-05-25 13:24:40 +02:00
Stenzekandrefractionpcsx2 44460365c0 GS/HW: Vectorize mem clears 2023-05-25 09:49:31 +01:00
Stenzekandrefractionpcsx2 38d9aa5e73 GS/HW: Detect row/page-based split clears
And turn them into a single mem clear.
2023-05-25 09:49:31 +01:00
descawedandrefractionpcsx2 830db2b326 GameDB: Fix missing textures in Galerians: Ash 2023-05-25 09:48:58 +01:00
refractionpcsx2 51165f6061 Patches: Fix parsing of double words. Expand error log. 2023-05-24 19:49:32 +01:00
Mrlinkwiiandrefractionpcsx2 2a9d38048e github: update issue templates 2023-05-24 17:44:47 +01:00
Stenzekandrefractionpcsx2 bba65b8a82 Patch: Discard patches with non-hex addresses/values 2023-05-24 12:24:47 +01:00
Stenzekandrefractionpcsx2 884086ba76 StringUtil: Fix incorrect value of endptr
And add associated unit tests.
2023-05-24 12:24:47 +01:00
Ty Lamontagneandrefractionpcsx2 1fa6614cd5 Achievements: Implement the ELF suffix hack from CDVD when hashing 2023-05-23 09:56:08 +01:00
Mrlinkwiiandlightningterror 57581724cd GameDB: add missing entries 2023-05-23 10:17:02 +02:00
lightningterror 0ae6f7efc5 GameDB: Add full mipmap with ps2 trilinear to 2002 FIFA World Cup.
Improves ground textures to match sw renderer.
2023-05-22 15:27:07 +02:00
Abel Briggsandrefractionpcsx2 d0346436fb LogSink: Log BIOS print syscall messages if EE console is enabled 2023-05-22 08:37:50 +01:00
JordanTheToasterandrefractionpcsx2 1b28980454 GameDB: HP COS Fixes
Fixes for Full mipmapping causing texture problems with Harrys and lighting being wonky at lower than full blending.
2023-05-21 15:48:25 +01:00
Stenzekandrefractionpcsx2 90a6088d61 GSRunner: Fix log file writing
Wasn't getting flushed/closed on shutdown.
2023-05-21 08:52:45 +01:00
TellowKrinkleandlightningterror 338a2beaf0 GS:MTL: Remove pre-10.14 fallback
We no longer support pre-10.14
2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror ff9a910c1a GS:MTL: Use GSTexture base class's clear tracking 2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror d88921bb58 GS: Remove ClearStencil from GSDevice
It's never used generically, and GSTexture's shared clear tracking doesn't support it
If anyone ever actually needs this, they should update GSTexture to make it properly tracked into a render pass load action
2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror c1f3f0a247 GS: Fix index expand buffer size
Expansion multiplies indices by 4 for vertices, so the maximum is 65535 / 4 = 16383
2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror df847835ad GS:MTL: Implement DrawMultiStretchRects 2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror 8aad1c78af GS:MTL: Remove hdr copy pipeline
No longer needed
2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror 7c97cf4799 GS:MTL: Implement InvalidateRenderTarget 2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror fd11523cf4 GS:MTL: Implement ClearSamplerCache 2023-05-20 10:59:23 +02:00
TellowKrinkleandlightningterror a293a9bd4b GS:GL: Fix GLContextAGL compile 2023-05-20 10:59:23 +02:00
refractionpcsx2 8de0eb3c06 GameDB: Readd software FMV fix for Onimusha Warlords (PAL) 2023-05-19 06:40:06 +01:00
refractionpcsx2 8bff172f0b GS: Extract end block address in to helper function 2023-05-19 06:40:06 +01:00
refractionpcsx2 7f26595804 GS-HW: Avoid clears with new targets 2023-05-19 06:40:06 +01:00
lightningterror 68ec70f24f GameDB: Add full mipmap with ps2 trilinear to Super Monkey Ball Adventure.
Improves textures to match sw renderer.
2023-05-18 21:41:59 +02:00
lightningterror 836591a44f GameDB: Correct a couple of regions for games.
From PAL-E to PAL-A.
From NTSC-J to NTSC-K.
2023-05-18 21:41:59 +02:00
refractionpcsx2 dd4ded3d4b GameDB: Add missing COP2 patches for Call of Duty Finest Hour 2023-05-16 23:16:13 +01:00
Mrlinkwiiandrefractionpcsx2 995e294856 GameDB : fixes for Bonus Demo 6 2023-05-16 19:55:03 +01:00
Stenzekandrefractionpcsx2 c4e623eec2 VMManager: Don't rescan symbols when swapping discs
The ELF isn't changing.
2023-05-16 12:58:19 +01:00
Stenzekandrefractionpcsx2 61253d8201 VMManager: Reload settings after shutting down
Prevents any whacky settings from the previous game hanging around until
the next one boots.
2023-05-16 12:58:19 +01:00
Stenzekandrefractionpcsx2 0f05967190 CommonHost: Purge and move functions to appropriate locations 2023-05-16 12:58:19 +01:00
Stenzekandrefractionpcsx2 ad0e469f87 Misc: Clang warning fixes 2023-05-16 12:58:19 +01:00
Stenzekandrefractionpcsx2 512d24cea6 Misc: More build system cleanups
Set UTF-8 source file format globally.
Set permissive/compliance mode globally.
Get rid of include of base 3rdparty directory, be explicit.
Get rid of duplicated properties.
Get rid of leftover plugin property files.
2023-05-16 12:58:19 +01:00
Stenzekandrefractionpcsx2 0850a3fab7 Misc: Support building without -fno-operator-names
Better to have standard compliance, and MSVC in conformance mode needs
it.
2023-05-16 12:58:19 +01:00
lightningterror 16db92526c GameDB: Add full mipmap with ps2 trilinear to Rally Shox.
Also add missing db entries.

Improves textures to match sw renderer.
2023-05-16 12:30:52 +02:00
lightningterror 30ad66e8f1 VMManager: Don't lookup the bios as a game.
Fixes the gamedb log falsely pasting that a bios
is not in the db.
2023-05-16 11:26:11 +02:00
refractionpcsx2 77f600a16c GameDB: Added round sprite fixes for Street Fighter Alpha/Zero 2023-05-16 01:20:45 +01:00
refractionpcsx2 d96bf7f951 GameDB: Add upscaling fixes for Vampire Darkstalkers Collection 2023-05-16 01:20:45 +01:00
refractionpcsx2 15948c2781 GS-HW: Allow recursive HW move with temp copy 2023-05-16 01:20:45 +01:00
refractionpcsx2 b0c744bd29 GS-HW: Invalidate local mem for whole texture on local->local copy 2023-05-16 01:20:45 +01:00
Stenzekandrefractionpcsx2 5eacfe1afb x86/microVU: Reference StateEnd instead of inlining state 2023-05-16 01:20:22 +01:00
refractionpcsx2 2f985b479e GS-TC: Delete fully dirtied old targets 2023-05-16 01:19:58 +01:00
PCSX2 Botandlightningterror e61d8f2f8f PAD: Update to latest controller database. 2023-05-15 19:22:33 +02:00
refractionpcsx2 f4e338f9fb Build: Fix GS Runner compilation.
Stuff got moved, GS Runner wasn't told :)
2023-05-14 02:45:30 +01:00
Mrlinkwiiandrefractionpcsx2 9509745be9 GameDB : add missing Gran Turismo fixes 2023-05-13 22:50:29 +01:00
JordanTheToasterandrefractionpcsx2 91b47134ad GameDB: Various fixes
Various fixes for Ace Combat 4 5 and Zero to fix broken upscaling on airburst and possibly other effects.
2023-05-13 16:43:16 +01:00
Stenzekandrefractionpcsx2 6426f4432e SPU2: Get rid of dynamic allocations 2023-05-13 16:39:40 +01:00
Stenzekandrefractionpcsx2 191ea50663 GS/HW: Fix GT4 render hack 2023-05-13 16:38:53 +01:00
Stenzekandrefractionpcsx2 7f5c0fca8f MSBuild: Fix lib/pdb output directory 2023-05-13 16:29:06 +01:00
refractionpcsx2 5f8798cf94 VMManager: Split reload game swap, avoid reloading patches 2023-05-13 16:27:53 +01:00
refractionpcsx2 3aac709682 CDVD: Reload game data when swapping discs to reflect new name. 2023-05-13 16:27:53 +01:00
isJuhnandrefractionpcsx2 e3962aa794 PINE: Update to the age of Qt 2023-05-13 16:17:30 +01:00
Stenzekandrefractionpcsx2 1964bbc03a MSBuild: Rename pcsx2core to pcsx2
No need to differentiate it, since wx is gone.
2023-05-13 07:12:12 +01:00
Stenzekandrefractionpcsx2 80675399aa Misc: Various cleanup
Move files from Frontend directory to pcsx2 and/or subdirectories.
Get rid of double GS init.
Combine HostSettings and Host.
Combine Frontend/Achievements.h and Achievements.h.
2023-05-13 07:12:12 +01:00
refractionpcsx2 6fb4c724bd VS: Reorganise some file filters 2023-05-13 06:24:15 +01:00
refractionpcsx2 b34606c9ce UI: Add ability to list .mdf files 2023-05-13 05:04:34 +01:00
refractionpcsx2 4e97381709 GS-HW: Fix bug in Prim cover with no gaps + allow horizontal strips 2023-05-13 05:04:16 +01:00
refractionpcsx2 d4db49f969 GS-PCRTC: Fix up Anti-Blur with negative framebuffer offsets 2023-05-13 04:34:26 +01:00
refractionpcsx2 4b54870da1 GameDB: Add MAD deinterlace and Round sprite to NASCAR Thunder games 2023-05-13 04:34:26 +01:00
refractionpcsx2 0ae91cbf64 GS-HW: Fix annoying NASCAR offsets in PCRTC 2023-05-13 04:34:26 +01:00
Mrlinkwiiandrefractionpcsx2 041abd8abc GameDB: fix up Midnight Club memcard filters 2023-05-13 01:08:05 +01:00
Stenzekandrefractionpcsx2 43be6883df GS/HW: Remove targets when invalidate area covers valid area 2023-05-12 16:24:03 +01:00
lightningterror ad4e95cb78 SPU2: Cleanup spu2.
Constants, initializations, casts, switch cases not handling default case, unused functions.
2023-05-12 15:55:29 +02:00
Stenzekandrefractionpcsx2 38480d3aed GS/HW: Fix crash in PossibleCLUTDraw() 2023-05-12 14:19:58 +01:00
Stenzekandrefractionpcsx2 3436bb3792 GS/HW: Include FBMSK in target lookups for debug traces 2023-05-12 14:19:58 +01:00
Stenzekandrefractionpcsx2 5bab8af38f GS/HW: Rename and improve dirty alpha to valid alpha 2023-05-12 14:19:58 +01:00
Stenzekandrefractionpcsx2 61f344dd66 GS/HW: Handle texture shuffles using region repeat
Ace Combat 04 reads RG, writes to RGBA by setting a MINU of 1015.
2023-05-12 14:19:58 +01:00
Stenzekandrefractionpcsx2 1811955fce GameDB: Add SW FMV render to Poinie's Poin
Game does 640x1232 draws to clear out most (but not all) of GS memory,
then 224 high draws to 1216 high targets, presumably moving GS memory
around.

Enabling SW FMV render isn't needed for the FMV, it's just a convenient
way to remove these targets from the TC, as the clearing/copying mess
happens before the FMVs play.
2023-05-12 12:37:00 +01:00
lightningterror 449da42108 USB: Fix struct member not used warnings.
Codacy.
2023-05-11 19:57:34 +02:00
Stenzekandrefractionpcsx2 9493d3e9c9 USB/GunCon2: Adjust calibration timer
Credit to @pcnimdock for debugging.
2023-05-11 16:24:27 +01:00
Stenzekandrefractionpcsx2 e5c1052062 GS: Add option to disable vertex shader expand
And automatically disable it on Fermi (buggy driver).
2023-05-11 16:18:01 +01:00
Stenzekandrefractionpcsx2 7edc4e2cb3 GS: Remove CRC hack levels
Replace it with a boolean "Disable Render Fixes" option.
2023-05-11 16:16:15 +01:00
Stenzekandrefractionpcsx2 7ca28fc796 GS/HW: Remove aggressive CRC hacks
GSC_AceCombat4 - couldn't get this to trigger.
GSC_FFXGames - dunno what this did, but FFX has been fine for some time.
GSC_Okami - breaks a bunch of the game's effects, downsample is intentional.
GSC_RedDeadRevolver - working as intended, patch on forums.
GSC_ShinOnimusha - breaks effects, only saves 5-10% GPU at 8x.
GSC_XenosagaE3 - breaks cutscenes, minimal perf difference.
2023-05-11 16:16:15 +01:00
refractionpcsx2 72f9bf83fd SIF: Correct junk data behaviour. Fixes True Crime Streets of LA 2023-05-11 16:03:13 +01:00
forrvalhallaandrefractionpcsx2 2695ddc9fc GameDB: Various fixes 2023-05-11 09:23:54 +01:00
JordanTheToasterandrefractionpcsx2 fbcc8671ac GameDB: Various fixes
Fixes for broken refraction effect in Crash WOC and broken FMVs in Army Men 2.
2023-05-10 13:27:29 +01:00
Stenzekandrefractionpcsx2 7e76230cf8 GameDB: Enable TexInRT for Project Snowblind
Seems it does the same target offset thing:

```
TC: Target 0x3600 detected in front of TBP 0x3560 with 64,32 offset (5 pages)
```
2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 ba27221bf2 GameDB: Enable TexInRT for Enthusia - Professional Racing
Fixes reflections (C32 target with offset C24 texture).
2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 6cf1501050 GameDB: Change Destroy All Humans to base tex-in-rt
Since it handles offset targets now, there's no need to use the merge
path, and the former is cheaper (no copy).

However, I'm keeping it around for Guitar Hero III (eventually I'll get
back to that..)
2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 a30ca0ce2a GS/HW: Remove Tomb Raider CRC hacks
It works correctly with tex-in-rt now.
2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 5e3e988846 GS/HW: Allow finding targets offset behind FBP for tex-in-rt 2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 bb42353c81 GS/HW: Make regions signed, and use compatible bits for tex-in-rt 2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 61740fc9ed GS/HW: Break channel shuffle on CBP change
Needed for Tomb Raider: Underworld
2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 ea30c90a6c GS/HW: Use source resolution rather than CRTC for channel shuffle 2023-05-10 13:26:19 +01:00
Stenzekandrefractionpcsx2 3968a82775 GS/HW: Turn GT4 CRC hack into a GSC instead
Keep the hacks with the rest of the hacks.
2023-05-10 13:26:19 +01:00
Goatman13andrefractionpcsx2 6e40081dd9 GameDB: Remove DOA2 iop patches.
Fixed in https://github.com/PCSX2/pcsx2/pull/3778
2023-05-09 18:41:40 +01:00
Stenzekandrefractionpcsx2 2b8b43c94c GS/Vulkan: Simplify and refactor swap chains 2023-05-09 13:44:56 +01:00
Stenzekandrefractionpcsx2 3f0ecc2284 GS/Vulkan: Submit cmdbuffer each frame even when surfaceless
Stops out-of-descriptor scenarios which are not realistic in the GS
runner.
2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 828e86bdf4 GS: Skip draws when scissor is invalid
i.e. the bottom-right is greater than the top-left.

tombraidertitle.gs.xz hits this.
2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 159d0c060f GS/Vulkan: Clear out previous texture binding when it's RT/DS 2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 4a29fdb3f2 GS/Vulkan: Ensure restarted render passes don't clear
We don't want to wipe out what's done, and we don't know the clear
values anyway.
2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 29da1bb9ef GS: Make context scissor.in an integer vector
Doesn't make sense for it to be floats, and saves a bunch of
conversions.
2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 47636bb30f Config: Fix incorrect key for DisableShaderCache 2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 5fe64396b4 GS/Vulkan: Fix incorrect layout during copy to self
Of course this happened in Dark Cloud 2.
2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 75b782f261 GS/Vulkan: Enable geometryShader for Primitive ID
Apparently it is needed..
2023-05-08 20:48:14 +01:00
Stenzekandrefractionpcsx2 4a5cf0efb9 GS: Combine texture classes and add custom layout for Vulkan 2023-05-08 20:48:14 +01:00
PCSX2 Botandlightningterror cfdae77331 PAD: Update to latest controller database. 2023-05-08 18:51:41 +02:00
lightningterror ec0aaff8ac GS: Replace EmuConfig.GS with GSConfig.
EmuConfig isn't safe to run on the gs thread.
2023-05-08 12:47:56 +02:00
refractionpcsx2 f651d8e26a GameDB: Add text fix for State of Emergency 2 2023-05-06 17:43:05 +01:00
Stenzekandrefractionpcsx2 0526769808 GS/Vulkan: Remove more unused code 2023-05-06 07:18:55 +01:00
Connor McLaughlinandrefractionpcsx2 1866745936 GS/DX12: Fix building in debug 2023-05-06 04:02:29 +01:00
245 changed files with 6176 additions and 6881 deletions
+11 -10
View File
@@ -12,21 +12,22 @@ body:
## Important: Read First
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
If you need help configuring the emulator please make a request on our forums or contact us on discord
If you need help configuring the emulator please make a request on our forums or contact us on discord.
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php).
Please make an effort to make sure your issue isn't already reported
Please make an effort to make sure your issue isn't already reported.
### Please Avoid Issues Pertaining to the Following:
- We are **not** accepting bug reports for **PSX mode** at this time
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest)
- We do **not** accept issues relating to **upscaling** at this time
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
- Please try your game at native resolution before creating an issue
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time
- We are **not** accepting bug reports for **PSX mode** at this time.
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest).
- We do **not** accept issues relating to **upscaling** at this time.
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling.
- Please try your game at native resolution before creating an issue.
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues.
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time.
- Any issues pertaining to Widescreen/no-interlace patches please forward them to the [patches repository](https://github.com/PCSX2/pcsx2_patches).
-If PCSX2 crashed, please post crash logs and the .dmp file if appropiate.
- type: textarea
id: desc
+19 -19
View File
@@ -12,20 +12,20 @@ body:
## Important: Read First
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
If you need help configuring the emulator please make a request on our forums or contact us on discord
If you need help configuring the emulator please make a request on our forums or contact us on discord.
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php).
Please make an effort to make sure your issue isn't already reported
Please make an effort to make sure your issue isn't already reported.
### Please Avoid Issues Pertaining to the Following:
- We are **not** accepting bug reports for **PSX mode** at this time
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest)
- We do **not** accept issues relating to **upscaling** at this time
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
- Please try your game at native resolution before creating an issue
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time
- We are **not** accepting bug reports for **PSX mode** at this time.
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest).
- We do **not** accept issues relating to **upscaling** at this time.
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling.
- Please try your game at native resolution before creating an issue.
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues.
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time.
- Any issues pertaining to Widescreen/no-interlace patches please forward them to the [patches repository](https://github.com/PCSX2/pcsx2_patches).
- type: textarea
@@ -55,13 +55,13 @@ body:
## System Info
Please make sure your system meets our requirements for OS version, CPU and GPU
- [System Requirements](https://github.com/PCSX2/pcsx2#system-requirements)
- [System Requirements](https://github.com/PCSX2/pcsx2#system-requirements).
Performance issues as a result of not meeting our hardware requirements are not valid
Performance issues as a result of not meeting our hardware requirements are not valid.
Please read our known issues pages for AMD and Intel drivers.
- [Intel Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-Intel-GPUs-All-you-need-to-know)
- [AMD Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-AMD-GPUs---All-you-need-to-know)
- [Intel Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-Intel-GPUs-All-you-need-to-know).
- [AMD Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-AMD-GPUs---All-you-need-to-know).
We are **not** accepting issues related to the **libretro** core. The libretro core is being maintained separately at this time
- type: input
@@ -120,11 +120,11 @@ body:
attributes:
label: Emulation Settings
description: |
Any non-default core settings. If you don't want to list them out, please provide screenshots of your configuration window
Any non-default core settings. If you don't want to list them out, please provide screenshots of your configuration window.
Please note that the safe preset works for most games. MTVU can have some compatibility issues so please disable it before making a report
Please note that the safe preset works for most games. MTVU can have some compatibility issues so please disable it before making a report.
If you need to modify the settings manually because a game requires you to do so to work, please state that explicitly
If you need to modify the settings manually because a game requires you to do so to work, please state that explicitly.
validations:
required: false
- type: textarea
@@ -139,8 +139,8 @@ body:
attributes:
label: "Logs & Dumps"
description: |
Please feel free to attach any logs, block dumps, GSdump, etc here
Please feel free to attach any logs, block dumps, GSdump, etc here.
If PCSX2 crashed, please post crash logs and the .dmp file if appropiate.
If your problem is graphical in nature it is highly recommended that you provide a GSdump. [GSdump Guide](https://forums.pcsx2.net/Thread-How-to-create-a-proper-GS-dump)
validations:
required: false
+2 -7
View File
@@ -33,14 +33,9 @@
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\imconfig.h" />
<ClInclude Include="include\imgui.h" />
@@ -60,4 +55,4 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>
+1 -1
View File
@@ -25,7 +25,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpgd", "3rdparty\jpgd\jpgd.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxproj", "{4639972E-424E-4E13-8B07-CA403C481346}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2core", "pcsx2\pcsx2core.vcxproj", "{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2", "pcsx2\pcsx2.vcxproj", "{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glad", "3rdparty\glad\glad.vcxproj", "{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}"
EndProject
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -534,6 +534,7 @@
030000009b2800002300000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
030000009b2800006900000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
030000009b2800000800000000000000,Raphnet Dreamcast Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows,
030000009b2800006200000000000000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
@@ -868,7 +869,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f0000ee00000000010000,Horipad Mini 4,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:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000242e0000ff0b000000010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Mac OS X,
03000000790000004e95000000010000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,
03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
03000000830500006020000000000000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,
03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,
@@ -1212,7 +1213,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Linux,
03000000242e00008816000001010000,Hyperkin X91,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,
03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,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:b0,y:b3,platform:Linux,
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
@@ -1512,6 +1513,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000008f0e00001431000010010000,SZMY Power PS3,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,
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,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:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,leftshoulder:b4,rightshoulder:b5,x:b3,y:b0,start:b7,platform:Linux,
030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
@@ -1587,6 +1590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
060000005e040000120b000007050000,Xbox Series Controller,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,
060000005e040000120b00000b050000,Xbox Series Controller,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,
060000005e040000120b00000f050000,Xbox Series Controller,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,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000450c00002043000010010000,XEOX SL6556 BK,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,
05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
+8 -6
View File
@@ -118,8 +118,7 @@ if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
elseif(NOT DEFINED ARCH_FLAG AND USE_CLANG_CL)
set(ARCH_FLAG "-msse4.1")
endif()
list(APPEND PCSX2_DEFS _ARCH_64=1 _M_X86=1)
set(_ARCH_64 1)
list(APPEND PCSX2_DEFS _M_X86=1)
set(_M_X86 1)
else()
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
@@ -136,12 +135,15 @@ option(USE_PGO_OPTIMIZE "Enable PGO optimization (use profile)")
# Note1: Builtin strcmp/memcmp was proved to be slower on Mesa than stdlib version.
# Note2: float operation SSE is impacted by the PCSX2 SSE configuration. In particular, flush to zero denormal.
if(MSVC AND NOT USE_CLANG_CL)
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>")
add_compile_options(
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>"
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>"
"$<$<COMPILE_LANGUAGE:CXX>:/permissive->"
"/Zo"
"/utf-8"
)
elseif(NOT MSVC)
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse)
# -fno-operator-names should only be for C++ files, not C files.
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-operator-names>)
endif()
set(CONFIG_REL_NO_DEB $<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>>)
+56
View File
@@ -0,0 +1,56 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
#include <type_traits>
#ifdef _MSC_VER
#include <stdlib.h>
#endif
template <typename T>
T ByteSwap(T value)
{
if constexpr (std::is_signed_v<T>)
{
return static_cast<T>(ByteSwap(std::make_unsigned_t<T>(value)));
}
else if constexpr (std::is_same_v<T, std::uint16_t>)
{
#ifdef _MSC_VER
return _byteswap_ushort(value);
#else
return __builtin_bswap16(value);
#endif
}
else if constexpr (std::is_same_v<T, std::uint32_t>)
{
#ifdef _MSC_VER
return _byteswap_ulong(value);
#else
return __builtin_bswap32(value);
#endif
}
else if constexpr (std::is_same_v<T, std::uint64_t>)
{
#ifdef _MSC_VER
return _byteswap_uint64(value);
#else
return __builtin_bswap64(value);
#endif
}
}
+5
View File
@@ -64,6 +64,7 @@ target_sources(common PRIVATE
AlignedMalloc.h
Assertions.h
boost_spsc_queue.hpp
ByteSwap.h
Console.h
CrashHandler.h
DynamicLibrary.h
@@ -154,6 +155,10 @@ if(APPLE)
)
target_compile_options(common PRIVATE -fobjc-arc)
target_link_options(common PRIVATE -fobjc-link-runtime)
target_link_libraries(common PRIVATE
"-framework Foundation"
"-framework IOKit"
)
endif()
if(DBUS_API)
-4
View File
@@ -181,10 +181,6 @@ namespace Perf
ml.method_size = static_cast<unsigned int>(size);
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml);
}
#else
static void RegisterMethod(const void* ptr, size_t size, const char* method)
{
}
#endif
#if (defined(__linux__) && (defined(ProfileWithPerf) || defined(ProfileWithPerfJitDump))) || defined(ENABLE_VTUNE)
+2 -8
View File
@@ -100,10 +100,7 @@ namespace StringUtil
return std::nullopt;
if (endptr)
{
const size_t remaining_len = end - ptr - 1;
*endptr = (remaining_len > 0) ? std::string_view(result.ptr, remaining_len) : std::string_view();
}
*endptr = (result.ptr < end) ? std::string_view(result.ptr, end - result.ptr) : std::string_view();
return value;
}
@@ -131,10 +128,7 @@ namespace StringUtil
return std::nullopt;
if (endptr)
{
const size_t remaining_len = end - ptr - 1;
*endptr = (remaining_len > 0) ? std::string_view(result.ptr, remaining_len) : std::string_view();
}
*endptr = (result.ptr < end) ? std::string_view(result.ptr, end - result.ptr) : std::string_view();
return value;
}
+3 -12
View File
@@ -22,7 +22,7 @@
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="vsprops\CommonLibrary.props" />
<Import Project="vsprops\3rdpartyDeps.props" />
<Import Project="vsprops\common.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Devel))" Project="vsprops\CodeGen_Devel.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="vsprops\CodeGen_Release.props" />
@@ -37,17 +37,10 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\libpng</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\jpgd</AdditionalIncludeDirectories>
<ExceptionHandling>Async</ExceptionHandling>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\fmt\include</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<ForcedIncludeFiles>PrecompiledHeader.h</ForcedIncludeFiles>
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
</ClCompile>
</ItemDefinitionGroup>
@@ -111,6 +104,7 @@
<ClInclude Include="Align.h" />
<ClInclude Include="AlignedMalloc.h" />
<ClInclude Include="BitCast.h" />
<ClInclude Include="ByteSwap.h" />
<ClInclude Include="CrashHandler.h" />
<ClInclude Include="DynamicLibrary.h" />
<ClInclude Include="Easing.h" />
@@ -180,9 +174,6 @@
<ClInclude Include="ZipHelpers.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\3rdparty\glad\glad.vcxproj">
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\jpgd\jpgd.vcxproj">
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
</ProjectReference>
+3
View File
@@ -351,6 +351,9 @@
<ClInclude Include="FileSystem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ByteSwap.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
-16
View File
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<_PropertySheetDisplayName>Pcsx3rdpartyDependencies</_PropertySheetDisplayName>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\;$(SolutionDir)3rdparty\soundtouch\soundtouch\;$(SolutionDir)3rdparty\rapidyaml\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\fmt\fmt\include\;$(SolutionDir)3rdparty\libchdr\libchdr\include;$(SolutionDir)3rdparty\wil\include;$(SolutionDir)3rdparty\Vulkan-Headers\include\;$(SolutionDir)3rdparty\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIL_SUPPRESS_EXCEPTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(SolutionDir)deps\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
</Project>
+1 -32
View File
@@ -1,38 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<_PropertySheetDisplayName>PcsxBaseProperties</_PropertySheetDisplayName>
<OutDir>$(SolutionDir)bin\$(PcsxSubsection)\</OutDir>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
<ExtensionsToDeleteOnClean>*.bsc;*.idb;*.sbr;*.res;*.pch;*.pdb;*.obj;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath);$(ExtensionsToDeleteOnClean)</ExtensionsToDeleteOnClean>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0A00;_WIN32_WINNT=0x0A00;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
<!-- Force ThinLTO for Release builds, MSVC doesn't seem to do it otherwise. -->
<!-- Also due to include order, needs to be set here, rather than in CodeGen_Release.props -->
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Release))"> -flto=thin %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<PreBuildEvent>
<Command>"$(SolutionDir)common\vsprops\preBuild.cmd"</Command>
</PreBuildEvent>
<ResourceCompile>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
</Project>
-15
View File
@@ -1,22 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<OutDir>$(SolutionDir)deps\$(PlatformName)\$(Configuration)\</OutDir>
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir);$(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;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
</Project>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<!-- This sucks. Need a better solution. -->
<PreBuildEvent>
<Command>"$(SolutionDir)common\vsprops\preBuild.cmd"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
</Project>
+33 -29
View File
@@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<ProjectRootDir>$(ProjectDir)\..\..</ProjectRootDir>
<SvnRootDir>$(ProjectRootDir)\..</SvnRootDir>
<SvnCommonDir>$(SvnRootDir)\common</SvnCommonDir>
<PcsxSubsection />
<SSEString />
<SSEString Condition="$(Configuration.Contains(AVX2))">-avx2</SSEString>
<ArchString />
@@ -17,42 +13,50 @@
<EXEString>$(ProjectName)$(ArchString)$(SSEString)$(ToolkitString)$(BuildString)</EXEString>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>./;$(ProjectDir);$(ProjectDir)x86;$(ProjectDir)x86\ix86-32;$(ProjectDir)IPU;$(ProjectDir)System;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_M_X86;TIXML_USE_STL;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir);$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;WINVER=0x0A00;_WIN32_WINNT=0x0A00;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeaderOutputFile>$(IntDir)pcsx2.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
<MinimalRebuild>false</MinimalRebuild>
<ConformanceMode>true</ConformanceMode>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
<!-- SH 2/3 flashlight, explicitly set here don't change -->
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
<FloatingPointModel>Precise</FloatingPointModel>
<!-- MSVC automatically adds __AVX__ and __AVX2__ appropriately -->
<PreprocessorDefinitions>_M_X86;__SSE4_1__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="!$(Configuration.Contains(Clang))">%(AdditionalOptions) /Zc:externConstexpr /Zc:__cplusplus /Zo /utf-8</AdditionalOptions>
<!-- Force ThinLTO for Release builds, MSVC doesn't seem to do it otherwise. -->
<!-- Also due to include order, needs to be set here, rather than in CodeGen_Release.props -->
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Release))"> -flto=thin %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>setupapi.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\;..\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;d3d12.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;OneCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<PreBuildEvent>
<Command>
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<BuildMacro Include="ProjectRootDir">
<Value>$(ProjectRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnRootDir">
<Value>$(SvnRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnCommonDir">
<Value>$(SvnCommonDir)</Value>
</BuildMacro>
<BuildMacro Include="PcsxSubsection">
<Value>$(PcsxSubsection)</Value>
</BuildMacro>
</ItemGroup>
</Project>
-32
View File
@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<PcsxSubsection>plugins</PcsxSubsection>
<ProjectRootDir>$(ProjectDir)..</ProjectRootDir>
<SvnRootDir>$(ProjectRootDir)\..\..\..</SvnRootDir>
<SvnCommonDir>$(SvnRootDir)\common</SvnCommonDir>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<_PropertySheetDisplayName>PluginSvnRoot</_PropertySheetDisplayName>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)\..\3rdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<BuildMacro Include="PcsxSubsection">
<Value>$(PcsxSubsection)</Value>
</BuildMacro>
<BuildMacro Include="ProjectRootDir">
<Value>$(ProjectRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnRootDir">
<Value>$(SvnRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnCommonDir">
<Value>$(SvnCommonDir)</Value>
</BuildMacro>
</ItemGroup>
</Project>
+13 -26
View File
@@ -37,25 +37,20 @@
#include "pcsx2/PrecompiledHeader.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/CDVD/CDVD.h"
#include "pcsx2/Frontend/CommonHost.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Frontend/ImGuiManager.h"
#include "pcsx2/Frontend/LogSink.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/Host.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/ImGui/ImGuiManager.h"
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/VMManager.h"
#ifdef ENABLE_ACHIEVEMENTS
#include "pcsx2/Frontend/Achievements.h"
#endif
#include "svnrev.h"
namespace GSRunner
@@ -87,14 +82,14 @@ static u32 s_loop_number = s_loop_count;
bool GSRunner::InitializeConfig()
{
if (!CommonHost::InitializeCriticalFolders())
if (!EmuFolders::InitializeCriticalFolders())
return false;
// don't provide an ini path, or bother loading. we'll store everything in memory.
MemorySettingsInterface& si = s_settings_interface;
Host::Internal::SetBaseSettingsLayer(&si);
CommonHost::SetDefaultSettings(si, true, true, true, true, true);
VMManager::SetDefaultSettings(si, true, true, true, true, true);
// complete as quickly as possible
si.SetBoolValue("EmuCore/GS", "FrameLimitEnable", false);
@@ -131,7 +126,7 @@ bool GSRunner::InitializeConfig()
si.SetStringValue("MemoryCards", fmt::format("Slot{}_Filename", i + 1).c_str(), "");
}
CommonHost::LoadStartupSettings();
VMManager::Internal::LoadStartupSettings();
return true;
}
@@ -142,12 +137,10 @@ void Host::CommitBaseSettingChanges()
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
{
CommonHost::LoadSettings(si, lock);
}
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
{
CommonHost::CheckForSettingsChanges(old_config);
}
bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool hotkeys, bool ui)
@@ -414,7 +407,7 @@ void GSRunner::InitializeConsole()
const char* var = std::getenv("PCSX2_NOCONSOLE");
s_no_console = (var && StringUtil::FromChars<bool>(var).value_or(false));
if (!s_no_console)
CommonHost::InitializeEarlyConsole();
LogSink::InitializeEarlyConsole();
}
bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& params)
@@ -540,7 +533,7 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
{
// disable timestamps, since we want to be able to diff the logs
Console.WriteLn("Logging to %s...", logfile);
CommonHost::SetFileLogPath(logfile);
LogSink::SetFileLogPath(logfile);
s_settings_interface.SetBoolValue("Logging", "EnableFileLogging", true);
s_settings_interface.SetBoolValue("Logging", "EnableTimestamps", false);
}
@@ -626,12 +619,8 @@ int main(int argc, char* argv[])
if (!GSRunner::ParseCommandLineArgs(argc, argv, params))
return EXIT_FAILURE;
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
{
Console.Error("Failed to allocate globals/memory.");
if (!VMManager::Internal::CPUThreadInitialize())
return EXIT_FAILURE;
}
if (s_use_window.value_or(true) && !GSRunner::CreatePlatformWindow())
{
@@ -653,16 +642,14 @@ int main(int argc, char* argv[])
VMManager::Shutdown(false);
}
InputManager::CloseSources();
VMManager::Internal::ReleaseMemory();
VMManager::Internal::ReleaseGlobals();
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
VMManager::Internal::CPUThreadShutdown();
GSRunner::DestroyPlatformWindow();
LogSink::CloseFileLog();
return EXIT_SUCCESS;
}
void Host::CPUThreadVSync()
void Host::VSyncOnCPUThread()
{
// update GS thread copy of frame number
GetMTGS().RunOnGSThread([frame_number = GSDumpReplayer::GetFrameNumber()]() { s_dump_frame_number = frame_number; });
+8 -64
View File
@@ -21,7 +21,7 @@
<ImportGroup Label="PropertySheets">
<Import Project="$(SolutionDir)common\vsprops\common.props" />
<Import Project="$(SolutionDir)common\vsprops\BaseProperties.props" />
<Import Project="$(SolutionDir)common\vsprops\3rdpartyDeps.props" />
<Import Project="$(SolutionDir)common\vsprops\GenerateSCMVersion.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="$(SolutionDir)common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Devel))" Project="$(SolutionDir)common\vsprops\CodeGen_Devel.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="$(SolutionDir)common\vsprops\CodeGen_Release.props" />
@@ -34,84 +34,28 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xbyak;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\freetype\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xz\xz\src\liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\simpleini\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)pcsx2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<!-- Needed for moc pch -->
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(ProjectDir)\Settings;$(ProjectDir)\GameList</AdditionalIncludeDirectories>
<ExceptionHandling>Async</ExceptionHandling>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\fmt\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\simpleini\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)pcsx2</AdditionalIncludeDirectories>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;DIRECTINPUT_VERSION=0x0800;PCSX2_CORE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
<MinimalRebuild>false</MinimalRebuild>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
<!-- SH 2/3 flashlight, explicitly set here don't change -->
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ConformanceMode>true</ConformanceMode>
<AdditionalOptions>/Zc:__cplusplus /Zo /utf-8%(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<LargeAddressAware>Yes</LargeAddressAware>
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;d3d12.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;OneCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)3rdparty\fmt\fmt.vcxproj">
<Project>{449ad25e-424a-4714-babc-68706cdcc33b}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\libjpeg\libjpeg.vcxproj">
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj">
<Project>{d6973076-9317-4ef2-a0b8-b7a18ac0713e}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\soundtouch\SoundTouch.vcxproj">
<Project>{e9b51944-7e6d-4bcd-83f2-7bbd5a46182d}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\xz\liblzma.vcxproj">
<Project>{12728250-16ec-4dc6-94d7-e21dd88947f8}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\libchdr\libchdr.vcxproj">
<Project>{a0d2b3ad-1f72-4ee3-8b5c-f2c358da35f0}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\zlib\zlib.vcxproj">
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\jpgd\jpgd.vcxproj">
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\imgui\imgui.vcxproj">
<Project>{88fb34ec-845e-4f21-a552-f1573b9ed167}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)common\common.vcxproj">
<Project>{4639972e-424e-4e13-8b07-ca403c481346}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2core.vcxproj">
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2.vcxproj">
<Project>{6c7986c4-3e4d-4dcc-b3c6-6bb12b238995}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp" />
+2 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -20,7 +20,7 @@
#include "QtHost.h"
#include "QtUtils.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "pcsx2/SysForwardDefs.h"
#include "svnrev.h"
+5 -5
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,12 +15,12 @@
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "pcsx2/Frontend/GameList.h"
#include "CoverDownloadDialog.h"
#include "pcsx2/GameList.h"
#include "common/Assertions.h"
CoverDownloadDialog::CoverDownloadDialog(QWidget* parent /*= nullptr*/)
: QDialog(parent)
{
+4 -5
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,16 +15,15 @@
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "pcsx2/Frontend/ImGuiManager.h"
#include "DisplayWidget.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
#include "pcsx2/ImGui/ImGuiManager.h"
#include "common/Assertions.h"
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
+5 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,8 +14,11 @@
*/
#pragma once
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/GameList.h"
#include "common/LRUCache.h"
#include <QtCore/QAbstractTableModel>
#include <QtGui/QPixmap>
#include <algorithm>
+8 -5
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,11 +15,12 @@
#include "PrecompiledHeader.h"
#include "GameListRefreshThread.h"
#include "pcsx2/GameList.h"
#include "common/ProgressCallback.h"
#include "common/Timer.h"
#include "pcsx2/Frontend/GameList.h"
#include "GameListRefreshThread.h"
#include <QtWidgets/QMessageBox>
@@ -64,7 +65,9 @@ void AsyncRefreshProgressCallback::SetProgressValue(u32 value)
fireUpdate();
}
void AsyncRefreshProgressCallback::SetTitle(const char* title) {}
void AsyncRefreshProgressCallback::SetTitle(const char* title)
{
}
void AsyncRefreshProgressCallback::DisplayError(const char* message)
{
+12 -11
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,11 +15,19 @@
#include "PrecompiledHeader.h"
#include "GameListModel.h"
#include "GameListRefreshThread.h"
#include "GameListWidget.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "pcsx2/GameList.h"
#include "pcsx2/Host.h"
#include "common/Assertions.h"
#include "common/StringUtil.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/HostSettings.h"
#include "fmt/format.h"
#include <QtCore/QSortFilterProxyModel>
#include <QtGui/QPixmap>
@@ -29,16 +37,9 @@
#include <QtWidgets/QMenu>
#include <QtWidgets/QScrollBar>
#include "GameListModel.h"
#include "GameListRefreshThread.h"
#include "GameListWidget.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "fmt/format.h"
static const char* SUPPORTED_FORMATS_STRING = QT_TRANSLATE_NOOP(GameListWidget,
".bin/.iso (ISO Disc Images)\n"
".mdf (Media Descriptor File)\n"
".chd (Compressed Hunks of Data)\n"
".cso (Compressed ISO)\n"
".gz (Gzip Compressed ISO)");
+5 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,9 +14,12 @@
*/
#pragma once
#include "pcsx2/Frontend/GameList.h"
#include "ui_EmptyGameListWidget.h"
#include "ui_GameListWidget.h"
#include "pcsx2/GameList.h"
#include <QtWidgets/QListView>
#include <QtWidgets/QTableView>
+32 -33
View File
@@ -15,31 +15,6 @@
#include "PrecompiledHeader.h"
#include <QtCore/QDateTime>
#include <QtGui/QCloseEvent>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QProgressBar>
#include <QtWidgets/QStyle>
#include <QtWidgets/QStyleFactory>
#include "common/Assertions.h"
#include "common/CocoaTools.h"
#include "common/FileSystem.h"
#include "pcsx2/CDVD/CDVDcommon.h"
#include "pcsx2/CDVD/CDVDdiscReader.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/Frontend/LogSink.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/Recording/InputRecording.h"
#include "pcsx2/Recording/InputRecordingControls.h"
#include "AboutDialog.h"
#include "AutoUpdaterDialog.h"
#include "CoverDownloadDialog.h"
@@ -49,27 +24,50 @@
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "Settings/ControllerSettingsDialog.h"
#include "Settings/GameListSettingsWidget.h"
#include "Settings/InterfaceSettingsWidget.h"
#include "SettingWidgetBinder.h"
#include "svnrev.h"
#include "Tools/InputRecording/InputRecordingViewer.h"
#include "Tools/InputRecording/NewInputRecordingDlg.h"
#include "svnrev.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/CDVD/CDVDcommon.h"
#include "pcsx2/CDVD/CDVDdiscReader.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/GameList.h"
#include "pcsx2/Host.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/Recording/InputRecording.h"
#include "pcsx2/Recording/InputRecordingControls.h"
#include "common/Assertions.h"
#include "common/CocoaTools.h"
#include "common/FileSystem.h"
#include <QtCore/QDateTime>
#include <QtGui/QCloseEvent>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QProgressBar>
#include <QtWidgets/QStyle>
#include <QtWidgets/QStyleFactory>
#ifdef _WIN32
#include "common/RedtapeWindows.h"
#include <Dbt.h>
#endif
#ifdef ENABLE_RAINTEGRATION
#include "pcsx2/Frontend/Achievements.h"
#endif
const char* MainWindow::OPEN_FILE_FILTER =
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.gz *.elf *.irx *.gs *.gs.xz *.gs.zst *.dump);;"
QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.mdf *.chd *.cso *.gz *.elf *.irx *.gs *.gs.xz *.gs.zst *.dump);;"
"Single-Track Raw Images (*.bin *.iso);;"
"Cue Sheets (*.cue);;"
"Media Descriptor File (*.mdf);;"
"MAME CHD Images (*.chd);;"
"CSO Images (*.cso);;"
"GZ Images (*.gz);;"
@@ -78,9 +76,10 @@ const char* MainWindow::OPEN_FILE_FILTER =
"GS Dumps (*.gs *.gs.xz *.gs.zst);;"
"Block Dumps (*.dump)");
const char* MainWindow::DISC_IMAGE_FILTER = QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.chd *.cso *.gz *.dump);;"
const char* MainWindow::DISC_IMAGE_FILTER = QT_TRANSLATE_NOOP("MainWindow", "All File Types (*.bin *.iso *.cue *.mdf *.chd *.cso *.gz *.dump);;"
"Single-Track Raw Images (*.bin *.iso);;"
"Cue Sheets (*.cue);;"
"Media Descriptor File (*.mdf);;"
"MAME CHD Images (*.chd);;"
"CSO Images (*.cso);;"
"GZ Images (*.gz);;"
+53 -62
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,8 +15,32 @@
#include "PrecompiledHeader.h"
#include <cmath>
#include <csignal>
#include "AutoUpdaterDialog.h"
#include "DisplayWidget.h"
#include "GameList/GameListWidget.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "svnrev.h"
#include "pcsx2/CDVD/CDVDcommon.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/CDVD/CDVD.h"
#include "pcsx2/Counters.h"
#include "pcsx2/DebugTools/Debug.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/GameList.h"
#include "pcsx2/Host.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/ImGui/FullscreenUI.h"
#include "pcsx2/ImGui/ImGuiManager.h"
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/VMManager.h"
#include "common/Assertions.h"
#include "common/Console.h"
@@ -28,25 +52,6 @@
#include "common/StringUtil.h"
#include "common/Timer.h"
#include "pcsx2/CDVD/CDVD.h"
#include "pcsx2/CDVD/CDVDcommon.h"
#include "pcsx2/Counters.h"
#include "pcsx2/DebugTools/Debug.h"
#include "pcsx2/Frontend/CommonHost.h"
#include "pcsx2/Frontend/FullscreenUI.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Frontend/ImGuiManager.h"
#include "pcsx2/Frontend/LogSink.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/VMManager.h"
#include <QtCore/QTimer>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMessageBox>
@@ -55,17 +60,8 @@
#include "fmt/core.h"
#include "AutoUpdaterDialog.h"
#include "DisplayWidget.h"
#include "GameList/GameListWidget.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "svnrev.h"
#ifdef ENABLE_ACHIEVEMENTS
#include "Frontend/Achievements.h"
#endif
#include <cmath>
#include <csignal>
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
@@ -120,6 +116,7 @@ void EmuThread::start()
pxAssertRel(!g_emu_thread, "Emu thread does not exist");
g_emu_thread = new EmuThread(QThread::currentThread());
g_emu_thread->setStackSize(VMManager::EMU_THREAD_STACK_SIZE);
g_emu_thread->QThread::start();
g_emu_thread->m_started_semaphore.acquire();
g_emu_thread->moveToThread(g_emu_thread);
@@ -374,7 +371,12 @@ void EmuThread::run()
connectSignals();
// Common host initialization (VM setup, etc).
CommonHost::CPUThreadInitialize();
if (!VMManager::Internal::CPUThreadInitialize())
{
VMManager::Internal::CPUThreadShutdown();
QMetaObject::invokeMethod(qApp, &QCoreApplication::quit, Qt::QueuedConnection);
return;
}
// Start background polling because the VM won't do it for us.
createBackgroundControllerPollTimer();
@@ -395,7 +397,7 @@ void EmuThread::run()
// Teardown in reverse order.
stopBackgroundControllerPollTimer();
destroyBackgroundControllerPollTimer();
CommonHost::CPUThreadShutdown();
VMManager::Internal::CPUThreadShutdown();
// Move back to the UI thread, since we're no longer running.
moveToThread(m_ui_thread);
@@ -569,7 +571,7 @@ void EmuThread::updateEmuFolders()
return;
}
Host::Internal::UpdateEmuFolders();
VMManager::Internal::UpdateEmuFolders();
}
void EmuThread::connectSignals()
@@ -585,7 +587,6 @@ void EmuThread::loadSettings(SettingsInterface& si, std::unique_lock<std::mutex>
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
{
CommonHost::LoadSettings(si, lock);
g_emu_thread->loadSettings(si, lock);
}
@@ -609,7 +610,6 @@ void EmuThread::checkForSettingChanges(const Pcsx2Config& old_config)
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
{
CommonHost::CheckForSettingsChanges(old_config);
g_emu_thread->checkForSettingChanges(old_config);
}
@@ -931,35 +931,29 @@ void Host::RequestResizeHostDisplay(s32 width, s32 height)
void Host::OnVMStarting()
{
CommonHost::OnVMStarting();
g_emu_thread->stopBackgroundControllerPollTimer();
emit g_emu_thread->onVMStarting();
}
void Host::OnVMStarted()
{
CommonHost::OnVMStarted();
emit g_emu_thread->onVMStarted();
}
void Host::OnVMDestroyed()
{
CommonHost::OnVMDestroyed();
emit g_emu_thread->onVMStopped();
g_emu_thread->startBackgroundControllerPollTimer();
}
void Host::OnVMPaused()
{
CommonHost::OnVMPaused();
g_emu_thread->startBackgroundControllerPollTimer();
emit g_emu_thread->onVMPaused();
}
void Host::OnVMResumed()
{
CommonHost::OnVMResumed();
// exit the event loop when we eventually return
g_emu_thread->getEventLoop()->quit();
g_emu_thread->stopBackgroundControllerPollTimer();
@@ -974,7 +968,6 @@ void Host::OnVMResumed()
void Host::OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
const std::string& game_name, u32 game_crc)
{
CommonHost::OnGameChanged(disc_path, elf_override, game_serial, game_name, game_crc);
emit g_emu_thread->onGameChanged(QString::fromStdString(disc_path), QString::fromStdString(elf_override),
QString::fromStdString(game_serial), QString::fromStdString(game_name), game_crc);
}
@@ -1121,10 +1114,9 @@ void Host::OnAchievementsRefreshed()
}
#endif
void Host::CPUThreadVSync()
void Host::VSyncOnCPUThread()
{
g_emu_thread->getEventLoop()->processEvents(QEventLoop::AllEvents);
CommonHost::CPUThreadVSync();
}
void Host::RunOnCPUThread(std::function<void()> function, bool block /* = false */)
@@ -1200,19 +1192,22 @@ SysMtgsThread& GetMTGS()
bool QtHost::InitializeConfig()
{
if (!CommonHost::InitializeCriticalFolders())
if (!EmuFolders::InitializeCriticalFolders())
{
QMessageBox::critical(nullptr, QStringLiteral("PCSX2"),
QStringLiteral("One or more critical directories are missing, your installation may be incomplete."));
return false;
}
// Write crash dumps to the data directory, since that'll be accessible for certain.
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
const std::string path(Path::Combine(EmuFolders::Settings, "PCSX2.ini"));
Console.WriteLn("Loading config from %s.", path.c_str());
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(path));
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get());
if (!s_base_settings_interface->Load() || !CommonHost::CheckSettingsVersion())
if (!s_base_settings_interface->Load() || !VMManager::Internal::CheckSettingsVersion())
{
// If the config file doesn't exist, assume this is a new install and don't prompt to overwrite.
if (FileSystem::FileExists(s_base_settings_interface->GetFileName().c_str()) &&
@@ -1223,12 +1218,12 @@ bool QtHost::InitializeConfig()
return false;
}
CommonHost::SetDefaultSettings(*s_base_settings_interface, true, true, true, true, true);
VMManager::SetDefaultSettings(*s_base_settings_interface, true, true, true, true, true);
SaveSettings();
}
CommonHost::SetBlockSystemConsole(QtHost::InNoGUIMode());
CommonHost::LoadStartupSettings();
LogSink::SetBlockSystemConsole(QtHost::InNoGUIMode());
VMManager::Internal::LoadStartupSettings();
return true;
}
@@ -1311,7 +1306,7 @@ bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool
{
{
auto lock = Host::GetSettingsLock();
CommonHost::SetDefaultSettings(*s_base_settings_interface.get(), folders, core, controllers, hotkeys, ui);
VMManager::SetDefaultSettings(*s_base_settings_interface.get(), folders, core, controllers, hotkeys, ui);
}
Host::CommitBaseSettingChanges();
@@ -1516,7 +1511,7 @@ void QtHost::HookSignals()
void QtHost::PrintCommandLineVersion()
{
CommonHost::InitializeEarlyConsole();
LogSink::InitializeEarlyConsole();
std::fprintf(stderr, "%s\n", (GetAppNameAndVersion() + GetAppConfigSuffix()).toUtf8().constData());
std::fprintf(stderr, "https://pcsx2.net/\n");
std::fprintf(stderr, "\n");
@@ -1632,7 +1627,7 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
}
else if (CHECK_ARG_PARAM(QStringLiteral("-logfile")))
{
CommonHost::SetFileLogPath((++it)->toStdString());
LogSink::SetFileLogPath((++it)->toStdString());
continue;
}
else if (CHECK_ARG(QStringLiteral("-bios")))
@@ -1653,7 +1648,7 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
}
else if (CHECK_ARG(QStringLiteral("-earlyconsolelog")))
{
CommonHost::InitializeEarlyConsole();
LogSink::InitializeEarlyConsole();
continue;
}
else if (CHECK_ARG(QStringLiteral("-bigpicture")))
@@ -1710,7 +1705,7 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
// or disc, we don't want to actually start.
if (autoboot && !autoboot->source_type.has_value() && autoboot->filename.empty() && autoboot->elf_override.empty())
{
CommonHost::InitializeEarlyConsole();
LogSink::InitializeEarlyConsole();
Console.Warning("Skipping autoboot due to no boot parameters.");
autoboot.reset();
}
@@ -1843,11 +1838,7 @@ int main(int argc, char* argv[])
s_base_settings_interface->Save();
// Ensure emulog is flushed.
if (emuLog)
{
std::fclose(emuLog);
emuLog = nullptr;
}
LogSink::CloseFileLog();
return result;
}
+2 -3
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -21,8 +21,7 @@
#include <optional>
#include "pcsx2/Host.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/VMManager.h"
#include <QtCore/QList>
+1 -1
View File
@@ -17,7 +17,7 @@
#include "QtUtils.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Input/InputManager.h"
#include "common/StringUtil.h"
+1 -1
View File
@@ -35,7 +35,7 @@
#include "common/Path.h"
#include "pcsx2/Config.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "QtHost.h"
#include "QtUtils.h"
+5 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,9 +14,12 @@
*/
#include "PrecompiledHeader.h"
#include "AchievementLoginDialog.h"
#include "pcsx2/Frontend/Achievements.h"
#include "QtHost.h"
#include "pcsx2/Achievements.h"
#include <QtWidgets/QMessageBox>
AchievementLoginDialog::AchievementLoginDialog(QWidget* parent)
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -22,8 +22,8 @@
#include "SettingWidgetBinder.h"
#include "QtUtils.h"
#include "pcsx2/Frontend/Achievements.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/Host.h"
#include "common/StringUtil.h"
@@ -67,6 +67,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.ntscFrameRate, "EmuCore/GS", "FramerateNTSC", 59.94f);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.palFrameRate, "EmuCore/GS", "FrameratePAL", 50.00f);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pineEnable, "EmuCore", "EnablePINE", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.pineSlot, "EmuCore", "PINESlot", 28011);
dialog->registerWidgetHelp(m_ui.eeRoundingMode, tr("Rounding Mode"), tr("Chop / Zero (Default)"), tr(""));
dialog->registerWidgetHelp(m_ui.eeClampMode, tr("Clamping Mode"), tr("Normal (Default)"), tr(""));
+41 -2
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>809</width>
<height>647</height>
<height>725</height>
</rect>
</property>
<property name="windowTitle">
@@ -37,7 +37,7 @@
<x>0</x>
<y>0</y>
<width>807</width>
<height>645</height>
<height>723</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -417,6 +417,45 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>PINE Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="1" column="1">
<widget class="QLineEdit" name="pineSlot">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Slot:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="pineEnable">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
+1 -1
View File
@@ -19,7 +19,7 @@
#include <QtWidgets/QFileDialog>
#include <algorithm>
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "pcsx2/ps2/BiosTools.h"
#include "BIOSSettingsWidget.h"
@@ -25,7 +25,7 @@
#include "common/StringUtil.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "Settings/ControllerBindingWidgets.h"
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,15 +15,16 @@
#include "PrecompiledHeader.h"
#include "Frontend/InputManager.h"
#include "Settings/ControllerGlobalSettingsWidget.h"
#include "Settings/ControllerSettingsDialog.h"
#include "Settings/ControllerSettingWidgetBinder.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "pcsx2/Input/InputManager.h"
#ifdef SDL_BUILD
#include "pcsx2/Frontend/SDLInputSource.h"
#include "pcsx2/Input/SDLInputSource.h"
#endif
ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent, ControllerSettingsDialog* dialog)
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,6 +15,11 @@
#pragma once
#include "pcsx2/Host.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
#include <optional>
#include <type_traits>
@@ -27,11 +32,6 @@
#include <QtWidgets/QSlider>
#include <QtWidgets/QSpinBox>
#include "pcsx2/HostSettings.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
/// This nastyness is required because input profiles aren't overlaid settings like the rest of them, it's
/// input profile *or* global, not both.
namespace ControllerSettingWidgetBinder
@@ -21,7 +21,6 @@
#include "Settings/ControllerBindingWidgets.h"
#include "Settings/HotkeySettingsWidget.h"
#include "pcsx2/Frontend/CommonHost.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/Sio.h"
@@ -208,7 +207,7 @@ void ControllerSettingsDialog::onRestoreDefaultsClicked()
// actually restore it
{
auto lock = Host::GetSettingsLock();
CommonHost::SetDefaultSettings(*Host::Internal::GetBaseSettingsLayer(), false, false, true, true, false);
VMManager::SetDefaultSettings(*Host::Internal::GetBaseSettingsLayer(), false, false, true, true, false);
}
Host::CommitBaseSettingChanges();
+4 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,8 +15,10 @@
#pragma once
#include "ui_ControllerSettingsDialog.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/USB/USB.h"
#include <QtCore/QList>
#include <QtCore/QPair>
#include <QtCore/QString>
+2 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -23,7 +23,7 @@
#include "common/Path.h"
#include "common/StringUtil.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "pcsx2/INISettingsInterface.h"
#include "DEV9SettingsWidget.h"
+4 -3
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -19,9 +19,10 @@
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"
#include <QtWidgets/QMessageBox>
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include <QtWidgets/QMessageBox>
DebugSettingsWidget::DebugSettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
@@ -19,7 +19,7 @@
#include <QtWidgets/QMessageBox>
#include <limits>
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "EmulationSettingsWidget.h"
#include "QtUtils.h"
+8 -8
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,22 +15,22 @@
#include "PrecompiledHeader.h"
#include "common/StringUtil.h"
#include "Frontend/GameList.h"
#include "PAD/Host/PAD.h"
#include "GameSummaryWidget.h"
#include "SettingsDialog.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include <QtCore/QDir>
#include <QtWidgets/QFileDialog>
#include "pcsx2/GameList.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "common/StringUtil.h"
#include "fmt/format.h"
#include <QtCore/QDir>
#include <QtWidgets/QFileDialog>
GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsDialog* dialog, QWidget* parent)
: m_dialog(dialog)
{
+7 -7
View File
@@ -21,7 +21,7 @@
#include "SettingsDialog.h"
#include <QtWidgets/QMessageBox>
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GS/GSCapture.h"
#include "pcsx2/GS/GSUtil.h"
@@ -181,8 +181,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
// HW Renderer Fixes
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.crcFixLevel, "EmuCore/GS", "crc_hack_level", static_cast<int>(CRCHackLevel::Automatic), -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1, -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderBW, "EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.cpuSpriteRenderLevel, "EmuCore/GS", "UserHacks_CPUSpriteRenderLevel", 0);
@@ -194,6 +192,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
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.disableSafeFeatures, "EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableRenderFixes, "EmuCore/GS", "UserHacks_DisableRenderFixes", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preloadFrameData, "EmuCore/GS", "preload_frame_with_gs_data", false);
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.disablePartialInvalidation, "EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
@@ -253,6 +252,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "EmuCore/GS", "DisableFramebufferFetch", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "EmuCore/GS", "DisableDualSourceBlend", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableShaderCache, "EmuCore/GS", "DisableShaderCache", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableVertexShaderExpand, "EmuCore/GS", "DisableVertexShaderExpand", false);
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.gsDownloadMode, "EmuCore/GS", "HWDownloadMode", static_cast<int>(GSHardwareDownloadMode::Enabled));
@@ -471,9 +471,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
"Unscaled: Native Dithering / Lowest dithering effect does not increase size of squares when upscaling.<br> "
"Scaled: Upscaling-aware / Highest dithering effect."));
dialog->registerWidgetHelp(m_ui.crcFixLevel, tr("CRC Fix Level"), tr("Automatic (Default)"),
tr("Control the number of Auto-CRC fixes and hacks applied to games."));
dialog->registerWidgetHelp(m_ui.blending, tr("Blending Accuracy"), tr("Basic (Recommended)"),
tr("Control the accuracy level of the GS blending unit emulation.<br> "
"The higher the setting, the more blending is emulated in the shader accurately, and the higher the speed penalty will "
@@ -545,6 +542,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
"Disables accurate GS Memory Clearing to be done on the CPU, and let the GPU handle it, which can help Kingdom Hearts "
"games."));
dialog->registerWidgetHelp(
m_ui.disableRenderFixes, tr("Disable Render Fixes"), tr("Unchecked"), tr("This option disables game-specific render fixes."));
dialog->registerWidgetHelp(m_ui.disablePartialInvalidation, tr("Disable Partial Source Invalidation"), tr("Unchecked"),
tr("By default, the texture cache handles partial invalidations. Unfortunately it is very costly to compute CPU wise. "
"This hack replaces the partial invalidation with a complete deletion of the texture to reduce the CPU load. "
@@ -1051,7 +1051,6 @@ void GraphicsSettingsWidget::resetManualHardwareFixes()
check_bool("EmuCore/GS", "UserHacks", false);
check_int("EmuCore/GS", "crc_hack_level", static_cast<int>(CRCHackLevel::Automatic));
check_int("EmuCore/GS", "UserHacks_Half_Bottom_Override", -1);
check_int("EmuCore/GS", "UserHacks_CPUSpriteRenderBW", 0);
check_int("EmuCore/GS", "UserHacks_CPUCLUTRender", 0);
@@ -1062,6 +1061,7 @@ void GraphicsSettingsWidget::resetManualHardwareFixes()
check_bool("EmuCore/GS", "UserHacks_CPU_FB_Conversion", false);
check_bool("EmuCore/GS", "UserHacks_DisableDepthSupport", false);
check_bool("EmuCore/GS", "UserHacks_Disable_Safe_Features", false);
check_bool("EmuCore/GS", "UserHacks_DisableRenderFixes", false);
check_bool("EmuCore/GS", "preload_frame_with_gs_data", false);
check_bool("EmuCore/GS", "UserHacks_DisablePartialInvalidation", false);
check_int("EmuCore/GS", "UserHacks_TextureInsideRt", static_cast<int>(GSTextureInRtMode::Disabled));
+91 -118
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>720</width>
<height>498</height>
<height>492</height>
</rect>
</property>
<property name="windowTitle">
@@ -781,54 +781,13 @@
</attribute>
<layout class="QFormLayout" name="hardwareFixesLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>CRC Fix Level:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="crcFixLevel">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>None (Debug)</string>
</property>
</item>
<item>
<property name="text">
<string>Minimum (Debug)</string>
</property>
</item>
<item>
<property name="text">
<string>Partial (OpenGL)</string>
</property>
</item>
<item>
<property name="text">
<string>Full (Direct3D)</string>
</property>
</item>
<item>
<property name="text">
<string>Aggressive</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Half Screen Fix:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="QComboBox" name="halfScreenFix">
<item>
<property name="text">
@@ -847,14 +806,14 @@
</item>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_36">
<property name="text">
<string>CPU Sprite Render Size:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
<item>
<widget class="QComboBox" name="cpuSpriteRenderBW">
@@ -936,14 +895,14 @@
</item>
</layout>
</item>
<item row="3" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Software CLUT Render:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="2" column="1">
<widget class="QComboBox" name="cpuCLUTRender">
<property name="currentText">
<string extracomment="0 (Disabled)">0 (Disabled)</string>
@@ -968,14 +927,14 @@
</item>
</widget>
</item>
<item row="4" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_47">
<property name="text">
<string extracomment="CLUT: Color Look Up Table, often referred to as a palette in non-PS2 things. GPU Target CLUT: GPU handling of when a game uses data from a render target as a CLUT.">GPU Target CLUT:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="3" column="1">
<widget class="QComboBox" name="gpuTargetCLUTMode">
<item>
<property name="text">
@@ -994,40 +953,14 @@
</item>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Texture Inside RT:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="textureInsideRt">
<item>
<property name="text">
<string>Disabled (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Inside Target</string>
</property>
</item>
<item>
<property name="text">
<string>Merge Targets</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Auto Flush:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="4" column="1">
<widget class="QComboBox" name="hwAutoFlush">
<item>
<property name="text">
@@ -1046,14 +979,40 @@
</item>
</widget>
</item>
<item row="7" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Texture Inside RT:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="textureInsideRt">
<item>
<property name="text">
<string>Disabled (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Inside Target</string>
</property>
</item>
<item>
<property name="text">
<string>Merge Targets</string>
</property>
</item>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Skipdraw Range:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="skipDrawStart">
@@ -1071,7 +1030,7 @@
</item>
</layout>
</item>
<item row="8" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="disableDepthEmulation">
@@ -1094,45 +1053,52 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="estimateTextureRegion">
<item row="4" column="1">
<widget class="QCheckBox" name="targetPartialInvalidation">
<property name="text">
<string>Estimate Texture Region</string>
<string>Target Partial Invalidation</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="frameBufferConversion">
<property name="text">
<string>Frame Buffer Conversion</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="gpuPaletteConversion">
<property name="text">
<string>GPU Palette Conversion</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="preloadFrameData">
<property name="text">
<string>Preload Frame Data</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QCheckBox" name="readTCOnClose">
<property name="text">
<string>Read Targets When Closing</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="targetPartialInvalidation">
<item row="2" column="1">
<widget class="QCheckBox" name="preloadFrameData">
<property name="text">
<string>Target Partial Invalidation</string>
<string>Preload Frame Data</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="gpuPaletteConversion">
<property name="text">
<string>GPU Palette Conversion</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="frameBufferConversion">
<property name="text">
<string>Frame Buffer Conversion</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="estimateTextureRegion">
<property name="text">
<string>Estimate Texture Region</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="disableRenderFixes">
<property name="text">
<string>Disable Render Fixes</string>
</property>
</widget>
</item>
@@ -2180,13 +2146,6 @@
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QCheckBox" name="disableDualSource">
<property name="text">
<string>Disable Dual Source Blending</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="disableFramebufferFetch">
<property name="text">
@@ -2194,10 +2153,10 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="useDebugDevice">
<item row="0" column="0">
<widget class="QCheckBox" name="disableDualSource">
<property name="text">
<string>Use Debug Device</string>
<string>Disable Dual Source Blending</string>
</property>
</widget>
</item>
@@ -2208,6 +2167,20 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="useDebugDevice">
<property name="text">
<string>Use Debug Device</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="disableVertexShaderExpand">
<property name="text">
<string>Disable Vertex Shader Expand</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
+4 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,12 +15,14 @@
#include "PrecompiledHeader.h"
#include "Frontend/InputManager.h"
#include "Settings/HotkeySettingsWidget.h"
#include "Settings/ControllerSettingsDialog.h"
#include "InputBindingWidget.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "pcsx2/Input/InputManager.h"
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMessageBox>
+5 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,9 +14,12 @@
*/
#pragma once
#include "ui_InputBindingDialog.h"
#include "pcsx2/Config.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Input/InputManager.h"
#include <QtWidgets/QDialog>
#include <optional>
#include <string>
+2 -2
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -24,7 +24,7 @@
#include <cmath>
#include <sstream>
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
+4 -3
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,9 +14,10 @@
*/
#pragma once
#include "common/Pcsx2Defs.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/Config.h"
#include "pcsx2/Input/InputManager.h"
#include <QtWidgets/QPushButton>
#include <optional>
#include <utility>
+22 -26
View File
@@ -15,38 +15,34 @@
#include "PrecompiledHeader.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/INISettingsInterface.h"
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "Settings/AchievementSettingsWidget.h"
#include "Settings/AdvancedSettingsWidget.h"
#include "Settings/AudioSettingsWidget.h"
#include "Settings/BIOSSettingsWidget.h"
#include "Settings/DEV9SettingsWidget.h"
#include "Settings/DebugSettingsWidget.h"
#include "Settings/EmulationSettingsWidget.h"
#include "Settings/FolderSettingsWidget.h"
#include "Settings/GameFixSettingsWidget.h"
#include "Settings/GameListSettingsWidget.h"
#include "Settings/GameSummaryWidget.h"
#include "Settings/GraphicsSettingsWidget.h"
#include "Settings/HotkeySettingsWidget.h"
#include "Settings/InterfaceSettingsWidget.h"
#include "Settings/MemoryCardSettingsWidget.h"
#include "SettingsDialog.h"
#include "AdvancedSettingsWidget.h"
#include "AudioSettingsWidget.h"
#include "BIOSSettingsWidget.h"
#include "EmulationSettingsWidget.h"
#include "GameSummaryWidget.h"
#include "GameFixSettingsWidget.h"
#include "GameListSettingsWidget.h"
#include "GraphicsSettingsWidget.h"
#include "DEV9SettingsWidget.h"
#include "FolderSettingsWidget.h"
#include "HotkeySettingsWidget.h"
#include "InterfaceSettingsWidget.h"
#include "MemoryCardSettingsWidget.h"
#include "DebugSettingsWidget.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/GameList.h"
#include "pcsx2/Host.h"
#include "pcsx2/INISettingsInterface.h"
#ifdef ENABLE_ACHIEVEMENTS
#include "AchievementSettingsWidget.h"
#include "pcsx2/Frontend/Achievements.h"
#endif
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QTextEdit>
+1 -1
View File
@@ -17,7 +17,7 @@
#include "QtHost.h"
#include "pcsx2/Config.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Host.h"
#include "common/Path.h"
+12 -70
View File
@@ -21,7 +21,7 @@
<ImportGroup Label="PropertySheets">
<Import Project="$(SolutionDir)common\vsprops\common.props" />
<Import Project="$(SolutionDir)common\vsprops\BaseProperties.props" />
<Import Project="$(SolutionDir)common\vsprops\3rdpartyDeps.props" />
<Import Project="$(SolutionDir)common\vsprops\GenerateSCMVersion.props" />
<Import Project="$(SolutionDir)common\vsprops\QtCompile.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="$(SolutionDir)common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Devel))" Project="$(SolutionDir)common\vsprops\CodeGen_Devel.props" />
@@ -35,51 +35,24 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xbyak;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\freetype\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xz\xz\src\liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\baseclasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\simpleini\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\lzma\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\demangler\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\sdl2\include;$(SolutionDir)3rdparty\sdl2\SDL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)pcsx2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\fmt\fmt\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\lzma\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\simpleini\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\demangler\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\sdl2\include;$(SolutionDir)3rdparty\sdl2\SDL\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)pcsx2</AdditionalIncludeDirectories>
<!-- Needed for moc pch -->
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(ProjectDir)\Settings;$(ProjectDir)\GameList;$(ProjectDir)\Tools\InputRecording;$(ProjectDir)\Debugger;$(ProjectDir)\Debugger\Models</AdditionalIncludeDirectories>
<ExceptionHandling>Async</ExceptionHandling>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;DIRECTINPUT_VERSION=0x0800;SDL_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- MSVC automatically adds __AVX__ and __AVX2__ appropriately -->
<PreprocessorDefinitions>__SSE4_1__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2)) Or $(Configuration.Contains(Clang))">NotSet</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2)) And !$(Configuration.Contains(Clang))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And !$(Configuration.Contains(AVX2))"> -march=nehalem %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(AVX2))"> -march=haswell %(AdditionalOptions)</AdditionalOptions>
<MinimalRebuild>false</MinimalRebuild>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
<!-- SH 2/3 flashlight, explicitly set here don't change -->
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;SDL_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- Current Qt debug builds assert on RTTI. Remove this once we next build Qt. -->
<RuntimeTypeInfo Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Debug))">true</RuntimeTypeInfo>
<AdditionalOptions>/Zc:__cplusplus /Zo /utf-8%(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<LargeAddressAware>Yes</LargeAddressAware>
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;d3d12.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;OneCore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(QtEntryPointLib);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
@@ -90,46 +63,15 @@
<ProjectReference Include="$(SolutionDir)3rdparty\fmt\fmt.vcxproj">
<Project>{449ad25e-424a-4714-babc-68706cdcc33b}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\libjpeg\libjpeg.vcxproj">
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj">
<Project>{d6973076-9317-4ef2-a0b8-b7a18ac0713e}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\soundtouch\SoundTouch.vcxproj">
<Project>{e9b51944-7e6d-4bcd-83f2-7bbd5a46182d}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\xz\liblzma.vcxproj">
<Project>{12728250-16ec-4dc6-94d7-e21dd88947f8}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\libchdr\libchdr.vcxproj">
<Project>{a0d2b3ad-1f72-4ee3-8b5c-f2c358da35f0}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\zlib\zlib.vcxproj">
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\jpgd\jpgd.vcxproj">
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\imgui\imgui.vcxproj">
<Project>{88fb34ec-845e-4f21-a552-f1573b9ed167}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)common\common.vcxproj">
<Project>{4639972e-424e-4e13-8b07-ca403c481346}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2core.vcxproj">
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2.vcxproj">
<Project>{6c7986c4-3e4d-4dcc-b3c6-6bb12b238995}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\lzma\lzma.vcxproj">
<Project>{a4323327-3f2b-4271-83d9-7f9a3c66b6b2}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\zydis\zydis.vcxproj">
<Project>{67d0160c-0fe4-44b9-ac2e-82bbcf4104df}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\demangler\demangler.vcxproj">
<Project>{1e3d706c-1d95-4e1b-bdf2-ca3d0007df7f}</Project>
</ProjectReference>
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -15,48 +15,47 @@
#include "PrecompiledHeader.h"
#include "Frontend/Achievements.h"
#include "Frontend/CommonHost.h"
#include "Frontend/FullscreenUI.h"
#include "Frontend/ImGuiFullscreen.h"
#include "Frontend/ImGuiManager.h"
#ifdef ENABLE_ACHIEVEMENTS
#include "Achievements.h"
#include "CDVD/IsoFS/IsoFS.h"
#include "CDVD/IsoFS/IsoFSCDVD.h"
#include "Elfheader.h"
#include "GS.h"
#include "Host.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiFullscreen.h"
#include "ImGui/ImGuiManager.h"
#include "IopMem.h"
#include "Memory.h"
#include "VMManager.h"
#include "svnrev.h"
#include "vtlb.h"
#include "common/Assertions.h"
#include "common/FileSystem.h"
#include "common/HTTPDownloader.h"
#include "common/Console.h"
#include "common/FileSystem.h"
#include "common/General.h"
#include "common/HTTPDownloader.h"
#include "common/MD5Digest.h"
#include "common/Path.h"
#include "common/ScopedGuard.h"
#include "common/StringUtil.h"
#include "common/Timer.h"
#include "fmt/core.h"
#include "rc_api_info.h"
#include "rc_api_request.h"
#include "rc_api_runtime.h"
#include "rc_api_user.h"
#include "rcheevos.h"
#include "fmt/core.h"
#include "CDVD/IsoFS/IsoFSCDVD.h"
#include "CDVD/IsoFS/IsoFS.h"
#include "Elfheader.h"
#include "GS.h"
#include "Host.h"
#include "HostSettings.h"
#include "IopMem.h"
#include "Memory.h"
#include "VMManager.h"
#include "vtlb.h"
#include "svnrev.h"
#include <algorithm>
#include <array>
#include <cstdarg>
#include <cstdlib>
#include <limits>
#include <functional>
#include <limits>
#include <optional>
#include <string>
#include <vector>
@@ -397,10 +396,8 @@ void Achievements::ClearGameInfo(bool clear_achievements, bool clear_leaderboard
s_has_rich_presence = false;
s_game_id = 0;
#ifdef ENABLE_DISCORD_PRESENCE
if (EmuConfig.EnableDiscordPresence)
CommonHost::UpdateDiscordPresence(s_rich_presence_string);
#endif
VMManager::UpdateDiscordPresence(s_rich_presence_string);
}
if (had_game)
@@ -879,6 +876,17 @@ const std::string& Achievements::GetRichPresenceString()
return s_rich_presence_string;
}
std::string Achievements::SafeGetRichPresenceString()
{
std::string rich_presence_string;
if (IsActive() && EmuConfig.Achievements.RichPresence)
{
std::unique_lock lock(s_achievements_mutex);
rich_presence_string = s_rich_presence_string;
}
return rich_presence_string;
}
void Achievements::EnsureCacheDirectoriesExist()
{
s_game_icon_cache_directory = Path::Combine(EmuFolders::Cache, "achievement_gameicon");
@@ -1351,8 +1359,19 @@ std::optional<std::vector<u8>> Achievements::ReadELFFromCurrentDisc(const std::s
std::optional<std::vector<u8>> ret;
try
{
// ELF suffix hack. Taken from CDVD::loadElf
// MLB2k6 has an elf whose suffix is actually ;2
std::string filepath(elf_path);
const std::string::size_type semi_pos = filepath.rfind(';');
if (semi_pos != std::string::npos && std::string_view(filepath).substr(semi_pos) != ";1")
{
Console.Warning("(Achievements) Non-conforming version suffix (%s) detected and replaced.", elf_path.c_str());
filepath.erase(semi_pos);
filepath += ";1";
}
IsoFSCDVD isofs;
IsoFile file(isofs, elf_path);
IsoFile file(isofs, filepath);
const u32 size = file.getLength();
ret = std::vector<u8>();
@@ -1550,10 +1569,8 @@ void Achievements::UpdateRichPresence()
Host::OnAchievementsRefreshed();
#ifdef ENABLE_DISCORD_PRESENCE
if (EmuConfig.EnableDiscordPresence)
CommonHost::UpdateDiscordPresence(s_rich_presence_string);
#endif
VMManager::UpdateDiscordPresence(s_rich_presence_string);
}
void Achievements::SendPingCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data)
@@ -2262,4 +2279,6 @@ void Achievements::RAIntegration::RACallbackWriteMemory(unsigned int address, un
PokeMemory(address, sizeof(value), nullptr, static_cast<unsigned>(value));
}
#endif
#endif // ENABLE_RAINTEGRATION
#endif // ENABLE_ACHIEVEMENTS
+192 -14
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,34 +14,190 @@
*/
#pragma once
#include "common/Pcsx2Types.h"
#include "Config.h"
#include <functional>
#include <mutex>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#ifdef ENABLE_ACHIEVEMENTS
namespace Achievements
{
#ifdef ENABLE_ACHIEVEMENTS
enum class AchievementCategory : u8
{
Local = 0,
Core = 3,
Unofficial = 5
};
// Implemented in Host.
extern bool OnReset();
extern void LoadState(const u8* state_data, u32 state_data_size);
extern std::vector<u8> SaveState();
extern void GameChanged(u32 crc);
struct Achievement
{
u32 id;
std::string title;
std::string description;
std::string memaddr;
std::string badge_name;
// badge paths are mutable because they're resolved when they're needed.
mutable std::string locked_badge_path;
mutable std::string unlocked_badge_path;
u32 points;
AchievementCategory category;
bool locked;
bool active;
bool primed;
};
struct Leaderboard
{
u32 id;
std::string title;
std::string description;
int format;
};
struct LeaderboardEntry
{
std::string user;
std::string formatted_score;
time_t submitted;
u32 rank;
bool is_self;
};
// RAIntegration only exists for Windows, so no point checking it on other platforms.
#ifdef ENABLE_RAINTEGRATION
bool IsUsingRAIntegration();
#else
__fi static bool IsUsingRAIntegration()
{
return false;
}
#endif
bool IsActive();
bool IsLoggedIn();
bool ChallengeModeActive();
bool LeaderboardsActive();
bool IsTestModeActive();
bool IsUnofficialTestModeActive();
bool IsRichPresenceEnabled();
bool HasActiveGame();
u32 GetGameID();
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
std::unique_lock<std::recursive_mutex> GetLock();
void Initialize();
void UpdateSettings(const Pcsx2Config::AchievementsOptions& old_config);
/// Called when the system is being reset. If it returns false, the reset should be aborted.
bool OnReset();
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
bool Shutdown();
/// Called when the system is being paused and resumed.
void OnPaused(bool paused);
/// Called once a frame at vsync time on the CPU thread.
void VSyncUpdate();
/// Called to process pending HTTP requests when the VM is paused, because otherwise the vsync event won't fire.
void ProcessPendingHTTPRequestsFromGSThread();
void LoadState(const u8* state_data, u32 state_data_size);
std::vector<u8> SaveState();
/// Returns true if the current game has any achievements or leaderboards.
/// Does not need to have the lock held.
bool SafeHasAchievementsOrLeaderboards();
const std::string& GetUsername();
const std::string& GetRichPresenceString();
std::string SafeGetRichPresenceString();
bool LoginAsync(const char* username, const char* password);
bool Login(const char* username, const char* password);
void Logout();
void GameChanged(u32 crc);
const std::string& GetGameTitle();
const std::string& GetGameIcon();
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
u32 GetUnlockedAchiementCount();
u32 GetAchievementCount();
u32 GetMaximumPointsForGame();
u32 GetCurrentPointsForGame();
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
const Leaderboard* GetLeaderboardByID(u32 id);
u32 GetLeaderboardCount();
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
const Achievement* GetAchievementByID(u32 id);
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
std::string GetAchievementProgressText(const Achievement& achievement);
const std::string& GetAchievementBadgePath(
const Achievement& achievement, bool download_if_missing = true, bool force_unlocked_icon = false);
std::string GetAchievementBadgeURL(const Achievement& achievement);
u32 GetPrimedAchievementCount();
#ifdef ENABLE_RAINTEGRATION
void SwitchToRAIntegration();
namespace RAIntegration
{
void MainWindowChanged(void* new_handle);
void GameChanged();
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
void ActivateMenuItem(int item);
} // namespace RAIntegration
#endif
/// Re-enables hardcode mode if it is enabled in the settings.
extern bool ResetChallengeMode();
bool ResetChallengeMode();
/// Forces hardcore mode off until next reset.
extern void DisableChallengeMode();
void DisableChallengeMode();
/// Prompts the user to disable hardcore mode, if they agree, returns true.
extern bool ConfirmChallengeModeDisable(const char* trigger);
bool ConfirmChallengeModeDisable(const char* trigger);
/// Returns true if features such as save states should be disabled.
extern bool ChallengeModeActive();
bool ChallengeModeActive();
} // namespace Achievements
#else
// Make noops when compiling without cheevos.
// Make noops when compiling without cheevos.
namespace Achievements
{
static inline void Initialize()
{
}
static inline void UpdateSettings(const Pcsx2Config::AchievementsOptions& old_config)
{
}
static inline void Shutdown()
{
}
static inline bool OnReset()
{
return true;
@@ -67,12 +223,34 @@ namespace Achievements
return false;
}
static inline void DisableChallengeMode() {}
static inline void DisableChallengeMode()
{
}
static inline bool ConfirmChallengeModeDisable(const char* trigger)
{
return true;
}
#endif
static inline void OnPaused(bool paused)
{
}
static inline void VSyncUpdate()
{
}
static std::string SafeGetRichPresenceString()
{
return {};
}
} // namespace Achievements
#endif
/// Functions implemented in the frontend.
namespace Host
{
void OnAchievementsRefreshed();
void OnAchievementsChallengeModeChanged();
} // namespace Host
+7
View File
@@ -18,6 +18,7 @@
#include "Common.h"
#include "IopHw.h"
#include "IopDma.h"
#include "VMManager.h"
#include <cctype>
#include <ctime>
@@ -1447,6 +1448,12 @@ void cdvdUpdateTrayState()
cdvd.Tray.trayState = CDVD_DISC_SEEKING;
cdvdUpdateStatus(CDVD_STATUS_SEEK);
cdvd.Tray.cdvdActionSeconds = 2;
// If we're swapping disc, reload the elf, patches etc to reflect the new disc.
if (g_GameStarted)
{
cdvdReloadElfInfo();
VMManager::Internal::SwappingGameOnCPUThread();
}
break;
case CDVD_DISC_SEEKING:
cdvd.Spinning = true;
+4 -5
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,16 +14,15 @@
*/
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "CsoFileReader.h"
#include "common/Pcsx2Types.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#ifdef __POSIX__
#include <zlib.h>
#else
#include <zlib/zlib.h>
#endif
// Implementation of CSO compressed ISO reading, based on:
// https://github.com/unknownbrackets/maxcso/blob/master/README_CSO.md
+9 -6
View File
@@ -14,15 +14,18 @@
*/
#include "PrecompiledHeader.h"
#include <fstream>
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "Config.h"
#include "ChunksCache.h"
#include "GzippedFileReader.h"
#include "HostSettings.h"
#include "zlib_indexed.h"
#include "Host.h"
#include "CDVD/zlib_indexed.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <fstream>
#define CLAMP(val, minval, maxval) (std::min(maxval, std::max(minval, val)))
-4
View File
@@ -100,11 +100,7 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __POSIX__
#include <zlib.h>
#else
#include <zlib/zlib.h>
#endif
#include "common/FileSystem.h"
+53 -83
View File
@@ -60,8 +60,8 @@ if(TARGET SDL2::SDL2 OR TARGET SDL2::SDL2-static)
target_link_libraries(PCSX2_FLAGS INTERFACE SDL2::SDL2)
endif()
target_sources(PCSX2 PRIVATE
Frontend/SDLInputSource.cpp
Frontend/SDLInputSource.h
Input/SDLInputSource.cpp
Input/SDLInputSource.h
)
endif()
@@ -69,20 +69,17 @@ if(WIN32)
set(MIN_WIN32 0x0A00)
target_compile_definitions(PCSX2_FLAGS INTERFACE
__SSE4_1__
DIRECTINPUT_VERSION=0x0800
WINVER=${MIN_WIN32}
_WIN32_WINNT=${MIN_WIN32}
WIN32_LEAN_AND_MEAN
LZMA_API_STATIC
WIL_SUPPRESS_EXCEPTIONS
)
target_include_directories(PCSX2_FLAGS INTERFACE
../3rdparty # GL headers
)
endif(WIN32)
# Main pcsx2 source
set(pcsx2Sources
Achievements.cpp
Cache.cpp
COP0.cpp
COP2.cpp
@@ -93,14 +90,20 @@ set(pcsx2Sources
FW.cpp
FiFo.cpp
FPU.cpp
GameList.cpp
Gif.cpp
Gif_Logger.cpp
Gif_Unit.cpp
GS.cpp
GSDumpReplayer.cpp
Host.cpp
Hotkeys.cpp
Hw.cpp
HwRead.cpp
HwWrite.cpp
LayeredSettingsInterface.cpp
LogSink.cpp
INISettingsInterface.cpp
Interpreter.cpp
IopBios.cpp
IopCounters.cpp
@@ -150,6 +153,7 @@ set(pcsx2Sources
Vif_Transfer.cpp
Vif_Unpack.cpp
VirtualMemory.cpp
VMManager.cpp
vtlb.cpp
VU0.cpp
VUmicro.cpp
@@ -159,7 +163,8 @@ set(pcsx2Sources
VU1microInterp.cpp
VUflags.cpp
VUmicroMem.cpp
VUops.cpp)
VUops.cpp
)
# Main pcsx2 header
set(pcsx2Headers
@@ -174,18 +179,23 @@ set(pcsx2Headers
GameDatabase.h
Elfheader.h
FW.h
GameList.h
Gif.h
Gif_Unit.h
GS.h
GSDumpReplayer.h
Hardware.h
Host.h
Hw.h
INISettingsInterface.h
IopBios.h
IopCounters.h
IopDma.h
IopGte.h
IopHw.h
IopMem.h
LayeredSettingsInterface.h
LogSink.h
PINE.h
Mdec.h
MTVU.h
@@ -216,6 +226,7 @@ set(pcsx2Headers
Vif.h
Vif_Unpack.h
VirtualMemory.h
VMManager.h
vtlb.h
VUflags.h
VUmicro.h
@@ -615,7 +626,7 @@ if(USE_OPENGL)
list(APPEND pcsx2GSHeaders GS/Renderers/OpenGL/GLContextWGL.h)
target_link_libraries(PCSX2_FLAGS INTERFACE opengl32.lib)
elseif(APPLE)
list(APPEND pcsx2GSSources GS/Renderers/OpenGL/GLContextAGL.cpp)
list(APPEND pcsx2GSSources GS/Renderers/OpenGL/GLContextAGL.mm)
list(APPEND pcsx2GSHeaders GS/Renderers/OpenGL/GLContextAGL.h)
else()
if(X11_API OR WAYLAND_API)
@@ -647,7 +658,6 @@ if(USE_VULKAN)
GS/Renderers/Vulkan/VKShaderCache.cpp
GS/Renderers/Vulkan/VKStreamBuffer.cpp
GS/Renderers/Vulkan/VKSwapChain.cpp
GS/Renderers/Vulkan/VKTexture.cpp
GS/Renderers/Vulkan/VKUtil.cpp
)
list(APPEND pcsx2GSHeaders
@@ -661,23 +671,9 @@ if(USE_VULKAN)
GS/Renderers/Vulkan/VKShaderCache.h
GS/Renderers/Vulkan/VKStreamBuffer.h
GS/Renderers/Vulkan/VKSwapChain.h
GS/Renderers/Vulkan/VKTexture.h
GS/Renderers/Vulkan/VKUtil.h
)
target_link_libraries(PCSX2_FLAGS INTERFACE Vulkan-Headers glslang)
if(APPLE)
# Needed for Metal surface creation.
target_compile_options(common PRIVATE -fobjc-arc)
target_link_options(common PRIVATE -fobjc-link-runtime)
elseif(NOT WIN32)
if(X11_API)
target_compile_definitions(common PUBLIC "VULKAN_USE_X11=1")
endif()
if(WAYLAND_API)
target_compile_definitions(common PUBLIC "VULKAN_USE_WAYLAND=1")
endif()
endif()
endif()
set(pcsx2GSMetalShaders
@@ -719,7 +715,6 @@ if(WIN32)
GS/Renderers/DX12/D3D12DescriptorHeapManager.cpp
GS/Renderers/DX12/D3D12ShaderCache.cpp
GS/Renderers/DX12/D3D12StreamBuffer.cpp
GS/Renderers/DX12/D3D12Texture.cpp
GS/Renderers/DX12/GSDevice12.cpp
GS/Renderers/DX12/GSTexture12.cpp
)
@@ -733,7 +728,6 @@ if(WIN32)
GS/Renderers/DX12/D3D12DescriptorHeapManager.h
GS/Renderers/DX12/D3D12ShaderCache.h
GS/Renderers/DX12/D3D12StreamBuffer.h
GS/Renderers/DX12/D3D12Texture.h
GS/Renderers/DX12/GSDevice12.h
GS/Renderers/DX12/GSTexture12.h
)
@@ -850,16 +844,27 @@ set(pcsx2DebugToolsHeaders
DebugTools/DisVUops.h
DebugTools/BiosDebugData.h)
# Frontend sources
set(pcsx2FrontendSources
Frontend/ImGuiManager.cpp
Frontend/ImGuiOverlays.cpp
set(pcsx2ImGuiSources
ImGui/FullscreenUI.cpp
ImGui/ImGuiFullscreen.cpp
ImGui/ImGuiManager.cpp
ImGui/ImGuiOverlays.cpp
)
# Frontend headers
set(pcsx2FrontendHeaders
Frontend/ImGuiManager.h
Frontend/ImGuiOverlays.h
set(pcsx2ImGuiHeaders
ImGui/FullscreenUI.h
ImGui/ImGuiFullscreen.h
ImGui/ImGuiManager.h
ImGui/ImGuiOverlays.h
)
set(pcsx2InputSources
Input/InputManager.cpp
Input/InputSource.cpp
)
set(pcsx2InputHeaders
Input/InputManager.h
Input/InputSource.h
)
if(APPLE)
@@ -878,42 +883,7 @@ if(APPLE)
)
endif()
list(APPEND pcsx2FrontendSources
Frontend/CommonHost.cpp
Frontend/CommonHotkeys.cpp
Frontend/FullscreenUI.cpp
Frontend/GameList.cpp
Frontend/HostSettings.cpp
Frontend/ImGuiFullscreen.cpp
Frontend/InputManager.cpp
Frontend/InputSource.cpp
Frontend/LayeredSettingsInterface.cpp
Frontend/LogSink.cpp
GSDumpReplayer.cpp
INISettingsInterface.cpp
VMManager.cpp
)
list(APPEND pcsx2FrontendHeaders
Frontend/CommonHost.h
Frontend/FullscreenUI.h
Frontend/GameList.h
Frontend/ImGuiFullscreen.h
Frontend/InputManager.h
Frontend/InputSource.h
Frontend/LayeredSettingsInterface.h
Frontend/LogSink.h
GSDumpReplayer.h
HostSettings.h
INISettingsInterface.h
VMManager.h)
if(USE_ACHIEVEMENTS)
list(APPEND pcsx2FrontendSources
Frontend/Achievements.cpp
)
list(APPEND pcsx2FrontendHeaders
Frontend/Achievements.h
)
target_compile_definitions(PCSX2_FLAGS INTERFACE
ENABLE_ACHIEVEMENTS
)
@@ -939,13 +909,13 @@ if(USE_DISCORD_PRESENCE)
)
endif()
if(WIN32)
list(APPEND pcsx2FrontendSources
Frontend/DInputSource.cpp
Frontend/XInputSource.cpp
list(APPEND pcsx2InputSources
Input/DInputSource.cpp
Input/XInputSource.cpp
)
list(APPEND pcsx2FrontendHeaders
Frontend/DInputSource.h
Frontend/XInputSource.h
list(APPEND pcsx2InputHeaders
Input/DInputSource.h
Input/XInputSource.h
)
endif()
@@ -1149,8 +1119,10 @@ target_sources(PCSX2 PRIVATE
${pcsx2RecordingSources}
${pcsx2DebugToolsSources}
${pcsx2DebugToolsHeaders}
${pcsx2FrontendSources}
${pcsx2FrontendHeaders}
${pcsx2ImGuiSources}
${pcsx2ImGuiHeaders}
${pcsx2InputSources}
${pcsx2InputHeaders}
${pcsx2ps2Sources}
${pcsx2ps2Headers}
)
@@ -1249,12 +1221,10 @@ endif()
# additonal include directories
target_include_directories(PCSX2_FLAGS INTERFACE
.
x86
${CMAKE_BINARY_DIR}/pcsx2
${CMAKE_BINARY_DIR}/common/include/
"${CMAKE_SOURCE_DIR}/3rdparty/jpgd/"
"${CMAKE_SOURCE_DIR}/3rdparty/xbyak/"
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_BINARY_DIR}/pcsx2"
"${CMAKE_BINARY_DIR}/common/include"
"${CMAKE_SOURCE_DIR}/3rdparty/xbyak"
"${FFMPEG_INCLUDE_DIRS}"
)
@@ -1413,7 +1383,7 @@ function(setup_main_executable target)
endif()
endfunction()
source_groups_from_vcxproj_filters(pcsx2core.vcxproj.filters)
source_groups_from_vcxproj_filters(pcsx2.vcxproj.filters)
# Unix-only files aren't in the vcxproj.filters
source_group(System/Ps2/DEV9 REGULAR_EXPRESSION DEV9/*)
+7 -11
View File
@@ -288,16 +288,6 @@ enum class HWMipmapLevel : s8
Full
};
enum class CRCHackLevel : s8
{
Automatic = -1,
Off,
Minimum,
Partial,
Full,
Aggressive
};
enum class AccBlendLevel : u8
{
Minimum,
@@ -657,6 +647,7 @@ struct Pcsx2Config
DisableShaderCache : 1,
DisableDualSourceBlend : 1,
DisableFramebufferFetch : 1,
DisableVertexShaderExpand : 1,
DisableThreadedPresentation : 1,
SkipDuplicateFrames : 1,
OsdShowMessages : 1,
@@ -685,6 +676,7 @@ struct Pcsx2Config
UserHacks_DisableDepthSupport : 1,
UserHacks_DisablePartialInvalidation : 1,
UserHacks_DisableSafeFeatures : 1,
UserHacks_DisableRenderFixes : 1,
UserHacks_MergePPSprite : 1,
UserHacks_WildHack : 1,
UserHacks_BilinearHack : 1,
@@ -742,7 +734,6 @@ struct Pcsx2Config
HWMipmapLevel HWMipmap = HWMipmapLevel::Automatic;
AccBlendLevel AccurateBlendingUnit = AccBlendLevel::Basic;
CRCHackLevel CRCHack = CRCHackLevel::Automatic;
BiFiltering TextureFiltering = BiFiltering::PS2;
TexturePreloadingLevel TexturePreloading = TexturePreloadingLevel::Full;
GSDumpCompressionMethod GSDumpCompression = GSDumpCompressionMethod::Zstandard;
@@ -1302,6 +1293,8 @@ struct Pcsx2Config
McdOptions Mcd[8];
std::string GzipIsoIndexTemplate; // for quick-access index with gzipped ISO
int PINESlot;
// Set at runtime, not loaded from config.
std::string CurrentBlockdump;
std::string CurrentIRX;
@@ -1352,6 +1345,9 @@ namespace EmuFolders
extern std::string InputProfiles;
extern std::string Videos;
/// Initializes critical folders (AppRoot, DataRoot, Settings). Call once on startup.
bool InitializeCriticalFolders();
// Assumes that AppRoot and DataRoot have been initialized.
void SetDefaults(SettingsInterface& si);
void LoadConfig(SettingsInterface& si);
+3 -3
View File
@@ -99,7 +99,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
WriteUInt16(identifyData, &index, sectorSize); //word 5
//Default Number of sectors per track (Retired)
WriteUInt16(identifyData, &index, defSectors); //word 6
//Reserved for assignment by the CompactFlash™ Association
//Reserved for assignment by the CompactFlash™ Association
index += 2 * 2; //word 7-8
//Retired
index += 1 * 2; //word 9
@@ -182,7 +182,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
WriteUInt16(identifyData, &index, 0x1F); //word 64 (pio3,4 supported) selection not reported here
//Minimum Multiword DMA transfer cycle time per word
WriteUInt16(identifyData, &index, 80); //word 65
//Manufacturers recommended Multiword DMA transfer cycle time
//Manufacturers recommended Multiword DMA transfer cycle time
WriteUInt16(identifyData, &index, 80); //word 66
//Minimum PIO transfer cycle time without flow control
WriteUInt16(identifyData, &index, 120); //word 67
@@ -307,7 +307,7 @@ void ATA::CreateHDDinfo(u64 sizeSectors)
*/
index = 93 * 2;
WriteUInt16(identifyData, &index, (u16)(1 | (1 << 14) | 0x2000)); //word 93
//Vendors recommended acoustic management value.
//Vendors recommended acoustic management value.
//94
//Stream Minimum Request Size
//95
+1 -1
View File
@@ -468,7 +468,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
valueStack.push_back(val);
}
break;
case EXOP_SIGNPLUS: // keine aktion nötig
case EXOP_SIGNPLUS: // keine aktion nötig
break;
case EXOP_SIGNMINUS: // -0
if (useFloat)
+2
View File
@@ -27,6 +27,7 @@ u32 ElfEntry;
std::pair<u32,u32> ElfTextRange;
std::string LastELF;
bool isPSXElf;
std::string ElfVersion;
// All of ElfObjects functions.
ElfObject::ElfObject(std::string srcfile, IsoFile& isofile, bool isPSXElf)
@@ -365,6 +366,7 @@ int GetPS2ElfName( std::string& name )
{
Console.WriteLn( Color_Blue, "(SYSTEM.CNF) Software version = %.*s",
static_cast<int>(value.size()), value.data());
ElfVersion = value;
}
}
+1
View File
@@ -163,3 +163,4 @@ extern u32 ElfEntry;
extern std::pair<u32,u32> ElfTextRange;
extern std::string LastELF;
extern bool isPSXElf;
extern std::string ElfVersion;
-173
View File
@@ -1,173 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Defs.h"
#include "pcsx2/Achievements.h"
#include "Config.h"
#include <functional>
#include <mutex>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
namespace Achievements
{
enum class AchievementCategory : u8
{
Local = 0,
Core = 3,
Unofficial = 5
};
struct Achievement
{
u32 id;
std::string title;
std::string description;
std::string memaddr;
std::string badge_name;
// badge paths are mutable because they're resolved when they're needed.
mutable std::string locked_badge_path;
mutable std::string unlocked_badge_path;
u32 points;
AchievementCategory category;
bool locked;
bool active;
bool primed;
};
struct Leaderboard
{
u32 id;
std::string title;
std::string description;
int format;
};
struct LeaderboardEntry
{
std::string user;
std::string formatted_score;
time_t submitted;
u32 rank;
bool is_self;
};
// RAIntegration only exists for Windows, so no point checking it on other platforms.
#ifdef ENABLE_RAINTEGRATION
bool IsUsingRAIntegration();
#else
static __fi bool IsUsingRAIntegration() { return false; }
#endif
bool IsActive();
bool IsLoggedIn();
bool ChallengeModeActive();
bool LeaderboardsActive();
bool IsTestModeActive();
bool IsUnofficialTestModeActive();
bool IsRichPresenceEnabled();
bool HasActiveGame();
u32 GetGameID();
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
std::unique_lock<std::recursive_mutex> GetLock();
void Initialize();
void UpdateSettings(const Pcsx2Config::AchievementsOptions& old_config);
/// Called when the system is being reset. If it returns false, the reset should be aborted.
bool OnReset();
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
bool Shutdown();
/// Called when the system is being paused and resumed.
void OnPaused(bool paused);
/// Called once a frame at vsync time on the CPU thread.
void VSyncUpdate();
/// Called to process pending HTTP requests when the VM is paused, because otherwise the vsync event won't fire.
void ProcessPendingHTTPRequestsFromGSThread();
void LoadState(const u8* state_data, u32 state_data_size);
std::vector<u8> SaveState();
/// Returns true if the current game has any achievements or leaderboards.
/// Does not need to have the lock held.
bool SafeHasAchievementsOrLeaderboards();
const std::string& GetUsername();
const std::string& GetRichPresenceString();
bool LoginAsync(const char* username, const char* password);
bool Login(const char* username, const char* password);
void Logout();
void GameChanged(u32 crc);
const std::string& GetGameTitle();
const std::string& GetGameIcon();
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
u32 GetUnlockedAchiementCount();
u32 GetAchievementCount();
u32 GetMaximumPointsForGame();
u32 GetCurrentPointsForGame();
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
const Leaderboard* GetLeaderboardByID(u32 id);
u32 GetLeaderboardCount();
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
const Achievement* GetAchievementByID(u32 id);
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
std::string GetAchievementProgressText(const Achievement& achievement);
const std::string& GetAchievementBadgePath(
const Achievement& achievement, bool download_if_missing = true, bool force_unlocked_icon = false);
std::string GetAchievementBadgeURL(const Achievement& achievement);
u32 GetPrimedAchievementCount();
#ifdef ENABLE_RAINTEGRATION
void SwitchToRAIntegration();
namespace RAIntegration
{
void MainWindowChanged(void* new_handle);
void GameChanged();
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
void ActivateMenuItem(int item);
} // namespace RAIntegration
#endif
} // namespace Achievements
/// Functions implemented in the frontend.
namespace Host
{
void OnAchievementsRefreshed();
void OnAchievementsChallengeModeChanged();
} // namespace Host
-544
View File
@@ -1,544 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/CrashHandler.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/Timer.h"
#include "common/Threading.h"
#include "Frontend/CommonHost.h"
#include "Frontend/FullscreenUI.h"
#include "Frontend/GameList.h"
#include "Frontend/LayeredSettingsInterface.h"
#include "Frontend/InputManager.h"
#include "Frontend/LogSink.h"
#include "GS.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#include "Host.h"
#include "HostSettings.h"
#include "IconsFontAwesome5.h"
#include "MemoryCardFile.h"
#include "PAD/Host/PAD.h"
#include "PerformanceMetrics.h"
#include "Sio.h"
#include "VMManager.h"
#ifdef ENABLE_ACHIEVEMENTS
#include "Frontend/Achievements.h"
#endif
#ifdef ENABLE_DISCORD_PRESENCE
#include "discord_rpc.h"
#endif
#ifdef _WIN32
#include "common/RedtapeWindows.h"
#include <KnownFolders.h>
#include <ShlObj.h>
#endif
static constexpr u32 SETTINGS_VERSION = 1;
namespace CommonHost
{
static void SetAppRoot();
static void SetResourcesDirectory();
static bool ShouldUsePortableMode();
static void SetDataDirectory();
static void SetCommonDefaultSettings(SettingsInterface& si);
static void UpdateInhibitScreensaver(bool allow);
static void UpdateSessionTime(const std::string& new_serial);
#ifdef ENABLE_DISCORD_PRESENCE
static void InitializeDiscordPresence();
static void ShutdownDiscordPresence();
static void PollDiscordPresence();
static std::string GetRichPresenceString();
#endif
} // namespace CommonHost
// Used to track play time. We use a monotonic timer here, in case of clock changes.
static u64 s_session_start_time = 0;
static std::string s_session_serial;
static bool s_screensaver_inhibited = false;
#ifdef ENABLE_DISCORD_PRESENCE
static bool s_discord_presence_active = false;
#endif
bool CommonHost::InitializeCriticalFolders()
{
SetAppRoot();
SetResourcesDirectory();
SetDataDirectory();
// logging of directories in case something goes wrong super early
Console.WriteLn("AppRoot Directory: %s", EmuFolders::AppRoot.c_str());
Console.WriteLn("DataRoot Directory: %s", EmuFolders::DataRoot.c_str());
Console.WriteLn("Resources Directory: %s", EmuFolders::Resources.c_str());
// allow SetDataDirectory() to change settings directory (if we want to split config later on)
if (EmuFolders::Settings.empty())
{
EmuFolders::Settings = Path::Combine(EmuFolders::DataRoot, "inis");
// Create settings directory if it doesn't exist. If we're not using portable mode, it won't.
if (!FileSystem::DirectoryExists(EmuFolders::Settings.c_str()))
FileSystem::CreateDirectoryPath(EmuFolders::Settings.c_str(), false);
}
// Write crash dumps to the data directory, since that'll be accessible for certain.
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
// the resources directory should exist, bail out if not
if (!FileSystem::DirectoryExists(EmuFolders::Resources.c_str()))
{
Console.Error("Resources directory is missing.");
return false;
}
return true;
}
void CommonHost::SetAppRoot()
{
std::string program_path(FileSystem::GetProgramPath());
Console.WriteLn("Program Path: %s", program_path.c_str());
EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path));
}
void CommonHost::SetResourcesDirectory()
{
#ifndef __APPLE__
// On Windows/Linux, these are in the binary directory.
EmuFolders::Resources = Path::Combine(EmuFolders::AppRoot, "resources");
#else
// On macOS, this is in the bundle resources directory.
EmuFolders::Resources = Path::Canonicalize(Path::Combine(EmuFolders::AppRoot, "../Resources"));
#endif
}
bool CommonHost::ShouldUsePortableMode()
{
// Check whether portable.ini exists in the program directory.
return FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "portable.ini").c_str());
}
void CommonHost::SetDataDirectory()
{
if (ShouldUsePortableMode())
{
EmuFolders::DataRoot = EmuFolders::AppRoot;
return;
}
#if defined(_WIN32)
// On Windows, use My Documents\PCSX2 to match old installs.
PWSTR documents_directory;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory)))
{
if (std::wcslen(documents_directory) > 0)
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "PCSX2");
CoTaskMemFree(documents_directory);
}
#elif defined(__linux__) || defined(__FreeBSD__)
// Use $XDG_CONFIG_HOME/PCSX2 if it exists.
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
{
EmuFolders::DataRoot = Path::Combine(xdg_config_home, "PCSX2");
}
else
{
// Use ~/PCSX2 for non-XDG, and ~/.config/PCSX2 for XDG.
// Maybe we should drop the former when Qt goes live.
const char* home_dir = getenv("HOME");
if (home_dir)
{
#ifdef USE_LEGACY_USER_DIRECTORY
EmuFolders::DataRoot = Path::Combine(home_dir, "PCSX2");
#else
// ~/.config should exist, but just in case it doesn't and this is a fresh profile..
const std::string config_dir(Path::Combine(home_dir, ".config"));
if (!FileSystem::DirectoryExists(config_dir.c_str()))
FileSystem::CreateDirectoryPath(config_dir.c_str(), false);
EmuFolders::DataRoot = Path::Combine(config_dir, "PCSX2");
#endif
}
}
#elif defined(__APPLE__)
static constexpr char MAC_DATA_DIR[] = "Library/Application Support/PCSX2";
const char* home_dir = getenv("HOME");
if (home_dir)
EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR);
#endif
// make sure it exists
if (!EmuFolders::DataRoot.empty() && !FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str()))
{
// we're in trouble if we fail to create this directory... but try to hobble on with portable
if (!FileSystem::CreateDirectoryPath(EmuFolders::DataRoot.c_str(), false))
EmuFolders::DataRoot.clear();
}
// couldn't determine the data directory? fallback to portable.
if (EmuFolders::DataRoot.empty())
EmuFolders::DataRoot = EmuFolders::AppRoot;
}
bool CommonHost::CheckSettingsVersion()
{
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
uint settings_version;
return (bsi->GetUIntValue("UI", "SettingsVersion", &settings_version) && settings_version == SETTINGS_VERSION);
}
void CommonHost::LoadStartupSettings()
{
SettingsInterface* bsi = Host::Internal::GetBaseSettingsLayer();
EmuFolders::LoadConfig(*bsi);
EmuFolders::EnsureFoldersExist();
UpdateLogging(*bsi);
#ifdef ENABLE_RAINTEGRATION
// RAIntegration switch must happen before the UI is created.
if (Host::GetBaseBoolSettingValue("Achievements", "UseRAIntegration", false))
Achievements::SwitchToRAIntegration();
#endif
}
void CommonHost::SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui)
{
if (si.GetUIntValue("UI", "SettingsVersion", 0u) != SETTINGS_VERSION)
si.SetUIntValue("UI", "SettingsVersion", SETTINGS_VERSION);
if (folders)
EmuFolders::SetDefaults(si);
if (core)
{
VMManager::SetDefaultSettings(si);
SetCommonDefaultSettings(si);
}
if (controllers)
PAD::SetDefaultControllerConfig(si);
if (hotkeys)
PAD::SetDefaultHotkeyConfig(si);
if (ui)
Host::SetDefaultUISettings(si);
}
void CommonHost::SetCommonDefaultSettings(SettingsInterface& si)
{
SetDefaultLoggingSettings(si);
}
void CommonHost::CPUThreadInitialize()
{
Threading::SetNameOfCurrentThread("CPU Thread");
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle::GetForCallingThread());
// neither of these should ever fail.
if (!VMManager::Internal::InitializeGlobals() || !VMManager::Internal::InitializeMemory())
pxFailRel("Failed to allocate memory map");
// We want settings loaded so we choose the correct renderer for big picture mode.
// This also sorts out input sources.
VMManager::LoadSettings();
#ifdef ENABLE_ACHIEVEMENTS
if (EmuConfig.Achievements.Enabled)
Achievements::Initialize();
#endif
#ifdef ENABLE_DISCORD_PRESENCE
if (EmuConfig.EnableDiscordPresence)
InitializeDiscordPresence();
#endif
}
void CommonHost::CPUThreadShutdown()
{
#ifdef ENABLE_DISCORD_PRESENCE
ShutdownDiscordPresence();
#endif
#ifdef ENABLE_ACHIEVEMENTS
Achievements::Shutdown();
#endif
InputManager::CloseSources();
VMManager::WaitForSaveStateFlush();
VMManager::Internal::ReleaseMemory();
VMManager::Internal::ReleaseGlobals();
PerformanceMetrics::SetCPUThread(Threading::ThreadHandle());
}
void CommonHost::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
{
SettingsInterface* binding_si = Host::GetSettingsInterfaceForBindings();
InputManager::ReloadSources(si, lock);
InputManager::ReloadBindings(si, *binding_si);
UpdateLogging(si);
}
void CommonHost::CheckForSettingsChanges(const Pcsx2Config& old_config)
{
#ifdef ENABLE_ACHIEVEMENTS
if (EmuConfig.Achievements != old_config.Achievements)
Achievements::UpdateSettings(old_config.Achievements);
#endif
FullscreenUI::CheckForConfigChanges(old_config);
if (EmuConfig.InhibitScreensaver != old_config.InhibitScreensaver)
UpdateInhibitScreensaver(EmuConfig.InhibitScreensaver && VMManager::GetState() == VMState::Running);
#ifdef ENABLE_DISCORD_PRESENCE
if (EmuConfig.EnableDiscordPresence != old_config.EnableDiscordPresence)
{
if (EmuConfig.EnableDiscordPresence)
InitializeDiscordPresence();
else
ShutdownDiscordPresence();
}
#endif
}
void CommonHost::OnVMStarting()
{
CommonHost::Internal::ResetVMHotkeyState();
}
void CommonHost::OnVMStarted()
{
FullscreenUI::OnVMStarted();
UpdateInhibitScreensaver(EmuConfig.InhibitScreensaver);
}
void CommonHost::OnVMDestroyed()
{
FullscreenUI::OnVMDestroyed();
UpdateInhibitScreensaver(false);
}
void CommonHost::OnVMPaused()
{
InputManager::PauseVibration();
#ifdef ENABLE_ACHIEVEMENTS
Achievements::OnPaused(true);
#endif
UpdateInhibitScreensaver(false);
}
void CommonHost::OnVMResumed()
{
#ifdef ENABLE_ACHIEVEMENTS
Achievements::OnPaused(false);
#endif
UpdateInhibitScreensaver(EmuConfig.InhibitScreensaver);
}
void CommonHost::OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
const std::string& game_name, u32 game_crc)
{
UpdateSessionTime(game_serial);
if (FullscreenUI::IsInitialized())
{
GetMTGS().RunOnGSThread([disc_path, game_serial, game_name, game_crc]() {
FullscreenUI::OnRunningGameChanged(std::move(disc_path), std::move(game_serial), std::move(game_name), game_crc);
});
}
#ifdef ENABLE_ACHIEVEMENTS
Achievements::GameChanged(game_crc);
#endif
#ifdef ENABLE_DISCORD_PRESENCE
UpdateDiscordPresence(GetRichPresenceString());
#endif
}
void CommonHost::CPUThreadVSync()
{
#ifdef ENABLE_ACHIEVEMENTS
if (Achievements::IsActive())
Achievements::VSyncUpdate();
#endif
#ifdef ENABLE_DISCORD_PRESENCE
PollDiscordPresence();
#endif
InputManager::PollSources();
}
bool Host::GetSerialAndCRCForFilename(const char* filename, std::string* serial, u32* crc)
{
{
auto lock = GameList::GetLock();
if (const GameList::Entry* entry = GameList::GetEntryForPath(filename); entry)
{
*serial = entry->serial;
*crc = entry->crc;
return true;
}
}
// Just scan it.. hopefully it'll come back okay.
GameList::Entry temp_entry;
if (GameList::PopulateEntryFromPath(filename, &temp_entry))
{
*serial = std::move(temp_entry.serial);
*crc = temp_entry.crc;
return true;
}
return false;
}
void CommonHost::UpdateInhibitScreensaver(bool inhibit)
{
if (s_screensaver_inhibited == inhibit)
return;
WindowInfo wi;
auto top_level_wi = Host::GetTopLevelWindowInfo();
if (top_level_wi.has_value())
wi = top_level_wi.value();
s_screensaver_inhibited = inhibit;
if (!WindowInfo::InhibitScreensaver(wi, inhibit) && inhibit)
Console.Warning("Failed to inhibit screen saver.");
}
void CommonHost::UpdateSessionTime(const std::string& new_serial)
{
if (s_session_serial == new_serial)
return;
const u64 ctime = Common::Timer::GetCurrentValue();
if (!s_session_serial.empty())
{
// round up to seconds
const std::time_t etime = static_cast<std::time_t>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
const std::time_t wtime = std::time(nullptr);
GameList::AddPlayedTimeForSerial(s_session_serial, wtime, etime);
}
s_session_serial = new_serial;
s_session_start_time = ctime;
}
u64 CommonHost::GetSessionPlayedTime()
{
const u64 ctime = Common::Timer::GetCurrentValue();
return static_cast<u64>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
}
#ifdef ENABLE_DISCORD_PRESENCE
void CommonHost::InitializeDiscordPresence()
{
if (s_discord_presence_active)
return;
DiscordEventHandlers handlers = {};
Discord_Initialize("1025789002055430154", &handlers, 0, nullptr);
s_discord_presence_active = true;
UpdateDiscordPresence(GetRichPresenceString());
}
void CommonHost::ShutdownDiscordPresence()
{
if (!s_discord_presence_active)
return;
Discord_ClearPresence();
Discord_RunCallbacks();
Discord_Shutdown();
s_discord_presence_active = false;
}
void CommonHost::UpdateDiscordPresence(const std::string& rich_presence)
{
if (!s_discord_presence_active)
return;
// https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields
DiscordRichPresence rp = {};
rp.largeImageKey = "4k-pcsx2";
rp.largeImageText = "PCSX2 Emulator";
rp.startTimestamp = std::time(nullptr);
std::string details_string;
if (VMManager::HasValidVM())
details_string = VMManager::GetGameName();
else
details_string = "No Game Running";
rp.details = details_string.c_str();
// Trim to 128 bytes as per Discord-RPC requirements
std::string state_string;
if (rich_presence.length() >= 128)
{
// 124 characters + 3 dots + null terminator
state_string = fmt::format("{}...", std::string_view(rich_presence).substr(0, 124));
}
else
{
state_string = rich_presence;
}
rp.state = state_string.c_str();
Discord_UpdatePresence(&rp);
Discord_RunCallbacks();
}
void CommonHost::PollDiscordPresence()
{
if (!s_discord_presence_active)
return;
Discord_RunCallbacks();
}
std::string CommonHost::GetRichPresenceString()
{
std::string rich_presence_string;
#ifdef ENABLE_ACHIEVEMENTS
if (Achievements::IsActive() && EmuConfig.Achievements.RichPresence)
{
auto lock = Achievements::GetLock();
rich_presence_string = Achievements::GetRichPresenceString();
}
#endif
return rich_presence_string;
}
#endif
-93
View File
@@ -1,93 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Defs.h"
#include <string>
#include <mutex>
#include "Config.h"
class SettingsInterface;
namespace Host
{
/// Sets host-specific default settings.
void SetDefaultUISettings(SettingsInterface& si);
} // namespace Host
namespace CommonHost
{
/// Initializes critical folders (AppRoot, DataRoot, Settings). Call once on startup.
bool InitializeCriticalFolders();
/// Checks settings version. Call once on startup. If it returns false, you should prompt the user to reset.
bool CheckSettingsVersion();
/// Loads early settings. Call once on startup.
void LoadStartupSettings();
/// Sets default settings for the specified categories.
void SetDefaultSettings(SettingsInterface& si, bool folders, bool core, bool controllers, bool hotkeys, bool ui);
/// Initializes common host state, called on the CPU thread.
void CPUThreadInitialize();
/// Cleans up common host state, called on the CPU thread.
void CPUThreadShutdown();
/// Loads common host settings (including input bindings).
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
/// Called after settings are updated.
void CheckForSettingsChanges(const Pcsx2Config& old_config);
/// Called when the VM is starting initialization, but has not been completed yet.
void OnVMStarting();
/// Called when the VM is created.
void OnVMStarted();
/// Called when the VM is shut down or destroyed.
void OnVMDestroyed();
/// Called when the VM is paused.
void OnVMPaused();
/// Called when the VM is resumed after being paused.
void OnVMResumed();
/// Called when the running executable changes.
void OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
const std::string& game_name, u32 game_crc);
/// Provided by the host; called once per frame at guest vsync.
void CPUThreadVSync();
/// Returns the time elapsed in the current play session.
u64 GetSessionPlayedTime();
#ifdef ENABLE_DISCORD_PRESENCE
/// Called when the rich presence string, provided by RetroAchievements, changes.
void UpdateDiscordPresence(const std::string& rich_presence);
#endif
namespace Internal
{
/// Resets any state for hotkey-related VMs, called on VM startup.
void ResetVMHotkeyState();
} // namespace Internal
} // namespace CommonHost
-262
View File
@@ -1,262 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/CrashHandler.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "Frontend/LayeredSettingsInterface.h"
#include "GS.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#include "Host.h"
#include "HostSettings.h"
#include "MemoryCardFile.h"
#include "Sio.h"
#include "VMManager.h"
static std::mutex s_settings_mutex;
static LayeredSettingsInterface s_layered_settings_interface;
std::unique_lock<std::mutex> Host::GetSettingsLock()
{
return std::unique_lock<std::mutex>(s_settings_mutex);
}
SettingsInterface* Host::GetSettingsInterface()
{
return &s_layered_settings_interface;
}
SettingsInterface* Host::GetSettingsInterfaceForBindings()
{
SettingsInterface* input_layer = s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
return input_layer ? input_layer : &s_layered_settings_interface;
}
std::string Host::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringValue(section, key, default_value);
}
bool Host::GetBaseBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetBoolValue(section, key, default_value);
}
int Host::GetBaseIntSettingValue(const char* section, const char* key, int default_value /*= 0*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetIntValue(section, key, default_value);
}
uint Host::GetBaseUIntSettingValue(const char* section, const char* key, uint default_value /*= 0*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetUIntValue(section, key, default_value);
}
float Host::GetBaseFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetFloatValue(section, key, default_value);
}
double Host::GetBaseDoubleSettingValue(const char* section, const char* key, double default_value /* = 0.0f */)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetDoubleValue(section, key, default_value);
}
std::vector<std::string> Host::GetBaseStringListSetting(const char* section, const char* key)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringList(section, key);
}
void Host::SetBaseBoolSettingValue(const char* section, const char* key, bool value)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetBoolValue(section, key, value);
}
void Host::SetBaseIntSettingValue(const char* section, const char* key, int value)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetIntValue(section, key, value);
}
void Host::SetBaseUIntSettingValue(const char* section, const char* key, uint value)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetUIntValue(section, key, value);
}
void Host::SetBaseFloatSettingValue(const char* section, const char* key, float value)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetFloatValue(section, key, value);
}
void Host::SetBaseStringSettingValue(const char* section, const char* key, const char* value)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringValue(section, key, value);
}
void Host::SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringList(section, key, values);
}
bool Host::AddBaseValueToStringList(const char* section, const char* key, const char* value)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->AddToStringList(section, key, value);
}
bool Host::RemoveBaseValueFromStringList(const char* section, const char* key, const char* value)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->RemoveFromStringList(section, key, value);
}
void Host::RemoveBaseSettingValue(const char* section, const char* key)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->DeleteValue(section, key);
}
std::string Host::GetStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetStringValue(section, key, default_value);
}
bool Host::GetBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetBoolValue(section, key, default_value);
}
int Host::GetIntSettingValue(const char* section, const char* key, int default_value /*= 0*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetIntValue(section, key, default_value);
}
uint Host::GetUIntSettingValue(const char* section, const char* key, uint default_value /*= 0*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetUIntValue(section, key, default_value);
}
float Host::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetFloatValue(section, key, default_value);
}
double Host::GetDoubleSettingValue(const char* section, const char* key, double default_value /*= 0.0f*/)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetDoubleValue(section, key, default_value);
}
std::vector<std::string> Host::GetStringListSetting(const char* section, const char* key)
{
std::unique_lock lock(s_settings_mutex);
return s_layered_settings_interface.GetStringList(section, key);
}
SettingsInterface* Host::Internal::GetBaseSettingsLayer()
{
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE);
}
SettingsInterface* Host::Internal::GetGameSettingsLayer()
{
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_GAME);
}
SettingsInterface* Host::Internal::GetInputSettingsLayer()
{
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
}
void Host::Internal::SetBaseSettingsLayer(SettingsInterface* sif)
{
pxAssertRel(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE) == nullptr, "Base layer has not been set");
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_BASE, sif);
}
void Host::Internal::SetGameSettingsLayer(SettingsInterface* sif)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_GAME, sif);
}
void Host::Internal::SetInputSettingsLayer(SettingsInterface* sif)
{
std::unique_lock lock(s_settings_mutex);
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_INPUT, sif);
}
void Host::Internal::UpdateEmuFolders()
{
const std::string old_cheats_directory(EmuFolders::Cheats);
const std::string old_cheats_ws_directory(EmuFolders::CheatsWS);
const std::string old_cheats_ni_directory(EmuFolders::CheatsNI);
const std::string old_memcards_directory(EmuFolders::MemoryCards);
const std::string old_textures_directory(EmuFolders::Textures);
const std::string old_videos_directory(EmuFolders::Videos);
EmuFolders::LoadConfig(*GetBaseSettingsLayer());
EmuFolders::EnsureFoldersExist();
if (VMManager::HasValidVM())
{
if (EmuFolders::Cheats != old_cheats_directory || EmuFolders::CheatsWS != old_cheats_ws_directory ||
EmuFolders::CheatsNI != old_cheats_ni_directory)
{
VMManager::ReloadPatches(true, true);
}
if (EmuFolders::MemoryCards != old_memcards_directory)
{
FileMcd_EmuClose();
FileMcd_EmuOpen();
AutoEject::SetAll();
}
if (EmuFolders::Textures != old_textures_directory)
{
GetMTGS().RunOnGSThread([]() {
if (VMManager::HasValidVM())
GSTextureReplacements::ReloadReplacementMap();
});
}
if (EmuFolders::Videos != old_videos_directory)
{
if (VMManager::HasValidVM())
GetMTGS().RunOnGSThread(&GSEndCapture);
}
}
}
+37 -65
View File
@@ -15,92 +15,68 @@
#include "PrecompiledHeader.h"
#include "Config.h"
#include "Counters.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiManager.h"
#include "GS.h"
#include "GSCapture.h"
#include "GSGL.h"
#include "GSUtil.h"
#include "GSExtra.h"
#include "Renderers/Null/GSRendererNull.h"
#include "Renderers/HW/GSRendererHW.h"
#include "Renderers/HW/GSTextureReplacements.h"
#include "GSGL.h"
#include "GSLzma.h"
#include "GSUtil.h"
#include "Host.h"
#include "Input/InputManager.h"
#include "MultiISA.h"
#include "pcsx2/GS.h"
#include "GS/Renderers/Null/GSRendererNull.h"
#include "GS/Renderers/HW/GSRendererHW.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#ifdef ENABLE_OPENGL
#include "GS/Renderers/OpenGL/GSDeviceOGL.h"
#endif
#ifdef __APPLE__
#include "GS/Renderers/Metal/GSMetalCPPAccessible.h"
#endif
#ifdef ENABLE_VULKAN
#include "GS/Renderers/Vulkan/GSDeviceVK.h"
#endif
#ifdef _WIN32
#include "GS/Renderers/DX11/GSDevice11.h"
#include "GS/Renderers/DX12/GSDevice12.h"
#include "GS/Renderers/DX11/D3D.h"
#endif
#include "common/Console.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "pcsx2/Config.h"
#include "pcsx2/Counters.h"
#include "pcsx2/Frontend/ImGuiManager.h"
#include "pcsx2/Host.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/Frontend/FullscreenUI.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/GS.h"
#include "fmt/format.h"
#ifdef ENABLE_OPENGL
#include "Renderers/OpenGL/GSDeviceOGL.h"
#endif
#ifdef __APPLE__
#include "Renderers/Metal/GSMetalCPPAccessible.h"
#endif
#ifdef ENABLE_VULKAN
#include "Renderers/Vulkan/GSDeviceVK.h"
#endif
#ifdef _WIN32
#include "Renderers/DX11/GSDevice11.h"
#include "Renderers/DX12/GSDevice12.h"
#include "GS/Renderers/DX11/D3D.h"
static HRESULT s_hr = E_FAIL;
#endif
#include <fstream>
// do NOT undefine this/put it above includes, as x11 people love to redefine
// things that make obscure compiler bugs, unless you want to run around and
// debug obscure compiler errors --govanify
#undef None
Pcsx2Config::GSOptions GSConfig;
static u64 s_next_manual_present_time;
int GSinit()
void GSinit()
{
GSVertexSW::InitStatic();
GSUtil::Init();
#ifdef _WIN32
s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif
return 0;
}
void GSshutdown()
{
GSclose();
#ifdef _WIN32
if (SUCCEEDED(s_hr))
{
::CoUninitialize();
s_hr = E_FAIL;
}
#endif
// ensure all screenshots have been saved
GSJoinSnapshotThreads();
}
@@ -189,7 +165,7 @@ static bool OpenGSDevice(GSRendererType renderer, bool clear_state_on_fail, bool
return false;
}
GSConfig.OsdShowGPU = EmuConfig.GS.OsdShowGPU && g_gs_device->SetGPUTimingEnabled(true);
GSConfig.OsdShowGPU = GSConfig.OsdShowGPU && g_gs_device->SetGPUTimingEnabled(true);
Console.WriteLn(Color_StrongGreen, "%s Graphics Driver Info:", GSDevice::RenderAPIToString(new_api));
Console.Indent().WriteLn(g_gs_device->GetDriverInfo());
@@ -348,7 +324,7 @@ bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* b
Host::ReportErrorAsync(
"Error", fmt::format("Failed to create render device. This may be due to your GPU not supporting the "
"chosen renderer ({}), or because your graphics drivers need to be updated.",
Pcsx2Config::GSOptions::GetRendererName(EmuConfig.GS.Renderer)));
Pcsx2Config::GSOptions::GetRendererName(GSConfig.Renderer)));
return false;
}
@@ -774,8 +750,7 @@ 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.SWExtraThreads != old_config.SWExtraThreads ||
if (GSConfig.SWExtraThreads != old_config.SWExtraThreads ||
GSConfig.SWExtraThreadsHeight != old_config.SWExtraThreadsHeight)
{
if (!GSreopen(false, true, old_config))
@@ -784,10 +759,7 @@ void GSUpdateConfig(const Pcsx2Config::GSOptions& new_config)
return;
}
// This is where we would do finer-grained checks in the future.
// For example, flushing the texture cache when mipmap settings change.
if (GSConfig.CRCHack != old_config.CRCHack ||
if (GSConfig.UserHacks_DisableRenderFixes != old_config.UserHacks_DisableRenderFixes ||
GSConfig.UpscaleMultiplier != old_config.UpscaleMultiplier ||
GSConfig.GetSkipCountFunctionId != old_config.GetSkipCountFunctionId ||
GSConfig.BeforeDrawFunctionId != old_config.BeforeDrawFunctionId)
+1 -1
View File
@@ -69,7 +69,7 @@ class HostDisplay;
s16 GSLookupGetSkipCountFunctionId(const std::string_view& name);
s16 GSLookupBeforeDrawFunctionId(const std::string_view& name);
int GSinit();
void GSinit();
void GSshutdown();
bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* basemem);
bool GSreopen(bool recreate_device, bool recreate_renderer, const Pcsx2Config::GSOptions& old_config);
+4
View File
@@ -33,4 +33,8 @@
<DisplayString Condition="m_type == 0">{{ RT @ BP={m_TEX0.TBP0,X}-{m_end_block,X} BW={m_TEX0.TBW} PSM={m_TEX0.PSM,X} {m_unscaled_size.x}x{m_unscaled_size.y} {m_valid.z},{m_valid.w} }}</DisplayString>
<DisplayString Condition="m_type == 1">{{ Depth @ BP={m_TEX0.TBP0,X}-{m_end_block,X} BW={m_TEX0.TBW} PSM={m_TEX0.PSM,X} {m_unscaled_size.x}x{m_unscaled_size.y} {m_valid.z},{m_valid.w} }}</DisplayString>
</Type>
<Type Name="GSTextureCache::SourceRegion">
<DisplayString>{{ Min=({(s16)(bits &amp; 0xFFFF)},{(s16)((bits >> 32) &amp; 0xFFFF)}} Max={(s16)((bits >> 16) &amp; 0xFFFF)},{(s16)((bits >> 48) &amp; 0xFFFF)}) }}</DisplayString>
</Type>
</AutoVisualizer>
+6 -40
View File
@@ -14,10 +14,12 @@
*/
#include "PrecompiledHeader.h"
#include "GSCrc.h"
#include "GSExtra.h"
#include "GS.h"
#include "HostSettings.h"
#include "GS/GSCrc.h"
#include "GS/GSExtra.h"
#include "GS/GS.h"
#include "Host.h"
#include "common/StringUtil.h"
const CRC::Game CRC::m_games[] =
@@ -31,42 +33,6 @@ const CRC::Game CRC::m_games[] =
{0x5C991F4E, ICO /* EU */},
{0x788D8B4F, ICO /* EU */},
{0x29C28734, ICO /* CH */},
{0x60013EBD, PolyphonyDigitalGames /* EU */}, // Gran Turismo Concept
{0x6810C3BC, PolyphonyDigitalGames /* CH */}, // Gran Turismo Concept 2002 Tokyo-Geneva
{0x0EEF32A3, PolyphonyDigitalGames /* KO */}, // Gran Turismo Concept 2002 Tokyo-Seoul
{0x3E9D448A, PolyphonyDigitalGames /* CH */}, // GT3
{0xAD66643C, PolyphonyDigitalGames /* CH */}, // GT3
{0x85AE91B3, PolyphonyDigitalGames /* US */}, // GT3
{0x8AA991B0, PolyphonyDigitalGames /* US */}, // GT3
{0xC220951A, PolyphonyDigitalGames /* JP */}, // GT3
{0x9DE5CF65, PolyphonyDigitalGames /* JP */}, // GT3
{0x706DFF80, PolyphonyDigitalGames /* JP */}, // GT3 Store Disc Vol. 2
{0x55CE5111, PolyphonyDigitalGames /* JP */}, // Gran Turismo 2000 Body Omen
{0xE9A7E08D, PolyphonyDigitalGames /* JP */}, // Gran Turismo 2000 Body Omen
{0xB590CE04, PolyphonyDigitalGames /* EU */}, // GT3
{0xC02C653E, PolyphonyDigitalGames /* CH */}, // GT4
{0x7ABDBB5E, PolyphonyDigitalGames /* CH */}, // GT4
{0xAEAD1CA3, PolyphonyDigitalGames /* JP */}, // GT4
{0xA3AF15A0, PolyphonyDigitalGames /* JP */}, // GT4 PS2 Racing Pack
{0xE906EA37, PolyphonyDigitalGames /* JP */}, // GT4 First Preview
{0xCA6243B9, PolyphonyDigitalGames /* JP */}, // GT4 Prologue
{0xDD764BBE, PolyphonyDigitalGames /* JP */}, // GT4 Prologue
{0xE1258846, PolyphonyDigitalGames /* JP */}, // GT4 Prologue
{0x27B8F05F, PolyphonyDigitalGames /* JP */}, // GT4 Prius Trial Version
{0x30E41D93, PolyphonyDigitalGames /* KO */}, // GT4
{0x715CF2EC, PolyphonyDigitalGames /* EU */}, // GT4
{0x44A61C8F, PolyphonyDigitalGames /* EU */}, // GT4
{0x0086E35B, PolyphonyDigitalGames /* EU */}, // GT4
{0x3FB69323, PolyphonyDigitalGames /* EU */}, // GT4 Prologue
{0x77E61C8A, PolyphonyDigitalGames /* US */}, // GT4
{0x33C6E35E, PolyphonyDigitalGames /* US */}, // GT4
{0x70538747, PolyphonyDigitalGames /* US */}, // GT4 Toyota Prius Trial
{0x32A1C752, PolyphonyDigitalGames /* US */}, // GT4 Online Beta
{0x2A84A1E2, PolyphonyDigitalGames /* US */}, // GT4 Mazda MX-5 Edition
{0x0087EEC4, PolyphonyDigitalGames /* NoRegion */}, // GT4 Online Beta, JP and US versions have the same CRC
{0x5AC7E79C, PolyphonyDigitalGames /* CH */}, // TouristTrophy
{0xFF9C0E93, PolyphonyDigitalGames /* US */}, // TouristTrophy
{0xCA9AA903, PolyphonyDigitalGames /* EU */}, // TouristTrophy
{0xFC46EA61, Tekken5 /* JP */},
{0x1F88EE37, Tekken5 /* EU */},
{0x1F88BECD, Tekken5 /* EU */}, // language selector...
-1
View File
@@ -25,7 +25,6 @@ public:
NoTitle,
GetawayGames,
ICO,
PolyphonyDigitalGames,
SMTNocturne,
Tekken5,
TitleCount,
+2 -2
View File
@@ -38,7 +38,7 @@ public:
struct
{
GSVector4 in;
GSVector4i in;
GSVector4i ex;
GSVector4i ofxy;
} scissor;
@@ -82,7 +82,7 @@ public:
scissor.ex.U16[2] = (u16)((SCISSOR.SCAX1 << 4) + XYOFFSET.OFX - 0x8000);
scissor.ex.U16[3] = (u16)((SCISSOR.SCAY1 << 4) + XYOFFSET.OFY - 0x8000);
scissor.in = GSVector4(
scissor.in = GSVector4i(
(int)SCISSOR.SCAX0,
(int)SCISSOR.SCAY0,
(int)SCISSOR.SCAX1 + 1,
-20
View File
@@ -131,12 +131,6 @@ __fi static T VectorAlign(T value)
// clang-format off
#ifdef __POSIX__
#include <zlib.h>
#else
#include <zlib/zlib.h>
#endif
#ifdef _MSC_VER
#define ALIGN_STACK(n) alignas(n) int dummy__; (void)dummy__;
#else
@@ -149,17 +143,3 @@ __fi static T VectorAlign(T value)
#define ALIGN_STACK(n) alignas(n) int dummy__;
#endif
#endif
#ifdef ENABLE_VTUNE
#include "jitprofiling.h"
#ifdef _WIN32
#pragma comment(lib, "jitprofiling.lib")
#endif
#endif
#ifdef _WIN32
#define DIRECTORY_SEPARATOR '\\'
#else
#include <sys/stat.h> // mkdir
#define DIRECTORY_SEPARATOR '/'
#endif
+16
View File
@@ -453,6 +453,22 @@ bool GSLocalMemory::IsPageAligned(u32 psm, const GSVector4i& rc)
return (rc & pgmsk).eq(GSVector4i::zero());
}
u32 GSLocalMemory::GetEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect)
{
u32 result = m_psm[psm].info.bn(rect.z - 1, rect.w - 1, bp, bw); // Valid only for color formats
// If rect is page aligned, we can assume it's the start of the next block-1 as the max block position.
// Using real end point for Z formats causes problems because it's a lower value.
const GSVector2i page_size = GSLocalMemory::m_psm[psm].pgs;
if ((rect.z & (page_size.x - 1)) == 0 && (rect.w & (page_size.y - 1)) == 0)
{
constexpr u32 page_mask = (1 << 5) - 1;
result = (((result + page_mask) & ~page_mask)) - 1;
}
return result;
}
///////////////////
void GSLocalMemory::ReadTexture(const GSOffset& off, const GSVector4i& r, u8* dst, int dstpitch, const GIFRegTEXA& TEXA)
+1
View File
@@ -546,6 +546,7 @@ public:
GSPixelOffset4* GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF);
std::vector<GSVector2i>* GetPage2TileMap(const GIFRegTEX0& TEX0);
static bool IsPageAligned(u32 psm, const GSVector4i& rc);
static u32 GetEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect);
// address
+17 -6
View File
@@ -827,7 +827,15 @@ void GSState::ApplyTEX0(GIFRegTEX0& TEX0)
m_mem.m_clut.ClearDrawInvalidity();
CLUTAutoFlush(PRIM->PRIM);
}
Flush(GSFlushReason::CLUTCHANGE);
// Abort any channel shuffle skipping, since this is likely part of a new shuffle.
// Test case: Tomb Raider series. This is gated by the CBP actually changing, because
// Urban Chaos writes to the memory backing the CLUT in the middle of a shuffle, and
// it's unclear whether the CLUT would actually get reloaded in that case.
if (TEX0.CBP != m_mem.m_clut.GetCLUTCBP())
m_channel_shuffle = false;
}
TEX0.CPSM &= 0xa; // 1010b
@@ -2579,7 +2587,7 @@ void GSState::SetGameCRC(u32 crc)
void GSState::UpdateCRCHacks()
{
m_game = CRC::Lookup((GSConfig.CRCHack != CRCHackLevel::Off) ? m_crc : 0);
m_game = CRC::Lookup(GSConfig.UserHacks_DisableRenderFixes ? 0 : m_crc);
}
//
@@ -2600,6 +2608,7 @@ void GSState::UpdateScissor()
{
m_scissor = m_context->scissor.ex;
m_ofxy = m_context->scissor.ofxy;
m_scissor_invalid = !m_context->scissor.in.gt32(m_context->scissor.in.zwzw()).allfalse();
}
void GSState::UpdateVertexKick()
@@ -2956,7 +2965,7 @@ __forceinline void GSState::HandleAutoFlush()
tex_rect += GSVector4i(0, 0, 0, 1);
const GSVector2i offset = GSVector2i(m_context->XYOFFSET.OFX, m_context->XYOFFSET.OFY);
const GSVector4i scissor = GSVector4i(m_context->scissor.in);
const GSVector4i scissor = m_context->scissor.in;
GSVector4i old_tex_rect = GSVector4i::zero();
int current_draw_end = m_index.tail;
@@ -3009,7 +3018,7 @@ __forceinline void GSState::HandleAutoFlush()
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));
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(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;
@@ -3110,6 +3119,9 @@ __forceinline void GSState::VertexKick(u32 skip)
if (m < n)
return;
// Skip draws when scissor is out of range (i.e. bottom-right is less than top-left), since everything will get clipped.
skip |= static_cast<u32>(m_scissor_invalid);
if (skip == 0 && (prim != GS_TRIANGLEFAN || m <= 4)) // m_vertex.xy only knows about the last 4 vertices, head could be far behind for fan
{
GSVector4i pmin, pmax;
@@ -3333,8 +3345,7 @@ __forceinline void GSState::VertexKick(u32 skip)
}
}
const GSVector4i scissor = GSVector4i(m_context->scissor.in);
temp_draw_rect = min.upl64(max).rintersect(scissor);
temp_draw_rect = min.upl64(max).rintersect(m_context->scissor.in);
}
CLUTAutoFlush(prim);
@@ -3498,7 +3509,7 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL
// When coordinates are fractional, GS appears to draw to the right/bottom (effectively
// taking the ceiling), not to the top/left (taking the floor).
const GSVector4i int_rc(m_vt.m_min.p.ceil().xyxy(m_vt.m_max.p.floor()));
const GSVector4i scissored_rc(int_rc.rintersect(GSVector4i(m_context->scissor.in)));
const GSVector4i scissored_rc(int_rc.rintersect(m_context->scissor.in));
if (!int_rc.eq(scissored_rc))
{
// draw will get scissored, adjust UVs to suit
+40 -22
View File
@@ -222,10 +222,12 @@ public:
u32 m_crc = 0;
CRC::Game m_game = {};
std::unique_ptr<GSDumpBase> m_dump;
bool m_scissor_invalid = false;
bool m_nativeres = false;
bool m_mipmap = false;
bool m_texflush_flag = false;
bool m_isPackedUV_HackFlag = false;
bool m_channel_shuffle = false;
u8 m_scanmask_used = 0;
u8 m_force_preload = 0;
u32 m_dirty_gs_regs = 0;
@@ -540,16 +542,10 @@ public:
GSVector4i out_rect = PCRTCDisplays[display].framebufferRect;
if (out_rect.z >= 2048)
{
out_rect.z -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.x;
out_rect.x = 0;
}
out_rect.z -= out_rect.x;
if (out_rect.w >= 2048)
{
out_rect.w -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.y;
out_rect.y = 0;
}
out_rect.w -= out_rect.y;
// Cap the framebuffer read to the maximum display height, otherwise the hardware renderer gets messy.
const int min_mag = std::max(1, PCRTCDisplays[display].magnification.y);
@@ -563,12 +559,6 @@ public:
offset = (max_height / min_mag) - offset;
out_rect.w = std::min(out_rect.w, offset);
// Hardware mode needs a wider framebuffer as it can't offset the read.
if (GSConfig.UseHardwareRenderer())
{
out_rect.z += PCRTCDisplays[display].framebufferOffsets.x;
out_rect.w += PCRTCDisplays[display].framebufferOffsets.y;
}
return GSVector2i(out_rect.z, out_rect.w);
}
}
@@ -645,21 +635,45 @@ public:
{
if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc && !scanmask)
{
if (abs(PCRTCDisplays[1].framebufferOffsets.y - PCRTCDisplays[0].framebufferOffsets.y) == 1
GSVector2i fb0 = GSVector2i(PCRTCDisplays[0].framebufferOffsets.x, PCRTCDisplays[0].framebufferOffsets.y);
GSVector2i fb1 = GSVector2i(PCRTCDisplays[1].framebufferOffsets.x, PCRTCDisplays[1].framebufferOffsets.y);
if (fb0.x + PCRTCDisplays[0].displayRect.z > 2048)
{
fb0.x -= 2048;
fb0.x = abs(fb0.x);
}
if (fb0.y + PCRTCDisplays[0].displayRect.w > 2048)
{
fb0.y -= 2048;
fb0.y = abs(fb0.y);
}
if (fb1.x + PCRTCDisplays[1].displayRect.z > 2048)
{
fb1.x -= 2048;
fb1.x = abs(fb1.x);
}
if (fb1.y + PCRTCDisplays[1].displayRect.w > 2048)
{
fb1.y -= 2048;
fb1.y = abs(fb1.y);
}
if (abs(fb1.y - fb0.y) == 1
&& PCRTCDisplays[0].displayRect.y == PCRTCDisplays[1].displayRect.y)
{
if (PCRTCDisplays[1].framebufferOffsets.y < PCRTCDisplays[0].framebufferOffsets.y)
PCRTCDisplays[0].framebufferOffsets.y = PCRTCDisplays[1].framebufferOffsets.y;
if (fb1.y < fb0.y)
PCRTCDisplays[0].framebufferOffsets.y = fb1.y;
else
PCRTCDisplays[1].framebufferOffsets.y = PCRTCDisplays[0].framebufferOffsets.y;
PCRTCDisplays[1].framebufferOffsets.y = fb0.y;
}
if (abs(PCRTCDisplays[1].framebufferOffsets.x - PCRTCDisplays[0].framebufferOffsets.x) == 1
if (abs(fb1.x - fb0.x) == 1
&& PCRTCDisplays[0].displayRect.x == PCRTCDisplays[1].displayRect.x)
{
if (PCRTCDisplays[1].framebufferOffsets.x < PCRTCDisplays[0].framebufferOffsets.x)
PCRTCDisplays[0].framebufferOffsets.x = PCRTCDisplays[1].framebufferOffsets.x;
if (fb1.x < fb0.x)
PCRTCDisplays[0].framebufferOffsets.x = fb1.x;
else
PCRTCDisplays[1].framebufferOffsets.x = PCRTCDisplays[0].framebufferOffsets.x;
PCRTCDisplays[1].framebufferOffsets.x = fb0.x;
}
}
PCRTCDisplays[0].framebufferRect.x += PCRTCDisplays[0].framebufferOffsets.x;
@@ -683,11 +697,15 @@ public:
{
if (PCRTCDisplays[display].framebufferRect.z >= 2048)
{
PCRTCDisplays[display].displayRect.x += 2048 - PCRTCDisplays[display].framebufferRect.x;
PCRTCDisplays[display].displayRect.z += 2048 - PCRTCDisplays[display].framebufferRect.x;
PCRTCDisplays[display].framebufferRect.x = 0;
PCRTCDisplays[display].framebufferRect.z -= 2048;
}
if (PCRTCDisplays[display].framebufferRect.w >= 2048)
{
PCRTCDisplays[display].displayRect.y += 2048 - PCRTCDisplays[display].framebufferRect.y;
PCRTCDisplays[display].displayRect.w += 2048 - PCRTCDisplays[display].framebufferRect.y;
PCRTCDisplays[display].framebufferRect.y = 0;
PCRTCDisplays[display].framebufferRect.w -= 2048;
}
-5
View File
@@ -196,11 +196,6 @@ u32 GSUtil::GetChannelMask(u32 spsm)
}
}
CRCHackLevel GSUtil::GetRecommendedCRCHackLevel(GSRendererType type)
{
return (type == GSRendererType::DX11 || type == GSRendererType::DX12) ? CRCHackLevel::Full : CRCHackLevel::Partial;
}
GSRendererType GSUtil::GetPreferredRenderer()
{
#if defined(__APPLE__)
-1
View File
@@ -35,7 +35,6 @@ public:
static bool HasSameSwizzleBits(u32 spsm, u32 dpsm);
static u32 GetChannelMask(u32 spsm);
static CRCHackLevel GetRecommendedCRCHackLevel(GSRendererType type);
static GSRendererType GetPreferredRenderer();
};
+4 -3
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -14,11 +14,12 @@
*/
#include "PrecompiledHeader.h"
#include "GSDevice.h"
#include "GS/Renderers/Common/GSDevice.h"
#include "GS/GSGL.h"
#include "GS/GS.h"
#include "Host.h"
#include "HostSettings.h"
#include "common/Align.h"
#include "common/StringUtil.h"
+1 -2
View File
@@ -754,7 +754,7 @@ protected:
static constexpr u32 MAX_POOLED_TEXTURES = 300;
static constexpr u32 MAX_TEXTURE_AGE = 10;
static constexpr u32 NUM_CAS_CONSTANTS = 12; // 8 plus src offset x/y, 16 byte alignment
static constexpr u32 EXPAND_BUFFER_SIZE = sizeof(u16) * 65532 * 6;
static constexpr u32 EXPAND_BUFFER_SIZE = sizeof(u16) * 16383 * 6;
WindowInfo m_window_info;
VsyncMode m_vsync_mode = VsyncMode::Off;
@@ -881,7 +881,6 @@ public:
virtual void ClearRenderTarget(GSTexture* t, u32 c) = 0;
virtual void InvalidateRenderTarget(GSTexture* t) = 0;
virtual void ClearDepth(GSTexture* t) = 0;
virtual void ClearStencil(GSTexture* t, u8 c) = 0;
virtual void PushDebugGroup(const char* fmt, ...) = 0;
virtual void PopDebugGroup() = 0;
+3 -3
View File
@@ -15,8 +15,8 @@
#include "PrecompiledHeader.h"
#include "Frontend/FullscreenUI.h"
#include "Frontend/ImGuiManager.h"
#include "ImGui/FullscreenUI.h"
#include "ImGui/ImGuiManager.h"
#include "GS/Renderers/Common/GSRenderer.h"
#include "GS/GSCapture.h"
#include "GS/GSGL.h"
@@ -24,7 +24,6 @@
#include "Host.h"
#include "PerformanceMetrics.h"
#include "pcsx2/Config.h"
#include "IconsFontAwesome5.h"
#include "VMManager.h"
#include "common/FileSystem.h"
@@ -34,6 +33,7 @@
#include "common/Timer.h"
#include "fmt/core.h"
#include "IconsFontAwesome5.h"
#include <algorithm>
#include <array>
+14 -1
View File
@@ -76,7 +76,7 @@ u32 GSTexture::GetCompressedBytesPerBlock(Format format)
1, // Invalid
4, // Color/RGBA8
8, // HDRColor/RGBA16
32, // DepthStencil
4, // DepthStencil
1, // UNorm8/R8
2, // UInt16/R16UI
4, // UInt32/R32UI
@@ -103,6 +103,19 @@ u32 GSTexture::GetCompressedBlockSize(Format format)
return 1;
}
u32 GSTexture::CalcUploadPitch(Format format, u32 width)
{
if (format >= Format::BC1 && format <= Format::BC7)
width = Common::AlignUpPow2(width, 4) / 4;
return width * GetCompressedBytesPerBlock(format);
}
u32 GSTexture::CalcUploadPitch(u32 width) const
{
return CalcUploadPitch(m_format, width);
}
u32 GSTexture::CalcUploadRowLengthFromPitch(u32 pitch) const
{
return CalcUploadRowLengthFromPitch(m_format, pitch);
+2
View File
@@ -106,11 +106,13 @@ public:
static u32 GetCompressedBytesPerBlock(Format format);
static u32 GetCompressedBlockSize(Format format);
static u32 CalcUploadPitch(Format format, u32 width);
static u32 CalcUploadRowLengthFromPitch(Format format, u32 pitch);
static u32 CalcUploadSize(Format format, u32 height, u32 pitch);
u32 GetCompressedBytesPerBlock() const;
u32 GetCompressedBlockSize() const;
u32 CalcUploadPitch(u32 width) const;
u32 CalcUploadRowLengthFromPitch(u32 pitch) const;
u32 CalcUploadSize(u32 height, u32 pitch) const;
+18 -4
View File
@@ -188,7 +188,7 @@ bool GSDevice11::Create()
}
}
SetFeatures();
SetFeatures(dxgi_adapter.get());
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/dx11/tfx.fx");
if (!shader.has_value())
@@ -532,7 +532,7 @@ void GSDevice11::Destroy()
#endif
}
void GSDevice11::SetFeatures()
void GSDevice11::SetFeatures(IDXGIAdapter1* adapter)
{
// Check all three formats, since the feature means any can be used.
m_features.dxt_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC1_UNORM) &&
@@ -542,7 +542,21 @@ void GSDevice11::SetFeatures()
m_features.bptc_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC7_UNORM);
const D3D_FEATURE_LEVEL feature_level = m_dev->GetFeatureLevel();
m_features.vs_expand = (feature_level >= D3D_FEATURE_LEVEL_11_0);
m_features.vs_expand = (!GSConfig.DisableVertexShaderExpand && feature_level >= D3D_FEATURE_LEVEL_11_0);
// NVIDIA GPUs prior to Kepler appear to have broken vertex shader buffer loading.
if (m_features.vs_expand && (D3D::GetVendorID(adapter) == D3D::VendorID::Nvidia))
{
// There's nothing Fermi specific which we can query in DX11. Closest we have is typed UAV loads,
// which is Kepler+. Anyone using Kepler should be using Vulkan anyway.
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options;
if (SUCCEEDED(m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &options, sizeof(options))) &&
!options.TypedUAVLoadAdditionalFormats)
{
Console.Warning("Disabling VS expand due to potentially buggy NVIDIA driver.");
m_features.vs_expand = false;
}
}
}
bool GSDevice11::HasSurface() const
@@ -602,7 +616,7 @@ bool GSDevice11::CreateSwapChain()
m_is_exclusive_fullscreen = false;
}
m_using_flip_model_swap_chain = !EmuConfig.GS.UseBlitSwapChain || m_is_exclusive_fullscreen;
m_using_flip_model_swap_chain = !GSConfig.UseBlitSwapChain || m_is_exclusive_fullscreen;
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
swap_chain_desc.Width = static_cast<u32>(client_rc.right - client_rc.left);
+2 -2
View File
@@ -118,7 +118,7 @@ private:
NUM_TIMESTAMP_QUERIES = 5,
};
void SetFeatures();
void SetFeatures(IDXGIAdapter1* adapter);
bool CreateSwapChain();
bool CreateSwapChainRTV();
@@ -313,7 +313,7 @@ public:
void ClearRenderTarget(GSTexture* t, u32 c) override;
void InvalidateRenderTarget(GSTexture* t) override;
void ClearDepth(GSTexture* t) override;
void ClearStencil(GSTexture* t, u8 c) override;
void ClearStencil(GSTexture* t, u8 c);
void PushDebugGroup(const char* fmt, ...) override;
void PopDebugGroup() override;
+4 -40
View File
@@ -16,10 +16,13 @@
#include "PrecompiledHeader.h"
#include "GS/Renderers/DX12/D3D12Context.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/General.h"
#include "common/ScopedGuard.h"
#include "common/Console.h"
#include "common/StringUtil.h"
#include "D3D12MemAlloc.h"
#include <algorithm>
@@ -665,45 +668,6 @@ bool D3D12Context::AllocatePreinitializedGPUBuffer(u32 size, ID3D12Resource** gp
return true;
}
u32 D3D12::GetTexelSize(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_R32G32B32A32_FLOAT:
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC7_UNORM:
return 16;
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
return 4;
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_SNORM:
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
case DXGI_FORMAT_R32_UINT:
case DXGI_FORMAT_R32_SINT:
return 4;
case DXGI_FORMAT_B5G5R5A1_UNORM:
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_R16_UINT:
case DXGI_FORMAT_R16_SINT:
return 2;
case DXGI_FORMAT_A8_UNORM:
case DXGI_FORMAT_R8_UNORM:
return 1;
default:
pxFailRel("Unknown format");
return 1;
}
}
#ifdef _DEBUG
void D3D12::SetObjectName(ID3D12Object* object, const char* name)
-2
View File
@@ -217,8 +217,6 @@ extern std::unique_ptr<D3D12Context> g_d3d12_context;
namespace D3D12
{
u32 GetTexelSize(DXGI_FORMAT format);
#ifdef _DEBUG
void SetObjectName(ID3D12Object* object, const char* name);
-508
View File
@@ -1,508 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "GS/Renderers/DX12/D3D12Texture.h"
#include "GS/Renderers/DX12/D3D12Context.h"
#include "common/Align.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/StringUtil.h"
#include "D3D12MemAlloc.h"
D3D12Texture::D3D12Texture() = default;
D3D12Texture::D3D12Texture(ID3D12Resource* resource, D3D12_RESOURCE_STATES state)
: m_resource(std::move(resource))
{
const D3D12_RESOURCE_DESC desc = GetDesc();
m_width = static_cast<u32>(desc.Width);
m_height = desc.Height;
m_levels = desc.MipLevels;
m_format = desc.Format;
}
D3D12Texture::D3D12Texture(D3D12Texture&& texture)
: m_resource(std::move(texture.m_resource))
, m_allocation(std::move(texture.m_allocation))
, m_srv_descriptor(texture.m_srv_descriptor)
, m_write_descriptor(texture.m_write_descriptor)
, m_width(texture.m_width)
, m_height(texture.m_height)
, m_levels(texture.m_levels)
, m_format(texture.m_format)
, m_state(texture.m_state)
, m_write_descriptor_type(texture.m_write_descriptor_type)
{
texture.m_srv_descriptor = {};
texture.m_write_descriptor = {};
texture.m_width = 0;
texture.m_height = 0;
texture.m_levels = 0;
texture.m_format = DXGI_FORMAT_UNKNOWN;
texture.m_state = D3D12_RESOURCE_STATE_COMMON;
texture.m_write_descriptor_type = WriteDescriptorType::None;
}
D3D12Texture::~D3D12Texture()
{
Destroy();
}
D3D12Texture& D3D12Texture::operator=(D3D12Texture&& texture)
{
Destroy();
m_resource = std::move(texture.m_resource);
m_allocation = std::move(texture.m_allocation);
m_srv_descriptor = texture.m_srv_descriptor;
m_write_descriptor = texture.m_write_descriptor;
m_width = texture.m_width;
m_height = texture.m_height;
m_levels = texture.m_levels;
m_format = texture.m_format;
m_state = texture.m_state;
m_write_descriptor_type = texture.m_write_descriptor_type;
texture.m_srv_descriptor = {};
texture.m_write_descriptor = {};
texture.m_width = 0;
texture.m_height = 0;
texture.m_levels = 0;
texture.m_format = DXGI_FORMAT_UNKNOWN;
texture.m_state = D3D12_RESOURCE_STATE_COMMON;
texture.m_write_descriptor_type = WriteDescriptorType::None;
return *this;
}
D3D12_RESOURCE_DESC D3D12Texture::GetDesc() const
{
return m_resource->GetDesc();
}
bool D3D12Texture::Create(u32 width, u32 height, u32 levels, DXGI_FORMAT format, DXGI_FORMAT srv_format,
DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format, D3D12_RESOURCE_FLAGS flags, u32 alloc_flags)
{
D3D12_RESOURCE_DESC desc = {};
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Width = width;
desc.Height = height;
desc.DepthOrArraySize = 1;
desc.MipLevels = levels;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
desc.Flags = flags;
D3D12_CLEAR_VALUE optimized_clear_value = {};
D3D12_RESOURCE_STATES state;
if (rtv_format != DXGI_FORMAT_UNKNOWN)
{
optimized_clear_value.Format = rtv_format;
state = D3D12_RESOURCE_STATE_RENDER_TARGET;
}
else if (dsv_format != DXGI_FORMAT_UNKNOWN)
{
optimized_clear_value.Format = dsv_format;
state = D3D12_RESOURCE_STATE_DEPTH_WRITE;
}
else
{
state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
}
D3D12MA::ALLOCATION_DESC allocationDesc = {};
allocationDesc.Flags = static_cast<D3D12MA::ALLOCATION_FLAGS>(alloc_flags) | D3D12MA::ALLOCATION_FLAG_WITHIN_BUDGET;
allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
ComPtr<ID3D12Resource> resource;
ComPtr<D3D12MA::Allocation> allocation;
HRESULT hr = g_d3d12_context->GetAllocator()->CreateResource(&allocationDesc, &desc, state,
(rtv_format != DXGI_FORMAT_UNKNOWN || dsv_format != DXGI_FORMAT_UNKNOWN) ? &optimized_clear_value : nullptr,
allocation.put(), IID_PPV_ARGS(resource.put()));
if (FAILED(hr))
{
// OOM isn't fatal.
if (hr != E_OUTOFMEMORY)
Console.Error("Create texture failed: 0x%08X", hr);
return false;
}
D3D12DescriptorHandle srv_descriptor, write_descriptor;
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
if (srv_format != DXGI_FORMAT_UNKNOWN)
{
if (!CreateSRVDescriptor(resource.get(), levels, srv_format, &srv_descriptor))
return false;
}
if (rtv_format != DXGI_FORMAT_UNKNOWN)
{
pxAssert(dsv_format == DXGI_FORMAT_UNKNOWN && !(flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS));
write_descriptor_type = D3D12Texture::WriteDescriptorType::RTV;
if (!CreateRTVDescriptor(resource.get(), rtv_format, &write_descriptor))
{
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
return false;
}
}
else if (dsv_format != DXGI_FORMAT_UNKNOWN && !(flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS))
{
write_descriptor_type = D3D12Texture::WriteDescriptorType::DSV;
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
{
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
return false;
}
}
else if (flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
{
write_descriptor_type = D3D12Texture::WriteDescriptorType::UAV;
if (!CreateUAVDescriptor(resource.get(), dsv_format, &write_descriptor))
{
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
return false;
}
}
Destroy(true);
m_resource = std::move(resource);
m_allocation = std::move(allocation);
m_srv_descriptor = std::move(srv_descriptor);
m_write_descriptor = std::move(write_descriptor);
m_width = width;
m_height = height;
m_levels = levels;
m_format = format;
m_state = state;
m_write_descriptor_type = write_descriptor_type;
return true;
}
bool D3D12Texture::Adopt(ComPtr<ID3D12Resource> texture, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
DXGI_FORMAT dsv_format, D3D12_RESOURCE_STATES state)
{
const D3D12_RESOURCE_DESC desc(texture->GetDesc());
D3D12DescriptorHandle srv_descriptor, write_descriptor;
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
if (srv_format != DXGI_FORMAT_UNKNOWN)
{
if (!CreateSRVDescriptor(texture.get(), desc.MipLevels, srv_format, &srv_descriptor))
return false;
}
if (rtv_format != DXGI_FORMAT_UNKNOWN)
{
pxAssert(dsv_format == DXGI_FORMAT_UNKNOWN);
write_descriptor_type = D3D12Texture::WriteDescriptorType::RTV;
if (!CreateRTVDescriptor(texture.get(), rtv_format, &write_descriptor))
{
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
return false;
}
}
else if (dsv_format != DXGI_FORMAT_UNKNOWN)
{
write_descriptor_type = D3D12Texture::WriteDescriptorType::DSV;
if (!CreateDSVDescriptor(texture.get(), dsv_format, &write_descriptor))
{
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
return false;
}
}
else if (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
{
write_descriptor_type = D3D12Texture::WriteDescriptorType::UAV;
if (!CreateUAVDescriptor(texture.get(), srv_format, &write_descriptor))
{
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
return false;
}
}
m_resource = std::move(texture);
m_allocation.reset();
m_srv_descriptor = std::move(srv_descriptor);
m_write_descriptor = std::move(write_descriptor);
m_write_descriptor_type = write_descriptor_type;
m_width = static_cast<u32>(desc.Width);
m_height = desc.Height;
m_levels = desc.MipLevels;
m_format = desc.Format;
m_state = state;
return true;
}
void D3D12Texture::Destroy(bool defer /* = true */)
{
if (defer)
{
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_srv_descriptor);
switch (m_write_descriptor_type)
{
case D3D12Texture::WriteDescriptorType::RTV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetRTVHeapManager(), &m_write_descriptor);
break;
case D3D12Texture::WriteDescriptorType::DSV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDSVHeapManager(), &m_write_descriptor);
break;
case D3D12Texture::WriteDescriptorType::UAV:
g_d3d12_context->DeferDescriptorDestruction(
g_d3d12_context->GetDescriptorHeapManager(), &m_write_descriptor);
break;
case D3D12Texture::WriteDescriptorType::None:
default:
break;
}
g_d3d12_context->DeferResourceDestruction(m_allocation.get(), m_resource.get());
m_resource.reset();
m_allocation.reset();
}
else
{
g_d3d12_context->GetDescriptorHeapManager().Free(&m_srv_descriptor);
switch (m_write_descriptor_type)
{
case D3D12Texture::WriteDescriptorType::RTV:
g_d3d12_context->GetRTVHeapManager().Free(&m_write_descriptor);
break;
case D3D12Texture::WriteDescriptorType::DSV:
g_d3d12_context->GetDSVHeapManager().Free(&m_write_descriptor);
break;
case D3D12Texture::WriteDescriptorType::UAV:
g_d3d12_context->GetDescriptorHeapManager().Free(&m_write_descriptor);
break;
case D3D12Texture::WriteDescriptorType::None:
default:
break;
}
m_resource.reset();
m_allocation.reset();
}
m_width = 0;
m_height = 0;
m_levels = 0;
m_format = DXGI_FORMAT_UNKNOWN;
m_write_descriptor_type = WriteDescriptorType::None;
}
void D3D12Texture::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state)
{
if (m_state == state)
return;
TransitionSubresourceToState(cmdlist, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, m_state, state);
m_state = state;
}
void D3D12Texture::TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 level,
D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const
{
const D3D12_RESOURCE_BARRIER barrier = {D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), level, before_state, after_state}}};
cmdlist->ResourceBarrier(1, &barrier);
}
ID3D12GraphicsCommandList* D3D12Texture::BeginStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y,
u32 width, u32 height, void** out_data, u32* out_data_pitch)
{
const u32 copy_pitch = Common::AlignUpPow2(width * D3D12::GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
const u32 upload_size = copy_pitch * height;
if (!g_d3d12_context->GetTextureStreamBuffer().ReserveMemory(upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
{
DevCon.WriteLn(
"Executing command buffer while waiting for %u bytes (%ux%u) in upload buffer", upload_size, width, height);
g_d3d12_context->ExecuteCommandList(D3D12Context::WaitType::None);
if (!g_d3d12_context->GetTextureStreamBuffer().ReserveMemory(
upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT))
{
Console.Error("Failed to reserve %u bytes for %ux%u upload", upload_size, width, height);
return nullptr;
}
// cmdlist change
cmdlist = g_d3d12_context->GetInitCommandList();
}
*out_data = g_d3d12_context->GetTextureStreamBuffer().GetCurrentHostPointer();
*out_data_pitch = copy_pitch;
return cmdlist;
}
void D3D12Texture::EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height)
{
const u32 copy_pitch = Common::AlignUpPow2(width * D3D12::GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
const u32 upload_size = copy_pitch * height;
D3D12StreamBuffer& sb = g_d3d12_context->GetTextureStreamBuffer();
const u32 sb_offset = sb.GetCurrentOffset();
sb.CommitMemory(upload_size);
CopyFromBuffer(cmdlist, level, x, y, width, height, copy_pitch, sb.GetBuffer(), sb_offset);
}
void D3D12Texture::CopyFromBuffer(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height,
u32 pitch, ID3D12Resource* buffer, u32 buffer_offset)
{
D3D12_TEXTURE_COPY_LOCATION src;
src.pResource = buffer;
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
src.PlacedFootprint.Offset = buffer_offset;
src.PlacedFootprint.Footprint.Width = width;
src.PlacedFootprint.Footprint.Height = height;
src.PlacedFootprint.Footprint.Depth = 1;
src.PlacedFootprint.Footprint.RowPitch = pitch;
src.PlacedFootprint.Footprint.Format = m_format;
D3D12_TEXTURE_COPY_LOCATION dst;
dst.pResource = m_resource.get();
dst.SubresourceIndex = level;
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
const D3D12_BOX src_box{0u, 0u, 0u, width, height, 1u};
const D3D12_RESOURCE_STATES old_state = m_state;
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
cmdlist->CopyTextureRegion(&dst, x, y, 0, &src, &src_box);
TransitionToState(cmdlist, old_state);
}
static ID3D12Resource* CreateStagingBuffer(u32 height, const void* data, u32 pitch, u32 upload_pitch, u32 upload_size)
{
wil::com_ptr_nothrow<ID3D12Resource> resource;
wil::com_ptr_nothrow<D3D12MA::Allocation> allocation;
const D3D12MA::ALLOCATION_DESC allocation_desc = {D3D12MA::ALLOCATION_FLAG_NONE, D3D12_HEAP_TYPE_UPLOAD};
const D3D12_RESOURCE_DESC resource_desc = {D3D12_RESOURCE_DIMENSION_BUFFER, 0, upload_size, 1, 1, 1,
DXGI_FORMAT_UNKNOWN, {1, 0}, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_RESOURCE_FLAG_NONE};
HRESULT hr = g_d3d12_context->GetAllocator()->CreateResource(&allocation_desc, &resource_desc,
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, allocation.put(), IID_PPV_ARGS(resource.put()));
if (FAILED(hr))
{
Console.Error("CreateResource() for upload staging buffer failed: %08X", hr);
return nullptr;
}
void* map;
const D3D12_RANGE read_range = {};
hr = resource->Map(0, &read_range, &map);
if (FAILED(hr))
{
Console.Error("Map() for upload staging buffer failed: %08X", hr);
return nullptr;
}
StringUtil::StrideMemCpy(map, upload_pitch, data, pitch, std::min(pitch, upload_pitch), height);
const D3D12_RANGE write_range = {0u, upload_size};
resource->Unmap(0, &write_range);
// queue them for destruction, since the upload happens in this cmdlist
g_d3d12_context->DeferResourceDestruction(allocation.get(), resource.get());
// AddRef()'ed by the defer above.
return resource.get();
}
bool D3D12Texture::LoadData(
ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch)
{
const u32 texel_size = D3D12::GetTexelSize(m_format);
const u32 upload_pitch = Common::AlignUpPow2(width * texel_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
const u32 upload_size = upload_pitch * height;
if (upload_size >= g_d3d12_context->GetTextureStreamBuffer().GetSize())
{
ID3D12Resource* staging_buffer = CreateStagingBuffer(height, data, pitch, upload_pitch, upload_size);
if (!staging_buffer)
return false;
CopyFromBuffer(cmdlist, level, x, y, width, height, upload_pitch, staging_buffer, 0);
return true;
}
void* write_ptr;
u32 write_pitch;
if (!(cmdlist = BeginStreamUpdate(cmdlist, level, x, y, width, height, &write_ptr, &write_pitch)))
return false;
StringUtil::StrideMemCpy(write_ptr, write_pitch, data, pitch, std::min(pitch, upload_pitch), height);
EndStreamUpdate(cmdlist, level, x, y, width, height);
return true;
}
bool D3D12Texture::CreateSRVDescriptor(
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate SRV descriptor");
return false;
}
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {
format, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
desc.Texture2D.MipLevels = levels;
g_d3d12_context->GetDevice()->CreateShaderResourceView(resource, &desc, dh->cpu_handle);
return true;
}
bool D3D12Texture::CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetRTVHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate SRV descriptor");
return false;
}
const D3D12_RENDER_TARGET_VIEW_DESC desc = {format, D3D12_RTV_DIMENSION_TEXTURE2D};
g_d3d12_context->GetDevice()->CreateRenderTargetView(resource, &desc, dh->cpu_handle);
return true;
}
bool D3D12Texture::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetDSVHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate SRV descriptor");
return false;
}
const D3D12_DEPTH_STENCIL_VIEW_DESC desc = {format, D3D12_DSV_DIMENSION_TEXTURE2D, D3D12_DSV_FLAG_NONE};
g_d3d12_context->GetDevice()->CreateDepthStencilView(resource, &desc, dh->cpu_handle);
return true;
}
bool D3D12Texture::CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate UAV descriptor");
return false;
}
const D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {format, D3D12_UAV_DIMENSION_TEXTURE2D};
g_d3d12_context->GetDevice()->CreateUnorderedAccessView(resource, nullptr, &desc, dh->cpu_handle);
return true;
}
-105
View File
@@ -1,105 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "GS/Renderers/DX12/D3D12DescriptorHeapManager.h"
namespace D3D12MA
{
class Allocation;
}
class D3D12StreamBuffer;
class D3D12Texture final
{
public:
template <typename T>
using ComPtr = wil::com_ptr_nothrow<T>;
D3D12Texture();
D3D12Texture(ID3D12Resource* resource, D3D12_RESOURCE_STATES state);
D3D12Texture(D3D12Texture&& texture);
D3D12Texture(const D3D12Texture&) = delete;
~D3D12Texture();
__fi ID3D12Resource* GetResource() const { return m_resource.get(); }
__fi D3D12MA::Allocation* GetAllocation() const { return m_allocation.get(); }
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
__fi const D3D12DescriptorHandle& GetWriteDescriptor() const { return m_write_descriptor; }
__fi D3D12_RESOURCE_STATES GetState() const { return m_state; }
__fi u32 GetWidth() const { return m_width; }
__fi u32 GetHeight() const { return m_height; }
__fi u32 GetLevels() const { return m_levels; }
__fi DXGI_FORMAT GetFormat() const { return m_format; }
__fi operator ID3D12Resource*() const { return m_resource.get(); }
__fi operator bool() const { return static_cast<bool>(m_resource); }
bool Create(u32 width, u32 height, u32 levels, DXGI_FORMAT format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
DXGI_FORMAT dsv_format, D3D12_RESOURCE_FLAGS flags, u32 alloc_flags = 0);
bool Adopt(ComPtr<ID3D12Resource> texture, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format,
D3D12_RESOURCE_STATES state);
D3D12_RESOURCE_DESC GetDesc() const;
void Destroy(bool defer = true);
void TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state);
void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, u32 level, D3D12_RESOURCE_STATES before_state,
D3D12_RESOURCE_STATES after_state) const;
D3D12Texture& operator=(const D3D12Texture&) = delete;
D3D12Texture& operator=(D3D12Texture&& texture);
// NOTE: Does not handle compressed formats.
ID3D12GraphicsCommandList* BeginStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width,
u32 height, void** out_data, u32* out_data_pitch);
void EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height);
bool LoadData(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data,
u32 pitch);
void CopyFromBuffer(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, u32 pitch,
ID3D12Resource* buffer, u32 buffer_offset);
private:
static bool CreateSRVDescriptor(
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
enum class WriteDescriptorType : u8
{
None,
RTV,
DSV,
UAV
};
ComPtr<ID3D12Resource> m_resource;
ComPtr<D3D12MA::Allocation> m_allocation;
D3D12DescriptorHandle m_srv_descriptor = {};
D3D12DescriptorHandle m_write_descriptor = {};
u32 m_width = 0;
u32 m_height = 0;
u32 m_levels = 0;
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
D3D12_RESOURCE_STATES m_state = D3D12_RESOURCE_STATE_COMMON;
WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;
};
+209 -181
View File
@@ -37,11 +37,17 @@
#include <sstream>
#include <limits>
static bool IsDATMConvertShader(ShaderConvert i) { return (i == ShaderConvert::DATM_0 || i == ShaderConvert::DATM_1); }
static bool IsDATEModePrimIDInit(u32 flag) { return flag == 1 || flag == 2; }
static bool IsDATMConvertShader(ShaderConvert i)
{
return (i == ShaderConvert::DATM_0 || i == ShaderConvert::DATM_1);
}
static bool IsDATEModePrimIDInit(u32 flag)
{
return flag == 1 || flag == 2;
}
static constexpr std::array<D3D12_PRIMITIVE_TOPOLOGY, 3> s_primitive_topology_mapping =
{{D3D_PRIMITIVE_TOPOLOGY_POINTLIST, D3D_PRIMITIVE_TOPOLOGY_LINELIST, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST}};
static constexpr std::array<D3D12_PRIMITIVE_TOPOLOGY, 3> s_primitive_topology_mapping = {
{D3D_PRIMITIVE_TOPOLOGY_POINTLIST, D3D_PRIMITIVE_TOPOLOGY_LINELIST, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST}};
static constexpr std::array<float, 4> s_present_clear_color = {};
@@ -122,13 +128,13 @@ bool GSDevice12::Create()
if (!GSDevice::Create())
return false;
m_dxgi_factory = D3D::CreateFactory(EmuConfig.GS.UseDebugDevice);
m_dxgi_factory = D3D::CreateFactory(GSConfig.UseDebugDevice);
if (!m_dxgi_factory)
return false;
ComPtr<IDXGIAdapter1> dxgi_adapter = D3D::GetAdapterByName(m_dxgi_factory.get(), EmuConfig.GS.Adapter);
ComPtr<IDXGIAdapter1> dxgi_adapter = D3D::GetAdapterByName(m_dxgi_factory.get(), GSConfig.Adapter);
if (!D3D12Context::Create(m_dxgi_factory.get(), dxgi_adapter.get(), EmuConfig.GS.UseDebugDevice))
if (!D3D12Context::Create(m_dxgi_factory.get(), dxgi_adapter.get(), GSConfig.UseDebugDevice))
{
Console.Error("Failed to create D3D12 context");
return false;
@@ -180,9 +186,8 @@ bool GSDevice12::Create()
if (!CreateBuffers())
return false;
if (!CompileConvertPipelines() || !CompilePresentPipelines() ||
!CompileInterlacePipelines() || !CompileMergePipelines() ||
!CompilePostProcessingPipelines())
if (!CompileConvertPipelines() || !CompilePresentPipelines() || !CompileInterlacePipelines() ||
!CompileMergePipelines() || !CompilePostProcessingPipelines())
{
Host::ReportErrorAsync("GS", "Failed to compile utility pipelines");
return false;
@@ -321,12 +326,12 @@ bool GSDevice12::CreateSwapChain()
// Render a frame as soon as possible to clear out whatever was previously being displayed.
EndRenderPass();
D3D12Texture& swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer];
GSTexture12* swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer].get();
ID3D12GraphicsCommandList4* cmdlist = g_d3d12_context->GetCommandList();
m_current_swap_chain_buffer = ((m_current_swap_chain_buffer + 1) % static_cast<u32>(m_swap_chain_buffers.size()));
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(swap_chain_buf.GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_PRESENT);
swap_chain_buf->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(swap_chain_buf->GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
swap_chain_buf->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_PRESENT);
ExecuteCommandList(false);
m_swap_chain->Present(0, m_using_allow_tearing ? DXGI_PRESENT_ALLOW_TEARING : 0);
return true;
@@ -350,9 +355,11 @@ bool GSDevice12::CreateSwapChainRTV()
return false;
}
D3D12Texture tex;
if (!tex.Adopt(std::move(backbuffer), DXGI_FORMAT_UNKNOWN, swap_chain_desc.BufferDesc.Format,
DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_STATE_PRESENT))
std::unique_ptr<GSTexture12> tex = GSTexture12::Adopt(std::move(backbuffer), GSTexture::Type::RenderTarget,
GSTexture::Format::Color, swap_chain_desc.BufferDesc.Width, swap_chain_desc.BufferDesc.Height, 1,
swap_chain_desc.BufferDesc.Format, DXGI_FORMAT_UNKNOWN, swap_chain_desc.BufferDesc.Format,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_STATE_COMMON);
if (!tex)
{
m_swap_chain_buffers.clear();
return false;
@@ -387,8 +394,8 @@ bool GSDevice12::CreateSwapChainRTV()
void GSDevice12::DestroySwapChainRTVs()
{
for (D3D12Texture& buffer : m_swap_chain_buffers)
buffer.Destroy(false);
for (std::unique_ptr<GSTexture12>& buffer : m_swap_chain_buffers)
buffer->Destroy(false);
m_swap_chain_buffers.clear();
m_current_swap_chain_buffer = 0;
}
@@ -522,12 +529,12 @@ GSDevice::PresentResult GSDevice12::BeginPresent(bool frame_skip)
return PresentResult::FrameSkipped;
}
D3D12Texture& swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer];
GSTexture12* swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer].get();
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(swap_chain_buf.GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
cmdlist->OMSetRenderTargets(1, &swap_chain_buf.GetWriteDescriptor().cpu_handle, FALSE, nullptr);
swap_chain_buf->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(swap_chain_buf->GetWriteDescriptor(), s_present_clear_color.data(), 0, nullptr);
cmdlist->OMSetRenderTargets(1, &swap_chain_buf->GetWriteDescriptor().cpu_handle, FALSE, nullptr);
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
const D3D12_VIEWPORT vp{0.0f, 0.0f, static_cast<float>(m_window_info.surface_width),
@@ -543,10 +550,10 @@ void GSDevice12::EndPresent()
{
RenderImGui();
D3D12Texture& swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer];
GSTexture12* swap_chain_buf = m_swap_chain_buffers[m_current_swap_chain_buffer].get();
m_current_swap_chain_buffer = ((m_current_swap_chain_buffer + 1) % static_cast<u32>(m_swap_chain_buffers.size()));
swap_chain_buf.TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PRESENT);
swap_chain_buf->TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PRESENT);
if (!g_d3d12_context->ExecuteCommandList(D3D12Context::WaitType::None))
{
m_device_lost = true;
@@ -603,7 +610,7 @@ bool GSDevice12::CheckFeatures()
m_features.clip_control = true;
m_features.stencil_buffer = true;
m_features.test_and_sample_depth = false;
m_features.vs_expand = true;
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
m_features.dxt_textures = g_d3d12_context->SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
g_d3d12_context->SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
@@ -643,7 +650,10 @@ void GSDevice12::ClearRenderTarget(GSTexture* t, const GSVector4& c)
static_cast<GSTexture12*>(t)->SetClearColor(c);
}
void GSDevice12::ClearRenderTarget(GSTexture* t, u32 c) { ClearRenderTarget(t, GSVector4::rgba32(c) * (1.0f / 255)); }
void GSDevice12::ClearRenderTarget(GSTexture* t, u32 c)
{
ClearRenderTarget(t, GSVector4::rgba32(c) * (1.0f / 255));
}
void GSDevice12::InvalidateRenderTarget(GSTexture* t)
{
@@ -667,34 +677,27 @@ void GSDevice12::ClearDepth(GSTexture* t)
static_cast<GSTexture12*>(t)->SetClearDepth(0.0f);
}
void GSDevice12::ClearStencil(GSTexture* t, u8 c)
void GSDevice12::LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format,
DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const
{
if (!t)
return;
EndRenderPass();
GSTexture12* dxt = static_cast<GSTexture12*>(t);
dxt->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
g_d3d12_context->GetCommandList()->ClearDepthStencilView(dxt->GetRTVOrDSVHandle(), D3D12_CLEAR_FLAG_STENCIL, 0.0f, c, 0, nullptr);
}
void GSDevice12::LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format, DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const
{
static constexpr std::array<std::array<DXGI_FORMAT, 4>, static_cast<int>(GSTexture::Format::BC7) + 1> s_format_mapping = {{
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // Invalid
{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN}, // Color
{DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_UNKNOWN}, // HDRColor
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT}, // DepthStencil
{DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN}, // UNorm8
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN}, // UInt16
{DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN}, // UInt32
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN}, // Int32
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC1
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC2
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC3
{DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC7
}};
static constexpr std::array<std::array<DXGI_FORMAT, 4>, static_cast<int>(GSTexture::Format::BC7) + 1>
s_format_mapping = {{
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // Invalid
{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_UNKNOWN}, // Color
{DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM,
DXGI_FORMAT_UNKNOWN}, // HDRColor
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT}, // DepthStencil
{DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN}, // UNorm8
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN}, // UInt16
{DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN}, // UInt32
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN}, // Int32
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC1
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC2
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC3
{DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN}, // BC7
}};
const auto& mapping = s_format_mapping[static_cast<int>(format)];
if (d3d_format)
@@ -712,16 +715,20 @@ GSTexture* GSDevice12::CreateSurface(GSTexture::Type type, int width, int height
const u32 clamped_width = static_cast<u32>(std::clamp<int>(width, 1, D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION));
const u32 clamped_height = static_cast<u32>(std::clamp<int>(height, 1, D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION));
DXGI_FORMAT d3d_format, srv_format, rtv_format, dsv_format;
LookupNativeFormat(format, &d3d_format, &srv_format, &rtv_format, &dsv_format);
DXGI_FORMAT dxgi_format, srv_format, rtv_format, dsv_format;
LookupNativeFormat(format, &dxgi_format, &srv_format, &rtv_format, &dsv_format);
std::unique_ptr<GSTexture12> tex(GSTexture12::Create(type, clamped_width, clamped_height, levels, format, d3d_format, srv_format, rtv_format, dsv_format));
const DXGI_FORMAT uav_format = (type == GSTexture::Type::RWTexture) ? dxgi_format : DXGI_FORMAT_UNKNOWN;
std::unique_ptr<GSTexture12> tex(GSTexture12::Create(type, format, clamped_width, clamped_height, levels,
dxgi_format, srv_format, rtv_format, dsv_format, uav_format));
if (!tex)
{
// We're probably out of vram, try flushing the command buffer to release pending textures.
PurgePool();
ExecuteCommandListAndRestartRenderPass(true, "Couldn't allocate texture.");
tex = GSTexture12::Create(type, clamped_width, clamped_height, levels, format, d3d_format, srv_format, rtv_format, dsv_format);
tex = GSTexture12::Create(type, format, clamped_width, clamped_height, levels, dxgi_format, srv_format,
rtv_format, dsv_format, uav_format);
}
return tex.release();
@@ -763,14 +770,14 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
if (dTexVK->GetType() != GSTexture::Type::DepthStencil)
{
dTexVK->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
g_d3d12_context->GetCommandList()->ClearRenderTargetView(dTexVK->GetRTVOrDSVHandle(),
sTexVK->GetClearColor().v, 0, nullptr);
g_d3d12_context->GetCommandList()->ClearRenderTargetView(
dTexVK->GetWriteDescriptor(), sTexVK->GetClearColor().v, 0, nullptr);
}
else
{
dTexVK->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
g_d3d12_context->GetCommandList()->ClearDepthStencilView(dTexVK->GetRTVOrDSVHandle(),
D3D12_CLEAR_FLAG_DEPTH, sTexVK->GetClearDepth(), 0, 0, nullptr);
g_d3d12_context->GetCommandList()->ClearDepthStencilView(
dTexVK->GetWriteDescriptor(), D3D12_CLEAR_FLAG_DEPTH, sTexVK->GetClearDepth(), 0, 0, nullptr);
}
return;
@@ -806,11 +813,9 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dstloc.SubresourceIndex = 0;
const D3D12_BOX srcbox{static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0u,
static_cast<UINT>(r.right), static_cast<UINT>(r.bottom), 1u};
g_d3d12_context->GetCommandList()->CopyTextureRegion(
&dstloc, destX, destY, 0,
&srcloc, &srcbox);
const D3D12_BOX srcbox{static_cast<UINT>(r.left), static_cast<UINT>(r.top), 0u, static_cast<UINT>(r.right),
static_cast<UINT>(r.bottom), 1u};
g_d3d12_context->GetCommandList()->CopyTextureRegion(&dstloc, destX, destY, 0, &srcloc, &srcbox);
dTexVK->SetState(GSTexture::State::Dirty);
}
@@ -853,7 +858,8 @@ void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
m_present[static_cast<int>(shader)].get(), linear, true);
}
void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
void GSDevice12::UpdateCLUTTexture(
GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
{
// match merge cb
struct Uniforms
@@ -873,7 +879,8 @@ void GSDevice12::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u
m_convert[static_cast<int>(shader)].get(), false, true);
}
void GSDevice12::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
void GSDevice12::ConvertToIndexedTexture(
GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
{
// match merge cb
struct Uniforms
@@ -1135,9 +1142,10 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
static_cast<GSTexture12*>(sTex[1])->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
OMSetRenderTargets(dTex, nullptr, darea);
SetUtilityTexture(sTex[1], sampler);
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, c);
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, c);
SetUtilityRootSignature();
SetPipeline(m_convert[static_cast<int>(ShaderConvert::COPY)].get());
DrawStretchRect(sRect[1], PMODE.SLBG ? dRect[2] : dRect[1], dsize);
@@ -1186,7 +1194,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
else if (!InRenderPass())
{
OMSetRenderTargets(dTex, nullptr, darea);
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
BeginRenderPass(
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
}
if (sTex[0] && sTex[0]->GetState() == GSTexture::State::Dirty)
@@ -1205,7 +1214,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
SetPipeline(m_convert[static_cast<int>(ShaderConvert::YUV)].get());
SetUtilityTexture(dTex, sampler);
OMSetRenderTargets(sTex[2], nullptr, fbarea);
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
BeginRenderPass(
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE);
DrawStretchRect(full_r, dRect[2], dsize);
}
@@ -1216,7 +1226,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
static_cast<GSTexture12*>(dTex)->TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
}
void GSDevice12::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
void GSDevice12::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb)
{
static_cast<GSTexture12*>(dTex)->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
@@ -1288,9 +1299,7 @@ bool GSDevice12::CompileCASPipelines()
if (!cas_source.has_value() || !GetCASShaderSource(&cas_source.value()))
return false;
static constexpr D3D_SHADER_MACRO sharpen_only_macros[] = {
{"CAS_SHARPEN_ONLY", "1"},
{nullptr, nullptr}};
static constexpr D3D_SHADER_MACRO sharpen_only_macros[] = {{"CAS_SHARPEN_ONLY", "1"}, {nullptr, nullptr}};
const ComPtr<ID3DBlob> cs_upscale(m_shader_cache.GetComputeShader(cas_source.value(), nullptr, "main"));
const ComPtr<ID3DBlob> cs_sharpen(m_shader_cache.GetComputeShader(cas_source.value(), sharpen_only_macros, "main"));
@@ -1430,8 +1439,8 @@ void GSDevice12::RenderImGui()
SetScissor(GSVector4i(clip));
// Since we don't have the GSTexture...
D3D12Texture* tex = static_cast<D3D12Texture*>(pcmd->GetTexID());
D3D12DescriptorHandle handle = tex ? tex->GetSRVDescriptor() : m_null_texture.GetSRVDescriptor();
GSTexture12* tex = static_cast<GSTexture12*>(pcmd->GetTexID());
D3D12DescriptorHandle handle = tex ? tex->GetSRVDescriptor() : m_null_texture->GetSRVDescriptor();
if (m_utility_texture_cpu != handle)
{
m_utility_texture_cpu = handle;
@@ -1455,19 +1464,20 @@ void GSDevice12::RenderImGui()
}
}
bool GSDevice12::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants)
bool GSDevice12::DoCAS(
GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants)
{
EndRenderPass();
GSTexture12* const sTex12 = static_cast<GSTexture12*>(sTex);
GSTexture12* const dTex12 = static_cast<GSTexture12*>(dTex);
D3D12DescriptorHandle sTexDH, dTexDH;
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetTexture().GetSRVDescriptor(), 1) ||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetTexture().GetWriteDescriptor(), 1))
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetSRVDescriptor(), 1) ||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetUAVDescriptor(), 1))
{
ExecuteCommandList(false, "Ran out of descriptors for CAS");
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetTexture().GetSRVDescriptor(), 1) ||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetTexture().GetWriteDescriptor(), 1))
if (!GetTextureGroupDescriptors(&sTexDH, &sTex12->GetSRVDescriptor(), 1) ||
!GetTextureGroupDescriptors(&dTexDH, &dTex12->GetUAVDescriptor(), 1))
{
Console.Error("Failed to allocate CAS descriptors.");
return false;
@@ -1475,12 +1485,13 @@ bool GSDevice12::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, cons
}
ID3D12GraphicsCommandList* const cmdlist = g_d3d12_context->GetCommandList();
const D3D12_RESOURCE_STATES old_state = sTex12->GetTexture().GetState();
sTex12->GetTexture().TransitionToState(cmdlist, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
dTex12->GetTexture().TransitionToState(cmdlist, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
const D3D12_RESOURCE_STATES old_state = sTex12->GetResourceState();
sTex12->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
dTex12->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
cmdlist->SetComputeRootSignature(m_cas_root_signature.get());
cmdlist->SetComputeRoot32BitConstants(CAS_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, NUM_CAS_CONSTANTS, constants.data(), 0);
cmdlist->SetComputeRoot32BitConstants(
CAS_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, NUM_CAS_CONSTANTS, constants.data(), 0);
cmdlist->SetComputeRootDescriptorTable(CAS_ROOT_SIGNATURE_PARAM_SRC_TEXTURE, sTexDH);
cmdlist->SetComputeRootDescriptorTable(CAS_ROOT_SIGNATURE_PARAM_DST_TEXTURE, dTexDH);
cmdlist->SetPipelineState(sharpen_only ? m_cas_sharpen_pipeline.get() : m_cas_upscale_pipeline.get());
@@ -1491,7 +1502,7 @@ bool GSDevice12::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, cons
const int dispatchY = (dTex->GetHeight() + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
cmdlist->Dispatch(dispatchX, dispatchY, 1);
sTex12->GetTexture().TransitionToState(cmdlist, old_state);
sTex12->TransitionToState(cmdlist, old_state);
return true;
}
@@ -1591,8 +1602,7 @@ bool GSDevice12::GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::S
}};
const u8 index = (static_cast<u8>(ss.IsMipFilterLinear()) << 2) |
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) |
static_cast<u8>(ss.IsMinFilterLinear());
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) | static_cast<u8>(ss.IsMinFilterLinear());
sd.Filter = filters[index];
}
@@ -1625,14 +1635,16 @@ void GSDevice12::ClearSamplerCache()
m_dirty_flags |= DIRTY_FLAG_TFX_SAMPLERS;
}
bool GSDevice12::GetTextureGroupDescriptors(D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count)
bool GSDevice12::GetTextureGroupDescriptors(
D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count)
{
if (!g_d3d12_context->GetDescriptorAllocator().Allocate(count, gpu_handle))
return false;
if (count == 1)
{
g_d3d12_context->GetDevice()->CopyDescriptorsSimple(1, *gpu_handle, cpu_handles[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
g_d3d12_context->GetDevice()->CopyDescriptorsSimple(
1, *gpu_handle, cpu_handles[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
return true;
}
@@ -1645,7 +1657,8 @@ bool GSDevice12::GetTextureGroupDescriptors(D3D12DescriptorHandle* gpu_handle, c
src_handles[i] = cpu_handles[i];
src_sizes[i] = 1;
}
g_d3d12_context->GetDevice()->CopyDescriptors(1, &dst_handle, &count, count, src_handles, src_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
g_d3d12_context->GetDevice()->CopyDescriptors(
1, &dst_handle, &count, count, src_handles, src_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
return true;
}
@@ -1671,14 +1684,14 @@ GSDevice12::ComPtr<ID3DBlob> GSDevice12::GetUtilityPixelShader(const std::string
bool GSDevice12::CreateNullTexture()
{
if (!m_null_texture.Create(1, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE))
{
m_null_texture =
GSTexture12::Create(GSTexture::Type::Texture, GSTexture::Format::Color, 1, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
if (!m_null_texture)
return false;
}
m_null_texture.TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
D3D12::SetObjectName(m_null_texture.GetResource(), "Null texture");
m_null_texture->TransitionToState(g_d3d12_context->GetCommandList(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
D3D12::SetObjectName(m_null_texture->GetResource(), "Null texture");
return true;
}
@@ -1838,15 +1851,14 @@ bool GSDevice12::CompileConvertPipelines()
for (u32 i = 0; i < 16; i++)
{
pxAssert(!m_color_copy[i]);
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, static_cast<u8>(i));
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE,
D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, static_cast<u8>(i));
m_color_copy[i] = gpb.Create(g_d3d12_context->GetDevice(), m_shader_cache, false);
if (!m_color_copy[i])
return false;
D3D12::SetObjectNameFormatted(m_color_copy[i].get(),
"Color copy pipeline (r=%u, g=%u, b=%u, a=%u)", i & 1u, (i >> 1) & 1u, (i >> 2) & 1u,
(i >> 3) & 1u);
D3D12::SetObjectNameFormatted(m_color_copy[i].get(), "Color copy pipeline (r=%u, g=%u, b=%u, a=%u)",
i & 1u, (i >> 1) & 1u, (i >> 2) & 1u, (i >> 3) & 1u);
}
}
else if (i == ShaderConvert::HDR_INIT || i == ShaderConvert::HDR_RESOLVE)
@@ -1863,14 +1875,16 @@ bool GSDevice12::CompileConvertPipelines()
if (!arr[ds])
return false;
D3D12::SetObjectNameFormatted(arr[ds].get(), "HDR %s/copy pipeline (ds=%u)", is_setup ? "setup" : "finish", ds);
D3D12::SetObjectNameFormatted(
arr[ds].get(), "HDR %s/copy pipeline (ds=%u)", is_setup ? "setup" : "finish", ds);
}
}
}
for (u32 datm = 0; datm < 2; datm++)
{
ComPtr<ID3DBlob> ps(GetUtilityPixelShader(*shader, datm ? "ps_stencil_image_init_1" : "ps_stencil_image_init_0"));
ComPtr<ID3DBlob> ps(
GetUtilityPixelShader(*shader, datm ? "ps_stencil_image_init_1" : "ps_stencil_image_init_0"));
if (!ps)
return false;
@@ -1879,8 +1893,8 @@ bool GSDevice12::CompileConvertPipelines()
gpb.SetPixelShader(ps.get());
gpb.SetNoDepthTestState();
gpb.SetNoStencilState();
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ONE, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ZERO, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_COLOR_WRITE_ENABLE_RED);
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ONE, D3D12_BLEND_OP_ADD, D3D12_BLEND_ZERO,
D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_COLOR_WRITE_ENABLE_RED);
for (u32 ds = 0; ds < 2; ds++)
{
@@ -1889,7 +1903,8 @@ bool GSDevice12::CompileConvertPipelines()
if (!m_date_image_setup_pipelines[ds][datm])
return false;
D3D12::SetObjectNameFormatted(m_date_image_setup_pipelines[ds][datm].get(), "DATE image clear pipeline (ds=%u, datm=%u)", ds, datm);
D3D12::SetObjectNameFormatted(
m_date_image_setup_pipelines[ds][datm].get(), "DATE image clear pipeline (ds=%u, datm=%u)", ds, datm);
}
}
@@ -2000,8 +2015,8 @@ bool GSDevice12::CompileMergePipelines()
return false;
gpb.SetPixelShader(ps.get());
gpb.SetBlendState(0, true, D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA,
D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD);
gpb.SetBlendState(0, true, D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD);
m_merge[i] = gpb.Create(g_d3d12_context->GetDevice(), m_shader_cache, false);
if (!m_merge[i])
@@ -2115,7 +2130,11 @@ void GSDevice12::DestroyResources()
m_utility_root_signature.reset();
m_tfx_root_signature.reset();
m_null_texture.Destroy(false);
if (m_null_texture)
{
m_null_texture->Destroy(false);
m_null_texture.reset();
}
m_shader_cache.Close();
}
@@ -2262,14 +2281,13 @@ GSDevice12::ComPtr<ID3D12PipelineState> GSDevice12::CreateTFXPipeline(const Pipe
// DepthStencil
if (p.ds)
{
static const D3D12_COMPARISON_FUNC ztst[] = {
D3D12_COMPARISON_FUNC_NEVER, D3D12_COMPARISON_FUNC_ALWAYS, D3D12_COMPARISON_FUNC_GREATER_EQUAL, D3D12_COMPARISON_FUNC_GREATER};
static const D3D12_COMPARISON_FUNC ztst[] = {D3D12_COMPARISON_FUNC_NEVER, D3D12_COMPARISON_FUNC_ALWAYS,
D3D12_COMPARISON_FUNC_GREATER_EQUAL, D3D12_COMPARISON_FUNC_GREATER};
gpb.SetDepthState((p.dss.ztst != ZTST_ALWAYS || p.dss.zwe), p.dss.zwe, ztst[p.dss.ztst]);
if (p.dss.date)
{
const D3D12_DEPTH_STENCILOP_DESC sos{D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP,
p.dss.date_one ? D3D12_STENCIL_OP_ZERO : D3D12_STENCIL_OP_KEEP,
D3D12_COMPARISON_FUNC_EQUAL};
p.dss.date_one ? D3D12_STENCIL_OP_ZERO : D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_EQUAL};
gpb.SetStencilState(true, 1, 1, sos, sos);
}
}
@@ -2304,8 +2322,8 @@ GSDevice12::ComPtr<ID3D12PipelineState> GSDevice12::CreateTFXPipeline(const Pipe
}
else
{
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, p.cms.wrgba);
gpb.SetBlendState(0, false, D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, D3D12_BLEND_ONE,
D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, p.cms.wrgba);
}
ComPtr<ID3D12PipelineState> pipeline(gpb.Create(g_d3d12_context->GetDevice(), m_shader_cache));
@@ -2343,7 +2361,7 @@ bool GSDevice12::BindDrawPipeline(const PipelineSelector& p)
void GSDevice12::InitializeState()
{
for (u32 i = 0; i < NUM_TOTAL_TFX_TEXTURES; i++)
m_tfx_textures[i] = m_null_texture.GetSRVDescriptor();
m_tfx_textures[i] = m_null_texture->GetSRVDescriptor();
m_tfx_sampler_sel = GSHWDrawConfig::SamplerSelector::Point().key;
InvalidateCachedState();
@@ -2403,11 +2421,14 @@ void GSDevice12::ExecuteCommandListAndRestartRenderPass(bool wait_for_completion
m_dirty_flags &= ~DIRTY_BASE_STATE;
// restart render pass
BeginRenderPass(
m_current_render_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
m_current_render_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
m_current_depth_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
m_current_depth_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS);
BeginRenderPass(m_current_render_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
m_current_render_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
m_current_depth_target ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
m_current_depth_target ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS);
}
}
@@ -2431,7 +2452,8 @@ void GSDevice12::InvalidateCachedState()
void GSDevice12::SetVertexBuffer(D3D12_GPU_VIRTUAL_ADDRESS buffer, size_t size, size_t stride)
{
if (m_vertex_buffer.BufferLocation == buffer && m_vertex_buffer.SizeInBytes == size && m_vertex_buffer.StrideInBytes == stride)
if (m_vertex_buffer.BufferLocation == buffer && m_vertex_buffer.SizeInBytes == size &&
m_vertex_buffer.StrideInBytes == stride)
return;
m_vertex_buffer.BufferLocation = buffer;
@@ -2486,9 +2508,9 @@ void GSDevice12::PSSetShaderResource(int i, GSTexture* sr, bool check_state)
GSTexture12* dtex = static_cast<GSTexture12*>(sr);
if (check_state)
{
if (dtex->GetTexture().GetState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE && InRenderPass())
if (dtex->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE && InRenderPass())
{
// Console.Warning("Ending render pass due to resource transition");
GL_INS("Ending render pass due to resource transition");
EndRenderPass();
}
@@ -2500,7 +2522,7 @@ void GSDevice12::PSSetShaderResource(int i, GSTexture* sr, bool check_state)
}
else
{
handle = m_null_texture.GetSRVDescriptor();
handle = m_null_texture->GetSRVDescriptor();
}
if (m_tfx_textures[i] == handle)
@@ -2543,7 +2565,7 @@ void GSDevice12::SetUtilityTexture(GSTexture* dtex, const D3D12DescriptorHandle&
}
else
{
handle = m_null_texture.GetSRVDescriptor();
handle = m_null_texture->GetSRVDescriptor();
}
if (m_utility_texture_cpu != handle)
@@ -2575,7 +2597,8 @@ void GSDevice12::SetUtilityTexture(GSTexture* dtex, const D3D12DescriptorHandle&
void GSDevice12::SetUtilityPushConstants(const void* data, u32 size)
{
g_d3d12_context->GetCommandList()->SetGraphicsRoot32BitConstants(UTILITY_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, (size + 3) / sizeof(u32), data, 0);
g_d3d12_context->GetCommandList()->SetGraphicsRoot32BitConstants(
UTILITY_ROOT_SIGNATURE_PARAM_PUSH_CONSTANTS, (size + 3) / sizeof(u32), data, 0);
}
void GSDevice12::UnbindTexture(GSTexture12* tex)
@@ -2584,7 +2607,7 @@ void GSDevice12::UnbindTexture(GSTexture12* tex)
{
if (m_tfx_textures[i] == tex->GetSRVDescriptor())
{
m_tfx_textures[i] = m_null_texture.GetSRVDescriptor();
m_tfx_textures[i] = m_null_texture->GetSRVDescriptor();
m_dirty_flags |= DIRTY_FLAG_TFX_TEXTURES;
}
}
@@ -2600,8 +2623,8 @@ void GSDevice12::UnbindTexture(GSTexture12* tex)
}
}
void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level, u32 src_width, u32 src_height)
void GSDevice12::RenderTextureMipmap(
GSTexture12* texture, u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level, u32 src_width, u32 src_height)
{
EndRenderPass();
@@ -2616,13 +2639,14 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
ExecuteCommandList(false);
// Setup views. This will be a partial view for the SRV.
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = {texture.GetFormat(), D3D12_RTV_DIMENSION_TEXTURE2D};
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = {texture->GetDXGIFormat(), D3D12_RTV_DIMENSION_TEXTURE2D};
rtv_desc.Texture2D = {dst_level, 0u};
g_d3d12_context->GetDevice()->CreateRenderTargetView(texture.GetResource(), &rtv_desc, rtv_handle);
g_d3d12_context->GetDevice()->CreateRenderTargetView(texture->GetResource(), &rtv_desc, rtv_handle);
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {texture.GetFormat(), D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {
texture->GetDXGIFormat(), D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
srv_desc.Texture2D = {src_level, 1u, 0u, 0.0f};
g_d3d12_context->GetDevice()->CreateShaderResourceView(texture.GetResource(), &srv_desc, srv_handle);
g_d3d12_context->GetDevice()->CreateShaderResourceView(texture->GetResource(), &srv_desc, srv_handle);
// We need to set the descriptors up manually, because we're not going through GSTexture.
if (!GetTextureGroupDescriptors(&m_utility_texture_gpu, &srv_handle, 1))
@@ -2636,10 +2660,12 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
// *now* we don't have to worry about running out of anything.
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
if (texture.GetState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
texture.TransitionSubresourceToState(cmdlist, src_level, texture.GetState(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
if (texture.GetState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
texture.TransitionSubresourceToState(cmdlist, dst_level, texture.GetState(), D3D12_RESOURCE_STATE_RENDER_TARGET);
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
texture->TransitionSubresourceToState(
cmdlist, src_level, texture->GetResourceState(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
texture->TransitionSubresourceToState(
cmdlist, dst_level, texture->GetResourceState(), D3D12_RESOURCE_STATE_RENDER_TARGET);
// We set the state directly here.
constexpr u32 MODIFIED_STATE = DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR | DIRTY_FLAG_RENDER_TARGET;
@@ -2647,7 +2673,7 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
// Using a render pass is probably a bit overkill.
const D3D12_DISCARD_REGION discard_region = {0u, nullptr, dst_level, 1u};
cmdlist->DiscardResource(texture.GetResource(), &discard_region);
cmdlist->DiscardResource(texture->GetResource(), &discard_region);
cmdlist->OMSetRenderTargets(1, &rtv_handle.cpu_handle, FALSE, nullptr);
const D3D12_VIEWPORT vp = {0.0f, 0.0f, static_cast<float>(dst_width), static_cast<float>(dst_height), 0.0f, 1.0f};
@@ -2662,10 +2688,12 @@ void GSDevice12::RenderTextureMipmap(const D3D12Texture& texture,
GSVector4(0.0f, 0.0f, static_cast<float>(dst_width), static_cast<float>(dst_height)),
GSVector2i(dst_width, dst_height));
if (texture.GetState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
texture.TransitionSubresourceToState(cmdlist, src_level, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, texture.GetState());
if (texture.GetState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
texture.TransitionSubresourceToState(cmdlist, dst_level, D3D12_RESOURCE_STATE_RENDER_TARGET, texture.GetState());
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
texture->TransitionSubresourceToState(
cmdlist, src_level, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, texture->GetResourceState());
if (texture->GetResourceState() != D3D12_RESOURCE_STATE_RENDER_TARGET)
texture->TransitionSubresourceToState(
cmdlist, dst_level, D3D12_RESOURCE_STATE_RENDER_TARGET, texture->GetResourceState());
// Must destroy after current cmdlist.
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &srv_handle);
@@ -2680,12 +2708,11 @@ bool GSDevice12::InRenderPass()
return m_in_render_pass;
}
void GSDevice12::BeginRenderPass(
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE color_end,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE depth_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end,
const GSVector4& clear_color /* = GSVector4::zero() */, float clear_depth /* = 0.0f */,
u8 clear_stencil /* = 0 */)
void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_begin,
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE color_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE depth_begin,
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin,
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end, const GSVector4& clear_color /* = GSVector4::zero() */,
float clear_depth /* = 0.0f */, u8 clear_stencil /* = 0 */)
{
if (m_in_render_pass)
EndRenderPass();
@@ -2697,12 +2724,13 @@ void GSDevice12::BeginRenderPass(
D3D12_RENDER_PASS_RENDER_TARGET_DESC rt = {};
if (m_current_render_target)
{
rt.cpuDescriptor = m_current_render_target->GetRTVOrDSVHandle();
rt.cpuDescriptor = m_current_render_target->GetWriteDescriptor();
rt.EndingAccess.Type = color_end;
rt.BeginningAccess.Type = color_begin;
if (color_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
{
LookupNativeFormat(m_current_render_target->GetFormat(), nullptr, &rt.BeginningAccess.Clear.ClearValue.Format, nullptr, nullptr);
LookupNativeFormat(m_current_render_target->GetFormat(), nullptr,
&rt.BeginningAccess.Clear.ClearValue.Format, nullptr, nullptr);
GSVector4::store<false>(rt.BeginningAccess.Clear.ClearValue.Color, clear_color);
}
}
@@ -2710,26 +2738,27 @@ void GSDevice12::BeginRenderPass(
D3D12_RENDER_PASS_DEPTH_STENCIL_DESC ds = {};
if (m_current_depth_target)
{
ds.cpuDescriptor = m_current_depth_target->GetRTVOrDSVHandle();
ds.cpuDescriptor = m_current_depth_target->GetWriteDescriptor();
ds.DepthEndingAccess.Type = depth_end;
ds.DepthBeginningAccess.Type = depth_begin;
if (depth_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
{
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr, &ds.DepthBeginningAccess.Clear.ClearValue.Format);
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr,
&ds.DepthBeginningAccess.Clear.ClearValue.Format);
ds.DepthBeginningAccess.Clear.ClearValue.DepthStencil.Depth = clear_depth;
}
ds.StencilEndingAccess.Type = stencil_end;
ds.StencilBeginningAccess.Type = stencil_begin;
if (stencil_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
{
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr, &ds.StencilBeginningAccess.Clear.ClearValue.Format);
LookupNativeFormat(m_current_depth_target->GetFormat(), nullptr, nullptr, nullptr,
&ds.StencilBeginningAccess.Clear.ClearValue.Format);
ds.StencilBeginningAccess.Clear.ClearValue.DepthStencil.Stencil = clear_stencil;
}
}
g_d3d12_context->GetCommandList()->BeginRenderPass(
m_current_render_target ? 1 : 0, m_current_render_target ? &rt : nullptr,
m_current_depth_target ? &ds : nullptr, D3D12_RENDER_PASS_FLAG_NONE);
g_d3d12_context->GetCommandList()->BeginRenderPass(m_current_render_target ? 1 : 0,
m_current_render_target ? &rt : nullptr, m_current_depth_target ? &ds : nullptr, D3D12_RENDER_PASS_FLAG_NONE);
}
void GSDevice12::EndRenderPass()
@@ -2745,7 +2774,6 @@ void GSDevice12::EndRenderPass()
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
g_d3d12_context->GetCommandList()->EndRenderPass();
}
void GSDevice12::SetViewport(const D3D12_VIEWPORT& viewport)
@@ -2811,12 +2839,12 @@ __ri void GSDevice12::ApplyBaseState(u32 flags, ID3D12GraphicsCommandList* cmdli
{
if (m_current_render_target)
{
cmdlist->OMSetRenderTargets(1, &m_current_render_target->GetRTVOrDSVHandle().cpu_handle, FALSE,
m_current_depth_target ? &m_current_depth_target->GetRTVOrDSVHandle().cpu_handle : nullptr);
cmdlist->OMSetRenderTargets(1, &m_current_render_target->GetWriteDescriptor().cpu_handle, FALSE,
m_current_depth_target ? &m_current_depth_target->GetWriteDescriptor().cpu_handle : nullptr);
}
else if (m_current_depth_target)
{
cmdlist->OMSetRenderTargets(0, nullptr, FALSE, &m_current_depth_target->GetRTVOrDSVHandle().cpu_handle);
cmdlist->OMSetRenderTargets(0, nullptr, FALSE, &m_current_depth_target->GetWriteDescriptor().cpu_handle);
}
}
}
@@ -2911,8 +2939,8 @@ bool GSDevice12::ApplyTFXState(bool already_execed)
{
m_current_root_signature = RootSignature::TFX;
flags |= DIRTY_FLAG_VS_CONSTANT_BUFFER_BINDING | DIRTY_FLAG_PS_CONSTANT_BUFFER_BINDING |
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 |
DIRTY_FLAG_PIPELINE;
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE |
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 | DIRTY_FLAG_PIPELINE;
cmdlist->SetGraphicsRootSignature(m_tfx_root_signature.get());
}
@@ -2998,8 +3026,8 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, bool datm, const GSVect
SetStencilRef(1);
BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
GSVector4::zero(), 0.0f, 0);
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, GSVector4::zero(),
0.0f, 0);
if (ApplyUtilityState())
DrawPrimitive();
@@ -3084,9 +3112,8 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe
void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
// Destination Alpha Setup
const bool stencil_DATE =
(config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne);
const bool stencil_DATE = (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne);
if (stencil_DATE)
SetupDATE(config.rt, config.ds, config.datm, config.drawarea);
@@ -3127,7 +3154,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
const GSVector2i rtsize(config.rt ? config.rt->GetSize() : config.ds->GetSize());
const GSVector4i render_area(
config.ps.hdr ? config.drawarea :
GSVector4i(Common::AlignDownPow2(config.scissor.left, render_area_alignment),
GSVector4i(Common::AlignDownPow2(config.scissor.left, render_area_alignment),
Common::AlignDownPow2(config.scissor.top, render_area_alignment),
std::min(Common::AlignUpPow2(config.scissor.right, render_area_alignment), rtsize.x),
std::min(Common::AlignUpPow2(config.scissor.bottom, render_area_alignment), rtsize.y)));
@@ -3177,8 +3204,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
{
EndRenderPass();
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}",
config.drawarea.left, config.drawarea.top,
GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}", config.drawarea.left, config.drawarea.top,
config.drawarea.width(), config.drawarea.height());
draw_rt_clone->SetState(GSTexture::State::Invalidated);
@@ -3218,13 +3244,14 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// Begin render pass if new target or out of the area.
if (!m_in_render_pass)
{
BeginRenderPass(
GetLoadOpForTexture(draw_rt),
BeginRenderPass(GetLoadOpForTexture(draw_rt),
draw_rt ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
GetLoadOpForTexture(draw_ds),
draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE :
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
stencil_DATE ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD :
D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
draw_rt ? draw_rt->GetClearColor() : GSVector4::zero(), draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1);
}
@@ -3305,7 +3332,8 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
// if this target was cleared and never drawn to, perform the clear as part of the resolve here.
BeginRenderPass(GetLoadOpForTexture(draw_rt), D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
GetLoadOpForTexture(draw_ds), draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
GetLoadOpForTexture(draw_ds),
draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
draw_rt->GetClearColor(), 0.0f, 0);
+24 -15
View File
@@ -141,7 +141,7 @@ public:
private:
ComPtr<IDXGIFactory5> m_dxgi_factory;
ComPtr<IDXGISwapChain1> m_swap_chain;
std::vector<D3D12Texture> m_swap_chain_buffers;
std::vector<std::unique_ptr<GSTexture12>> m_swap_chain_buffers;
u32 m_current_swap_chain_buffer = 0;
bool m_allow_tearing_supported = false;
@@ -177,7 +177,8 @@ private:
ComPtr<ID3D12PipelineState> m_imgui_pipeline;
std::unordered_map<u32, ComPtr<ID3DBlob>> m_tfx_vertex_shaders;
std::unordered_map<GSHWDrawConfig::PSSelector, ComPtr<ID3DBlob>, GSHWDrawConfig::PSSelectorHash> m_tfx_pixel_shaders;
std::unordered_map<GSHWDrawConfig::PSSelector, ComPtr<ID3DBlob>, GSHWDrawConfig::PSSelectorHash>
m_tfx_pixel_shaders;
std::unordered_map<PipelineSelector, ComPtr<ID3D12PipelineState>, PipelineSelectorHash> m_tfx_pipelines;
ComPtr<ID3D12RootSignature> m_cas_root_signature;
@@ -191,26 +192,31 @@ private:
ComPtr<ID3DBlob> m_convert_vs;
std::string m_tfx_source;
void LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format, DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const;
void LookupNativeFormat(GSTexture::Format format, DXGI_FORMAT* d3d_format, DXGI_FORMAT* srv_format,
DXGI_FORMAT* rtv_format, DXGI_FORMAT* dsv_format) const;
bool CreateSwapChain();
bool CreateSwapChainRTV();
void DestroySwapChainRTVs();
void DestroySwapChain();
GSTexture* CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) override;
GSTexture* CreateSurface(
GSTexture::Type type, int width, int height, int levels, GSTexture::Format format) override;
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE,
const GSRegEXTBUF& EXTBUF, const GSVector4& c, const bool linear) final;
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
void DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
ShaderInterlace shader, bool linear, const InterlaceConstantBuffer& cb) final;
void DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4]) final;
void DoFXAA(GSTexture* sTex, GSTexture* dTex) final;
bool DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants) final;
bool DoCAS(
GSTexture* sTex, GSTexture* dTex, bool sharpen_only, const std::array<u32, NUM_CAS_CONSTANTS>& constants) final;
bool GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::SamplerSelector ss);
void ClearSamplerCache() final;
bool GetTextureGroupDescriptors(D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count);
bool GetTextureGroupDescriptors(
D3D12DescriptorHandle* gpu_handle, const D3D12DescriptorHandle* cpu_handles, u32 count);
const ID3DBlob* GetTFXVertexShader(GSHWDrawConfig::VSSelector sel);
const ID3DBlob* GetTFXPixelShader(const GSHWDrawConfig::PSSelector& sel);
@@ -277,7 +283,6 @@ public:
void ClearRenderTarget(GSTexture* t, u32 c) override;
void InvalidateRenderTarget(GSTexture* t) override;
void ClearDepth(GSTexture* t) override;
void ClearStencil(GSTexture* t, u8 c) override;
std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) override;
@@ -289,10 +294,13 @@ public:
bool green, bool blue, bool alpha) override;
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
PresentShader shader, float shaderTime, bool linear) override;
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
void UpdateCLUTTexture(
GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM,
GSTexture* dTex, u32 DBW, u32 DPSM) override;
void DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
void DrawMultiStretchRects(
const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
void DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture12* dTex, ShaderConvert shader);
void BeginRenderPassForStretchRect(
@@ -347,8 +355,8 @@ public:
// Assumes that the previous level has been transitioned to PS resource,
// and the current level has been transitioned to RT.
void RenderTextureMipmap(const D3D12Texture& texture,
u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level, u32 src_width, u32 src_height);
void RenderTextureMipmap(GSTexture12* texture, u32 dst_level, u32 dst_width, u32 dst_height, u32 src_level,
u32 src_width, u32 src_height);
// Ends a render pass if we're currently in one.
// When Bind() is next called, the pass will be restarted.
@@ -401,7 +409,8 @@ private:
DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR | DIRTY_FLAG_RENDER_TARGET | DIRTY_FLAG_PIPELINE |
DIRTY_FLAG_BLEND_CONSTANTS | DIRTY_FLAG_STENCIL_REF,
DIRTY_TFX_STATE = DIRTY_BASE_STATE | DIRTY_FLAG_TFX_TEXTURES | DIRTY_FLAG_TFX_SAMPLERS | DIRTY_FLAG_TFX_RT_TEXTURES,
DIRTY_TFX_STATE =
DIRTY_BASE_STATE | DIRTY_FLAG_TFX_TEXTURES | DIRTY_FLAG_TFX_SAMPLERS | DIRTY_FLAG_TFX_RT_TEXTURES,
DIRTY_UTILITY_STATE = DIRTY_BASE_STATE,
DIRTY_CONSTANT_BUFFER_STATE = DIRTY_FLAG_VS_CONSTANT_BUFFER | DIRTY_FLAG_PS_CONSTANT_BUFFER,
};
@@ -451,7 +460,7 @@ private:
RootSignature m_current_root_signature = RootSignature::Undefined;
const ID3D12PipelineState* m_current_pipeline = nullptr;
D3D12Texture m_null_texture;
std::unique_ptr<GSTexture12> m_null_texture;
// current pipeline selector - we save this in the struct to avoid re-zeroing it every draw
PipelineSelector m_pipeline_selector = {};
+349 -95
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -28,99 +28,338 @@
#include "D3D12MemAlloc.h"
GSTexture12::GSTexture12(Type type, Format format, D3D12Texture texture)
: m_texture(std::move(texture))
GSTexture12::GSTexture12(Type type, Format format, int width, int height, int levels, DXGI_FORMAT dxgi_format,
wil::com_ptr_nothrow<ID3D12Resource> resource, wil::com_ptr_nothrow<D3D12MA::Allocation> allocation,
const D3D12DescriptorHandle& srv_descriptor, const D3D12DescriptorHandle& write_descriptor,
const D3D12DescriptorHandle& uav_descriptor, WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state)
: m_resource(std::move(resource))
, m_allocation(std::move(allocation))
, m_srv_descriptor(srv_descriptor)
, m_write_descriptor(write_descriptor)
, m_uav_descriptor(uav_descriptor)
, m_write_descriptor_type(wdtype)
, m_dxgi_format(dxgi_format)
, m_resource_state(resource_state)
{
m_type = type;
m_format = format;
m_size.x = m_texture.GetWidth();
m_size.y = m_texture.GetHeight();
m_mipmap_levels = m_texture.GetLevels();
m_size.x = width;
m_size.y = height;
m_mipmap_levels = levels;
}
GSTexture12::~GSTexture12()
{
GSDevice12::GetInstance()->UnbindTexture(this);
Destroy(true);
}
std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, u32 width, u32 height, u32 levels, Format format,
DXGI_FORMAT d3d_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format)
void GSTexture12::Destroy(bool defer)
{
GSDevice12::GetInstance()->UnbindTexture(this);
if (defer)
{
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_srv_descriptor);
switch (m_write_descriptor_type)
{
case WriteDescriptorType::RTV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetRTVHeapManager(), &m_write_descriptor);
break;
case WriteDescriptorType::DSV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDSVHeapManager(), &m_write_descriptor);
break;
case WriteDescriptorType::None:
default:
break;
}
if (m_uav_descriptor)
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_uav_descriptor);
g_d3d12_context->DeferResourceDestruction(m_allocation.get(), m_resource.get());
m_resource.reset();
m_allocation.reset();
}
else
{
g_d3d12_context->GetDescriptorHeapManager().Free(&m_srv_descriptor);
switch (m_write_descriptor_type)
{
case WriteDescriptorType::RTV:
g_d3d12_context->GetRTVHeapManager().Free(&m_write_descriptor);
break;
case WriteDescriptorType::DSV:
g_d3d12_context->GetDSVHeapManager().Free(&m_write_descriptor);
break;
case WriteDescriptorType::None:
default:
break;
}
if (m_uav_descriptor)
g_d3d12_context->GetDescriptorHeapManager().Free(&m_uav_descriptor);
m_resource.reset();
m_allocation.reset();
}
m_write_descriptor_type = WriteDescriptorType::None;
}
std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int width, int height, int levels,
DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format,
DXGI_FORMAT uav_format)
{
D3D12_RESOURCE_DESC desc = {};
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Width = width;
desc.Height = height;
desc.DepthOrArraySize = 1;
desc.MipLevels = levels;
desc.Format = dxgi_format;
desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
D3D12MA::ALLOCATION_DESC allocationDesc = {};
allocationDesc.Flags = D3D12MA::ALLOCATION_FLAG_WITHIN_BUDGET;
allocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
D3D12_CLEAR_VALUE optimized_clear_value = {};
D3D12_RESOURCE_STATES state;
switch (type)
{
case Type::Texture:
{
// This is a little annoying. basically, to do mipmap generation, we need to be a render target.
// If it's a compressed texture, we won't be generating mips anyway, so this should be fine.
const D3D12_RESOURCE_FLAGS flags = (levels > 1 && !IsCompressedFormat(format)) ?
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET :
D3D12_RESOURCE_FLAG_NONE;
D3D12Texture texture;
if (!texture.Create(
width, height, levels, d3d_format, srv_format, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, flags))
{
return {};
}
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u texture", width, height);
return std::make_unique<GSTexture12>(type, format, std::move(texture));
desc.Flags = (levels > 1 && !IsCompressedFormat(format)) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET :
D3D12_RESOURCE_FLAG_NONE;
state = D3D12_RESOURCE_STATE_COPY_DEST;
}
break;
case Type::RenderTarget:
{
pxAssert(levels == 1);
// RT's tend to be larger, so we'll keep them committed for speed.
D3D12Texture texture;
if (!texture.Create(width, height, levels, d3d_format, srv_format, rtv_format, DXGI_FORMAT_UNKNOWN,
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12MA::ALLOCATION_FLAG_COMMITTED))
{
return {};
}
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u render target", width, height);
return std::make_unique<GSTexture12>(type, format, std::move(texture));
pxAssert(levels == 1);
allocationDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
optimized_clear_value.Format = rtv_format;
state = D3D12_RESOURCE_STATE_RENDER_TARGET;
}
break;
case Type::DepthStencil:
{
pxAssert(levels == 1);
D3D12Texture texture;
if (!texture.Create(width, height, levels, d3d_format, srv_format, DXGI_FORMAT_UNKNOWN, dsv_format,
D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12MA::ALLOCATION_FLAG_COMMITTED))
{
return {};
}
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u depth stencil", width, height);
return std::make_unique<GSTexture12>(type, format, std::move(texture));
allocationDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
optimized_clear_value.Format = dsv_format;
state = D3D12_RESOURCE_STATE_DEPTH_WRITE;
}
break;
case Type::RWTexture:
{
pxAssert(levels == 1);
D3D12Texture texture;
if (!texture.Create(width, height, levels, d3d_format, srv_format, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12MA::ALLOCATION_FLAG_COMMITTED))
{
return {};
}
D3D12::SetObjectNameFormatted(texture.GetResource(), "%ux%u RW texture", width, height);
return std::make_unique<GSTexture12>(type, format, std::move(texture));
allocationDesc.Flags |= D3D12MA::ALLOCATION_FLAG_COMMITTED;
state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
}
break;
default:
return {};
}
if (uav_format != DXGI_FORMAT_UNKNOWN)
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
wil::com_ptr_nothrow<ID3D12Resource> resource;
wil::com_ptr_nothrow<D3D12MA::Allocation> allocation;
HRESULT hr = g_d3d12_context->GetAllocator()->CreateResource(&allocationDesc, &desc, state,
(type == Type::RenderTarget || type == Type::DepthStencil) ? &optimized_clear_value : nullptr, allocation.put(),
IID_PPV_ARGS(resource.put()));
if (FAILED(hr))
{
// OOM isn't fatal.
if (hr != E_OUTOFMEMORY)
Console.Error("Create texture failed: 0x%08X", hr);
return {};
}
D3D12DescriptorHandle srv_descriptor, write_descriptor, uav_descriptor;
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
if (srv_format != DXGI_FORMAT_UNKNOWN)
{
if (!CreateSRVDescriptor(resource.get(), levels, srv_format, &srv_descriptor))
return {};
}
switch (type)
{
case Type::Texture:
{
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d texture", width, height);
}
break;
case Type::RenderTarget:
{
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d render target", width, height);
write_descriptor_type = WriteDescriptorType::RTV;
if (!CreateRTVDescriptor(resource.get(), rtv_format, &write_descriptor))
{
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
return {};
}
}
break;
case Type::DepthStencil:
{
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d depth stencil", width, height);
write_descriptor_type = WriteDescriptorType::DSV;
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
{
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
return {};
}
}
break;
case Type::RWTexture:
{
D3D12::SetObjectNameFormatted(resource.get(), "%dx%d RW texture", width, height);
}
break;
default:
break;
}
if (uav_format != DXGI_FORMAT_UNKNOWN && !CreateUAVDescriptor(resource.get(), dsv_format, &uav_descriptor))
{
g_d3d12_context->GetDescriptorHeapManager().Free(&write_descriptor);
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
return {};
}
return std::unique_ptr<GSTexture12>(
new GSTexture12(type, format, width, height, levels, dxgi_format, std::move(resource), std::move(allocation),
srv_descriptor, write_descriptor, uav_descriptor, write_descriptor_type, state));
}
std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resource> resource, Type type, Format format,
int width, int height, int levels, DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
DXGI_FORMAT dsv_format, DXGI_FORMAT uav_format, D3D12_RESOURCE_STATES resource_state)
{
const D3D12_RESOURCE_DESC desc = resource->GetDesc();
D3D12DescriptorHandle srv_descriptor, write_descriptor, uav_descriptor;
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
if (srv_format != DXGI_FORMAT_UNKNOWN)
{
if (!CreateSRVDescriptor(resource.get(), desc.MipLevels, srv_format, &srv_descriptor))
return {};
}
if (type == Type::RenderTarget)
{
write_descriptor_type = WriteDescriptorType::RTV;
if (!CreateRTVDescriptor(resource.get(), rtv_format, &write_descriptor))
{
g_d3d12_context->GetRTVHeapManager().Free(&srv_descriptor);
return {};
}
}
else if (type == Type::DepthStencil)
{
write_descriptor_type = WriteDescriptorType::DSV;
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
{
g_d3d12_context->GetDSVHeapManager().Free(&srv_descriptor);
return {};
}
}
if (uav_format != DXGI_FORMAT_UNKNOWN)
{
if (!CreateUAVDescriptor(resource.get(), srv_format, &uav_descriptor))
{
g_d3d12_context->GetDescriptorHeapManager().Free(&write_descriptor);
g_d3d12_context->GetDescriptorHeapManager().Free(&srv_descriptor);
return {};
}
}
return std::unique_ptr<GSTexture12>(new GSTexture12(type, format, static_cast<u32>(desc.Width), desc.Height,
desc.MipLevels, desc.Format, std::move(resource), {}, srv_descriptor, write_descriptor, uav_descriptor,
write_descriptor_type, resource_state));
}
bool GSTexture12::CreateSRVDescriptor(
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate SRV descriptor");
return false;
}
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {
format, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
desc.Texture2D.MipLevels = levels;
g_d3d12_context->GetDevice()->CreateShaderResourceView(resource, &desc, dh->cpu_handle);
return true;
}
bool GSTexture12::CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetRTVHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate SRV descriptor");
return false;
}
const D3D12_RENDER_TARGET_VIEW_DESC desc = {format, D3D12_RTV_DIMENSION_TEXTURE2D};
g_d3d12_context->GetDevice()->CreateRenderTargetView(resource, &desc, dh->cpu_handle);
return true;
}
bool GSTexture12::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetDSVHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate SRV descriptor");
return false;
}
const D3D12_DEPTH_STENCIL_VIEW_DESC desc = {format, D3D12_DSV_DIMENSION_TEXTURE2D, D3D12_DSV_FLAG_NONE};
g_d3d12_context->GetDevice()->CreateDepthStencilView(resource, &desc, dh->cpu_handle);
return true;
}
bool GSTexture12::CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
{
if (!g_d3d12_context->GetDescriptorHeapManager().Allocate(dh))
{
Console.Error("Failed to allocate UAV descriptor");
return false;
}
const D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {format, D3D12_UAV_DIMENSION_TEXTURE2D};
g_d3d12_context->GetDevice()->CreateUnorderedAccessView(resource, nullptr, &desc, dh->cpu_handle);
return true;
}
void* GSTexture12::GetNativeHandle() const
{
return const_cast<D3D12Texture*>(&m_texture);
return const_cast<GSTexture12*>(this);
}
ID3D12GraphicsCommandList* GSTexture12::GetCommandBufferForUpdate()
@@ -198,7 +437,7 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
srcloc.PlacedFootprint.Footprint.Width = width;
srcloc.PlacedFootprint.Footprint.Height = height;
srcloc.PlacedFootprint.Footprint.Depth = 1;
srcloc.PlacedFootprint.Footprint.Format = m_texture.GetFormat();
srcloc.PlacedFootprint.Footprint.Format = m_dxgi_format;
srcloc.PlacedFootprint.Footprint.RowPitch = upload_pitch;
// If the texture is larger than half our streaming buffer size, use a separate buffer.
@@ -235,10 +474,10 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
GL_PUSH("GSTexture12::Update({%d,%d} %dx%d Lvl:%u", r.x, r.y, r.width(), r.height(), layer);
// first time the texture is used? don't leave it undefined
if (m_texture.GetState() == D3D12_RESOURCE_STATE_COMMON)
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
else if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
m_texture.TransitionSubresourceToState(cmdlist, layer, m_texture.GetState(), D3D12_RESOURCE_STATE_COPY_DEST);
if (m_resource_state == D3D12_RESOURCE_STATE_COMMON)
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
else if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
TransitionSubresourceToState(cmdlist, layer, m_resource_state, D3D12_RESOURCE_STATE_COPY_DEST);
// if we're an rt and have been cleared, and the full rect isn't being uploaded, do the clear
if (m_type == Type::RenderTarget)
@@ -250,7 +489,7 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
}
D3D12_TEXTURE_COPY_LOCATION dstloc;
dstloc.pResource = m_texture.GetResource();
dstloc.pResource = m_resource.get();
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dstloc.SubresourceIndex = layer;
@@ -258,8 +497,8 @@ bool GSTexture12::Update(const GSVector4i& r, const void* data, int pitch, int l
cmdlist->CopyTextureRegion(&dstloc, Common::AlignDownPow2((u32)r.x, block_size),
Common::AlignDownPow2((u32)r.y, block_size), 0, &srcloc, &srcbox);
if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
m_texture.TransitionSubresourceToState(cmdlist, layer, D3D12_RESOURCE_STATE_COPY_DEST, m_texture.GetState());
if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
TransitionSubresourceToState(cmdlist, layer, D3D12_RESOURCE_STATE_COPY_DEST, m_resource_state);
if (m_type == Type::Texture)
m_needs_mipmaps_generated |= (layer == 0);
@@ -273,11 +512,9 @@ bool GSTexture12::Map(GSMap& m, const GSVector4i* r, int layer)
return false;
// map for writing
m_map_area = r ? *r : GSVector4i(0, 0, m_texture.GetWidth(), m_texture.GetHeight());
m_map_area = r ? *r : GetRect();
m_map_level = layer;
m.pitch = Common::AlignUpPow2(
m_map_area.width() * D3D12::GetTexelSize(m_texture.GetFormat()), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
m.pitch = Common::AlignUpPow2(CalcUploadPitch(m_map_area.width()), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
// see note in Update() for the reason why.
const u32 required_size = CalcUploadSize(m_map_area.height(), m.pitch);
@@ -300,14 +537,12 @@ bool GSTexture12::Map(GSMap& m, const GSVector4i* r, int layer)
void GSTexture12::Unmap()
{
// this can't handle blocks/compressed formats at the moment.
pxAssert(m_map_level < m_texture.GetLevels() && !IsCompressedFormat());
pxAssert(m_map_level < m_mipmap_levels && !IsCompressedFormat());
g_perfmon.Put(GSPerfMon::TextureUploads, 1);
// TODO: non-tightly-packed formats
const u32 width = static_cast<u32>(m_map_area.width());
const u32 height = static_cast<u32>(m_map_area.height());
const u32 pitch = Common::AlignUpPow2(
m_map_area.width() * D3D12::GetTexelSize(m_texture.GetFormat()), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
const u32 width = m_map_area.width();
const u32 height = m_map_area.height();
const u32 pitch = Common::AlignUpPow2(CalcUploadPitch(width), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
const u32 required_size = CalcUploadSize(height, pitch);
D3D12StreamBuffer& buffer = g_d3d12_context->GetTextureStreamBuffer();
const u32 buffer_offset = buffer.GetCurrentOffset();
@@ -318,11 +553,10 @@ void GSTexture12::Unmap()
m_map_area.height(), m_map_level);
// first time the texture is used? don't leave it undefined
if (m_texture.GetState() == D3D12_RESOURCE_STATE_COMMON)
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
else if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
m_texture.TransitionSubresourceToState(
cmdlist, m_map_level, m_texture.GetState(), D3D12_RESOURCE_STATE_COPY_DEST);
if (m_resource_state == D3D12_RESOURCE_STATE_COMMON)
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_COPY_DEST);
else if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
TransitionSubresourceToState(cmdlist, m_map_level, m_resource_state, D3D12_RESOURCE_STATE_COPY_DEST);
// if we're an rt and have been cleared, and the full rect isn't being uploaded, do the clear
if (m_type == Type::RenderTarget)
@@ -340,20 +574,19 @@ void GSTexture12::Unmap()
srcloc.PlacedFootprint.Footprint.Width = width;
srcloc.PlacedFootprint.Footprint.Height = height;
srcloc.PlacedFootprint.Footprint.Depth = 1;
srcloc.PlacedFootprint.Footprint.Format = m_texture.GetFormat();
srcloc.PlacedFootprint.Footprint.Format = m_dxgi_format;
srcloc.PlacedFootprint.Footprint.RowPitch = pitch;
D3D12_TEXTURE_COPY_LOCATION dstloc;
dstloc.pResource = m_texture.GetResource();
dstloc.pResource = m_resource.get();
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dstloc.SubresourceIndex = m_map_level;
const D3D12_BOX srcbox{0u, 0u, 0u, width, height, 1};
cmdlist->CopyTextureRegion(&dstloc, m_map_area.x, m_map_area.y, 0, &srcloc, &srcbox);
if (m_texture.GetState() != D3D12_RESOURCE_STATE_COPY_DEST)
m_texture.TransitionSubresourceToState(
cmdlist, m_map_level, D3D12_RESOURCE_STATE_COPY_DEST, m_texture.GetState());
if (m_resource_state != D3D12_RESOURCE_STATE_COPY_DEST)
TransitionSubresourceToState(cmdlist, m_map_level, D3D12_RESOURCE_STATE_COPY_DEST, m_resource_state);
if (m_type == Type::Texture)
m_needs_mipmaps_generated |= (m_map_level == 0);
@@ -372,7 +605,7 @@ void GSTexture12::GenerateMipmap()
const int dst_height = std::max<int>(m_size.y >> dst_level, 1);
GSDevice12::GetInstance()->RenderTextureMipmap(
m_texture, dst_level, dst_width, dst_height, src_level, src_width, src_height);
this, dst_level, dst_width, dst_height, src_level, src_width, src_height);
}
SetUsedThisCommandBuffer();
@@ -381,16 +614,39 @@ void GSTexture12::GenerateMipmap()
void GSTexture12::Swap(GSTexture* tex)
{
GSTexture::Swap(tex);
std::swap(m_texture, static_cast<GSTexture12*>(tex)->m_texture);
std::swap(m_resource, static_cast<GSTexture12*>(tex)->m_resource);
std::swap(m_allocation, static_cast<GSTexture12*>(tex)->m_allocation);
std::swap(m_srv_descriptor, static_cast<GSTexture12*>(tex)->m_srv_descriptor);
std::swap(m_write_descriptor, static_cast<GSTexture12*>(tex)->m_write_descriptor);
std::swap(m_write_descriptor_type, static_cast<GSTexture12*>(tex)->m_write_descriptor_type);
std::swap(m_dxgi_format, static_cast<GSTexture12*>(tex)->m_dxgi_format);
std::swap(m_resource_state, static_cast<GSTexture12*>(tex)->m_resource_state);
std::swap(m_use_fence_counter, static_cast<GSTexture12*>(tex)->m_use_fence_counter);
std::swap(m_clear_value, static_cast<GSTexture12*>(tex)->m_clear_value);
std::swap(m_map_area, static_cast<GSTexture12*>(tex)->m_map_area);
std::swap(m_map_level, static_cast<GSTexture12*>(tex)->m_map_level);
std::swap(m_map_area, static_cast<GSTexture12*>(tex)->m_map_area);
}
void GSTexture12::TransitionToState(D3D12_RESOURCE_STATES state)
{
m_texture.TransitionToState(g_d3d12_context->GetCommandList(), state);
TransitionToState(g_d3d12_context->GetCommandList(), state);
}
void GSTexture12::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state)
{
if (m_resource_state == state)
return;
TransitionSubresourceToState(cmdlist, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, m_resource_state, state);
m_resource_state = state;
}
void GSTexture12::TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, int level,
D3D12_RESOURCE_STATES before_state, D3D12_RESOURCE_STATES after_state) const
{
const D3D12_RESOURCE_BARRIER barrier = {D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), static_cast<u32>(level), before_state, after_state}}};
cmdlist->ResourceBarrier(1, &barrier);
}
void GSTexture12::CommitClear()
@@ -407,14 +663,14 @@ void GSTexture12::CommitClear(ID3D12GraphicsCommandList* cmdlist)
{
if (IsDepthStencil())
{
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_DEPTH_WRITE);
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_DEPTH_WRITE);
cmdlist->ClearDepthStencilView(
m_texture.GetWriteDescriptor(), D3D12_CLEAR_FLAG_DEPTH, m_clear_value.depth, 0, 0, nullptr);
GetWriteDescriptor(), D3D12_CLEAR_FLAG_DEPTH, m_clear_value.depth, 0, 0, nullptr);
}
else
{
m_texture.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(m_texture.GetWriteDescriptor(), m_clear_value.color, 0, nullptr);
TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(GetWriteDescriptor(), m_clear_value.color, 0, nullptr);
}
SetState(GSTexture::State::Dirty);
@@ -498,7 +754,7 @@ void GSDownloadTexture12::CopyFromTexture(
dstloc.pResource = m_buffer.get();
dstloc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
dstloc.PlacedFootprint.Offset = copy_offset;
dstloc.PlacedFootprint.Footprint.Format = tex12->GetNativeFormat();
dstloc.PlacedFootprint.Footprint.Format = tex12->GetDXGIFormat();
dstloc.PlacedFootprint.Footprint.Width = drc.width();
dstloc.PlacedFootprint.Footprint.Height = drc.height();
dstloc.PlacedFootprint.Footprint.Depth = 1;
@@ -506,8 +762,7 @@ void GSDownloadTexture12::CopyFromTexture(
const D3D12_RESOURCE_STATES old_layout = tex12->GetResourceState();
if (old_layout != D3D12_RESOURCE_STATE_COPY_SOURCE)
tex12->GetTexture().TransitionSubresourceToState(
cmdlist, src_level, old_layout, D3D12_RESOURCE_STATE_COPY_SOURCE);
tex12->TransitionSubresourceToState(cmdlist, src_level, old_layout, D3D12_RESOURCE_STATE_COPY_SOURCE);
// TODO: Rules for depth buffers here?
const D3D12_BOX srcbox{static_cast<UINT>(src.left), static_cast<UINT>(src.top), 0u, static_cast<UINT>(src.right),
@@ -515,8 +770,7 @@ void GSDownloadTexture12::CopyFromTexture(
cmdlist->CopyTextureRegion(&dstloc, 0, 0, 0, &srcloc, &srcbox);
if (old_layout != D3D12_RESOURCE_STATE_COPY_SOURCE)
tex12->GetTexture().TransitionSubresourceToState(
cmdlist, src_level, D3D12_RESOURCE_STATE_COPY_SOURCE, old_layout);
tex12->TransitionSubresourceToState(cmdlist, src_level, D3D12_RESOURCE_STATE_COPY_SOURCE, old_layout);
m_copy_fence_value = g_d3d12_context->GetCurrentFenceValue();
m_needs_flush = true;
+58 -13
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@@ -18,23 +18,35 @@
#include "GS/GS.h"
#include "GS/Renderers/Common/GSTexture.h"
#include "GS/Renderers/DX12/D3D12Context.h"
#include "GS/Renderers/DX12/D3D12Texture.h"
#include "GS/Renderers/DX12/D3D12DescriptorHeapManager.h"
#include "common/RedtapeWilCom.h"
#include <limits>
namespace D3D12MA
{
class Allocation;
}
class GSTexture12 final : public GSTexture
{
public:
GSTexture12(Type type, Format format, D3D12Texture texture);
~GSTexture12() override;
static std::unique_ptr<GSTexture12> Create(Type type, u32 width, u32 height, u32 levels, Format format,
DXGI_FORMAT d3d_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format);
static std::unique_ptr<GSTexture12> Create(Type type, Format format, int width, int height, int levels,
DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format, DXGI_FORMAT dsv_format,
DXGI_FORMAT uav_format);
static std::unique_ptr<GSTexture12> Adopt(wil::com_ptr_nothrow<ID3D12Resource> resource, Type type, Format format,
int width, int height, int levels, DXGI_FORMAT dxgi_format, DXGI_FORMAT srv_format, DXGI_FORMAT rtv_format,
DXGI_FORMAT dsv_format, DXGI_FORMAT uav_format, D3D12_RESOURCE_STATES resource_state);
__fi D3D12Texture& GetTexture() { return m_texture; }
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_texture.GetSRVDescriptor(); }
__fi const D3D12DescriptorHandle& GetRTVOrDSVHandle() const { return m_texture.GetWriteDescriptor(); }
__fi D3D12_RESOURCE_STATES GetResourceState() const { return m_texture.GetState(); }
__fi DXGI_FORMAT GetNativeFormat() const { return m_texture.GetFormat(); }
__fi ID3D12Resource* GetResource() const { return m_texture.GetResource(); }
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
__fi const D3D12DescriptorHandle& GetWriteDescriptor() const { return m_write_descriptor; }
__fi const D3D12DescriptorHandle& GetUAVDescriptor() const { return m_uav_descriptor; }
__fi D3D12_RESOURCE_STATES GetResourceState() const { return m_resource_state; }
__fi DXGI_FORMAT GetDXGIFormat() const { return m_dxgi_format; }
__fi ID3D12Resource* GetResource() const { return m_resource.get(); }
void* GetNativeHandle() const override;
@@ -48,22 +60,55 @@ public:
void CommitClear();
void CommitClear(ID3D12GraphicsCommandList* cmdlist);
void Destroy(bool defer = true);
void TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state);
void TransitionSubresourceToState(ID3D12GraphicsCommandList* cmdlist, int level, D3D12_RESOURCE_STATES before_state,
D3D12_RESOURCE_STATES after_state) const;
// Call when the texture is bound to the pipeline, or read from in a copy.
__fi void SetUsedThisCommandBuffer() { m_use_fence_counter = g_d3d12_context->GetCurrentFenceValue(); }
private:
enum class WriteDescriptorType : u8
{
None,
RTV,
DSV
};
GSTexture12(Type type, Format format, int width, int height, int levels, DXGI_FORMAT dxgi_format,
wil::com_ptr_nothrow<ID3D12Resource> resource, wil::com_ptr_nothrow<D3D12MA::Allocation> allocation,
const D3D12DescriptorHandle& srv_descriptor, const D3D12DescriptorHandle& write_descriptor,
const D3D12DescriptorHandle& uav_descriptor, WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state);
static bool CreateSRVDescriptor(
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
ID3D12GraphicsCommandList* GetCommandBufferForUpdate();
ID3D12Resource* AllocateUploadStagingBuffer(const void* data, u32 pitch, u32 upload_pitch, u32 height) const;
void CopyTextureDataForUpload(void* dst, const void* src, u32 pitch, u32 upload_pitch, u32 height) const;
D3D12Texture m_texture;
wil::com_ptr_nothrow<ID3D12Resource> m_resource;
wil::com_ptr_nothrow<D3D12MA::Allocation> m_allocation;
D3D12DescriptorHandle m_srv_descriptor = {};
D3D12DescriptorHandle m_write_descriptor = {};
D3D12DescriptorHandle m_uav_descriptor = {};
WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;
DXGI_FORMAT m_dxgi_format = DXGI_FORMAT_UNKNOWN;
D3D12_RESOURCE_STATES m_resource_state = D3D12_RESOURCE_STATE_COMMON;
// Contains the fence counter when the texture was last used.
// When this matches the current fence counter, the texture was used this command buffer.
u64 m_use_fence_counter = 0;
int m_map_level = std::numeric_limits<int>::max();
GSVector4i m_map_area = GSVector4i::zero();
u32 m_map_level = UINT32_MAX;
};
class GSDownloadTexture12 final : public GSDownloadTexture

Some files were not shown because too many files have changed in this diff Show More