Compare commits

...

815 Commits

Author SHA1 Message Date
KamFretoZ
683c8d0cc3 Qt: Icon Revamps 2023-06-15 20:51:15 +10:00
Stenzek
bca20c9e27 Common: Call dwmapi directly 2023-06-15 20:46:56 +10:00
Stenzek
1de3e0986e Build: Remove unused pthreads.props 2023-06-15 20:46:56 +10:00
Abel Briggs
8b2fa73b45 Debugger/MemoryView: Support pasting hex/text from clipboard 2023-06-15 00:08:15 +10:00
Stenzek
1b953c1dc7 CI/Linux: Add Flatpak build files 2023-06-14 22:56:37 +10:00
Stenzek
c33960b411 CI/Linux: Allow path to clang and build deps to be set at build time 2023-06-14 22:56:37 +10:00
Stenzek
8d5728097b CMake: Add USE_LINKED_FFMPEG option 2023-06-14 22:56:37 +10:00
refractionpcsx2
9706045656 GS: Fix reg used to get frame mask on autoflush 2023-06-13 14:10:01 +01:00
refractionpcsx2
3a953eb5df GS: Flush when FRAME or Z matches write location 2023-06-13 14:10:01 +01:00
refractionpcsx2
35971b29bc GS: Skip autoflush optimisation when pending texflush 2023-06-13 14:09:38 +01:00
maxdunbar
76cbc64f99 Docs: update build guide URLs (#8972) 2023-06-13 05:10:06 +01:00
PCSX2 Bot
8f8c85273c PAD: Update to latest controller database. 2023-06-12 18:46:05 +02:00
pgert
25b953b7ec GameDB: minor correction (#8954) 2023-06-12 13:07:31 +01:00
Stenzek
c40f205bd3 GS/Capture: Fix audio encoding without format conversion 2023-06-12 20:44:10 +10:00
Mrlinkwii
be1b698af1 GameDB: correct Frogger Rescue serial 2023-06-11 12:47:04 +01:00
Sestain
c9ec71eeba GameDB: Added fixes for Crash Bandicoot 5 2023-06-11 12:43:57 +01:00
Stenzek
4df27e6efb GS/Vulkan: Add missing chain to exclusive fullscreen control 2023-06-11 13:02:36 +10:00
Stenzek
02f3279dec GS/HW: Get rid of padding in present UBO
It was adding additional padding, which blew the block size out.
2023-06-11 13:02:36 +10:00
refractionpcsx2
21900555dc DEV9: swap unlocks to avoid potential deadlock 2023-06-10 15:23:08 +01:00
Silent
5a4e21287a Achievements: Retain Hardcore Mode state after toggling Test Mode/Rich Presence 2023-06-10 15:17:46 +01:00
Silent
3e8e5216eb Patch: Always enumerate patches/cheats for UI 2023-06-10 15:17:46 +01:00
refractionpcsx2
c679de8e39 USB: Properly initialise effect unions (C rules gotcha) 2023-06-10 13:10:58 +01:00
refractionpcsx2
a979d2283f USB: Increase length of FFB events 2023-06-10 13:10:58 +01:00
refractionpcsx2
3254714b70 USB: Improve FFB for steering wheels 2023-06-10 13:10:58 +01:00
Stenzek
65374f50cf VMManager: Fix patches OSD not getting shown in some cases 2023-06-10 12:35:08 +10:00
Mrlinkwii
1a62cd064c GameDB: add missing entry for Nuga-Cel 2023-06-09 17:45:25 +01:00
Stenzek
40bd19ccbb VMManager: Move unknown serial print to UpdateRunningGame() 2023-06-09 00:59:16 +10:00
Stenzek
642adffeb8 Revert "Patches: Don't reload GameDB when crc is 0."
This reverts commit 5b942f0508.

This was causing patches to not get removed when resetting.
2023-06-09 00:59:16 +10:00
lightningterror
5b942f0508 Patches: Don't reload GameDB when crc is 0.
Bios uses crc 0, spams useless log that bios serial is not in the gamedb.
2023-06-08 00:57:31 +01:00
Ty Lamontagne
b4b5b58e35 IsoFS: Create 'hard-links' for non-conforming version suffixes 2023-06-07 20:41:12 +01:00
DarkC
bf4672fb2b Qt: Add missing bigpicture parameter to help text 2023-06-07 20:38:18 +01:00
lightningterror
d6e2dcd25b Qt: Fix Wunused-variable warning. 2023-06-06 12:46:46 +02:00
lightningterror
3b7d22153f SPR: Cleanup constants. 2023-06-06 12:46:46 +02:00
lightningterror
490a8d35cb GIF: Cleanup Gif.
Constants, initializations, declarations, unused code.
2023-06-06 12:46:46 +02:00
TellowKrinkle
260846e9e9 CMake: Don't use system rapidyaml in default builds 2023-06-06 11:29:40 +01:00
Stenzek
d1ed5aadc2 VMManager: Fix patches when booting with a state 2023-06-06 11:25:46 +01:00
JordanTheToaster
1067ed309a GameDB: Various fixes
Fixes for missing lighting in No One Lives Forever and somehow fixes Spongebob Revenge of The Flying Dutchman not starting a new game in the PAL version.
2023-06-05 16:34:11 +01:00
refractionpcsx2
1ef9bc464d GS-HW: Only preload targets when data is needed 2023-06-05 11:26:33 +01:00
Stenzek
ba3a7fc11a GS/HW: Rename IsBlendedOrOpaque() to IsDiscardingDstColor()
And remove the dst color output case, this is clearly wrong when we're
using this to try to identify clears.
2023-06-05 11:26:33 +01:00
Stenzek
c44b4c3d35 GS/HW: Black blending should preserve RGB, not A 2023-06-05 11:26:33 +01:00
Stenzek
c79c79fe0e GS/HW: Fix PrimitiveCoversWithoutGaps returning true with gaps
Previously it only checked that all sprites matched in size, not that
there wasn't actually any gaps between them.
2023-06-05 11:26:33 +01:00
Stenzek
a7c70a3916 GS/Vulkan: Colclip drawback shouldn't use DONT_CARE load op 2023-06-05 11:26:33 +01:00
TellowKrinkle
325a8cba58 GS:MTL: Fix ICE on macOS 10.15
Apparently the Catalina Intel UHD 630 backend compiler ICE's on use of the bool3 constructor over a float3...
(Weirdly this happens on the Metal22 metallib compiled for 10.15 but not on the one compiled for 10.13... we do still want PrimID support if possible so I'd rather not remove it if I don't have to)
2023-06-05 11:26:23 +01:00
refractionpcsx2
35387eeabb GIF: Fix some incorrect unknown register warnings 2023-06-04 18:20:02 +01:00
Stenzek
9d3de8631c Patch: Add "bytes" type
Allows patching an arbitrary range of bytes.
2023-06-03 23:09:52 +01:00
Stenzek
940e211bb6 Patch: Improve logging 2023-06-03 23:09:52 +01:00
Mrlinkwii
5eb425bc4c GameDB: Fix up some names 2023-06-02 17:57:01 +01:00
refractionpcsx2
bd6b529157 Patches: Allow duplicate lines with complex types 2023-06-01 16:08:22 +01:00
Stenzek
0d59e0a2e9 GS/Vulkan: Remove render area heuristics
And just set the render area to the full target every time.

Except colclip draws.
2023-06-01 15:56:25 +01:00
JordanTheToaster
1826d122f5 GameDB: Various fixes
Fixes for FMVs blowing up the HC in Ace Combat games and FMVs being broken in Jonnys Mad Trixx.
2023-06-01 12:06:16 +01:00
Stenzek
ed6dd6f6cd CI: Update build to use patches.zip instead of cheats 2023-05-31 16:38:14 +01:00
Stenzek
81da9fb5a4 Patch: Add new toggleable cheat and patch interface 2023-05-31 16:38:14 +01:00
Mrlinkwii
ec35330593 GameDB: Fixes for Onimusha Warlords 2023-05-30 23:52:59 +01:00
Stenzek
f741953ee4 Qt: Add memory cards to per-game settings 2023-05-30 18:21:00 +01:00
lightningterror
c0343897cd GameDB: Add full mipmap with ps2 trilinear to ESPN NFL 2K5.
Improves textures to match sw renderer.
2023-05-30 16:16:34 +02:00
refractionpcsx2
d880f8cde5 GS-TC: Fix bugs with target resize and borders in texture min max 2023-05-30 13:32:30 +02:00
TheLastRar
1175bd822c Github: Update issue template
Corrects spelling of appropriate
Adds text area for logs/dumps for the application template
Clarifies that dumps should be in a zip file
2023-05-28 19:29:14 +01:00
Stenzek
63a141abe6 GS/HW: Don't preload large framebuffer alpha textures 2023-05-28 17:31:04 +01:00
Stenzek
abce57ce9c GS: Enable API debug logging in Devel builds 2023-05-28 14:55:53 +01:00
JordanTheToaster
c471f7cf6c GameDB: Urban Chaos Light alignment fix
Fixes light alignment at native resolution to match software.
2023-05-28 01:33:05 +01:00
TellowKrinkle
656c2775ac CMake: Add vtune support on Windows 2023-05-27 17:54:53 +02:00
TellowKrinkle
a2c6e050d7 VMManager: MacOS CPU count detection 2023-05-27 04:57:50 +01:00
Mrlinkwii
f3adb05b1c GameDB: add various entries 2023-05-26 19:43:34 +01:00
Stenzek
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
Stenzek
680affd1fe Common: Add ByteSwap.h
Provides a C++23-like std::byteswap implementation.
2023-05-25 16:47:36 +01:00
TellowKrinkle
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
Stenzek
44460365c0 GS/HW: Vectorize mem clears 2023-05-25 09:49:31 +01:00
Stenzek
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
descawed
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
Mrlinkwii
2a9d38048e github: update issue templates 2023-05-24 17:44:47 +01:00
Stenzek
bba65b8a82 Patch: Discard patches with non-hex addresses/values 2023-05-24 12:24:47 +01:00
Stenzek
884086ba76 StringUtil: Fix incorrect value of endptr
And add associated unit tests.
2023-05-24 12:24:47 +01:00
Ty Lamontagne
1fa6614cd5 Achievements: Implement the ELF suffix hack from CDVD when hashing 2023-05-23 09:56:08 +01:00
Mrlinkwii
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 Briggs
d0346436fb LogSink: Log BIOS print syscall messages if EE console is enabled 2023-05-22 08:37:50 +01:00
JordanTheToaster
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
Stenzek
90a6088d61 GSRunner: Fix log file writing
Wasn't getting flushed/closed on shutdown.
2023-05-21 08:52:45 +01:00
TellowKrinkle
338a2beaf0 GS:MTL: Remove pre-10.14 fallback
We no longer support pre-10.14
2023-05-20 10:59:23 +02:00
TellowKrinkle
ff9a910c1a GS:MTL: Use GSTexture base class's clear tracking 2023-05-20 10:59:23 +02:00
TellowKrinkle
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
TellowKrinkle
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
TellowKrinkle
df847835ad GS:MTL: Implement DrawMultiStretchRects 2023-05-20 10:59:23 +02:00
TellowKrinkle
8aad1c78af GS:MTL: Remove hdr copy pipeline
No longer needed
2023-05-20 10:59:23 +02:00
TellowKrinkle
7c97cf4799 GS:MTL: Implement InvalidateRenderTarget 2023-05-20 10:59:23 +02:00
TellowKrinkle
fd11523cf4 GS:MTL: Implement ClearSamplerCache 2023-05-20 10:59:23 +02:00
TellowKrinkle
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
Mrlinkwii
995e294856 GameDB : fixes for Bonus Demo 6 2023-05-16 19:55:03 +01:00
Stenzek
c4e623eec2 VMManager: Don't rescan symbols when swapping discs
The ELF isn't changing.
2023-05-16 12:58:19 +01:00
Stenzek
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
Stenzek
0f05967190 CommonHost: Purge and move functions to appropriate locations 2023-05-16 12:58:19 +01:00
Stenzek
ad0e469f87 Misc: Clang warning fixes 2023-05-16 12:58:19 +01:00
Stenzek
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
Stenzek
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
Stenzek
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 Bot
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
Mrlinkwii
9509745be9 GameDB : add missing Gran Turismo fixes 2023-05-13 22:50:29 +01:00
JordanTheToaster
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
Stenzek
6426f4432e SPU2: Get rid of dynamic allocations 2023-05-13 16:39:40 +01:00
Stenzek
191ea50663 GS/HW: Fix GT4 render hack 2023-05-13 16:38:53 +01:00
Stenzek
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
isJuhn
e3962aa794 PINE: Update to the age of Qt 2023-05-13 16:17:30 +01:00
Stenzek
1964bbc03a MSBuild: Rename pcsx2core to pcsx2
No need to differentiate it, since wx is gone.
2023-05-13 07:12:12 +01:00
Stenzek
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
Mrlinkwii
041abd8abc GameDB: fix up Midnight Club memcard filters 2023-05-13 01:08:05 +01:00
Stenzek
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
Stenzek
38480d3aed GS/HW: Fix crash in PossibleCLUTDraw() 2023-05-12 14:19:58 +01:00
Stenzek
3436bb3792 GS/HW: Include FBMSK in target lookups for debug traces 2023-05-12 14:19:58 +01:00
Stenzek
5bab8af38f GS/HW: Rename and improve dirty alpha to valid alpha 2023-05-12 14:19:58 +01:00
Stenzek
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
Stenzek
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
Stenzek
9493d3e9c9 USB/GunCon2: Adjust calibration timer
Credit to @pcnimdock for debugging.
2023-05-11 16:24:27 +01:00
Stenzek
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
Stenzek
7edc4e2cb3 GS: Remove CRC hack levels
Replace it with a boolean "Disable Render Fixes" option.
2023-05-11 16:16:15 +01:00
Stenzek
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
forrvalhalla
2695ddc9fc GameDB: Various fixes 2023-05-11 09:23:54 +01:00
JordanTheToaster
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
Stenzek
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
Stenzek
ba27221bf2 GameDB: Enable TexInRT for Enthusia - Professional Racing
Fixes reflections (C32 target with offset C24 texture).
2023-05-10 13:26:19 +01:00
Stenzek
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
Stenzek
a30ca0ce2a GS/HW: Remove Tomb Raider CRC hacks
It works correctly with tex-in-rt now.
2023-05-10 13:26:19 +01:00
Stenzek
5e3e988846 GS/HW: Allow finding targets offset behind FBP for tex-in-rt 2023-05-10 13:26:19 +01:00
Stenzek
bb42353c81 GS/HW: Make regions signed, and use compatible bits for tex-in-rt 2023-05-10 13:26:19 +01:00
Stenzek
61740fc9ed GS/HW: Break channel shuffle on CBP change
Needed for Tomb Raider: Underworld
2023-05-10 13:26:19 +01:00
Stenzek
ea30c90a6c GS/HW: Use source resolution rather than CRTC for channel shuffle 2023-05-10 13:26:19 +01:00
Stenzek
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
Goatman13
6e40081dd9 GameDB: Remove DOA2 iop patches.
Fixed in https://github.com/PCSX2/pcsx2/pull/3778
2023-05-09 18:41:40 +01:00
Stenzek
2b8b43c94c GS/Vulkan: Simplify and refactor swap chains 2023-05-09 13:44:56 +01:00
Stenzek
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
Stenzek
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
Stenzek
159d0c060f GS/Vulkan: Clear out previous texture binding when it's RT/DS 2023-05-08 20:48:14 +01:00
Stenzek
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
Stenzek
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
Stenzek
47636bb30f Config: Fix incorrect key for DisableShaderCache 2023-05-08 20:48:14 +01:00
Stenzek
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
Stenzek
75b782f261 GS/Vulkan: Enable geometryShader for Primitive ID
Apparently it is needed..
2023-05-08 20:48:14 +01:00
Stenzek
4a5cf0efb9 GS: Combine texture classes and add custom layout for Vulkan 2023-05-08 20:48:14 +01:00
PCSX2 Bot
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
Stenzek
0526769808 GS/Vulkan: Remove more unused code 2023-05-06 07:18:55 +01:00
Connor McLaughlin
1866745936 GS/DX12: Fix building in debug 2023-05-06 04:02:29 +01:00
Stenzek
920c5ab266 Qt: Expose disable shader cache option 2023-05-06 03:40:00 +01:00
Stenzek
c57d8980a1 GS: Move Vulkan helpers from common to GS 2023-05-06 03:40:00 +01:00
Stenzek
0ed418834a GS: Move OpenGL helpers from common to GS 2023-05-06 03:40:00 +01:00
Stenzek
083969a3d2 GS: Move DirectX helpers from common to GS 2023-05-06 03:40:00 +01:00
Ty Lamontagne
6740fff179 Profiling: Fix missing cast breaking VTune builds on Linux
Also remove now-pointless SW-JIT VTune code.
2023-05-06 03:15:46 +01:00
JordanTheToaster
25e24d1d09 GameDB: More Juiced 1 FIxes
Fixes for broken headlights and enforcing high blending for more accuracy.
2023-05-06 00:52:47 +01:00
refractionpcsx2
76cc9c8b21 GS: Only update dirty on local invalidate if bp matches 2023-05-05 14:58:41 +01:00
Regan Green
7dcf6b70d9 GameDB: Apply THUG2 GS HW fixes to THAW 2023-05-05 13:00:44 +01:00
Regan Green
f26b26b73e GameDB: Tony Hawk's post-processing fixes 2023-05-05 13:00:44 +01:00
JordanTheToaster
055beaa27a GameDB: Juiced 1 FIxes
Fixes for broken window and shadow rendering headlight brightness and overbightness in hardware mode.
2023-05-05 10:21:25 +01:00
lightningterror
a4623c3c63 Qt: Sort checkbox upscale and renderer hw hacks in alphabetical order. 2023-05-05 00:31:01 +02:00
Zwip-Zwap Zapony
4e3a94809d GameDB: Secret Agent Clank compat and bloom fix 2023-05-04 22:37:58 +01:00
JordanTheToaster
5ff64899e6 GameDB: True Crime LA Fixes
Fixes for the sun going through buildings.
2023-05-04 18:00:51 +01:00
lightningterror
971f172c91 GS: Cleanup GSRenderer.
Constants, casting.
2023-05-04 16:37:39 +02:00
CharlesThobe
4671167a2c VIF: Fix assertion error not returning int value 2023-05-04 14:39:14 +01:00
CharlesThobe
7aff4ee4cb Misc: Minor cleanup 2023-05-04 14:39:14 +01:00
JordanTheToaster
30f7685435 GameDB: Various fixes
Fixes for Underground 1 PAL and Transformers.
2023-05-04 12:53:26 +01:00
refractionpcsx2
341f377e6d VIF: Improve IR setup for skipped unpack inputs/writes 2023-05-04 01:37:54 +01:00
refractionpcsx2
fe4788ae3f GS:MTL: Extend render pass restart avoidance code to depth-only passes
Previously only worked when the depth texture was removed, but not when the color texture was removed
2023-05-04 00:10:14 +01:00
Connor McLaughlin
e133e89b6b Qt: Fix crash in graphics settings on Linux 2023-05-03 16:39:48 +01:00
refractionpcsx2
bf6a0a035a VIF-JIT: Ignore completely write protected vectors 2023-05-02 23:19:02 +01:00
refractionpcsx2
790447ecc9 VIF-JIT: Use non-reserved XMM for zero register 2023-05-02 21:27:53 +01:00
Stenzek
47506d1433 GS/HW: Don't memclear with vertical gaps in the sprites
Xenosaga 3's FMVs clear out a top/bottom letterbox.
2023-05-02 21:12:18 +01:00
Stenzek
933e6aa62e GS/HW: Fix target region textures not getting invalidated
Xenosaga 3 has tex-in-RT, offsetting a source from a larger target, but
the invalidation kills the target but not the source otherwise.

Also fixes m_from_target_TEX0 being tested when it might not be valid.
2023-05-02 21:12:18 +01:00
Stenzek
6736ef1d44 GS/Vulkan: Add exclusive fullscreen control option 2023-05-02 19:55:43 +01:00
refractionpcsx2
3e631e047f GS-HW: Avoid clear misdetection with DATE enabled 2023-05-02 19:55:32 +01:00
refractionpcsx2
dd2d4edffc VIF-JIT: Get rid of mem read for mask 2023-05-02 18:20:55 +01:00
refractionpcsx2
fd2960c9cb VIF-JIT: Skip src reads on fill writes using regs
Clean up some of the code
2023-05-02 18:20:55 +01:00
refractionpcsx2
c2907ea58f VIF-JIT: Clean up pointless code, optimise protected vector copies 2023-05-02 18:20:55 +01:00
PCSX2 Bot
41f62cf53d PAD: Update to latest controller database. 2023-05-02 11:49:57 +02:00
Ty Lamontagne
e462f1ff9c iR3000: Fix memchecks that only log 2023-05-01 07:02:21 +01:00
Ty Lamontagne
5b0b6191d8 iR5900: Fix memchecks that only log 2023-05-01 07:02:21 +01:00
Ty Lamontagne
ab9a1e4307 R5900 interpreter: Fix breakpoint exits
Exit exceptions were not being caught, causing a crash.
2023-05-01 07:02:21 +01:00
Ty Lamontagne
029c11c8d2 Debugger: Fix an oversight on how breakpoints are managed 2023-05-01 07:02:21 +01:00
TellowKrinkle
e221d31b45 GS:OGL:Shaders: Formatting 2023-04-30 23:48:49 +02:00
lightningterror
dfbdaa651c vcxproj.filters: Remove common_header.glsl mention.
No longer exists.
2023-04-30 23:48:49 +02:00
CharlesThobe
9de152b8ee Linux: implement DBus screensaver inhibitor 2023-04-30 19:18:53 +01:00
Mrlinkwii
360f9afb70 GameDB: Fixes for Shin Sangoku Musou Series Collection Joukan 2023-04-30 16:41:40 +01:00
Connor McLaughlin
1b81825218 x86/microVU: Fix typo in VI CRC
Doesn't actually affect anything, only for debugging.
2023-04-30 06:12:01 +01:00
Stenzek
b3e6e28827 x86/iR5900: Fast forward timeout loops 2023-04-30 04:52:50 +01:00
Stenzek
eaceb27879 x86/microVU: Remove redundant cmp in mVUtestCycles 2023-04-29 18:24:49 +01:00
Stenzek
cd9b6c7ac3 x86/microVU: Pack VF cycles into bitfields
The VF cycle count doesn't go above 4, across 32 registers that saves 64
bytes.

Also gets rid of blockhasmbit, since save states are getting invalidated
anyway, it was never used.

[SAVEVERSION+] VU struct changes.
2023-04-29 18:24:49 +01:00
TellowKrinkle
d3e527f2a4 GS:MTL: Always end all encoders on FlushEncoders
Previously, texture upload encoders weren't submitted if no rendering had been done, which would result in an assertion failure if the device was destroyed in that state, as the encoders would be released without calling `endEncoding` on them.
2023-04-29 17:37:24 +01:00
TellowKrinkle
b47fdcdfab GS: Fix crash when looking up color textures with depth lookups 2023-04-29 17:02:16 +01:00
Stenzek
2550ad7fd1 GS/HW: Detect clears spanning multiple sprites
Fixes GT4 rendering to >1000x1000 targets.
2023-04-29 17:01:15 +01:00
Stenzek
1717f584a0 GS/HW: Add flush reason to draw tracing 2023-04-29 17:01:15 +01:00
Stenzek
0822d3e3e5 GS/HW: Cache possible mem clear value 2023-04-29 17:01:15 +01:00
Stenzek
ec41af760a GS/Vulkan: Make primid not require barycentric extension 2023-04-29 16:23:09 +01:00
Stenzek
a5ed24ca88 Perf: Support instruction-level profiling with jitdump on Linux 2023-04-29 16:22:37 +01:00
Stenzek
b3697579c0 GS/Vulkan: Simplify GPU selection
Hopefully stops a crash on broken drivers.
2023-04-29 16:20:01 +01:00
JordanTheToaster
388da2058b GameDB: FFXII texture fixes
Fixes for broken textures on player model.
2023-04-29 08:01:59 +01:00
Stenzek
aa9a0dca4b GS/HW: Fix HW move debug message 2023-04-28 13:34:45 +02:00
Stenzek
2a892da0da GS/HW: Improve split shuffle detection
Fixes transition effects in DBZ BT3 PAL.
2023-04-28 13:34:45 +02:00
Stenzek
9237bf9429 GS/HW: Relax PSM match requirement for move targets
Fixes broken car preview in Tokyo Xtreme Racer Zero.
2023-04-28 13:34:45 +02:00
Stenzek
10533dce02 GS/HW: Swap xyxy() for upld()
In theory more efficient.
2023-04-28 13:34:45 +02:00
Stenzek
b5ebc19eff GS/HW: Don't mess with ZMSK for no_ds
Fixes broken depth in Superman Returns.
2023-04-28 13:34:45 +02:00
Stenzek
6535e7e43a GS: Add natvis for vector types 2023-04-28 10:22:45 +01:00
Ty Lamontagne
5f9473ef02 ci: Update labeler debugger directories 2023-04-28 06:15:27 +01:00
Stenzek
fbb1c7cb8e GS/OGL: Don't reuse targets when they're the texture
I don't trust drivers to insert a barrier here. At least one of them
gets it wrong.

Also moves the masking of depth/colour to the common renderer for
consistency.
2023-04-27 23:22:09 +01:00
lightningterror
2d97d85ca5 GS-hw: Use correct format specifier for blend log, use constants for mergesprite log. 2023-04-27 21:20:31 +02:00
Stenzek
ecd7d0fc35 GS/HW: Fix pipeline/shader duplication 2023-04-27 12:01:34 +01:00
Stenzek
0c389789f3 GS: Fix hang when switching renderer while fullscreen 2023-04-27 09:17:27 +01:00
Stenzek
d8239664a8 GS/Vulkan: Re-enable async presentation 2023-04-27 09:17:16 +01:00
rayanHappy
c06d4f477a Misc: remove unneeded file and clean up a 32bit check 2023-04-27 09:09:04 +01:00
refractionpcsx2
cdd88a6e5c GS-HW: Fix std::sort comparator for purging hash cache 2023-04-27 09:07:21 +01:00
refractionpcsx2
5a73fa2d23 GS-TC: Update dirty read overlap on local mem invalidate 2023-04-27 09:07:05 +01:00
Stenzek
0367851b8e GS: Make TEXFLUSH a flag instead 2023-04-26 16:00:59 +01:00
Stenzek
33b2f6331c GS/HW: Allow auto flush to be applied only to sprites 2023-04-26 16:00:59 +01:00
Stenzek
befbf57191 GS: Refactor exclusive fullscreen yet again
Also acquire render window as late as possible.
Limits the duration that the main window isn't displaying anything.
2023-04-26 16:00:39 +01:00
JordanTheToaster
20d040d5d1 GameDB: Disney Golf Fixes
Fixes for grass rendering to match software with mipmapping and trilinear filtering.
2023-04-26 02:07:15 +01:00
TellowKrinkle
06fdc75945 CMake: Properly fail on windeployqt failure 2023-04-26 02:06:58 +01:00
refractionpcsx2
ded971a3ec Build: Fix Qtdir for windows build workdflows 2023-04-25 22:57:05 +01:00
Stenzek
abc0f99ddd Qt: Move themes to its own file
It's getting a bit out of hand.
2023-04-25 21:53:30 +01:00
Stenzek
b3a88d6ea7 Qt: Migrate to 6.5.0 on Windows 2023-04-25 21:53:30 +01:00
refractionpcsx2
76014b7cb9 GS-TC: Use the expected rect to expand the target when Tex is RT. 2023-04-25 20:53:31 +01:00
Stenzek
0ab6eb6587 GS: Rework texture pooling behavior
- Split into texture/target pools.
 - Keep textures around when they're used recently regardless of size
   (saves work in the backend/driver).
 - Don't boot textures out of the pool when it's an idle frame.
2023-04-25 20:53:21 +01:00
Stenzek
a4e99366fb GS/HW: Put a cap on the hash cache count
As well as VRAM usage. Stops Corvette allocating 16,000+ textures.

Also reduce max age for hash cache sources, since they get kept around
in the latter for another 30 frames.
2023-04-25 20:53:21 +01:00
Stenzek
a32ab4cc97 GS: Refactor ResizeTexture() to ResizeRenderTarget() 2023-04-25 20:53:21 +01:00
JordanTheToaster
e7f3c42f9d GameDB: Various FIFA 2001-2004 fixes
Fixes for broken player textures and some missing fixes.
2023-04-25 20:53:05 +01:00
Ty Lamontagne
d76a0d7416 Debugger: Implement BC0XY branches & their condition evaluation 2023-04-25 17:28:31 +01:00
Stuart Kenny
79f4af8ab5 Qt: Delete SDLRawInput on non win32 builds 2023-04-25 15:05:30 +01:00
Stuart Kenny
a5f83329cb FullscreenUI: Only show SDL Raw on win32 builds. 2023-04-25 15:05:30 +01:00
rayanHappy
267479f31d Misc: Cmake and GCC compiler flags cleanups 2023-04-25 15:04:39 +01:00
rayanHappy
164462e510 Misc: Remove ICC compiler support 2023-04-25 15:04:39 +01:00
TellowKrinkle
6331df306f qt:resources: Use black and white icon for forum menu entry 2023-04-25 15:04:26 +01:00
TellowKrinkle
027ceebcbd qt:resources: Use black and white icons for discord menu icon 2023-04-25 15:04:26 +01:00
TellowKrinkle
edb2c0080c qt:resources: Use separate black/white github icon 2023-04-25 15:04:26 +01:00
TellowKrinkle
caafc87b29 qt:resources: Sort qrc filenames
Many filesystems (e.g. btrfs, apfs) return results in some internal non-alphabetical ordering, which isn't great for minimizing changes to files
2023-04-25 15:04:26 +01:00
TellowKrinkle
5d37cac4a0 qt:resources: Skip dotfiles when generating qrc 2023-04-25 15:04:26 +01:00
Stenzek
8f68e096d4 GS/HW: Avoid render pass restarts to turn off RT
Significantly reduces render passes in Sly 2.
2023-04-24 22:17:25 +01:00
Stenzek
430cad48e3 GS/Metal: Get rid of redundant pointer 2023-04-24 22:17:04 +01:00
Stenzek
757a9532e6 GS: Add Render Pass stats 2023-04-24 22:17:04 +01:00
KamFretoZ
f26f8cafa9 Qt: Even more fixes to the Cobalt Theme 2023-04-24 19:24:19 +02:00
KamFretoZ
128a79e355 Qt: Help menu icon fix for macOS user 2023-04-24 19:24:19 +02:00
PCSX2 Bot
cc2d99db3a PAD: Update to latest controller database. 2023-04-24 19:21:18 +02:00
KamFretoZ
30a31d931a Qt: Add extra icons to the help menu 2023-04-23 03:56:36 +01:00
KamFretoZ
1c30d449bf Tools: Fix filename lookup error on the python glyph updater script 2023-04-23 03:56:36 +01:00
refractionpcsx2
dc4ce58248 VU-JIT: Avoid writeReg stealing loadReg GPR 2023-04-23 03:54:53 +01:00
Mrlinkwii
dc93e861c7 GameDB: various fixes 2023-04-22 23:58:58 +01:00
refractionpcsx2
960daf27e2 GameDB: Add FullVU0SyncHack to the linter 2023-04-22 23:38:05 +01:00
Goatman13
844f21344d GameDB: Add patch for Michigan: Report from Hell 2023-04-22 16:55:27 +01:00
refractionpcsx2
535ad110e3 VU-JIT: Backup non cached VI before writing to it when load != write 2023-04-22 15:15:25 +01:00
JordanTheToaster
0e0d7a5441 GameDB: Various fixes
Fixes for vertical lines in Ring of Red and invisible text in Dynasty Warriors 2.
2023-04-22 03:03:27 +01:00
SeruranBlue
ed63221c7e GameDB: Fixes for Air Ranger: Rescue Helicopter (#8711) 2023-04-22 03:02:46 +01:00
seta-san
f9c2d7767d CDVD: Fix Error Message in InputIsoFile.cpp 2023-04-21 10:53:48 +01:00
Berylskid
cb91478590 UI: Correct Recommended Value for Show Indicators 2023-04-20 10:18:25 +01:00
Mrlinkwii
5dec7fe27d GameDB : fixes for Hanjuku Hero 4 2023-04-19 23:30:31 +01:00
Berylskid
575d487c65 GameDB: Fix Armored Core water and game names (#8702) 2023-04-19 19:14:37 +01:00
Stenzek
2b9289f402 GS/HW: Fix missing init of non-CLUT replacement textures 2023-04-19 13:38:20 +01:00
Mrlinkwii
9273683d3c GameDB: fixes for Dark cloud 2023-04-17 21:06:48 +01:00
PCSX2 Bot
88f8465e7e PAD: Update to latest controller database. 2023-04-17 20:02:50 +02:00
refractionpcsx2
f26031cada Vif: Fix up Instant DMA behaviour 2023-04-16 21:15:26 +01:00
JordanTheToaster
3352d71515 GameDB: Various fixes
Fixes for a potential slowdown in Super Robot Taisen and replace disabling Instant VU with InstantDMA in MGS 3 Subsistence.
2023-04-16 21:10:31 +02:00
Connor McLaughlin
999f9532ee GS: Warning fix 2023-04-16 06:43:22 +01:00
Stenzek
d1f62ca9bf GS: Remove GSVertexList
It doesn't appear to be used anywhere.
2023-04-16 06:35:05 +01:00
Stenzek
ef9f0cf635 GS: Replace magic alignment number with constant
And ensure it gets used in None preloading.
2023-04-16 06:35:05 +01:00
Stenzek
d745564451 GS/HW: Adjust Black/Burnout sky CRC hack
Apparently some stages use a sky height of 128 instead of 256?
2023-04-15 22:01:38 +01:00
Stenzek
d37ac992fc GS/HW: Use bitfield extract for VS expand (GL/VK) 2023-04-15 20:10:25 +01:00
Stenzek
e7fc3de90c GS/HW: Ensure region texture mipmaps don't go out of bounds 2023-04-15 20:10:15 +01:00
Stenzek
bde81380c3 GS/SW: Stop C rasterizer crashing with AA1 2023-04-15 20:10:03 +01:00
Stenzek
839b482cb5 GS: Use 16-bit indices instead of 32-bit
Save some bandwidth.
2023-04-15 20:10:03 +01:00
Stenzek
72f70d4789 GS/Vulkan: Clear textures/RTs at end of frame
Prevents us from updating potentially changed-state descriptors.
2023-04-15 20:09:48 +01:00
Stenzek
d646bbf5c1 GS/Vulkan: Prioritize VK_EXT_rasterization_order_attachment_access
.. over the ARM version. But continue to support both.
2023-04-15 20:09:48 +01:00
Stenzek
e68aaf6540 GS/Vulkan: Saturate ImGui scissor to zero 2023-04-15 20:09:48 +01:00
Stenzek
20ab5ed0fa GS/Vulkan: Don't assume opaque composite alpha is supported 2023-04-15 20:09:48 +01:00
Stenzek
8590e390a2 GS/Vulkan: Don't enable geometryShader 2023-04-15 20:09:48 +01:00
Stenzek
ab1d558420 GS/Vulkan: Make provoking vertex consistent across pipelines 2023-04-15 20:09:48 +01:00
Stenzek
53c9021455 GS/HW: Don't attempt to colour copy into depth target 2023-04-15 20:09:26 +01:00
Stenzek
8bd00e2433 GS: Remove unused scissor variables 2023-04-15 18:01:52 +01:00
Stenzek
c045feae50 GS/HW: Skip draws on reset until scissor is set 2023-04-15 18:01:52 +01:00
Stenzek
7531080e51 GS/HW: Only force shader sampling for non-32bit targets
Not sources.
2023-04-15 17:37:34 +01:00
TellowKrinkle
bf57ab3e39 GS:OGL: Support vs expand on older GL with SSBO extension 2023-04-15 04:29:10 +01:00
JordanTheToaster
dfcb96a4b6 GameDB: Various fixes
Fixes for bloom alignment in Dogz and Catz and broken sun in Ace Combat 4.
2023-04-14 23:01:26 +01:00
refractionpcsx2
5c4fad6725 GameDB: Remove no longer needed Spyro patches 2023-04-14 18:17:44 +01:00
refractionpcsx2
988b1ad03b SPU2: Don't make end IRQ positions inclusive 2023-04-14 18:17:44 +01:00
refractionpcsx2
79705a2514 SPU2: Increase maximum ADSR rate from 0x3FFF to 0x4000 2023-04-14 18:17:44 +01:00
JordanTheToaster
0919b15183 GameDB: Various fixes
Fixes for Dogz and Catz vertical lines and black squares and a workaround for FMVs causing screen shaking in NFS U2.
2023-04-14 13:13:35 +01:00
kenshen112
8162c87884 GameIndex: Added Boss Hang Fix to more regions.
Added Kirie hang fix to Fatal Frame Korea and Asia.
2023-04-14 09:23:35 +01:00
Stuart Kenny
09394ee4b7 Qt: Hide SDL Raw option on non win32 builds 2023-04-13 12:14:15 +01:00
Stenzek
7f7dd60587 GS/HW: VS expand instead of GS for DX/GL/Vulkan 2023-04-13 11:12:11 +01:00
Stenzek
6877abb2ec GS/HW: Remove FFXII CRC hack
No longer needed, and it causes issues with splitting point draws.
2023-04-13 11:12:11 +01:00
Stenzek
ce5dd88790 GS/OGL: Fix GL error on shutdown 2023-04-13 11:12:11 +01:00
Stenzek
5bc9d625e7 GL/StreamBuffer: Align CPU side fallback buffers 2023-04-13 11:12:11 +01:00
Connor McLaughlin
1d7a69ad40 AppImage: Include libxcb-cursor 2023-04-13 10:51:09 +01:00
JordanTheToaster
f7d87076a3 Qt: Adjust MTVU core count text
The wording here was causing confusion and unneeded arguments over what it actually means.
2023-04-13 09:39:02 +01:00
JordanTheToaster
9d20b4d6a6 GameDB: Soulcalibur 2&3 blending recommendations
Fixes menu transparency when using high blending.
2023-04-13 09:39:02 +01:00
TellowKrinkle
128cf9b57d 3rdparty:macOS: Update to Qt 6.4.3
Gives us 5 more months to decide whether we want to use 6.2 LTS or drop macOS 10.14 and macOS 10.15 support
2023-04-13 08:27:49 +01:00
TellowKrinkle
e5b7adb228 3rdparty:linux: Update to Qt 6.5.0 2023-04-13 08:27:49 +01:00
TellowKrinkle
bd5ae66fbe 3rdparty: Update SDL to 2.26.5 2023-04-13 08:27:49 +01:00
Romain Tisserand
a3af4155f8 3rdparty: Bump libchdr to support raw DVD ISO as CHD 2023-04-12 09:37:46 +01:00
refractionpcsx2
1ec83dc790 SPU2: Fix savestate loading setting incorrect variable 2023-04-11 18:45:27 +01:00
Stenzek
f26cc38b80 SPU2: Store DMA pointers as offsets in save state
[SAVEVERSION+] Sadly need to bump save state, don't want to have a mess
of different version handling here.
2023-04-11 15:30:54 +01:00
lightningterror
d9f537e9dc GS-hw: Fix Wsign-compare warning. 2023-04-11 01:06:15 +02:00
PCSX2 Bot
94c75df0d0 PAD: Update to latest controller database. 2023-04-10 20:35:28 +02:00
Stenzek
423a8884e8 GS/Vulkan: Don't try to render out of bounds in Interlace() 2023-04-10 16:51:01 +01:00
Stenzek
1f26502c64 GS/HW: Always convert float depth to integer on readback
Even if it's been reinterpreted as a colour format.
2023-04-10 16:51:01 +01:00
dependabot[bot]
f61f7bb711 Bump peter-evans/create-pull-request from 4 to 5
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4 to 5.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v4...v5)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 16:13:04 +02:00
KamFretoZ
971acd3fdb Qt: Fills in the settings help description fields 2023-04-09 19:13:09 +01:00
JordanTheToaster
bba070bdbf GameDB: PAL ZoE 2 Text fix
Fixes cut off text in PAL versions of Zone of the Enders 2
2023-04-09 19:12:56 +01:00
Connor McLaughlin
6c4152a7e0 GS/HW: Update 32-bit flag for depth buffers too
Jackie Chan Adventures re-uses a previous C32 target pointer as a Z16S
depth buffer, but it does clear it inbetween. So we need to remove the
32-bit flag on the clear.
2023-04-09 17:56:49 +01:00
Stenzek
f569ad0970 GS/HW: Allow translating targets for depth sources
Fixes broken half screen in Miami Vice and 10 Pin - Champions Alley.
2023-04-09 17:56:49 +01:00
Stenzek
f16a291412 GS/HW: Adjust TextureMinMax end coordinate when point sampling 2023-04-09 17:56:49 +01:00
refractionpcsx2
e0cfa2dff3 EE/COP2: Increase likely clear sync 2023-04-09 17:23:09 +01:00
Stenzek
bf9d087e74 GS/HW: Adjust Burnout CRC to fully skip broken post effect 2023-04-09 16:28:57 +01:00
JordanTheToaster
b245dd55d6 Github: Change emu bug report template
Missed when changing the other template.
2023-04-09 16:26:23 +01:00
JordanTheToaster
1e3f429169 GameDB: Various fixes
Alieviates high VU % usage in Pilot Down Behind Enemy Lines and sets max blending level to minimum for other Monster Hunter games to fix heavy GPU usage for no reason.
2023-04-09 16:26:23 +01:00
refractionpcsx2
8d429c7e5a GameDB: Update the VU clamp mode on Ultimate Spider-Man 2023-04-09 16:24:46 +01:00
Stenzek
b9be3ad3b8 GS/HW: Tiny optimization in source lookup
Don't want to do divides per-target.
2023-04-09 06:01:54 +01:00
refractionpcsx2
3099090e6a GameDB: Add InstantDMA to Jak 3 for holes in face geometry 2023-04-09 05:56:58 +01:00
refractionpcsx2
5e27c65615 EE/COP2: Check for likely zero clears in COP2 synced ops 2023-04-09 05:55:15 +01:00
refractionpcsx2
8b32382e1b GameDB: Add Autoflush and HPO Special to Ultimate Spider-Man 2023-04-09 03:31:41 +01:00
arcum42
60047e8029 common: Remove some unneeded includes. 2023-04-08 20:26:39 +01:00
arcum42
e37fff1213 common: Remove SafeList and SafeAllignedArray as unused. 2023-04-08 20:26:39 +01:00
JordanTheToaster
64a6d8027b GS: Reset performance counters on renderer switch
Resets performance counters on renderer switch.
2023-04-08 13:37:21 +01:00
Stenzek
cd4434135e GSRunner: Don't skip dumps with dots in their filename 2023-04-08 13:36:45 +01:00
Stenzek
747e11d7dd GS/HW: Allow region targets for half-right fix 2023-04-08 12:44:33 +01:00
Stenzek
3cae728aba Qt: Recreate new window immediately when switching APIs 2023-04-08 12:42:34 +02:00
Stenzek
7f24a5cf82 GS: Fix crash when resizing window 2023-04-08 04:05:45 +01:00
refractionpcsx2
1b8f5f232a GS-HW: Fix bug with looping invalidation 2023-04-08 00:08:08 +01:00
refractionpcsx2
77d37de18c GameDB: Add mipmapping to Hasbro Family Game Night 2023-04-07 20:34:03 +01:00
Mrlinkwii
5ea3fb8e1e Github: Update issue template 2023-04-07 19:52:50 +01:00
refractionpcsx2
d683aa43d8 GS: Clean up Host->Local code 2023-04-07 17:18:33 +01:00
refractionpcsx2
d4c3501bb8 GS: Retool downloads to buffer full read 2023-04-07 17:18:33 +01:00
Stenzek
f2229a0007 GS/OGL: Don't leak shader objects when compiling 2023-04-07 17:18:21 +01:00
Stenzek
2a06bb6e2c GS/OGL: Use VS/GS selectors from base class 2023-04-07 17:18:21 +01:00
lightningterror
a06f890ab9 GS: Fix Wunused-variable warning. 2023-04-07 01:26:00 +02:00
refractionpcsx2
bbe22f95d1 GS: Avoid modifying single QW downloads as they go to a register
Also avoid downloading more than requested
2023-04-06 23:26:59 +01:00
Stenzek
631f75a79c GS/HW: Don't break out of target search loop on dirty target 2023-04-06 14:28:19 +01:00
Stenzek
c121aae8f1 GS: Add VS natvis files for FastList and TC Targets 2023-04-06 14:27:36 +01:00
refractionpcsx2
fed7629632 GS: Fix typo in ResizeTexture which was causing a crash 2023-04-06 14:27:08 +01:00
Stenzek
0825ca736f GS/HW: Add other StretchRect() calls to texture copies counter
Better reflects GPU work.
2023-04-06 14:20:20 +01:00
Stenzek
660974c9d1 GS/HW: Update target in new format when reinterpreting
Fixes block scrambling in Budokai 3 during screen transitions.
2023-04-06 14:20:20 +01:00
Stenzek
4404b06d2a Qt: Fix lockup when cancelling shutdown and fullscreen 2023-04-06 08:48:07 +01:00
Stenzek
daef69099b Qt: Fix improper shutdown with CTRL+C 2023-04-06 08:48:07 +01:00
Stenzek
6362994fd8 GS: Default to Vulkan for suitable GPUs on Linux 2023-04-06 08:48:07 +01:00
Stenzek
398cf43782 GS: Combine HostDisplay with GSDevice
GS/DX11: Don't throw bad_alloc on surface creation fail

GS: Link device and host display construction/destruction

FullscreenUI: Replace HostDisplayTexture with GSTexture

GS: Purge HostDisplayTexture

GS: Move everything in HostDisplay to GSDevice

GS: Move ImGui rendering to GSDevice

GS: Get rid of reset/store API state
2023-04-06 08:48:07 +01:00
refractionpcsx2
77f8a0f5f6 Counters: Retool UpdateVSyncRate 2023-04-06 08:47:35 +01:00
lightningterror
d7e54ccbed CDVD: Fix struct member variables not used.
Codacy.
2023-04-05 20:15:18 +02:00
lightningterror
53a8855696 INISettingsInterface: Fix scope of variable warning.
Codacy.
2023-04-05 20:15:18 +02:00
lightningterror
bd16ed1340 iR5900: Fix scope of variable warning.
Codacy.
2023-04-05 20:15:18 +02:00
lightningterror
dd365fe334 GS-hw/tc: Fix Wsign-compare warnings. 2023-04-05 20:15:18 +02:00
refractionpcsx2
2a6ba739bc GS-HW: Fix stretch rects errantly discarding data 2023-04-05 16:29:36 +01:00
refractionpcsx2
a863466f70 GS-HW: Better handle double half clears + masked channels + invalidate
Also add Auto Flush to Power Drome US, apparently it wasn't there.
2023-04-05 16:29:36 +01:00
refractionpcsx2
32f07f4aae GS-HW: Read back TC on GS CSR Reset 2023-04-05 16:29:36 +01:00
refractionpcsx2
3ed0e010be GS-TC: Improve handing of wrapping targets in tex in rt 2023-04-05 16:29:36 +01:00
GiladNir
fb3c0c8138 GameDB: Added fixes for Fatal Frame and Siren 2023-04-05 15:10:48 +01:00
Stenzek
58ded2e0d0 GS/HW: Fix incorrect hashing of non-palette textures 2023-04-05 15:01:42 +01:00
Stenzek
369b9a4808 Misc: Fix up a few recent clang warnings 2023-04-05 12:43:45 +01:00
Stenzek
0bd57986a9 GS/HW: Don't try to use forced trilinear on shuffles 2023-04-05 12:43:45 +01:00
refractionpcsx2
559b88438b GS: Fix some Scanmask situations in PCRTC 2023-04-04 17:33:32 +01:00
refractionpcsx2
5d140f7db3 GS: Fix missing PSM references. 2023-04-04 17:32:59 +01:00
Stenzek
7b512ce296 GS/HW: Fix Final Fantasy XII CRC hack 2023-04-04 17:27:57 +01:00
refractionpcsx2
ada291c0f6 GS: Remove redundant PSM enum naming 2023-04-04 13:56:44 +01:00
refractionpcsx2
857cb36707 GS-HW: Add CRC hack for NFS Undercover to handle weird shuffle 2023-04-04 13:56:44 +01:00
refractionpcsx2
4a702e0585 EE: Clear reset required status on JIT overflow reset 2023-04-04 11:16:31 +01:00
refractionpcsx2
eac420f205 GameDB: Replace Tex in RT with Partial Target Invalidation, Dark Cloud 2 2023-04-03 21:54:31 +01:00
TellowKrinkle
23d4fa9d9e GS:MTL: Process uv in place
The separate uv_out made it easy to make mistakes, especially when copying code from other renderers
2023-04-03 20:21:15 +01:00
From: TellowKrinkle
f6523f34d8 GS:MTL: Implement region rect 2023-04-03 20:21:15 +01:00
TellowKrinkle
82971d3ef7 GS:MTL: Test and sample depth should be supported
Untested, but we restart the render pass if it's detected, which should be accurate, even if it's not the most efficient.
2023-04-03 20:21:15 +01:00
PCSX2 Bot
8d9a5111a1 PAD: Update to latest controller database. 2023-04-03 18:10:16 +02:00
Stenzek
e8dac0051c GS: Move expanded dither storage to software renderer
Hardware doesn't use it.
2023-04-03 14:19:46 +01:00
Stenzek
72802aa125 GS/HW: Move channel shuffle test to top of Draw() 2023-04-03 14:19:46 +01:00
Stenzek
f77a5c23fc GS/HW: Get rid of GSFrameInfo 2023-04-03 14:19:46 +01:00
Stenzek
cf772fcdd6 GS: Reuse backup environment instead of copying 2023-04-03 14:19:46 +01:00
Stenzek
4313c64d9d GS: Remove unused offsets (tex/fzb) 2023-04-03 14:19:46 +01:00
refractionpcsx2
38bf916231 GS: Update fixes for Sacred Blaze 2023-04-02 19:44:11 +01:00
refractionpcsx2
cf59c0b854 GS/Counters: Catch SMODE changes and update VSync rate 2023-04-02 16:19:11 +01:00
refractionpcsx2
10e192deed GS/Counters: Use progressive check, not GSSetCRT for interlace mode 2023-04-02 16:19:11 +01:00
refractionpcsx2
b3fb6e7822 GS: Don't reset CRT mode on reset 2023-04-02 13:11:27 +02:00
Stenzek
3f640ed7eb GS/HW: Fix blue screen in GT4 transitions 2023-04-02 13:10:08 +02:00
Stenzek
cc814585ee GS/OGL: Fix incorrect binding in multi stretch rect 2023-04-02 04:29:56 +01:00
refractionpcsx2
b0d26c8242 EE: Correct FPU_MUL_HACK result value 2023-04-02 04:09:47 +01:00
Stuart Kenny
4133be28c6 USB: Remove force feedback logspam 2023-04-02 01:56:00 +01:00
JordanTheToaster
6e81879436 GameDB: Various fixes
Fixes for Driv3r and VP2.
2023-04-01 23:45:10 +01:00
refractionpcsx2
5ea670ece4 GS-HW: Handle triangle memory clears 2023-04-01 16:47:29 +01:00
Stenzek
e8e9702d7e GS/HW: Swap Crash WoC CRC hack for native palette draws 2023-04-01 15:45:14 +01:00
Stenzek
4cbdbaabdb GS/HW: Add NativePaletteDraw upscaling fix 2023-04-01 15:45:14 +01:00
Stenzek
f332d4f880 GS/HW: Set no_ds if Z tests are disabled and masked 2023-04-01 15:45:14 +01:00
Stenzek
5ce418cdaf GS/HW: Set m_channel_shuffle if late tests succeed 2023-04-01 15:45:14 +01:00
Stenzek
81ab2b9cd1 GS/HW: Minor texture cache cleanups 2023-04-01 15:45:14 +01:00
Stenzek
c441d76b7b GS/HW: Fix some asserts tripping in debug builds 2023-04-01 15:45:14 +01:00
Stenzek
fcbc027abc GS: Unify D3D device creation paths
Also makes Vulkan the device for Intel Arc GPUs.
2023-04-01 14:15:18 +01:00
Stenzek
8989b69ce8 GS: Fix crash on shutdown when using software renderer 2023-04-01 14:14:19 +01:00
Stenzek
e9a624ab54 Qt: Fix main window closing on fullscreen shutdown 2023-04-01 14:14:00 +01:00
Stuart Kenny
8a9df89bf6 SDLInputSource: SDL raw input as config option. 2023-04-01 02:32:01 +01:00
JordanTheToaster
e95d75e01f GameDB: Fix missing Tekken 5 demo
Fixes for missing Tekken 5 demo that caused camera issues.
2023-04-01 01:44:17 +01:00
Mrlinkwii
bbe58b07a8 GameDB: fixes for Super Trucks Racing 2023-03-31 21:29:46 +01:00
tangomike99
7886c9ea27 GameDB: Fix fog line in Over the Hedge 2023-03-31 21:29:34 +01:00
tangomike99
1c072f38bb GameDB: Fix blurriness in Sitting Ducks 2023-03-31 21:29:34 +01:00
KamFretoZ
6c2bbdef1f Qt: Theme Polishes for Pizza and Cobalt 2023-03-31 20:16:33 +01:00
Stenzek
a5ebb388a0 CMake: Enable RAIntegration on Windows builds 2023-03-31 15:46:33 +01:00
Buzzardsoul
9c91c700ac GameDB: Add roundsprite 2 to Samurai Warriors 2 2023-03-31 11:59:44 +01:00
Stenzek
28b111b669 x86/iFPU: Inline FPU_MUL_HACK to dynarec
Fixes Tales of Destiny crashing on clang builds (clang was using r8,
which was allocated by a caller, msvc was not).
2023-03-31 11:39:46 +01:00
Stenzek
1be6e1f374 Misc: Fix a bunch of warnings 2023-03-31 11:39:46 +01:00
Stenzek
fff8592b4e GS/HW: Fix GT4/T5 CRC hacks in DirectX renderers 2023-03-31 11:24:31 +01:00
lightningterror
4af3856d15 GS: Bump shader cache version. 2023-03-31 10:18:27 +01:00
lightningterror
8a06fb1840 GS: Fix fxaa bad shader on opengl. 2023-03-31 10:18:27 +01:00
Stuart Kenny
e2e2ab62f4 MSBuild: Enable DirectX in cmake SDL build 2023-03-31 10:12:14 +01:00
Ty Lamontagne
e7e3f30fce 3rdparty: Update SDL2 2023-03-31 02:06:32 +01:00
Stenzek
affc45e752 GSDumpReplayer: Fix crash when downloading Z24 targets
e.g. Lego Racers 2
2023-03-30 21:55:50 +01:00
Stenzek
d70334ee57 GS/HW: Slight shader simplification
- Don't declare texture if it's not read from. Stops Vulkan validation
   layers whinging.

 - Get rid of OpenGL common_header.glsl, and use name linking instead of
   leftovers from separate shader objects.
2023-03-30 21:55:50 +01:00
Stenzek
1c600c7068 GS/HW: Remove m_used from SourceMap
Not used anymore, since we don't age the TC when there's no draws.
2023-03-30 21:55:50 +01:00
Stenzek
7a93f1fc23 GS/HW: Remove KOF2002/SVCChaos CRC hacks
10 Pin - Champions Alley needs texture-inside-RT in LookupDepthSource(),
but otherwise nothing else appears to break if we fall back to normal
lookup for Z sources.

Relaxes the page alignment requirement for split texture shuffle
detection, Psi-Ops does an A->A copy with coordinates offset by +8.
2023-03-30 21:55:50 +01:00
Stenzek
9c2f7aeb6a GS/HW: Get rid of reset-32bits-fmt flag hack
Doesn't appear to be needed anymore.
2023-03-30 21:55:50 +01:00
Stenzek
8af2d17d1f GS/HW: Cache target widths as well as heights
Avoids redundant resizes.

Also align widths to page sizes, like heights.
2023-03-30 21:55:50 +01:00
Stenzek
65d78eff57 GS/HW: Sample depth buffer instead copying when safe
OpenGL and Vulkan only.
2023-03-30 21:55:50 +01:00
Stenzek
8be9e2dc71 GameDB: Remove preload/CPU FB for Crash WoC
Fog effect works correctly now (at least at 1x).
2023-03-30 21:55:50 +01:00
Stenzek
faecc6913b GS/HW: Texture cache improvements
GS/HW: Only use temporary source for recursive draw

.. and don't insert it into the page map.

GS/HW: Lookup page list for depth sources

GS/HW: Avoid target copies by using shader sampling

GS/HW: Make texture cache a global pointer

GS/HW: Remove GetID() from GSTexture

It only made sense for OpenGL, was always zero in Vulkan.

GS/HW: Rewrite texture sampling hazard detection

Also avoid redundant channel shuffle setup.

GS/HW: Turn Haunting Ground CRC into an OI fix
2023-03-30 21:55:50 +01:00
Stenzek
ed90c8868f GS/HW: Don't leave ZBUF_TEX0 partially uninitialized 2023-03-30 21:55:50 +01:00
Stenzek
71edce43ca GS/HW: Fix incorrect condition for continuing channel shuffle 2023-03-30 21:55:50 +01:00
Stenzek
4e9ef34f58 GS/HW: Fix incorrect end block computation in Overlaps() 2023-03-30 21:55:50 +01:00
Stenzek
de55596926 GS/Vulkan: Include source code in shader debug info 2023-03-30 21:55:50 +01:00
JordanTheToaster
316bc422bc GameDB: Various fixes
Fixes lack of sun intensity in WRC texture distortion in Ultimate Spiderman and missing serials and fixes for those serials for Sakura Taisen.
2023-03-30 20:40:03 +01:00
Stenzek
c73ae3dfb3 x86/iR5900: Get rid of eeRecIsReset
It was preventing the rec being reset inbetween launching different games.
2023-03-30 19:45:11 +01:00
Stenzek
27b45276ae SPU2: Remove GetLongName() from SndOutModule
Unused since WX.
2023-03-30 16:55:17 +01:00
JordanTheToaster
b00852fada GameDB: More WWE text fixes
Adds the text fix to WWE 2007 to 2010
2023-03-30 11:03:29 +01:00
refractionpcsx2
663f61f4e1 GS-TC: only escape Local Mem Invalidate early on exact BP match 2023-03-30 11:03:10 +01:00
refractionpcsx2
110bc64ee4 GS-TC: Fix up page translation logic, clean up variables 2023-03-30 11:03:10 +01:00
refractionpcsx2
3764e773b3 GS-HW: Check what channel is being read during a possible split shuffle 2023-03-30 11:03:01 +01:00
icup321
682f0c7984 GameDB: Add Mipmap/Trilinear to SpongeBob Movie & Incredibles
Update settings for The Incredibles + ROTU and The SpongeBob Movie Game
2023-03-30 09:46:43 +01:00
JordanTheToaster
93014bfede CI: Switch Windows Qt builds to Clang
Switches the Qt builds over to using Clang by default which should be a bit faster overall.
2023-03-30 09:27:10 +01:00
JordanTheToaster
4dd946bc8a CI: Remove separate Windows builds
Removes the AVX2 and SSE4 builds in favour of the unified Qt build.
2023-03-29 20:00:51 -05:00
JordanTheToaster
2222007516 GameDB: WWE 2011 Text fixes
Fixes for the broken text in WWE 2011.
2023-03-29 17:28:55 +01:00
refractionpcsx2
b09e3b0613 GS: Split ModXY in to its own function 2023-03-29 17:08:41 +01:00
refractionpcsx2
3a193956ff GS: Provide HPO Normal offsets when there is no RT. 2023-03-29 17:08:41 +01:00
Mrlinkwii
786eedf2f2 GameDB: fixes for various games 2023-03-29 15:18:16 +01:00
Stuart Kenny
f217519e97 GameDB: Fix WRC 4 car discolouration 2023-03-29 11:50:13 +01:00
Buzzardsoul
4caaa70726 GameDB: Add Mipmap and Trilinear to The Incredibles 2023-03-28 21:54:57 +01:00
JordanTheToaster
02a27a6974 GameDB: Rogue Galaxy character fix
Fixes broken characters in Rogue Galaxy.
2023-03-28 19:52:17 +02:00
Stenzek
6d7eceb4f1 GS/HW: Remove JakGames/JakX CRC hack 2023-03-28 11:21:47 +01:00
Stenzek
f52e72b026 GS/HW: Swap OI_JakGames CRC hack for CPU sprite render 2023-03-28 11:21:47 +01:00
Stenzek
ebeb646e4d GS/HW: Relax CPU sprite render requirements further via levels 2023-03-28 11:21:47 +01:00
refractionpcsx2
70c1620a87 GameDB: Add Partial Target Invalidation for Fatal Frame III
aka Project Zero 3
2023-03-28 11:09:44 +01:00
refractionpcsx2
d45964d0c7 GS-HW: improve dirty handling with expanded tex is rt's 2023-03-28 11:09:44 +01:00
refractionpcsx2
e67aa73e75 GS-HW: Round up rect for hardware draws 2023-03-28 11:09:44 +01:00
refractionpcsx2
cb2fe3792a GS-HW: Resize RT used as larger source 2023-03-28 11:09:44 +01:00
Stenzek
2b94cfe782 GS/HW: Allow strip channel shuffles to be detected
Fixes fog wall in WRC 4.
2023-03-27 18:29:01 +02:00
PCSX2 Bot
a1c99f3e7a PAD: Update to latest controller database. 2023-03-27 18:28:13 +02:00
Stenzek
57fa3ac653 ChdFileReader: Prefer using TOC for file size over header
The header is incorrect, and pads each track to 4 frames.
2023-03-27 10:21:10 +01:00
refractionpcsx2
01b6e1b88d CDVD: Add missing TOC information 2023-03-27 10:21:10 +01:00
refractionpcsx2
294aca82c4 GS-TC: Give option to match target on exact memory addresses
Chances of it being the wrong thing but having the same start/end address is pretty slim. Hopefully
2023-03-26 22:28:23 +01:00
refractionpcsx2
d080e7e7bd VTLB: Show rough EE PC when a TLB miss happens 2023-03-26 22:14:28 +01:00
refractionpcsx2
66a13d4c3a GS-TC: Only stop checking for RT's if whole read is inside that RT. 2023-03-26 15:28:14 +01:00
JordanTheToaster
87c76ad010 GameDB: Various fixes
Helps alleviate some issues in Shrek 2 and removes round sprite and merge sprite from Driv3r as they cause issues
2023-03-25 06:16:25 +00:00
Dreadmoth
822d292e2f GameDB: Ratchet & Clank 1&2
Fixes broken pause menu.
2023-03-25 06:06:24 +00:00
KamFretoZ
42155dd11b Qt: Add a New Light Theme and Cobalt Theme Fix (#8471) 2023-03-24 12:03:05 +00:00
Stenzek
9b1a2d9eaf GS/DX11: Fix incorrect UBO for P8 conversion 2023-03-24 11:43:51 +00:00
TellowKrinkle
8d0307cedd UI: Fix build with achievements disabled 2023-03-23 23:48:40 -05:00
refractionpcsx2
72b38ce712 CDVD: Don't auto mount disc again if game ejects it. 2023-03-23 20:40:45 +00:00
refractionpcsx2
caf8eedd76 CDVD: Correct SCMD error states and init SCMD result 2023-03-23 20:40:45 +00:00
refractionpcsx2
181b05daf0 CDVD: Don't let it try to close the tray if it isn't open 2023-03-23 20:40:45 +00:00
refractionpcsx2
92b21ac9c2 CDVD: Correct status sequence during disc swap. 2023-03-23 20:40:45 +00:00
Berylskid
ad12a3f735 UI: Correct Recommended Values for a few items (#8465) 2023-03-22 13:25:31 +00:00
Stenzek
badca7c20b GS/HW: Fix texture replacement precaching option 2023-03-22 10:03:31 +00:00
Stenzek
7cdcfd4b1a Qt: Remove backup AppImage on next launch 2023-03-21 13:48:50 +00:00
Stenzek
b02af117f8 CMake: Swap -g for -g1 in Linux Release builds
-g tends to blow the AppImage sizes up a bit too much...
2023-03-21 13:48:16 +00:00
Stenzek
87d269512e GS/HW: Compiler warning fixes 2023-03-21 13:15:31 +00:00
Stenzek
3346349bba GS: Remove GSDeviceNull
It hasn't been used in a while, we just use a normal device
and null renderer instead.
2023-03-21 13:15:31 +00:00
Mrlinkwii
280a41806f GameDB: fixes for Metal Gear Solid 3 Snake Eater 2023-03-20 21:27:03 +00:00
Ikko Eltociear Ashimine
134937082d Counters: fix typo
recieve -> receive
2023-03-20 15:46:56 +00:00
Stenzek
1499994143 CI: Update Linux to Qt 6.4.3 and SDL2 2.26.4 2023-03-20 15:46:32 +00:00
Stenzek
5805142fd7 CrashHandler: Print backtrace on Linux 2023-03-20 15:46:32 +00:00
Stenzek
5fc855e519 CMake: Add libbacktrace module 2023-03-20 15:46:32 +00:00
Stenzek
8c8bf22892 CI: Build libbacktrace in Linux deps 2023-03-20 15:46:32 +00:00
Stenzek
ec927e5dd9 CMake: Force debug symbols in Linux Release builds 2023-03-20 15:46:32 +00:00
refractionpcsx2
3a042d8c14 GS: Compensate for misaligned 24bit partial local->host transfers 2023-03-20 14:35:31 +00:00
JordanTheToaster
fc88d1de85 GameDB: From Soft game fixes
Adds partial target invalidation to every From Soft game because they used way too much glue.
2023-03-20 11:19:49 +00:00
JordanTheToaster
6cf48e9e2b GameDB: Various fixes
Fixes R&C 3 broken pause menu and broken textures in AC Last Raven.
2023-03-20 10:05:00 +00:00
refractionpcsx2
db22377a0d GS: Remove ExpandTarget on EE Write 2023-03-19 23:32:17 +00:00
Silent
443cc08229 VMManager: Fix "X widescreen patches loaded" text when loading from files 2023-03-19 23:31:52 +00:00
Stenzek
6ad222117d GS: Reduce MAD buffering draw size
It's silly to draw to the whole double-sized render target, but discard
half the pixels.

Also centralizes the constant setup, get rid of the duplication.
2023-03-19 23:31:37 +00:00
Stenzek
b26acad721 GS: Sample LOD 0 explicitly in interlace shaders
Can't use normal sampling because the derivates are undefined in
non-uniform control flow (in MAD).
2023-03-19 23:31:37 +00:00
refractionpcsx2
76e8bfe42f GS-TC: Make sure drawn/target coords match for adjusting drawn rect 2023-03-19 15:18:54 +00:00
refractionpcsx2
1f6704dbda GS-TC: mask target rect with drawn area before download. 2023-03-19 15:18:54 +00:00
Toastarrr
33ea4e6225 Debugger: fix memory search crash 2023-03-19 13:44:11 +00:00
Toastarrr
d9cecbde7d Debugger: use unsigned long long for memory search 2023-03-19 13:44:11 +00:00
JordanTheToaster
84fab9ccd3 ImGuiOverlays: Fix incorrect fix naming
Fixes incorrect target partial invalidation overlay name and makes autoflush more distinct from anisotropic filtering.
2023-03-19 13:18:37 +00:00
JordanTheToaster
137dfc20fa GameDB: Various fixes
Fixes for Smash Cars This is Football 2002 and Champions Return to Arms.
2023-03-19 13:18:37 +00:00
TellowKrinkle
f39e856fee iR5900: Don't limit block sizes to 16 bits 2023-03-19 11:40:51 +00:00
Connor McLaughlin
e91aabc843 Qt: Fix graphics settings opening to other pages
Regression from 2b49614df9
2023-03-19 11:15:53 +00:00
Mrlinkwii
f85a99b6f0 GameDB: fixes for True Crime - Streets of L.A. 2023-03-19 00:15:29 +00:00
TellowKrinkle
a59f95317a Core: Use auto for ryml noderefs
The return type switched between 0.4 and 0.5, so this will be compatible with both
2023-03-18 17:28:30 -05:00
Mrlinkwii
6923000b52 GameDB: remove SoftwareRendererFMVHack from Siren 2 2023-03-18 22:26:41 +00:00
Víctor "IlDucci
83471bdacd Qt:i18n: Adding I18N comments for translators, minor typo fixes (#8048) 2023-03-18 16:14:55 -05:00
refractionpcsx2
18045c195a GameDB: Readd Tex in RT for Xenosaga Ep.III 2023-03-18 17:07:29 +00:00
refractionpcsx2
b1edadfe3a GameDB: Add partial target invalidation to Ratchet Gladiator/Deadlocked 2023-03-18 17:07:29 +00:00
refractionpcsx2
ed5984aa3a GS-TC: Update draw rect on draw + invalidate bad match old targets 2023-03-18 17:07:29 +00:00
refractionpcsx2
bfca8b8461 GS-HW: Update dirty PCRTC framebuffer on output 2023-03-18 17:07:29 +00:00
refractionpcsx2
63cb0f3577 GameDB: Add partial target invalidation to ZoE 2nd Runner + MGS2 2023-03-18 17:07:29 +00:00
refractionpcsx2
2b49614df9 GS-HW: Don't bilinear dirty rects by default, added as upscale hack. 2023-03-18 17:07:29 +00:00
refractionpcsx2
fa439a465d GS-TC: Fix dirty rect sizes and merging. 2023-03-18 17:07:29 +00:00
refractionpcsx2
11a74c2c05 GS: Fix up some dirty behaviour, allow dirtying by page 2023-03-18 17:07:29 +00:00
refractionpcsx2
a693efad1e GameDB: Correct Dog's Life fixes 2023-03-18 17:07:29 +00:00
refractionpcsx2
75357a2f0a GS-TC: Remove uses of Surface Offsets where possible. 2023-03-18 17:07:29 +00:00
refractionpcsx2
a70f5ebc08 GS-TC: Rewrite rect translation 2023-03-18 17:07:29 +00:00
refractionpcsx2
b161df69e1 GS-TC: Fix up expand targets when mixing 24 and 32bit. 2023-03-18 17:07:29 +00:00
refractionpcsx2
85a0e75e28 GameDB: Add needed updates for Siren 2 and Legion 2023-03-18 17:07:29 +00:00
refractionpcsx2
56022a9af3 GS-TC: Remove uses of Surface Offsets where possible. 2023-03-18 17:07:29 +00:00
refractionpcsx2
5cbcf706e9 GS-HW: use page aligned rects for inexact matches when possible 2023-03-18 17:07:29 +00:00
refractionpcsx2
500b449422 GS-HW: Correct region size when source is in render target 2023-03-18 15:36:18 +00:00
Mrlinkwii
8b78388834 GameDB: various fixes 2023-03-18 13:49:37 +00:00
Mrlinkwii
b44d40d919 GameDB: remove not needed game fix for Yakuza 2023-03-18 13:49:17 +00:00
Mrlinkwii
f8310e0a35 GS/CRC : purge Yakuza CRC hack 2023-03-18 13:49:17 +00:00
refractionpcsx2
59dc0e2cbf GS-SW: Fix rects for sw dumps 2023-03-18 12:49:15 +00:00
refractionpcsx2
6a4a7b1a3b HW-CRC: Draw glass smash on CPU in Burnout 3 2023-03-18 12:49:15 +00:00
lightningterror
d62a7999fb GS-hw: Clean up Wunused-variable warnings. 2023-03-17 20:20:10 +01:00
TellowKrinkle
0ba1a42867 CI:macOS: Use xz for distribution
macOS 10.14 fixed a bug where Archive Utility couldn't decompress .tar.xz and is now our minimum version
2023-03-17 03:18:02 +01:00
JordanTheToaster
68ef49aef5 GameDB: SMT DS Fixes
Fixes broken effects when using lower than high blending.
2023-03-17 00:55:51 +00:00
Buzzardsoul
d0a65153df GameDB: Add Mipmap and Trilinear to Spyro: Enter the Dragonfly 2023-03-17 00:55:36 +00:00
refractionpcsx2
ac113b48e7 COP2: Mask R register on CFC2 reads 2023-03-17 00:43:23 +00:00
Mrlinkwii
6e14680ac7 GameDB: add fixes for Lupin III - Columbus no Isan wa Akenisomaru and fix game names 2023-03-16 13:23:09 +00:00
Mrlinkwii
ba03a533d8 GameDB: fixes for Biker Mice from Mars 2023-03-15 23:21:34 +00:00
JordanTheToaster
9abbecb286 GameDB: Various fixes
Fixes for incorrect region codes and adding merge sprite to Zone of Enders 2 to fix beeg bloom.
2023-03-15 20:39:44 +00:00
refractionpcsx2
9a20ea5c21 GS: Detect double width texture shuffles 2023-03-14 18:13:07 +00:00
refractionpcsx2
8ac4b125d2 UI: Fix masking of Target Partial Invalidation with Tex in RT 2023-03-14 15:04:10 +00:00
refractionpcsx2
f9b682ad10 GS: Fix integer scaling when using Bilinear (Sharp) 2023-03-14 14:51:00 +00:00
TellowKrinkle
58959b6114 CMake: Output test logs on failure 2023-03-13 20:45:12 +00:00
TellowKrinkle
b90405a7d2 GHActions:Windows: Add CMake clang-cl build 2023-03-13 20:45:12 +00:00
TellowKrinkle
e0a1613ad9 CMake: Allow overriding the exe name 2023-03-13 20:45:12 +00:00
TellowKrinkle
11930ed7a2 CMake: Clang-cl support 2023-03-13 20:45:12 +00:00
JordanTheToaster
f3ff1cec54 Documentation: Remove unused files
Removes old or unused files from the docs folder.
2023-03-13 20:29:27 +00:00
Stenzek
435e73d838 GS/HW: Texture cache improvements
Change texture scale from vector to scalar

 - Independent X and Y scaling is long gone.
 - Also separate size and scale in TC lookup

Move clear value for texture to base class

Align heights to page size

 - Since FRAME and Z are in page units, we can't have two targets
 - overlapping within the same page.
 - Stops some small resizes too.
 - Test cases: Genji and Spider-Man 2 shadows.

Don't modify target TEX0 on shuffle/clear

Move upscale multiplier to uniform

Make P8 conversion page-aware

Fix incorrect depth preload shader

Improve HLE of texture shuffles

When a texture shuffle is split into two half-screen draws, we skip the
first, and draw the whole thing in the second, taking care of when both
the texture and framebuffer are offset.
2023-03-13 20:29:05 +00:00
Stenzek
2fdea258fa GS/HW: Fix incorrect depth preload shader 2023-03-13 20:29:05 +00:00
Stenzek
b453a6a46d GS/Vulkan: Actually disable shader cache when requested 2023-03-13 20:29:05 +00:00
Stenzek
5b88e637d8 GS/Vulkan: Fix clear order in Merge/Interlace
Fixes blank frame when changing resolutions.
2023-03-13 20:29:05 +00:00
Stenzek
ac02bcbe33 GSRunner: Default to window but surfaceless when scripted 2023-03-13 20:29:05 +00:00
Stenzek
9efdeae3ac GSRunner: Reduce log spam 2023-03-13 20:29:05 +00:00
Stenzek
54e59e2f7b GSRunner: Support upscale parameter 2023-03-13 20:29:05 +00:00
PCSX2 Bot
2c4e02ff34 PAD: Update to latest controller database. 2023-03-13 17:56:18 +01:00
Berylskid
2a306cbd91 GS-OGL: Remove available_vram (#8389) 2023-03-13 09:07:34 +00:00
Víctor "IlDucci
b244136179 GUI/Qt: Minor text corrections, nitpicks (#8213)
- Adding the actual corrections from #8048 that were not added by #8119.
 - Fixing typos and missing ending periods.
 - Unifying the writing of certain terms:
   - Memory Card uppercased following Sony's writing (taken from PS2 manual).
   - gamefixes/game fixes -> game fixes
   - fast forward/fastforward/fast-forward -> fast-forward (taken from Oxford)
   - slowmotion/slow motion/slow-motion -> slow-motion (following the same convention as before, as I could not find this in Oxford's)
   - framebuffer/frame buffer -> framebuffer
   - Xbox name properly uppercased (for Controller settings)
 - Correcting RA's Rich Presence to separate it from Discord's Rich Presence (after discussions in the Translations channel).
 - Unification of option names in the option area and the hint area.
 - Adding a fix for the (currently broken) Stretch Height/Vertical Stretch tooltip.
2023-03-12 19:34:20 -05:00
Stenzek
b897f367ce FullscreenUI: Mirror Qt graphics settings changes 2023-03-12 16:21:36 +00:00
refractionpcsx2
6c46418f68 CI: Remove WrapGS from GameDB Schema 2023-03-12 15:11:29 +00:00
refractionpcsx2
f0d5d21e64 GS-Config: Remove remnants of the WrapMem setting. 2023-03-12 15:11:29 +00:00
Stenzek
93490876c9 Qt: Fix crash when changing renderer 2023-03-12 15:11:16 +00:00
Stenzek
74763d2156 Qt: Hide manual hardware fixes from global settings 2023-03-12 14:27:20 +00:00
Stenzek
b849d9862d Qt: Move CRC Fix Level to HW Fixes 2023-03-12 14:27:20 +00:00
Stenzek
cd575e0ed8 Qt: Move GPU Palette Conversion to HW Fixes 2023-03-12 14:27:20 +00:00
Stenzek
b5fbd88c34 GS/HW: Move old-target invalidation to after draw
Fixes crash in Radiata Stories.
2023-03-12 14:25:45 +00:00
refractionpcsx2
6003673165 GS-HW: Correct page aligned end blocks 2023-03-12 12:52:53 +00:00
refractionpcsx2
4555667554 GS: Rename bad_shader files to pcsx2_bad_shader for linux clarity 2023-03-12 00:07:52 +00:00
TellowKrinkle
c0db6d49f4 GS:MTL: Fix wrong function constant type 2023-03-11 23:34:56 +00:00
Buzzardsoul
6630066f0b GameDB: Add missing Tony Hawk's Underground 2 fixes. 2023-03-11 21:43:54 +00:00
Buzzardsoul
20e6a55dd1 GameDB: Add blending level 3 to Tony Hawk's Underground 2 2023-03-11 21:22:35 +00:00
Mrlinkwii
d3f82c800f GameDB: add fixes to Crouching Tiger, Hidden Dragon 2023-03-11 21:06:08 +00:00
JordanTheToaster
e0e525d9ae ImGuiOverlays: Add missing fix to status bar
Adds Estimate Texture Region and GPU CLUT to the status bar as well as amends the names of CPU CLUT and GPU CLUT.
2023-03-11 20:41:19 +00:00
Buzzardsoul
12f4d6f872 GameDB: Add Mipmap and Trilinear to Tony Hawk's Underground 2 (#8372) 2023-03-11 20:40:39 +00:00
lightningterror
0668e9bad9 GS: Bump shader cache version. 2023-03-11 20:44:11 +01:00
lightningterror
06aed8491c GS-hw: Separate the Alpha masked Ad case from blend hw bit.
Allows for cleaner code.
2023-03-11 20:44:11 +01:00
lightningterror
df2d11e70d GS-hw: Blend table formatting. 2023-03-11 20:44:11 +01:00
lightningterror
2dde8a5e90 GS-hw: No need to set both BLEND_NO_REC and BLEND_A_MAX in table.
Setting only BLEND_NO_REC is enough as blending is free.
2023-03-11 20:44:11 +01:00
lightningterror
674b13fb3f GS-hw: Cleanup BLEND_C_CLR blend flags.
Rename BLEND_C_CLR to BLEND_HW_CLR.
Merge CLR2_AF and CLR2_AS to CLR2, don't need to be separate as we rely on PS_BLEND_C in shader.
2023-03-11 20:44:11 +01:00
lightningterror
ab17c3693f Gs-hw: Clean up blend flags.
Re arrange them from hw to sw.
2023-03-11 20:44:11 +01:00
lightningterror
a6c372de46 GS-hw: Rename clr_hw to blend_hw PSSampler bit. 2023-03-11 20:44:11 +01:00
lightningterror
62497b9300 GS-hw: Rename PS_CLR_HW to PS_BLEND_HW shader macro. 2023-03-11 20:44:11 +01:00
Yiays
1461a3f8d7 Readme: Update cpubenchmark links (#8331) 2023-03-11 16:40:37 +00:00
JordanTheToaster
686b31765d GameDB: Various fixes
Adds estimate texture region to Combat Elite WWII Paratroopers and round sprite half to Champions Return To Arms to fix lines in HUD and menus.
2023-03-11 16:34:06 +00:00
lightningterror
05e4e98e64 GS: Bump shader cache version. 2023-03-09 21:08:52 +01:00
lightningterror
e95b60d527 GS-hw: Cleanup hw blend clr cases.
Cleanup redundant Blend C sets, they are already set properly beforehand.
Cleanup multiple barrier sets for Ad cases, set one at the end instead.
Cleanup conditions, reduce and cleanup the code.
2023-03-09 21:08:52 +01:00
lightningterror
59aba9f757 GS-hw: Support Ad masked alpha on blend mix 1 and 2 clr cases. 2023-03-09 21:08:52 +01:00
Buzzardsoul
248e94dc4c GameDB: Add autoflush to Dirge of Cerberus: Final Fantasy VII (#8351) 2023-03-09 16:09:53 +00:00
kamfretoz
a7d574cff0 Qt: Fix description for Trigger & Button Deadzone 2023-03-09 16:04:35 +00:00
Stenzek
ad05193916 GameDatabase: Fix recommended blending message
It was reading from the GS thread copy instead of the CPU thread config.
2023-03-09 12:44:21 +01:00
Stenzek
b24b353b2d Qt: Change Profile label to Editing Profile
Hopefully less confusing this way.
2023-03-09 08:40:35 +01:00
Stenzek
18e4a04dba PAD: Add pressure option to macros 2023-03-09 08:40:35 +01:00
Stenzek
30989761e2 Qt: Fix sensitivity/deadzone showing for shift-click macro trigger 2023-03-09 08:40:35 +01:00
Stenzek
b219ee9049 GS/Metal: Align texture upload pitch to 32 bytes 2023-03-09 08:40:09 +01:00
TellowKrinkle
98c611e404 GS:MTL: Don't start render passes with no targets 2023-03-09 08:37:57 +01:00
TellowKrinkle
7a4ef32210 Qt: Restore main menu settings button
Required for expected behavior on macOS
2023-03-09 08:36:48 +01:00
lightningterror
c3359cea1f Qt: Disable framebuffer fetch option on d3d. 2023-03-08 20:23:01 +01:00
JordanTheToaster
f73a2d571f GameDB: Add missing Ponkotsu Roman Fixes
Adds missing JP fixes for Ponkotsu Roman Daikatsugeki Bumpy Trot.
2023-03-07 18:59:59 +00:00
JordanTheToaster
6dfb02c826 GSDumpReplayer: Fix widescreen patch crashing
Fixes a regression which caused PCSX2 to crash if you loaded a dump with widescreen patches enabled.
2023-03-07 14:19:55 +01:00
lightningterror
6c093fc81e GS: Bump shader cache version. 2023-03-06 23:36:54 +01:00
lightningterror
911d35e800 GS-hw: Fix invert rounding for accumulation blend on gl.
Also make the checks consistent for all renderers.
2023-03-06 23:36:54 +01:00
lightningterror
084fdc0a65 GS: Bump shader cache version. 2023-03-06 19:49:27 +01:00
lightningterror
1382fe9c6c GS-metal: Automatically adjust color compensation based on rgb value for hw blend clr3 case.
Auto adjust when any color is higher than 128 ( 1.0f) to get more accurate color results.
2023-03-06 19:49:27 +01:00
lightningterror
b33242830e GS-vk: Automatically adjust color compensation based on rgb value for hw blend clr3 case.
Auto adjust when any color is higher than 128 ( 1.0f) to get more accurate color results.
2023-03-06 19:49:27 +01:00
lightningterror
8c0ee33c4c GS-ogl: Automatically adjust color compensation based on rgb value for hw blend clr3 case.
Auto adjust when any color is higher than 128 ( 1.0f) to get more accurate color results.
2023-03-06 19:49:27 +01:00
lightningterror
e8cf4822b1 GS-d3d: Automatically adjust color compensation based on rgb value for hw blend clr3 case.
Auto adjust when any color is higher than 128 ( 1.0f) to get more accurate color results.
2023-03-06 19:49:27 +01:00
PCSX2 Bot
3462f02ce2 PAD: Update to latest controller database. 2023-03-06 17:07:54 +01:00
Stenzek
1a67b2146a GS/HW: Fix incorrect condition in DX11/OGL 2023-03-06 09:11:51 +00:00
Stenzek
eb0d18f484 GSDumpReplayer: Fix resetting
And get rid of memory reset, it's never used.
2023-03-06 09:11:08 +00:00
Stenzek
c783fc0f59 GSDumpReplayer: Update serial on dump load
Fixes title and HW fixes not applying when dragging a new GS dump onto a
running PCSX2.
2023-03-05 15:41:42 +00:00
refractionpcsx2
31d02c1278 GS-TC: Allow TBW expansion 2023-03-05 11:17:33 +00:00
JordanTheToaster
85f96bb248 GameDB: Various recommendations and fixes
Adds a variety of fixes and recommendation's for users to ignore.
2023-03-05 10:06:51 +00:00
Stenzek
229cf908b7 GS/HW: Use multi stretch for preloading 2023-03-05 10:03:15 +00:00
Stenzek
89b18275c0 GS/DX11: Get rid of runtime blend state creation 2023-03-05 10:03:15 +00:00
Stenzek
b8a86baec7 GS/HW: Implement multi stretch for DX11/DX12/OpenGL 2023-03-05 10:03:15 +00:00
Stenzek
8505e9203a Qt: Support changing running GS dump by drag/dropping 2023-03-03 16:43:16 +00:00
Stenzek
5d95a503bf Qt: Fix crash when spamming shutdown button 2023-03-03 16:43:16 +00:00
Stenzek
36c7f96a1e GS/HW: Get rid of GetOutputSize()
And use PCRTCDisplays instead.
2023-03-03 16:42:54 +00:00
Mrlinkwii
b40b606608 GameDB: update Oneechanbara2Special 2023-03-03 16:42:24 +00:00
Mrlinkwii
03764a624f GS/CRC: purge Oneechanbara2Special CRC 2023-03-03 16:42:24 +00:00
RedDevilus
962cfa9441 GameDB: Steambot Chronicles + typo fix
- Steambot Chronicles has quite an extensive hack for a game doing weird stuff with their Z-buffer, it does mess with the sea being green which is incorrect but the game also looks off for rest of the cutscene.

- misalgined typo to misaligned
2023-03-03 16:42:09 +00:00
lightningterror
b2f30ab080 GS: Bump shader cache version. 2023-03-03 16:35:10 +01:00
lightningterror
24c42ae2d9 GS-hw: Replace alpha factor/alpha source1 with source 1 color.
Output 1 will be used since we want to modify each color channel based on overflow value.
2023-03-03 16:35:10 +01:00
lightningterror
af9353298c GS-metal: Add clr3 case for blend mix 2.
When Cs*(Alpha + 1) overflows compensate with adjusting Alpha output for Cd*Alpha.
2023-03-03 16:35:10 +01:00
lightningterror
a3ecf0b0bd GS-vk: Add clr3 case for blend mix 2.
When Cs*(Alpha + 1) overflows compensate with adjusting Alpha output for Cd*Alpha.
2023-03-03 16:35:10 +01:00
lightningterror
58cb6ab728 GS-ogl: Add clr3 case for blend mix 2.
When Cs*(Alpha + 1) overflows compensate with adjusting Alpha output for Cd*Alpha.
2023-03-03 16:35:10 +01:00
lightningterror
f478b3959c GS-d3d: Add clr3 case for blend mix 2.
When Cs*(Alpha + 1) overflows compensate with adjusting Alpha output for Cd*Alpha.
2023-03-03 16:35:10 +01:00
Stenzek
35ce680859 GameDB: Add PCRTCOffsets to Xiaolin Showdown
Stops screen shaking.
2023-03-03 15:33:47 +00:00
Stenzek
7df189ced4 GameDB: Add PCRTC and blending HW fixes 2023-03-03 15:33:47 +00:00
Stenzek
c35092504c GS/HW: Avoid copying an empty rectangle
Fixes a possible validation error in Ultraman Fighting Evolution -
Rebirth.
2023-03-03 14:59:07 +00:00
Stenzek
0bff6f7ad9 GS/HW: Require FBW=1 for Jak OI fix
The legit palette draws all seem to use FBW 1.

There's a couple of draws which use the alpha channel of the FB which
are currently falsely triggering.
2023-03-03 14:04:43 +00:00
JordanTheToaster
805f985144 GameDB: Gun fixes
Fixes for rainbowing at the edges of the screen missing bloom intensity and alignment and reflections on water and ground textures.
2023-03-02 21:16:57 +00:00
Stenzek
12e578b93c GS/Vulkan: Don't skip barrier with colclip+readwrite date
Value written from HDR setup must be visible for any DATE reads. Fixes
flickering in DBZ BT2.
2023-03-02 17:01:50 +00:00
JordanTheToaster
1312952305 GameDB: Various fixes
Adds Tex In RT 2 to Armoured Core 2 to fix texture corruption in future and adds merge sprite to Destroy All Humans 1&2 to further fix misaligned bloom.
2023-03-02 15:50:02 +00:00
Stenzek
6118b94f9e GS/Vulkan: Fix a bunch of validation warnings
None of these were errors, but it's still good to have clean output.
2023-03-02 15:49:13 +00:00
Stenzek
520320535e Qt: Clear all keyboard bind states when focus is lost 2023-03-02 15:49:04 +00:00
Mrlinkwii
262b5f1dc0 GameDB: add fixes to Knight Rider - The Game 2023-03-02 11:07:28 +00:00
Mrlinkwii
ac36162ddc GameDB: upscaling fixes for Springdale 2023-03-02 09:50:38 +00:00
Stenzek
9b813f4ae3 Qt: Fix skipdraw not being hidden globally again
And slience a warning in TC.
2023-03-02 09:34:41 +00:00
JordanTheToaster
35d05b8653 GameDB: DAH 1&2 Fixes
Fixes for misaligned bloom and sun occlusion and intensity in Destroy All Humans 1 and 2.
2023-03-02 09:18:18 +00:00
Mrlinkwii
e4d6b87e5d GameDB: add textureInsideRT to NBA '07 featuring The Life Vol.2 2023-03-02 01:34:39 +00:00
Stenzek
64b38e5a4a GS/HW: Add "Merge Targets" texture-in-RT mode
Can take several targets from the cache, and create a combined/merged
source from them.

Fixes shadow maps in Destroy All Humans.
2023-03-01 21:13:37 +00:00
Stenzek
75957c84e3 GS: Add "multi stretch rect" drawing to device 2023-03-01 21:13:37 +00:00
Silent
c33fb2adbd Qt: Add a context menu to the toolbar's Settings button when the game is running
A new small context menu that allows to select between global settings
and game settings.
2023-03-01 20:38:42 +00:00
Silent
97d3baba35 Qt: Move "Game Properties" from View to Settings 2023-03-01 20:38:42 +00:00
Stenzek
e91f9925f8 Qt: Display a slightly more helpful error on display create failure 2023-03-01 20:37:18 +00:00
Stenzek
b484f7aef0 Context/Vulkan: Handle VK_INCOMPLETE return from vkEnumeratePhysicalDevices() 2023-03-01 20:37:18 +00:00
Stenzek
9a3904103a GS/HW: Fix off by one in estimate texture region
And enable it for Justice League.
2023-03-01 20:36:36 +00:00
refractionpcsx2
2a2d39b392 GS-TC: On invalidate of the alpha of 32bit, drop back to 24bit 2023-03-01 20:35:38 +00:00
Stenzek
3005ba629f GS/Vulkan: Fix RT being left bound as texture 2023-03-01 21:02:57 +01:00
Mrlinkwii
795741a341 GameDB: various fixes 2023-02-28 21:39:50 +00:00
JordanTheToaster
da98465d4b GameDB: Remove unneeded Midnight Club 3 fixes
Removes the texture preloading restriction as the game no longer violently blows up during gameplay with the hash cache enabled.
2023-02-28 20:52:03 +00:00
Stenzek
d28e46796f GameDB: Enable estimate texture region on Snowblind games 2023-02-28 17:39:15 +00:00
Stenzek
43c6e321f5 GS/HW: Add a new option to attempt to reduce large texture sizes
For Snowblind games which use 1024x1024 textures and UVs.
2023-02-28 17:39:15 +00:00
Stenzek
4595c2feec GS/HW: Allow moves to create larger targets, align to 64 width 2023-02-28 17:39:15 +00:00
Stenzek
8b4402c517 Qt: Skipdraw shouldn't be visible in global settings 2023-02-28 11:49:26 +00:00
Stenzek
e08ae7e8fa GS/HW: Handle end-of-memory wrapping for surface Overlaps() 2023-02-28 09:12:14 +00:00
Stenzek
753efd8c4a GS/HW: Track target sources in all pages
... instead of just the first page it falls within.
2023-02-28 09:12:14 +00:00
forrvalhalla
cb786f0320 GameDB: Various Armored Core Improvements 2023-02-28 08:51:39 +00:00
PCSX2 Bot
6ff64cc984 PAD: Update to latest controller database. 2023-02-27 18:29:35 +01:00
Mrlinkwii
475b816280 Gamedb: remove HPO normal from Dragon Ball Z Budokai - Tenkaichi 2 2023-02-27 13:51:37 +01:00
Stenzek
229005942f GS/DX12: Add missing clip_control support flag
Fixes depth inaccuracy in WWE SmackDown! Here Comes the Pain.
2023-02-27 13:19:51 +01:00
Stenzek
4af25d20fe GS: Fix output equal check in Merge() 2023-02-27 10:21:39 +00:00
Stenzek
6bf5b9a8e3 GS/HW: Fix incorrect size of region mipmap levels 2023-02-27 07:55:58 +00:00
Stenzek
be769c28fa Qt: Cancel game list refresh before GetSaveStateFileName()
Fixes lockup/crash when starting a file early.
2023-02-26 22:27:49 +00:00
JordanTheToaster
3128c48d5b GameDB: Dance Summit 2001 Fixes
Adds paltex to Dance Summit 2001 to massive increase FPS and reduce hash cache usage dramatically.
2023-02-26 22:27:39 +00:00
RedDevilus
5c7161fd2f GameDB: NASCAR '06 Total Team Control
Forces Adaptive TFF to stop bouncing/shaking vertical screen
2023-02-26 15:38:48 +00:00
Stenzek
e85790b84b GS/HW: Don't try to draw with invalid TEX0 configuration
Fixes the texture cache falling apart in 007: Everything or Nothing.
2023-02-26 15:37:58 +00:00
Stenzek
980e2f67fd Qt: Don't display updater if running a game or fullscreen 2023-02-26 15:33:02 +00:00
TellowKrinkle
7781907f0e GS: Blend truncation and dither goes the other way when subtracting
Truncation happens after subtraction, so it's the equivalent of rounding the value to subtract *up* instead of down
2023-02-26 07:22:32 +01:00
TellowKrinkle
1d145dd48a GS:MTL: Clip control is supported
(Well technically, it's not but the default value is the one we want)
2023-02-26 07:22:32 +01:00
TellowKrinkle
1a1eb30e60 GS:MTL: Properly initialize has variable 2023-02-26 07:22:32 +01:00
TellowKrinkle
a7e2b98dc7 Vulkan: Format tfx.glsl 2023-02-26 07:22:32 +01:00
Stenzek
2bf74622a5 GS/DX12: Fix potential crash in PrimID DATE setup 2023-02-26 03:49:40 +00:00
refractionpcsx2
6bcaef9325 GS-HW: Allow swapping of start/end block on overlap check within page 2023-02-26 01:29:49 +00:00
refractionpcsx2
0b3aac3d91 GS-HW: Add channel masks to dirty rects, allows partial updates 2023-02-26 01:29:49 +00:00
refractionpcsx2
9a53f0f853 GS-HW: Improve Local->Host and preload accuracy. 2023-02-26 01:29:49 +00:00
refractionpcsx2
a97df14064 GS-HW: Set scale on temporary depth stencil 2023-02-26 01:29:34 +00:00
RedDevilus
9a0cd1157f GameDB: Timesplitters Series + minor maintenance
- Timesplitters 2 (normal vertex screwing up bottom)
- Timesplitters Future Perfect (remove depth lines)
- Dragon Ball Z - Infinite World (dash
2023-02-26 01:13:24 +00:00
Mrlinkwii
16c41255d0 Gamedb: remove disable partial invalidation from fatal frame 2023-02-26 00:24:24 +00:00
Stenzek
c2d1e5bd18 GameDB: Switch CPU CLUT for GPU CLUT in The Godfather
It can do 10+ readbacks in one frame, which is way too much.
2023-02-25 12:31:28 +00:00
Stenzek
3c85ba3eb8 GS/HW: Use 1023 for skip-target-creation threshold
Fixes target blowout in The Godfather (it does a 1023x1023 draw on
boot).
2023-02-25 12:31:28 +00:00
JordanTheToaster
f3b67b158c GameDB: Gorwlanser 5&6 and Poinies Poin Fixes
Adds Texture in RT to Growlanser 5 and 6 to fix a layering issue and to Poinies Poin to fix text corruption after an FMV.
2023-02-25 12:28:05 +00:00
kamfretoz
8dac10ae36 Qt: Add a new theme, Cobalt Sky. 2023-02-25 11:00:56 +00:00
JordanTheToaster
6b81050283 GameDB: 007 EON Fixes
Adds mipmapping full and trilinear PS2 to 007 Everything Or Nothing to fix up texture detail and removes mipmapping from Fifa games to prevent players from going bald or having rainbow vomit shirts.
2023-02-25 10:55:53 +00:00
Stenzek
b4beacfc43 GS/OGL: Avoid framebuffer swaps when depth is being alternated 2023-02-25 08:18:34 +00:00
Stenzek
1b607a8c4d GameDB: Add partial target invalidation to affected games 2023-02-25 08:18:34 +00:00
Stenzek
4583c64ff7 GS/HW: Add partial target invalidation option
Eventually hopefully we can make this the default, but it breaks too
much at the moment.

Fixes missing/corrupted textures in True Crime: New York City.
2023-02-25 08:18:34 +00:00
Stenzek
a06a07d961 GS/HW: Allow sw prim render when texture rect is dirty
Gets rid of an unnecessary readback in True Crime: New York City.
2023-02-25 08:18:34 +00:00
Stenzek
520a369872 GS/HW: Prevent out of bounds copy in OI_BlitFMV() 2023-02-25 08:18:34 +00:00
Stenzek
1eaec773e2 GS/HW: Don't allocate Z buffer if tests always pass
.. and Z is masked.

Stops some offscreen targets from expanding in size.

Partial fix for regressions in True Crime: New York City.
2023-02-25 08:18:34 +00:00
Stenzek
3433a42e42 GS/DX12: Fix incorrect pipeline RT format 2023-02-25 03:04:50 +00:00
lightningterror
e01eac615d GS-tc: Fix Wreorder-ctor warning. 2023-02-24 11:29:53 +01:00
lightningterror
8116646dee GS: Bump shader cache version. 2023-02-24 02:06:00 +01:00
lightningterror
7f7950cd6b GS-d3d: Check each channel individually if it overflows and do corrections. 2023-02-24 02:06:00 +01:00
lightningterror
2eb11ded52 GS-metal: Check each channel individually if it overflows and do corrections. 2023-02-24 02:06:00 +01:00
lightningterror
bd64ad510b GS-vk: Check each channel individually if it overflows and do corrections. 2023-02-24 02:06:00 +01:00
lightningterror
4e9b7e61a7 GS-ogl: Check each channel individually if it overflows and do corrections. 2023-02-24 02:06:00 +01:00
lightningterror
37b19495a8 GS-hw: Use rgb color for second output instead of alpha.
We want different alpha value for each channel.
2023-02-24 02:06:00 +01:00
refractionpcsx2
c12b412e87 GS-HW: Remove debug message, partial Clang format GSRendererHW.cpp 2023-02-23 23:21:53 +00:00
refractionpcsx2
17f137f8be GS-HW: Slightly better check for target expanding 2023-02-23 20:13:01 +00:00
JordanTheToaster
fcc627c65c GameDB: Various fixes
Fixes for missing bloom intensity in Ferrari Challenge mipmapping in Dark Cloud and adjusts HPO on The Dog Island and adding missing Scandinavia entrys.
2023-02-23 19:37:29 +00:00
refractionpcsx2
5bb3d8e60d GS-HW: Improve GS read target detection, avoid reading dirty targets. 2023-02-23 18:27:01 +00:00
refractionpcsx2
264086e0aa GS-HW: Improve clear detection and avoid making bad render targets 2023-02-23 18:27:01 +00:00
refractionpcsx2
6013d7172a GS-HW: Drop to CPU CLUT w/e invalidate only if dirty covers whole tex 2023-02-23 18:27:01 +00:00
refractionpcsx2
a7714b2725 MCD: Stop Memcard Folders spamming the console/OSD when saving a game 2023-02-23 18:02:07 +00:00
Stenzek
f9dcac8cd0 GS/HW: Make readback-on-close a HW fix
Unfortunately it's too risky to enable by default all the time. So,
we'll make it a hw fix, and hopefully one day can make it default on.

Also makes save states readback the TC as well.
2023-02-23 17:25:03 +00:00
Stenzek
2487322e47 GS/HW: Track which bits are actually written to targets
Fixes Burnout 3 sky getting corrupted when flushing.
2023-02-23 17:25:03 +00:00
Stenzek
c7e9c9542e GS/HW: Don't try to dirty targets which don't overlap
The current invalidation code sucks, but at least this stops things
which are blatently wrong from happening.
2023-02-23 10:12:05 +00:00
Stenzek
c1bc1af302 GS/HW: Don't mess with the buffer width of the target on invalidate 2023-02-23 10:12:05 +00:00
Stenzek
739f9ec758 GS/HW: Set valid rect on targets created by Move 2023-02-23 10:12:05 +00:00
refractionpcsx2
f70a140f42 GS-HW: Fix Download readbacks and limit FB resizing 2023-02-22 11:50:11 +00:00
refractionpcsx2
a716e69dc0 GameDB: Remove no longer needed SW FMV switch fixes 2023-02-21 16:15:29 +00:00
refractionpcsx2
0c6e1a4d56 GS-HW: Invalidate overlapped target when expanding. 2023-02-21 16:15:29 +00:00
Stenzek
faf36ecba6 GS/D3D: Default to D3D11 for Intel 2023-02-21 15:49:59 +00:00
Stenzek
49f2900e1f GS/D3D: Combine driver version lookup for D3D11+D3D12 2023-02-21 15:49:59 +00:00
AKuHAK
8bd522d283 BiosTools: Implement SysGetBiosDiscID function, for Bios Serial used EXTINFO build unique timestamp 2023-02-21 15:24:36 +00:00
AKuHAK
e9034a1ba1 Biostools: remove unused external variable BiosZone 2023-02-21 15:24:36 +00:00
Stenzek
03feacd69a GS/HW: Use FB size instead of output size for target lookup
Fixes render target height doubling unnecessarily in Ridge Racer V.
2023-02-21 15:22:09 +00:00
Stenzek
0c9f44d8a4 GS/HW: Don't allow region textures to make sources larger
Currently not handled. Fixes Ridge Racer V intro again.
2023-02-21 15:22:09 +00:00
RedDevilus
39fb64cdcd GameDB: Dark Cloud 2 + Dark Chronicle
I had a dark joke on the fix, but let's not jester about it. The clown now has more colors than just 1.
2023-02-21 14:10:14 +00:00
JordanTheToaster
d531a7f1af GameDB: Remove CPU CLUT from Transformers The Game
Something changed and now this just causes rainbow vomit in game and in menus instead of fixing the issue it was originally put in for.
2023-02-21 09:36:49 +00:00
PCSX2 Bot
bb7ff414ae PAD: Update to latest controller database. 2023-02-21 02:14:48 +01:00
JordanTheToaster
215f112521 GameDB: Port patch to PAL Transformers ROTF
Ports a patch over to the PAL version to fix the pause menu hud and other parts.
2023-02-19 15:50:05 +00:00
Florin9doi
644766d965 USB: Fix Sega Seamic buttons 2023-02-19 13:15:53 +01:00
JordanTheToaster
1e1a555d3b GameDB: Various fixes
Fixes for Transformers Revenge of the Fallen misaligned bloom and soft shadows and Legend of Kay broken shadow rectangles and misaligned bloom.
2023-02-19 03:53:20 +00:00
refractionpcsx2
c64ae2684d GS-PCRTC: Handle extended height when there's a negative offset 2023-02-19 00:57:52 +00:00
refractionpcsx2
50ed04436d GS-HW: Preserve width of frame textures 2023-02-19 00:57:38 +00:00
Stenzek
2fb9beca52 GS/HW: Use block instead of page pointer for height lookup
Some callers were using blocks, others were using pages before.

Enables target expansion in Stuntman, which slightly improves rendering
without CPU sprite. The full "fix" needs page handling in P8 conversion.
2023-02-19 00:57:24 +00:00
refractionpcsx2
cd4c1e920e GS: Flush targets back to GS memory when swapping renderers 2023-02-19 00:57:01 +00:00
refractionpcsx2
e846ac367a GS-HW: Fix downloads in offset BP and different widths 2023-02-19 00:03:49 +00:00
Mrlinkwii
ef31c733ee Gamedb: update Armored Core - Nexus 2023-02-18 15:53:30 +00:00
Stenzek
724aa657f3 Qt: Fix window geometry not saving on exit 2023-02-18 14:50:09 +00:00
kenshen112
0284c35f4c GameDB: Add Fatal Frame 1 / Project Zero final boss game bug fix patch 2023-02-18 05:04:20 +00:00
TheTechnician27
6ce33de287 UI: Update and Add mouseover dialog (#8119) 2023-02-18 01:58:32 +00:00
refractionpcsx2
6ccfa011d4 Pad/Counters: Rearrange Pad/Core updates on VSync
Apparently this gets around some weird input lag issue.
2023-02-18 01:13:39 +00:00
refractionpcsx2
c9078af45e GS: Bump shader cache version 2023-02-17 19:40:16 +00:00
refractionpcsx2
6745428d0c GS-SW: Fix SW texture dumping 2023-02-17 19:06:35 +00:00
refractionpcsx2
925e874ada GS-HW: Fix real 16bit value shuffles 2023-02-17 19:06:35 +00:00
lightningterror
03f0f2f803 GameDB: Add missing db entry for Silent Scope 3.
Korean version.
2023-02-17 16:35:46 +01:00
lightningterror
857360d6b2 GameDB: Add full mipmap with ps2 trilinear to Matrix, The - Path of Neo.
Improves ground textures to match sw renderer.
2023-02-17 16:35:46 +01:00
Stenzek
2dd76c3f12 GS/HW: Force region match on fixed TEX0
Fixes lightmapping in Spinter Cell - Double Agent.
2023-02-17 13:20:04 +00:00
Stenzek
666de3a874 GS/HW: Allow hardware sampling when clamp_max is larger
Fixes some mipmapping issues in GT4.
2023-02-17 13:20:04 +00:00
Stenzek
e0e9b64db6 GS/HW: Fix region textures being used when redundant 2023-02-17 13:20:04 +00:00
JordanTheToaster
2f521348c6 GameDB: Add VU Sync hack to Salt Lake 2002
Fixes the awful flickering and missing textures that happens all over the game.
2023-02-17 13:12:33 +00:00
Stenzek
8ac2949a1f GS/HW: Fix incorrect bitfield width in height cache
This lead to duplication and possibly larger-than-intended heights.
2023-02-16 16:44:40 +00:00
Stenzek
d0d5d991ce GS/HW: Fix repeat sampler being used for region clamp/repeat
The coordinates are clamped in the shader, but normalized UV of 1 and
bilinear may repeat.
2023-02-16 16:44:40 +00:00
Mrlinkwii
1fc2d7de3c GameDB : remove skipdraw from Need for Speed - Undercover 2023-02-16 15:00:27 +00:00
refractionpcsx2
2598e8d9b9 GS-PCRTC: Fix Anti-blur in screen offset.
No this doesn't mean it won't look blurry, that's a downside of screen offsets in some games, but it might look *less* blurry.
2023-02-16 14:47:09 +00:00
refractionpcsx2
01f65e98e6 GS-PCRTC: Fix up some PCRTC anti-blur behaviour + code cleanup 2023-02-16 14:47:09 +00:00
Ganael Laplanche
c5330cf166 Common: FreeBSD fixes. (#8163)
* Fix SIGSEGV handler on FreeBSD

* Fix config dir location on FreeBSD
2023-02-16 09:30:18 +01:00
JordanTheToaster
b78796d0c1 GameDB: Add HPO Special to Arthur and the minimoys
Fixes misaligned bloom that looks gross.
2023-02-16 00:32:17 +00:00
RedDevilus
da1e9db2c0 GameDB: Ruff Trigger
Rename Europe serial and fix offset and blooming.
2023-02-15 19:18:11 +00:00
RedDevilus
6beb6aa05b GameDB: Bakugan Battle Brawlers
Se Deinterlace to Adaptive TFF. I thought this was fixed but needs to be checked later.
2023-02-15 19:15:49 +00:00
Mrlinkwii
6ea7777a3a GS-HW: remove Fighting Beauty Wulong & Spartan Total Warrior CRC (#8158) 2023-02-15 14:56:53 +00:00
Stenzek
f97191e241 GS/HW: Split up consecutive channel shuffles 2023-02-15 11:04:05 +00:00
Stenzek
51420dade4 VMManager: Clear host root on booting ISO 2023-02-15 10:04:39 +00:00
Tokman5
cc55c01197 GameDB: Add EETimingHack to Crazy Taxi 2023-02-15 10:04:04 +00:00
JordanTheToaster
86ce464ee3 GameDB: Fix V-Rally 3 graphical corruption
Fixes random graphical corruption that can happen by adding EE Timing hack.
2023-02-15 00:04:44 +00:00
refractionpcsx2
0fa52a75ad GS-HW: Optimise readback performance for some cases 2023-02-14 22:27:35 +00:00
Mrlinkwii
c91e7dc3b0 GameDB: remove not needed hw fixes for Metal Slug 6 2023-02-14 22:27:17 +00:00
Mrlinkwii
88034b176c GS-HW:purge MetalSlug6 CRC 2023-02-14 22:27:17 +00:00
JordanTheToaster
efeaff488c GameDB: Add HPO Special to 007 EON
Lines bad must fix lines.
2023-02-14 17:49:53 +00:00
Berylskid
5df30f5bdd OSD: Change the lower limit of OSD Scale from 100 to 50 (#8135) 2023-02-14 14:03:24 +00:00
C.W. Betts
cf179c42b8 cmake: Quiet macOS building warning, we can build on macOS just fine. (#8136) 2023-02-14 11:32:39 +01:00
Berylskid
a615f8bf17 Qt: Change "Save State On Shutdown" to Unchecked (#8147) 2023-02-14 10:30:34 +00:00
refractionpcsx2
b38964e814 GS: Partial revert of #8101 pending investigation.
Sometimes great ideas don't always go smoothly to plan, this is one of those, but it will be back when we work out what's up with Soul Calibur 2 and DBZ BT3 :)
2023-02-14 10:23:09 +00:00
JordanTheToaster
013c9eec58 GameDB: Various fixes
Some fixes I missed in the last PR because I am a doughnut and can't remember what I needed to do.
2023-02-14 00:20:52 +00:00
refractionpcsx2
ddbd6eddf7 GameDB: Add Autoflush for Astro Boy and CPU Sprite for Alias 2023-02-14 00:18:08 +00:00
refractionpcsx2
982fd42683 GS: Preload whenever it matches an upload. GUI option forces preloads. 2023-02-14 00:18:08 +00:00
RedDevilus
90e28e7957 GameDB: Fix Japanese KH2 - Final Mix
Change Normal Vertex halfpixel with roundsprite
2023-02-13 23:59:41 +00:00
JordanTheToaster
f4201f3947 GameDB: Remove fix from Soulcalibur 3
No longer needed as the hash cache no longer does an explosion.
2023-02-13 23:27:27 +00:00
PCSX2 Bot
7844b40243 PAD: Update to latest controller database. 2023-02-13 17:37:59 +01:00
JordanTheToaster
d0839a3d55 GameDB: Fixes for graphics in Mana Khemia 2
Fixes missing graphical effects in battles by disabling mvu speedhack.
2023-02-13 16:07:31 +00:00
JordanTheToaster
876fd9ba9e GameDB: Vexx underwater rendering fixes
Adds Tex in RT to fix underwater rendering being totally broken.
2023-02-13 09:37:31 +00:00
lightningterror
e12717c108 CDVD: Fix FreeBSD compile. 2023-02-13 03:02:59 +01:00
refractionpcsx2
af0b17bb7a Counters: Present at VSync End 2023-02-12 21:13:42 +00:00
Stenzek
6f595b7d87 GS/HW: Allow previous frame in depth source lookup
Fixes pulling random junk from local memory in Black after adjusting
vsync timing.
2023-02-12 21:13:42 +00:00
JordanTheToaster
59cbdc79f5 GameDB: Fixes for V-Rally 3 and Berserk
Fixes sun occlusion in V-Rally 3 and fixes missing subtitles in FMVs in Berserk.
2023-02-12 19:28:13 +00:00
refractionpcsx2
50ff3649b1 GS: Fix divide by zero error 2023-02-12 19:14:54 +00:00
refractionpcsx2
9ca9db8770 GS: Fix undefined behaviour bug in PCRTC 2023-02-12 15:03:24 +00:00
Stenzek
fa70f0e764 GS/HW: Don't age texture cache on idle frames 2023-02-12 08:34:39 +00:00
Stenzek
3eb629f133 InputManager: Restore passing wheel events to ImGui 2023-02-12 07:25:56 +00:00
Stenzek
c9aba6bbe1 GS/TextureCache: Allow tex-in-rt for 16/24/32-bit targets
Fixes swirl battle transition in Valkyrie Profile 2.
Fixes top-left screen rendering in Lego Racers 2.
2023-02-12 07:07:52 +00:00
Stenzek
0a26adae76 GS/TextureCache: Dirty with target PSM/TBW, not the EE write 2023-02-12 07:07:52 +00:00
Stenzek
f0798f6510 GS/HW: Combine dirty rectangles for target updates
Fewer texture uploads makes Intel GPUs happy.
2023-02-12 07:07:52 +00:00
refractionpcsx2
245b03e208 GS: Limit the height of framebuffer reads 2023-02-12 07:07:26 +00:00
refractionpcsx2
4e31e5fdc2 GS: Use linear interpolation for Screen Offsets 2023-02-12 04:34:07 +00:00
Stenzek
750a74206c InputManager: Warning fix/default interia value 2023-02-12 04:32:47 +00:00
Stenzek
7e64dc2576 GS/HW: Don't defer TC reset until next vsync 2023-02-12 04:32:47 +00:00
Stenzek
8a08e2fd97 GS: Make sure everything in GSState is initialized 2023-02-12 04:32:47 +00:00
Stenzek
d0a933cda8 GS/TextureCache: Clear surface offset cache on reset
Also get rid of RemovePartial(), it's never called.
2023-02-12 04:32:47 +00:00
lightningterror
d00845f56b GameDB: Add missing Need for Speed - Carbon entry. 2023-02-12 00:46:01 +00:00
lightningterror
3350e5ebb1 GameDB: Replace DMABusyHack with InstantDMAHack for MGS2 Sons of Liberty.
DMA timing problem.
Fixes broken half-bottom artifacts.
2023-02-12 00:46:01 +00:00
SideProjectsLab
aeb4445cad Qt/Input: Improved how mouse movements are mapped to analog (#7910) 2023-02-11 23:58:58 +00:00
refractionpcsx2
73abae8cb9 GameDB: Remove forced deinterlacing modes which are no longer required 2023-02-11 20:08:36 +00:00
refractionpcsx2
7ecc7b76ba GS-PCRTC: Improve automatic de-interlacing to avoid it more often. 2023-02-11 20:08:36 +00:00
refractionpcsx2
71d0bbbc25 GS: Rework of PCRTC code. 2023-02-11 20:08:36 +00:00
JordanTheToaster
26e691ba93 GameDB: Update HPO on Spider Man 2
Changes HPO to HPO Special to fix rainbow garbage on the top and left side of the screen when moving.
2023-02-11 17:43:05 +00:00
Stenzek
c7352d9e10 GS: Attempt to recreate device if GPU crashes 2023-02-11 15:33:55 +00:00
Stenzek
7b8f9a54ec GS/HW: Purge FFX-2 depth clear CRC hack 2023-02-11 15:26:04 +00:00
JordanTheToaster
28980af858 GameDB: Port COP2 patch for Disneys Cars
Ports patch to fix broken collisions to PAL Disney's Cars
2023-02-11 15:24:23 +00:00
Stenzek
80dce398e0 GS/HW: Carefully allow move to create new targets
Xenosaga I does a move from BP 1C00 to E00, then from E00 to 2A00 a few
frames later for its cutscene transitions. 2A00 then gets used as a
texture and blended on top of the later frames. Because there's no
target at 2A00, the move falls back to the CPU, and E00 contains junk
which gets moved and eventually preloaded instead.

Gradius V uses moves for a screen move/wobble-like effect, by moving
chunks of the framebuffer out, then using those as a texture. It's not
broken at the moment, but it does readback (slow), and break upscaling.
2023-02-11 07:16:19 +00:00
TheTechnician27
06db8eec48 Context.cpp: fix minor typo 2023-02-11 06:46:44 +00:00
Stenzek
9c720efe46 GS/OGL: Fix possible crash downloading odd texture sizes 2023-02-11 06:43:20 +00:00
refractionpcsx2
cbf91a8d19 GS-HW: Tighten CLUT detection slightly. 2023-02-11 02:07:01 +00:00
TheTechnician27
f99414708d Readme: Two minor changes to the README (#8105) 2023-02-11 00:00:25 +00:00
refractionpcsx2
9549a6b16a GS: Fix TME processing when Alpha->IsBlack & !TEX0->TCC 2023-02-10 23:48:43 +00:00
lightningterror
3206094545 GameDB: Add full mipmap and trilinear ps2 to Hard Hitter games.
Improves ground texture rendering.
2023-02-10 22:24:33 +01:00
Stenzek
5cfae80701 GL/OpenGL: Add a hidden [EmuCore/GS] DisableGLDownloadPBO option
.. to disable the use of PBOs when reading back.
2023-02-10 14:38:21 +00:00
JordanTheToaster
b4d140c6bb GameDB: Fixes for 187 Ride or Die
Add autoflush to soften bloom and HPO Special Texture to fix misaligned bloom.
2023-02-10 14:15:51 +00:00
Stenzek
c65eb3c3ee GS/HW: Fix crash with AVX2 due to unaligned pitch 2023-02-10 14:15:33 +00:00
Mrlinkwii
eec0984dbe Gamedb: remove skipdraw from Need for Speed - Undercover 2023-02-10 14:47:52 +01:00
658 changed files with 46033 additions and 39914 deletions

View File

@@ -12,19 +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 a [proper PSX emulator](https://emulation.gametechwiki.com/index.php/PlayStation_emulators)
- 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 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
id: desc
attributes:
@@ -76,3 +79,12 @@ body:
placeholder: "Example: Arch"
validations:
required: false
- type: textarea
id: logsDumps
attributes:
label: "Logs & Dumps"
description: |
Please feel free to attach any logs here.
If PCSX2 crashed, please post crash logs and the .dmp file (in a zip file) if appropriate.
validations:
required: false

View File

@@ -12,19 +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 a [proper PSX emulator](https://emulation.gametechwiki.com/index.php/PlayStation_emulators)
- 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 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
id: desc
attributes:
@@ -52,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
@@ -117,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
@@ -136,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 (in a zip file) if appropriate.
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

4
.github/labeler.yml vendored
View File

@@ -39,8 +39,8 @@
'Debugger':
- 'pcsx2/DebugTools/*'
- 'pcsx2/DebugTools/**/*'
- 'pcsx2/gui/Debugger/*'
- 'pcsx2/gui/Debugger/**/*'
- 'pcsx2-qt/Debugger/*'
- 'pcsx2-qt/Debugger/**/*'
'IPC':
- 'pcsx2/IPC*'
- 'pcsx2/**/IPC*'

View File

@@ -19,7 +19,7 @@ jobs:
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
uses: peter-evans/create-pull-request@v5
with:
title: "PAD: Update to latest controller database"
commit-message: "PAD: Update to latest controller database."

View File

@@ -0,0 +1,90 @@
name: Flatpak Build Steps
on:
workflow_call:
inputs:
jobName:
required: true
type: string
os:
required: false
type: string
default: ubuntu-22.04
platform:
required: false
type: string
default: x64
compiler:
required: true
type: string
cmakeflags:
required: true
type: string
publish:
required: false
type: boolean
default: false
detail:
required: false
type: string
default: ""
patches_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
jobs:
build_linux:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v3
with:
submodules: recursive
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
env:
OS: linux
GUI_FRAMEWORK: QT
BUILD_SYSTEM: flatpak
ARCH: ${{ inputs.platform }}
EVENT_NAME: ${{ github.event_name }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUM: ${{ github.event.pull_request.number }}
PR_SHA: ${{ github.event.pull_request.head.sha }}
run: ./.github/workflows/scripts/common/name-artifacts.sh
- name: Install Packages
env:
COMPILER: ${{ inputs.compiler }}
run: .github/workflows/scripts/linux/install-packages-flatpak.sh
- name: Download patches
run: |
cd bin/resources
aria2c -Z "${{ inputs.patches_url }}/patches.zip"
- name: Generate AppStream XML
run: |
./.github/workflows/scripts/linux/generate-metainfo.sh .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
cat .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
appstream-util validate .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
- name: Build Flatpak
uses: flatpak/flatpak-github-actions/flatpak-builder@v6.1
with:
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
manifest-path: .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
arch: x86_64
build-bundle: true
verbose: true
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
# TODO: Push to flathub

View File

@@ -18,3 +18,11 @@ jobs:
cmakeflags: ""
buildAppImage: true
secrets: inherit
build_linux_flatpak:
name: "Flatpak"
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Qt"
compiler: clang
cmakeflags: ""
publish: false

View File

@@ -28,7 +28,7 @@ on:
required: false
type: string
default: ""
cheats_url:
patches_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
@@ -93,16 +93,19 @@ jobs:
if: steps.cache-deps.outputs.cache-hit != 'true'
run: .github/workflows/scripts/linux/build-dependencies-qt.sh
- name: Download cheats
- name: Download patches
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
aria2c -Z "${{ inputs.patches_url }}/patches.zip"
- name: Generate CMake
env:
COMPILER: ${{ inputs.compiler }}
ADDITIONAL_CMAKE_ARGS: ${{ inputs.cmakeflags }}
run: .github/workflows/scripts/linux/generate-cmake-qt.sh
CLANG_PATH: /usr/bin/clang-12
CLANGXX_PATH: /usr/bin/clang++-12
run: |
DEPS_PREFIX="$HOME/deps" .github/workflows/scripts/linux/generate-cmake-qt.sh
- name: Build PCSX2
working-directory: build

View File

@@ -17,7 +17,7 @@ on:
gui:
required: true
type: string
cheats_url:
patches_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
@@ -82,10 +82,10 @@ jobs:
GUI: ${{ inputs.gui }}
run: .github/workflows/scripts/macos/build-dependencies.sh
- name: Download cheats
- name: Download patches
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
aria2c -Z "${{ inputs.patches_url }}/patches.zip"
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
- name: Prepare ccache timestamp
@@ -144,12 +144,12 @@ jobs:
APPNAME="PCSX2-$TAG"
fi
mv build/pcsx2*/PCSX2.app "$APPNAME.app"
tar cvzf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.gz" "$APPNAME.app"
tar --options xz:compression-level=9 -cvJf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" "$APPNAME.app"
mkdir ci-artifacts
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.gz" ci-artifacts/macOS-${{ inputs.gui }}.tar.gz
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS-${{ inputs.gui }}.tar.xz
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
path: "*.tar.gz"
path: "*.tar.xz"

View File

@@ -18,6 +18,16 @@ jobs:
cmakeflags: ""
buildAppImage: true
secrets: inherit
build_linux_flatpak:
if: github.repository == 'PCSX2/pcsx2'
name: "Linux"
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Flatpak"
compiler: clang
cmakeflags: ""
publish: true
secrets: inherit
# Windows
build_windows_qt:
@@ -28,25 +38,7 @@ jobs:
jobName: Qt
configuration: CMake
buildSystem: cmake
secrets: inherit
build_qt_sse4:
if: github.repository == 'PCSX2/pcsx2'
name: "Windows - SSE4"
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
configuration: Release
simd: "SSE4"
secrets: inherit
build_qt_avx2:
if: github.repository == 'PCSX2/pcsx2'
name: "Windows - AVX2"
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
configuration: Release AVX2
cmakeFlags: -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
secrets: inherit
# MacOS
@@ -63,10 +55,9 @@ jobs:
upload_artifacts:
if: github.repository == 'PCSX2/pcsx2'
needs:
- build_linux_flatpak
- build_linux_qt
- build_windows_qt
- build_qt_sse4
- build_qt_avx2
- build_macos_qt
name: "Upload Artifacts"
runs-on: ubuntu-latest

View File

@@ -30,7 +30,7 @@ fi
# Add cmake if used to differentate it from msbuild builds
# Else the two artifacts will have the same name and the files will be merged
if [[ ! -z "${BUILD_SYSTEM}" ]]; then
if [ "${BUILD_SYSTEM}" == "cmake" ]; then
if [[ "${BUILD_SYSTEM}" == "cmake" ]] || [[ "${BUILD_SYSTEM}" == "flatpak" ]]; then
NAME="${NAME}-${BUILD_SYSTEM}"
fi
fi

View File

@@ -87,6 +87,7 @@ declare -a SYSLIBS=(
"libvorbis.so.0"
"libvorbisenc.so.2"
"libxcb.so.1"
"libxcb-cursor.so.0"
"libxcb-render.so.0"
"libxcb-shm.so.0"
"libxkbcommon.so.0"
@@ -157,6 +158,7 @@ declare -a SYSLIBS=(
"libhx509.so.5"
"libsqlite3.so.0"
"libcrypt.so.1"
"libdbus-1.so.3"
)
declare -a DEPLIBS=(
@@ -206,6 +208,9 @@ mkdir "$OUTDIR/usr"
echo "Copying binary and resources..."
cp -a "$BUILDDIR/bin" "$OUTDIR/usr"
# Get rid of unit tests, we don't want them bloating the squashfs.
rm -fv "$OUTDIR"/usr/bin/*_test
# Patch RPATH so the binary goes hunting for shared libraries in the AppDir instead of system.
echo "Patching RPATH in ${BINARY}..."
patchelf --set-rpath '$ORIGIN/../lib' "$OUTDIR/usr/bin/$BINARY"

View File

@@ -4,23 +4,26 @@ set -e
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.26.0
QT=6.3.1
SDL=SDL2-2.26.5
QT=6.5.0
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
mkdir -p deps-build
cd deps-build
cat > SHASUMS <<EOF
8000d7169febce93c84b6bdf376631f8179132fd69f7015d4dadb8b9c2bdb295 $SDL.tar.gz
0a64421d9c2469c2c48490a032ab91d547017c9cc171f3f8070bc31888f24e03 qtbase-everywhere-src-$QT.tar.xz
7b19f418e6f7b8e23344082dd04440aacf5da23c5a73980ba22ae4eba4f87df7 qtsvg-everywhere-src-$QT.tar.xz
c412750f2aa3beb93fce5f30517c607f55daaeb7d0407af206a8adf917e126c1 qttools-everywhere-src-$QT.tar.xz
d7bdd55e2908ded901dcc262157100af2a490bf04d31e32995f6d91d78dfdb97 qttranslations-everywhere-src-$QT.tar.xz
6f14fea2d172a5b4170be3efcb0e58535f6605b61bcd823f6d5c9d165bb8c0f0 qtwayland-everywhere-src-$QT.tar.xz
ad8fea3da1be64c83c45b1d363a6b4ba8fd60f5bde3b23ec73855709ec5eabf7 $SDL.tar.gz
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
fde1aa7b4fbe64ec1b4fc576a57f4688ad1453d2fab59cbadd948a10a6eaf5ef qtbase-everywhere-src-$QT.tar.xz
64ca7e61f44d51e28bcbb4e0509299b53a9a7e38879e00a7fe91643196067a4f qtsvg-everywhere-src-$QT.tar.xz
49c33d96b0a44988be954269b8ce3d1a495b439726e03a6be7c0d50a686369c4 qttools-everywhere-src-$QT.tar.xz
fc85d0fd8393f518653ccada1014177a56df6e73f30f3b64eea0c2e4a0067a3d qttranslations-everywhere-src-$QT.tar.xz
ccc57fa277fc5f1c1c2c4733eae80a60996b67a067233c47809e542aa31759a3 qtwayland-everywhere-src-$QT.tar.xz
EOF
curl -L \
-O "https://libsdl.org/release/$SDL.tar.gz" \
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
@@ -37,6 +40,14 @@ make "-j$NPROCS"
make install
cd ..
echo "Building libbacktrace..."
unzip "$LIBBACKTRACE.zip"
cd "libbacktrace-$LIBBACKTRACE"
./configure --prefix="$HOME/deps"
make
make install
cd ..
# Couple notes:
# -fontconfig is needed otherwise Qt Widgets render only boxes.
# -qt-doubleconversion avoids a dependency on libdouble-conversion.
@@ -65,19 +76,6 @@ cd ../../
echo "Building Qt Wayland..."
tar xf "qtwayland-everywhere-src-$QT.tar.xz"
cd "qtwayland-everywhere-src-$QT"
# qtwayland does not build without qml/qtdeclarative in 6.3.1. Work around it.
patch -u src/compositor/CMakeLists.txt <<EOF
--- src/compositor/CMakeLists.txt 2022-06-08 13:44:30.000000000 +1000
+++ src/compositor/CMakeLists.txt 2022-07-17 20:05:25.461881785 +1000
@@ -46,7 +46,6 @@
global/qtwaylandcompositorglobal.h
global/qtwaylandqmlinclude.h
global/qwaylandcompositorextension.cpp global/qwaylandcompositorextension.h global/qwaylandcompositorextension_p.h
- global/qwaylandquickextension.cpp global/qwaylandquickextension.h
global/qwaylandutils_p.h
hardware_integration/qwlclientbufferintegration.cpp hardware_integration/qwlclientbufferintegration_p.h
wayland_wrapper/qwlbuffermanager.cpp wayland_wrapper/qwlbuffermanager_p.h
EOF
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
@@ -103,6 +101,30 @@ patch -u src/linguist/CMakeLists.txt <<EOF
add_subdirectory(linguist)
endif()
EOF
# Also force disable clang scanning, it gets very confused.
patch -u configure.cmake <<EOF
--- configure.cmake
+++ configure.cmake
@@ -14,12 +14,12 @@
# Presumably because 6.0 ClangConfig.cmake files are not good enough?
# In any case explicitly request a minimum version of 8.x for now, otherwise
# building with CMake will fail at compilation time.
-qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
+#qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
# special case end
-if(TARGET WrapLibClang::WrapLibClang)
- set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
-endif()
+#if(TARGET WrapLibClang::WrapLibClang)
+# set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
+#endif()
EOF
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF ..

View File

@@ -0,0 +1,24 @@
{
"name": "libpcap",
"buildsystem": "cmake-ninja",
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://github.com/the-tcpdump-group/libpcap.git",
"tag": "libpcap-1.10.4",
"commit": "104271ba4a14de6743e43bcf87536786d8fddea4"
}
],
"cleanup": [
"/bin",
"/include",
"/lib/*.a",
"/lib/*.la",
"/lib/pkgconfig",
"/share/man"
]
}

View File

@@ -0,0 +1,24 @@
{
"name": "libaio",
"no-autogen": true,
"make-install-args": [
"prefix=/app"
],
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://pagure.io/libaio.git",
"tag": "libaio-0.3.113",
"commit": "1b18bfafc6a2f7b9fa2c6be77a95afed8b7be448"
}
],
"cleanup": [
"/include",
"/lib/*.a",
"/lib/*.la"
]
}

View File

@@ -0,0 +1,25 @@
{
"name": "soundtouch",
"buildsystem": "cmake-ninja",
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://codeberg.org/soundtouch/soundtouch.git",
"tag": "2.3.2",
"commit": "29fba832a7920a04eab956b3990c50e13d8c93f9"
}
],
"cleanup": [
"/bin",
"/include",
"/lib/*.a",
"/lib/*.la",
"/lib/cmake",
"/lib/pkgconfig",
"/share/doc"
]
}

View File

@@ -0,0 +1,45 @@
{
"name": "sdl2",
"buildsystem": "autotools",
"no-autogen": true,
"config-opts": [
"--disable-dbus",
"--without-x",
"--disable-video-opengl",
"--disable-video-opengles",
"--disable-video-vulkan",
"--disable-wayland-shared",
"--disable-ime",
"--disable-oss",
"--disable-alsa",
"--disable-jack",
"--disable-esd",
"--disable-pipewire",
"--disable-pulseaudio",
"--disable-arts",
"--disable-nas",
"--disable-sndio",
"--disable-fusionsound",
"--disable-diskaudio"
],
"build-options": {
"strip": true
},
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL2-2.26.5.tar.gz",
"sha256": "ad8fea3da1be64c83c45b1d363a6b4ba8fd60f5bde3b23ec73855709ec5eabf7"
}
],
"cleanup": [
"/bin",
"/include",
"/lib/*.a",
"/lib/*.la",
"/lib/cmake",
"/lib/pkgconfig",
"/share/aclocal"
]
}

View File

@@ -0,0 +1,22 @@
{
"name": "libbacktrace",
"buildsystem": "autotools",
"no-autogen": true,
"build-options": {
"strip": false,
"no-debuginfo": true
},
"sources": [
{
"type": "git",
"url": "https://github.com/ianlancetaylor/libbacktrace.git",
"commit": "ad106d5fdd5d960bd33fae1c48a351af567fd075"
}
],
"cleanup": [
"/include",
"/lib/*.a",
"/lib/*.la"
]
}

View File

@@ -0,0 +1,67 @@
{
"app-id": "net.pcsx2.PCSX2",
"runtime": "org.kde.Platform",
"runtime-version": "6.5",
"sdk": "org.kde.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.llvm16"
],
"add-build-extensions": {
"org.freedesktop.Platform.ffmpeg-full": {
"directory": "lib/ffmpeg",
"version": "22.08",
"add-ld-path": "."
}
},
"command": "pcsx2-qt",
"finish-args": [
"--device=all",
"--share=network",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--socket=pulseaudio",
"--filesystem=host:ro"
],
"modules": [
"modules/10-libpcap.json",
"modules/11-libaio.json",
"modules/12-soundtouch.json",
"modules/20-sdl2.json",
"modules/21-libbacktrace.json",
{
"name": "pcsx2",
"buildsystem": "simple",
"build-options": {
"strip": false,
"no-debuginfo": true,
"env": {
"DEPS_PREFIX": "/app",
"COMPILER": "clang",
"CLANG_PATH": "/usr/lib/sdk/llvm16/bin/clang",
"CLANGXX_PATH": "/usr/lib/sdk/llvm16/bin/clang++",
"ADDITIONAL_CMAKE_ARGS": "-DUSE_LINKED_FFMPEG=ON"
}
},
"sources": [
{
"type": "dir",
"path": "../../../../.."
}
],
"build-commands": [
".github/workflows/scripts/linux/generate-cmake-qt.sh",
"cd build && ../.github/workflows/scripts/linux/compile.sh && cd ..",
"cp -a build/bin ${FLATPAK_DEST}",
"cd build && ninja unittests && cd .."
],
"post-install": [
"install -Dm644 bin/resources/icons/AppIconLarge.png ${FLATPAK_DEST}/share/icons/hicolor/256x256/apps/net.pcsx2.PCSX2.png",
"install -Dm644 .github/workflows/scripts/linux/pcsx2-qt.desktop ${FLATPAK_DEST}/share/applications/net.pcsx2.PCSX2.desktop",
"desktop-file-edit --set-key=Icon --set-value=net.pcsx2.PCSX2 ${FLATPAK_DEST}/share/applications/net.pcsx2.PCSX2.desktop",
"install -Dm644 .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml ${FLATPAK_DEST}/share/metainfo/net.pcsx2.PCSX2.metainfo.xml"
]
}
]
}

View File

@@ -2,16 +2,28 @@
set -e
if [[ -z "${DEPS_PREFIX}" ]]; then
echo "DEPS_PREFIX is not set."
exit 1
fi
echo "Using build dependencies from: ${DEPS_PREFIX}"
if [ "${COMPILER}" = "clang" ]; then
if [[ -z "${CLANG_PATH}" ]] || [[ -z "${CLANGXX_PATH}" ]]; then
echo "CLANG_PATH or CLANGXX_PATH is not set."
exit 1
fi
echo "Using clang toolchain"
cat > "$HOME/clang-toolchain.cmake" << EOF
set(CMAKE_C_COMPILER /usr/bin/clang-12)
set(CMAKE_CXX_COMPILER /usr/bin/clang++-12)
cat > "clang-toolchain.cmake" << EOF
set(CMAKE_C_COMPILER "${CLANG_PATH}")
set(CMAKE_CXX_COMPILER "${CLANGXX_PATH}")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
EOF
ADDITIONAL_CMAKE_ARGS="$ADDITIONAL_CMAKE_ARGS -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_TOOLCHAIN_FILE=$HOME/clang-toolchain.cmake"
ADDITIONAL_CMAKE_ARGS="$ADDITIONAL_CMAKE_ARGS -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_TOOLCHAIN_FILE=clang-toolchain.cmake"
fi
echo "Additional CMake Args - ${ADDITIONAL_CMAKE_ARGS}"
@@ -31,7 +43,7 @@ cmake \
-DX11_API=ON \
-DWAYLAND_API=ON \
-DENABLE_SETCAP=OFF \
-DCMAKE_PREFIX_PATH="$HOME/deps" \
-DCMAKE_PREFIX_PATH="${DEPS_PREFIX}" \
-DUSE_SYSTEM_SDL2=ON \
-DUSE_SYSTEM_ZSTD=OFF \
-DDISABLE_ADVANCE_SIMD=TRUE

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
if [[ $# -lt 1 ]]; then
echo "Output file must be provided as a parameter"
exit 1
fi
OUTFILE=$1
GIT_DATE=$(git log -1 --pretty=%cd --date=short)
GIT_VERSION=$(git tag --points-at HEAD)
if [[ "${GIT_VERSION}" == "" ]]; then
GIT_VERSION=$(git rev-parse HEAD)
fi
echo "GIT_DATE: ${GIT_DATE}"
echo "GIT_VERSION: ${GIT_VERSION}"
cp "${SCRIPTDIR}"/pcsx2-qt.metainfo.xml.in "${OUTFILE}"
sed -i -e "s/@GIT_VERSION@/${GIT_VERSION}/" "${OUTFILE}"
sed -i -e "s/@GIT_DATE@/${GIT_DATE}/" "${OUTFILE}"

View File

@@ -0,0 +1,38 @@
#!/bin/bash
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
source "$SCRIPTDIR/functions.sh"
set -e
ARCH=x86_64
KDE_BRANCH=6.5
BRANCH=22.08
# Build packages.
declare -a BUILD_PACKAGES=(
"flatpak"
"flatpak-builder"
"appstream-util"
)
# Flatpak runtimes and SDKs.
declare -a FLATPAK_PACKAGES=(
"org.kde.Platform/${ARCH}/${KDE_BRANCH}"
"org.kde.Sdk/${ARCH}/${KDE_BRANCH}"
"org.freedesktop.Platform.ffmpeg-full/${ARCH}/${BRANCH}"
"org.freedesktop.Sdk.Extension.llvm16/${ARCH}/${BRANCH}"
)
retry_command sudo apt-get -qq update
# Install packages needed for building
echo "Will install the following packages for building - ${BUILD_PACKAGES[*]}"
retry_command sudo apt-get -y install "${BUILD_PACKAGES[@]}"
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# Install packages needed for building
echo "Will install the following packages for building - ${FLATPAK_PACKAGES[*]}"
retry_command sudo flatpak -y install "${FLATPAK_PACKAGES[@]}"

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>net.pcsx2.PCSX2</id>
<launchable type="desktop-id">net.pcsx2.PCSX2.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<name>PCSX2</name>
<developer_name>PCSX2</developer_name>
<summary>PlayStation 2 Emulator</summary>
<description>
<p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p>
<p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p>
</description>
<url type="homepage">https://pcsx2.net/</url>
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
<content_rating type="oars-1.1"/>
<update_contact>pcsx2_AT_pcsx2.net</update_contact>
<releases>
<release version="@GIT_VERSION@" date="@GIT_DATE@" />
</releases>
</component>

View File

@@ -6,11 +6,11 @@ export MACOSX_DEPLOYMENT_TARGET=10.14
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.26.0
SDL=SDL2-2.26.5
PNG=1.6.37
JPG=9e
SOUNDTOUCH=soundtouch-2.3.1
QT=6.3.1
QT=6.4.3
mkdir deps-build
cd deps-build
@@ -21,14 +21,14 @@ export CFLAGS="-I$INSTALLDIR/include -Os $CFLAGS"
export CXXFLAGS="-I$INSTALLDIR/include -Os $CXXFLAGS"
cat > SHASUMS <<EOF
8000d7169febce93c84b6bdf376631f8179132fd69f7015d4dadb8b9c2bdb295 $SDL.tar.gz
ad8fea3da1be64c83c45b1d363a6b4ba8fd60f5bde3b23ec73855709ec5eabf7 $SDL.tar.gz
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-$PNG.tar.xz
4077d6a6a75aeb01884f708919d25934c93305e49f7e3f36db9129320e6f4f3d jpegsrc.v$JPG.tar.gz
6900996607258496ce126924a19fe9d598af9d892cf3f33d1e4daaa9b42ae0b1 $SOUNDTOUCH.tar.gz
0a64421d9c2469c2c48490a032ab91d547017c9cc171f3f8070bc31888f24e03 qtbase-everywhere-src-$QT.tar.xz
7b19f418e6f7b8e23344082dd04440aacf5da23c5a73980ba22ae4eba4f87df7 qtsvg-everywhere-src-$QT.tar.xz
c412750f2aa3beb93fce5f30517c607f55daaeb7d0407af206a8adf917e126c1 qttools-everywhere-src-$QT.tar.xz
d7bdd55e2908ded901dcc262157100af2a490bf04d31e32995f6d91d78dfdb97 qttranslations-everywhere-src-$QT.tar.xz
5087c9e5b0165e7bc3c1a4ab176b35d0cd8f52636aea903fa377bdba00891a60 qtbase-everywhere-src-$QT.tar.xz
88315f886cf81898705e487cedba6e6160724359d23c518c92c333c098879a4a qtsvg-everywhere-src-$QT.tar.xz
867df829cd5cd3ae8efe62e825503123542764b13c96953511e567df70c5a091 qttools-everywhere-src-$QT.tar.xz
79e56b7800d49649a8a8010818538c367a829e0b7a09d5f60bd3aecf5abe972c qttranslations-everywhere-src-$QT.tar.xz
EOF
curl -L \

View File

@@ -4,7 +4,7 @@ import shutil
tag = os.environ['TAG'].split("refs/tags/")[1]
scan_dir = os.environ['SCAN_DIR']
output_dir = os.environ['OUT_DIR']
accepted_exts = ["AppImage", "tar.gz", "7z"]
accepted_exts = ["AppImage", "flatpak", "tar.xz", "7z"]
for dir_name in os.listdir(scan_dir):
@@ -12,7 +12,10 @@ for dir_name in os.listdir(scan_dir):
if "macos" in dir_name.lower():
asset_name += "-macos"
elif "linux" in dir_name.lower():
asset_name += "-linux-AppImage-64bit"
if "flatpak" in dir_name.lower():
asset_name += "-linux-Flatpak-64bit"
else:
asset_name += "-linux-AppImage-64bit"
elif "windows" in dir_name.lower():
asset_name += "-windows-64bit"
else:

View File

@@ -38,8 +38,8 @@ jobs:
configuration: Release AVX2
secrets: inherit
build_qt_sse4_cmake:
name: "CMake SSE4"
build_qt_cmake:
name: "CMake"
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
@@ -65,3 +65,13 @@ jobs:
jobName: Qt Clang
configuration: Release Clang AVX2
secrets: inherit
build_qt_cmake_clang:
name: "CMake"
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt Clang
configuration: CMake
buildSystem: cmake
cmakeFlags: -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DPCSX2_EXE_NAME=pcsx2-qt-clang
secrets: inherit

View File

@@ -25,15 +25,19 @@ on:
required: false
type: string
default: msbuild
cmakeFlags:
required: false
type: string
default: ""
qt_binary_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2-windows-dependencies/releases/download/2022-11-20/qt-6.4.0-x64.7z
default: https://github.com/PCSX2/pcsx2-windows-dependencies/releases/download/2023-04-25/qt-6.5.0-x64.7z
qt_dir:
required: false
type: string
default: 3rdparty\qt\6.4.0\msvc2022_64
cheats_url:
default: 3rdparty\qt\6.5.0\msvc2022_64
patches_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
@@ -80,11 +84,11 @@ jobs:
7z x qt-*-x64.7z
del qt-*-x64.7z
- name: Download cheats
- name: Download patches
shell: cmd
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
aria2c -Z "${{ inputs.patches_url }}/patches.zip"
- name: Generate CMake
if: inputs.configuration == 'CMake'
@@ -92,7 +96,7 @@ jobs:
shell: cmd
run: |
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake . -B build "-DCMAKE_PREFIX_PATH=%cd%\${{ inputs.qt_dir }}" -DQT_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DDISABLE_ADVANCE_SIMD=ON -G Ninja
cmake . -B build ${{ inputs.cmakeFlags }} "-DCMAKE_PREFIX_PATH=%cd%\${{ inputs.qt_dir }}" -DQT_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DDISABLE_ADVANCE_SIMD=ON -G Ninja
- name: Build PCSX2
shell: cmd

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>

10
3rdparty/rainterface/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,10 @@
add_library(rainterface
RA_Consoles.h
RA_Emulators.h
RA_Interface.cpp
RA_Interface.h
)
target_include_directories(rainterface PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(rainterface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")

View File

@@ -18,7 +18,7 @@ set(SDL_X11 OFF CACHE BOOL "")
set(SDL_WAYLAND OFF CACHE BOOL "")
set(SDL_RPI OFF CACHE BOOL "")
set(SDL_COCOA ON CACHE BOOL "")
set(SDL_DIRECTX OFF CACHE BOOL "")
set(SDL_DIRECTX ON CACHE BOOL "")
set(SDL_WASAPI OFF CACHE BOOL "")
set(SDL_RENDER_D3D OFF CACHE BOOL "")
set(SDL_RENDER_METAL OFF CACHE BOOL "")

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

View File

@@ -22,7 +22,7 @@ Installers and binaries for both stable and development builds are available fro
| Operating System | CPU | GPU | RAM |
| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| - Windows 10 21H2 (1809 or later) (64-bit) <br/> - Ubuntu 20.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports SSE4.1 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/singleThread.html) rating near or greater than 1800 <br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - Vulkan 1.1 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (Geforce GTX 750 Radeon RX 560 Intel Arc A380) <br/> - 2 GB Video Memory | 4 GB |
| - Windows 10 21H2 (1809 or later) (64-bit) <br/> - Ubuntu 20.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports SSE4.1 <br/> - [PassMark Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 1800<br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - Vulkan 1.1 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (Geforce GTX 750, Radeon RX 560, Intel Arc A380) <br/> - 2 GB Video Memory | 4 GB |
_Note: Recommended Single Thread Performance is based on moderately complex games. Games that pushed the PS2 hardware to its limits will struggle on CPUs at this level. Some release titles and 2D games which underutilized the PS2 hardware may run on CPUs rated as low as 1200. A quick reference for CPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:CPU_intensive_games), [Forum](https://forums.pcsx2.net/Thread-LIST-The-Most-CPU-Intensive-Games) and CPU **light** games: [Forum](https://forums.pcsx2.net/Thread-LIST-Games-that-don-t-need-a-strong-CPU-to-emulate)_
@@ -30,16 +30,16 @@ _Note: Recommended Single Thread Performance is based on moderately complex game
| Operating System | CPU | GPU | RAM |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| - Windows 10 21H2 (1809 or later) (64-bit) <br/> - Ubuntu 22.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports AVX2 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/singleThread.html) rating near or greater than 2600 <br/> - Four physical cores, with or without hyperthreading | - Direct3D12 support <br/> - OpenGL 4.6 support <br/> - Vulkan 1.3 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 6000 (GeForce GTX 1650 Radeon RX 570) <br/> - 4 GB Video Memory | 8 GB |
| - Windows 10 21H2 (1809 or later) (64-bit) <br/> - Ubuntu 22.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports AVX2 <br/> - [PassMark Single Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 2600<br/> - Four physical cores, with or without hyperthreading | - Direct3D12 support <br/> - OpenGL 4.6 support <br/> - Vulkan 1.3 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 6000 (GeForce GTX 1650, Radeon RX 570) <br/> - 4 GB Video Memory | 8 GB |
_Note: Recommended GPU is based on 3x Internal, ~1080p resolution requirements. Higher resolutions will require stronger cards; 6x Internal, ~4K resolution will require a [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 12000 (GeForce RTX 2060 Radeon RX 6600 Intel Arc A750). Just like CPU requirements, this is also highly game dependent. A quick reference for GPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:GPU_intensive_games)_
### Technical Notes
- You need the [Visual C++ 2019 x64 Redistributables](https://support.microsoft.com/en-us/help/2977003/) to run PCSX2.
- You need the [Visual C++ 2019 x64 Redistributables](https://support.microsoft.com/en-us/help/2977003/) to run PCSX2 on Windows.
- Windows XP and Direct3D9 support was dropped after stable release 1.4.0.
- Windows 7, Windows 8.0, and Windows 8.1 support was dropped after stable release 1.6.0.
- 32-bit and wxwidgets support was dropped after stable release 1.6.0, with the wxwidgets code being removed completely on 25th December 2022.
- 32-bit and wxWidgets support was dropped after stable release 1.6.0, with the wxWidgets code being removed completely on 25th December 2022.
- Make sure to update your operating system and drivers to ensure you have the best experience possible. Having a newer GPU is also recommended so you have the latest supported drivers.
- Because of copyright issues, and the complexity of trying to work around it, you need a BIOS dump extracted from a legitimately-owned PS2 console to use the emulator. For more information about the BIOS and how to get it from your console, visit [this page](pcsx2/Docs/PCSX2_FAQ.md#question-13-where-do-i-get-a-ps2-bios).
- PCSX2 uses two CPU cores for emulation by default. A third core can be used via the MTVU speed hack, which is compatible with most games. This can be a significant speedup on CPUs with 3+ cores, but it may be a slowdown on GS-limited games (or on CPUs with fewer than 2 cores). Software renderers will then additionally use however many rendering threads it is set to and will need higher core counts to run efficiently.

View File

@@ -1,189 +0,0 @@
.\" Copyright 2002-2017 PCSX2 Dev Team
.\"
.\" This is free documentation; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
.\" published by the Free Software Foundation; either version 3 of
.\" the License, or (at your option) any later version.
.\"
.\" The GNU General Public License's references to "object code"
.\" and "executables" are to be interpreted as the output of any
.\" document formatting or typesetting system, including
.\" intermediate and printed output.
.\"
.\" This manual 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 this manual; if not, see
.\" http://www.gnu.org/licenses.
.Dd January 10, 2017
.Dt PCSX2 1
.Os
.Sh NAME
.Nm PCSX2
.Nd PlayStation(R)2 Console Emulator
.Sh SYNOPSIS
.Nm
.Op Fl h
.Op Fl \-cfg Ns = Ns Ar file
.Op Fl \-cfgpath Ns = Ns Ar path
.Op Fl \-console
.Op Fl \-forcewiz
.Op Fl \-portable
.Op Fl \-profiling
.Op Fl \-elf Ns = Ns Ar file
.Op Fl \-irx Ns = Ns Ar file
.Op Fl \-nogui
.Op Fl \-noguiprompt
.Op Fl \-nodisc
.Op Fl \-usecd
.Op Fl \-fullscreen
.Op Fl \-windowed
.Op Fl \-nohacks
.Op Fl \-fullboot
.Op Fl \-gamefixes Ns = Ns Ar string
.Op Fl \-gs Ns = Ns Ar file
.Op Fl \-pad Ns = Ns Ar file
.Op Fl \-spu2 Ns = Ns Ar file
.Op Fl \-cdvd Ns = Ns Ar file
.Op Fl \-usb Ns = Ns Ar file
.Op Fl \-fw Ns = Ns Ar file
.Op Fl \-dev9 Ns = Ns Ar file
.Op Ar iso
.Sh DESCRIPTION
.Nm
is an open-source PlayStation 2 (AKA PS2) emulator.
Its purpose is to emulate the PS2 hardware, using a combination of MIPS CPU
interpreters, recompilers and a virtual machine that manages hardware states and
PS2 memory.
This allows you to play PS2 games on your PC, with many additional features and
benefits.
.Sh GENERAL OPTIONS
.Bl -tag -width Ds
.It Fl h , Fl \-help
Displays the list of available command line options.
.It Fl \-cfg Ns = Ns Ar file
Uses
.Ar file
instead of PCSX2_vm.ini as the configuration file.
It does not affect plugins.
.It Fl \-cfgpath Ns = Ns Ar path
Specifies
.Ar path
as the configuration file path.
It affects both
.Nm
and the plugins.
.It Fl \-console
Forces the program log to be visible.
.It Fl \-forcewiz
Forces the First-Time Wizard to run.
.It Fl \-portable
Runs
.Nm
in portable mode.
.It Fl \-profiling
Makes it easier to use profiling tools.
.El
.Sh AUTO-RUN OPTIONS
.Bl -tag -width Ds
.It Ar iso
Loads and runs
.Ar iso
at startup using the
.Nm
internal ISO loader.
.It Fl \-elf Ns = Ns Ar file
Executes
.Ar file
as an ELF image.
.It Fl \-irx Ns = Ns Ar file
Executes
.Ar file
as an IRX image.
.It Fl \-nogui
Disables display of the GUI while running games.
.Nm
will terminate when the game window is closed.
.It Fl \-noguiprompt
Prompt before exiting when
.Fl \-nogui
is used.
.It Fl \-nodisc
Boots with an empty DVD tray.
Use this to boot into the PS2 system menu.
.It Fl \-usecd
Boots using the configured CDVD plugin instead of booting
.Ar iso .
.It Fl \-fullscreen
Runs the game in fullscreen mode.
.It Fl \-windowed
Runs the game in windowed mode.
.El
.Sh COMPATIBILITY OPTIONS
.Bl -tag -width Ds
.It Fl \-nohacks
Disables all speedhacks.
.It Fl \-fullboot
Disables the fast boot feature.
.It Fl \-gamefixes= Ns Ar string
Enable specific gamefixes for this session.
.Ar string
is a comma-separated list of gamefixes.
.Pp
Valid gamefixes: VuAddSub, VuClipFlag, FpuCompare, FpuMul, FpuNegDiv, XGKick,
IpuWait, EETiming, SkipMpeg, OPHFlag, DMABusy,VIFFIFO, VIF1Stall, GIFFIFO,
FMVinSoftware, GoemonTlb, ScarfaceIbit.
.El
.Sh PLUGIN OVERRIDES
.Bl -tag -width Ds
.It Fl \-gs Ns = Ns Ar file
Uses
.Ar file
as the GS plugin.
.It Fl \-pad Ns = Ns Ar file
Uses
.Ar file
as the PAD plugin.
.It Fl \-spu2 Ns = Ns Ar file
Uses
.Ar file
as the SPU2 plugin.
.It Fl \-cdvd Ns = Ns Ar file
Uses
.Ar file
as the CDVD plugin.
.It Fl \-usb Ns = Ns Ar file
Uses
.Ar file
as the USB plugin.
.It Fl \-fw Ns = Ns Ar file
Uses
.Ar file
as the FW plugin.
.It Fl \-dev9 Ns = Ns Ar file
Uses
.Ar file
as the DEV9 plugin.
.El
.Sh FILES
.Bl -tag -width Ds
.It $XDG_CONFIG_DIR/PCSX2 or $HOME/PCSX2
User configuration and data directory.
.El
.Sh AUTHORS
.An PCSX2 Dev Team and many other contributors
.Sh BUGS
Bugs can be reported by submitting an issue at the
.Lk https://github.com/PCSX2/pcsx2/issues "PCSX2 GitHub issue tracker" .
.Sh PCSX2 RELATED WEBSITES
.Bl -bullet
.It
.Lk http://github.com/PCSX2/pcsx2 "PCSX2 git repository"
.It
.Lk http://pcsx2.net "PCSX2 website"
.It
.Lk http://forums.pcsx2.net "PCSX2 forums"
.El

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -66,12 +66,12 @@
03000000c82d00000021000000000000,8BitDo SN30 Pro,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:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000121000000000000,8BitDo SN30 Pro for Android,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00000260000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000261000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00001130000000000000,8BitDo Ultimate Wired,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:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00001230000000000000,8BitDo Ultimate Wireless,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00001330000000000000,8BitDo Ultimate Wireless,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:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00000121000000000000,8BitDo Xbox One SN30 Pro,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
@@ -105,6 +105,8 @@
03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000050b00000579000000000000,ASUS ROG Kunai 3,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000050b00000679000000000000,ASUS ROG Kunai 3,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:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,start:b3,platform:Windows,
03000000503200000210000000000000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
03000000e4150000103f000000000000,Batarang,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000d6200000e557000000000000,Batarang PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,
@@ -184,13 +186,14 @@
03000000ad1b000028f0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000ad1b00002ef0000000000000,Fightpad,a:b0,b:b1,back:b6,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:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000ad1b000038f0000000000000,Fightpad TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03005036852100000000000000000000,Final Fantasy XIV Online 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:Windows,
03000000f806000001a3000000000000,Firestorm,a:b9,b:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b10,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b12,x:b8,y:b4,platform:Windows,
03000000b50700000399000000000000,Firestorm 2,a:b2,b:b4,back:b10,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b9,start:b11,x:b3,y:b5,platform:Windows,
03000000b50700001302000000000000,Firestorm D3,a:b0,b:b2,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,x:b1,y:b3,platform:Windows,
03000000b40400001024000000000000,Flydigi Apex,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:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,platform:Windows,
03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,
03000000b40400001224000000000000,Flydigi Vader 2 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,paddle3:b17,paddle4:b18,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000151900004000000000000000,Flydigi Vader 2,a:b27,b:b26,back:b19,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b23,leftstick:b17,lefttrigger:b21,leftx:a0,lefty:a1,misc1:b15,paddle1:b11,paddle2:b10,paddle3:b13,paddle4:b12,rightshoulder:b22,rightstick:b16,righttrigger:b20,rightx:a3,righty:a4,start:b18,x:b25,y:b24,platform:Windows,
03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b14,paddle1:b4,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,
03000000b40400001224000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
0300000066f700000100000000000000,Game VIB Joystick,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:Windows,
03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
@@ -302,6 +305,7 @@
03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows,
03000000242e0000ff0b000000000000,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:Windows,
03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows,
03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -374,7 +378,7 @@
030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
030000008f0e00001330000000000000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,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:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
@@ -446,7 +450,7 @@
03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,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:b1,y:b0,platform:Windows,
030000006f0e00000901000000000000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00000901000000000000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows,
03000000666600006706000000000000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
@@ -530,9 +534,11 @@
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,
030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
@@ -543,8 +549,9 @@
030000009b2800001e00000000000000,Raphnet Vectrex Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a1,lefty:a2,x:b2,y:b3,platform:Windows,
030000009b2800002b00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
030000009b2800002c00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
030000009b2800008000000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,x:b0,y:b5,back:b2,guide:b10,start:b3,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpleft:b14,dpdown:b13,dpright:b15,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows,
030000009b2800008000000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000f8270000bf0b000000000000,Razer Kishi,a:b6,b:b7,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b18,leftshoulder:b12,leftstick:b19,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b13,rightstick:b20,righttrigger:b15,rightx:a2,righty:a5,start:b17,x:b9,y:b10,platform:Windows,
03000000321500000204000000000000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000104000000000000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000010000000000000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -657,6 +664,8 @@
03000000ba2200000701000000000000,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:a3,righty:a2,start:b9,x:b3,y:b2,platform:Windows,
03000000c61100001000000000000000,Tencent Xianyou Gamepad,a:b0,b:b1,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:a3,righty:a4,x:b3,y:b4,platform:Windows,
03000000790000002601000000000000,TGZ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
03000000591c00002400000000000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000591c00002600000000000000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,start:b7,x:b3,y:b0,platform:Windows,
030000004f04000015b3000000000000,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:Windows,
030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation 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:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -812,6 +821,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000050b00000579000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
03000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
03000000503200000110000047010000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:Mac OS X,
03000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,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:Mac OS X,
03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -824,8 +835,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000791d00000103000009010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
030000006e0500000720000010020000,Elecom JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Mac OS X,
030000006f0e00008401000003010000,Faceoff Premiere Wired Pro Controller for Nintendo Switch,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:b13,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Mac OS X,
03000000151900004000000001000000,Flydigi Vader 2,a:b14,b:b15,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Mac OS X,
03000000b40400001124000001040000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000b40400001224000003030000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
03000000ac0500001a06000002020000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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:Mac OS X,
03000000ad1b000001f9000000000000,Gamestop BB070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
@@ -850,13 +862,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00003801000008010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Mac OS X,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f0000aa00000072050000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
030000000d0f00000002000015010000,Hori Switch Split Pad Pro,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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006e00000000010000,Horipad 4 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:Mac OS X,
030000000d0f00006600000000010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000000000,Horipad FPS Plus 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:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
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,
@@ -888,6 +901,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
03000000790000000018000000010000,Mayflash Wii U Pro Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
030000005e0400002800000002010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Mac OS X,
030000005e0400000300000006010000,Microsoft SideWinder,a:b0,b:b1,back:b9,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Mac OS X,
030000005e0400000700000006010000,Microsoft SideWinder,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Mac OS X,
030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
03000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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:Mac OS X,
@@ -904,7 +919,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Mac OS X,
030000006f0e00000901000002010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000666600006706000088020000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Mac OS X,
030000004c050000da0c000000010000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -947,6 +962,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c0500006802000002100000,Rii RK707,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b3,righttrigger:b9,rightx:a2,righty:a3,start:b1,x:b15,y:b12,platform:Mac OS X,
03000000c6240000fefa000000000000,Rock Candy PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000006f0e00008701000005010000,Rock Candy Switch 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:Mac OS X,
03000000e804000000a000001b010000,Samsung EIGP20,a:b1,b:b3,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b11,leftx:a1,lefty:a3,rightshoulder:b12,rightx:a4,righty:a5,start:b16,x:b7,y:b9,platform:Mac OS X,
03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Mac OS X,
03000000a30c00002500000006020000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Mac OS X,
03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
@@ -969,6 +985,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f0000f600000000010000,Switch Hori Pad,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:Mac OS X,
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000001c18000003100000,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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000591c00002400000021000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000591c00002600000021000000,THEGamepad,a:b2,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Mac OS X,
030000004f04000015b3000000000000,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:Mac OS X,
030000004f0400000ed0000000020000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
@@ -992,6 +1010,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000130b000011050000,Xbox One 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:Mac OS X,
030000005e040000200b000011050000,Xbox One 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:Mac OS X,
030000005e040000200b000013050000,Xbox One 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:Mac OS X,
030000005e040000200b000015050000,Xbox One 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:Mac OS X,
030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
@@ -1067,6 +1086,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00001230000011010000,8BitDo Ultimate Wireless,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,
03000000c82d00001330000011010000,8BitDo Ultimate Wireless,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:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,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,
05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,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,
05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
@@ -1124,14 +1145,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,
030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03005036852100000201000010010000,Final Fantasy XIV Online 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,
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000b40400001224000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000007e0500003703000000000000,GameCube Adapter,a:b0,b:b1,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
19000000030000000300000002030000,GameForce Controller,a:b1,b:b0,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000558500001b06000010010000,GameSir G4 Pro,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,
05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,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,
03000000ac0500007a05000011010000,GameSir G5,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000bc2000005656000011010000,GameSir T4w,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,
03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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,
0500000047532047616d657061640000,GameStop Gamepad,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,
@@ -1176,6 +1200,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00006a00000011010000,Hori Real Arcade Pro 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006b00000011010000,Hori Real Arcade Pro 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:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00008501000015010000,Hori Switch Split Pad Pro,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,
030000000d0f00006e00000011010000,Horipad 4 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,
030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000ee00000011010000,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:Linux,
@@ -1185,9 +1210,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux,
03000000242e0000ff0b000011010000,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:Linux,
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,
@@ -1249,28 +1275,31 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,
03000000790000000018000011010000,Mayflash Wii U Pro Adapter,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,
03000000b50700001203000010010000,Mega World Logic 3 Controller,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,
03000000b50700004f00000000010000,Mega World Logic 3 Controller,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:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux,
03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux,
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
030000005e0400000700000000010000,Microsoft SideWinder Gamepad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
030000005e0400000300000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
030000005e0400000700000000010000,Microsoft SideWinder,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
030000005e0400000e00000000010000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux,
030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008902000021010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,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,
030000005e0400008e02000004010000,Microsoft Xbox 360,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,
030000005e0400008e02000056210000,Microsoft Xbox 360,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,
030000005e0400008e02000062230000,Microsoft Xbox 360,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,
030000005e040000120b00000b050000,Microsoft Xbox One,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,
030000005e040000d102000001010000,Microsoft Xbox One,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,
030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,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,
030000005e040000dd02000003020000,Microsoft Xbox One 2015,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,
030000005e040000dd02000003020000,Microsoft Xbox One,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,
030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,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,
030000005e040000e302000003020000,Microsoft Xbox One Elite,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,
030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000ea02000008040000,Microsoft Xbox One S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e040000120b00000b050000,Microsoft 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,
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
05000000e80400006e0400001b010000,Mocute 053X M59,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,
050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
@@ -1301,14 +1330,18 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000007e0500000920000000026803,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Linux,
030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux,
05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
030000007e0500001920000011810000,NSO N64 Controller,+rightx:b10,+righty:b8,-rightx:b9,-righty:b7,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b3,lefttrigger:b2,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b4,righttrigger:b5,start:b6,platform:Linux,
050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500001920000001800000,NSO N64 Controller,+rightx:b10,+righty:b8,-rightx:b9,-righty:b7,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b3,lefttrigger:b2,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b4,righttrigger:b5,start:b6,platform:Linux,
030000007e0500001720000011810000,NSO SNES Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b8,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500001720000001800000,NSO SNES Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
@@ -1330,9 +1363,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000c802000012010000,PDP Kingdom Hearts 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,
030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006f0e00002801000011010000,PDP PS3 Rock Candy 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,
030000006f0e00000901000011010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,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,
030000006f0e0000d802000006640000,PDP 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,
03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
@@ -1432,6 +1467,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,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,x:b0,y:b1,platform:Linux,
03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000a306000020f6000011010000,Saitek PS2700 Rumble,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:a4,start:b9,x:b0,y:b3,platform:Linux,
05000000e804000000a000001b010000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,
03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,
@@ -1477,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,
@@ -1502,6 +1540,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,
03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,
030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
06000000f51000000870000003010000,Turtle Beach Recon,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
@@ -1525,14 +1564,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
0000000058626f782047616d65706100,Xbox Gamepad,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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000005e040000120b000009050000,Xbox One 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,
030000005e040000d102000002010000,Xbox One 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,
030000005e040000ea02000000000000,Xbox One 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,
030000005e040000ea02000001030000,Xbox One 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,
050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,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,
050000005e040000fd02000030110000,Xbox One 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,
060000005e040000120b000007050000,Xbox One 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,
050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000220b000013050000,Xbox One Elite 2 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,
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
@@ -1540,16 +1577,21 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
060000005e040000ea0200000d050000,Xbox One S 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,
030000005e040000120b000001050000,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,
030000005e040000120b000005050000,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,
030000005e040000120b000007050000,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,
030000005e040000120b000009050000,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,
030000005e040000120b00000d050000,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,
030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,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,
030000005e040000130b000005050000,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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000001050000,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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000005050000,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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
050000005e040000130b000007050000,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,
050000005e040000130b000009050000,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,
050000005e040000130b000011050000,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,
050000005e040000130b000013050000,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,
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,
030000005e040000120b000007050000,Xbox Series X 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,
050000005e040000130b000007050000,Xbox Series X 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,
050000005e040000130b000011050000,Xbox Series X 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,
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,

View File

@@ -28,6 +28,7 @@
in vec2 PSin_t;
layout(location = 0) out vec4 SV_Target0;
layout(binding = 0) uniform sampler2D TextureSampler;
#elif (FXAA_GLSL_VK == 1)

View File

@@ -1,9 +1,5 @@
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
#ifndef PS_SCALE_FACTOR
#define PS_SCALE_FACTOR 1
#endif
struct VS_INPUT
{
float4 p : POSITION;
@@ -24,7 +20,6 @@ cbuffer cb0 : register(b0)
int EMODA;
int EMODC;
int DOFFSET;
int cb0_pad;
};
static const float3x3 rgb2yuv =
@@ -274,16 +269,25 @@ PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
uint2 subblock = pos & uint2(7u, 1u);
uint2 coord = block | subblock;
// Compensate for potentially differing page pitch.
uint SBW = uint(EMODA);
uint DBW = uint(EMODC);
uint2 block_xy = coord / uint2(64, 32);
uint block_num = (block_xy.y * (DBW / 128)) + block_xy.x;
uint2 block_offset = uint2((block_num % (SBW / 64)) * 64, (block_num / (SBW / 64)) * 32);
coord = (coord % uint2(64, 32)) + block_offset;
// Apply offset to cols 1 and 2
uint is_col23 = pos.y & 4u;
uint is_col13 = pos.y & 2u;
uint is_col12 = is_col23 ^ (is_col13 << 1);
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR)
coord = uint2(float2(coord) * PS_SCALE_FACTOR);
float ScaleFactor = BGColor.x;
if (floor(ScaleFactor) != ScaleFactor)
coord = uint2(float2(coord) * ScaleFactor);
else
coord *= PS_SCALE_FACTOR;
coord *= uint(ScaleFactor);
float4 pixel = Texture.Load(int3(int2(coord), 0));
float2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga;
@@ -295,7 +299,7 @@ PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
PS_OUTPUT ps_convert_clut_4(PS_INPUT input)
{
// Borrowing the YUV constant buffer.
float2 scale = BGColor.xy;
float scale = BGColor.x;
uint2 offset = uint2(uint(EMODA), uint(EMODC)) + uint(DOFFSET);
// CLUT4 is easy, just two rows of 8x8.
@@ -310,7 +314,7 @@ PS_OUTPUT ps_convert_clut_4(PS_INPUT input)
PS_OUTPUT ps_convert_clut_8(PS_INPUT input)
{
float2 scale = BGColor.xy;
float scale = BGColor.x;
uint2 offset = uint2(uint(EMODA), uint(EMODC));
uint index = min(uint(input.p.x) + uint(DOFFSET), 255u);

View File

@@ -0,0 +1,36 @@
cbuffer vertexBuffer : register(b0)
{
float4x4 ProjectionMatrix;
};
struct VS_INPUT
{
float2 pos : POSITION;
float4 col : COLOR0;
float2 uv : TEXCOORD0;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 col : COLOR0;
float2 uv : TEXCOORD0;
};
PS_INPUT vs_main(VS_INPUT input)
{
PS_INPUT output;
output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));
output.col = input.col;
output.uv = input.uv;
return output;
}
sampler sampler0 : register(s0);
Texture2D texture0 : register(t0);
float4 ps_main(PS_INPUT input) : SV_Target
{
float4 out_col = input.col * texture0.Sample(sampler0, input.uv);
return out_col;
}

View File

@@ -23,7 +23,7 @@ float4 ps_main0(PS_INPUT input) : SV_Target0
const int vpos = int(input.p.y); // vertical position of destination texture
if ((vpos & 1) == field)
return Texture.Sample(Sampler, input.t);
return Texture.SampleLevel(Sampler, input.t, 0);
else
discard;
@@ -34,7 +34,7 @@ float4 ps_main0(PS_INPUT input) : SV_Target0
// Bob shader
float4 ps_main1(PS_INPUT input) : SV_Target0
{
return Texture.Sample(Sampler, input.t);
return Texture.SampleLevel(Sampler, input.t, 0);
}
@@ -42,9 +42,9 @@ float4 ps_main1(PS_INPUT input) : SV_Target0
float4 ps_main2(PS_INPUT input) : SV_Target0
{
float2 vstep = float2(0.0f, ZrH.y);
float4 c0 = Texture.Sample(Sampler, input.t - vstep);
float4 c1 = Texture.Sample(Sampler, input.t);
float4 c2 = Texture.Sample(Sampler, input.t + vstep);
float4 c0 = Texture.SampleLevel(Sampler, input.t - vstep, 0);
float4 c1 = Texture.SampleLevel(Sampler, input.t, 0);
float4 c2 = Texture.SampleLevel(Sampler, input.t + vstep, 0);
return (c0 + c1 * 2 + c2) / 4;
}
@@ -66,15 +66,11 @@ float4 ps_main3(PS_INPUT input) : SV_Target0
const int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
const int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
const int vpos = int(input.p.y) + lofs; // vertical position of destination texture
const float2 bofs = float2(0.0f, 0.5f * bank); // vertical offset of the current bank relative to source texture size
const float2 vscale = float2(1.0f, 2.0f); // scaling factor from source to destination texture
const float2 optr = input.t - bofs; // used to check if the current destination line is within the current bank
const float2 iptr = optr * vscale; // pointer to the current pixel in the source texture
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
return Texture.Sample(Sampler, iptr);
if ((vpos & 1) == field)
return Texture.SampleLevel(Sampler, input.t, 0);
else
discard;
@@ -133,13 +129,13 @@ float4 ps_main4(PS_INPUT input) : SV_Target0
// calculating motion, only relevant for missing lines where the "center line" is pointed by p_t1
float4 hn = Texture.Sample(Sampler, p_t0 - lofs); // new high pixel
float4 cn = Texture.Sample(Sampler, p_t1); // new center pixel
float4 ln = Texture.Sample(Sampler, p_t0 + lofs); // new low pixel
float4 hn = Texture.SampleLevel(Sampler, p_t0 - lofs, 0); // new high pixel
float4 cn = Texture.SampleLevel(Sampler, p_t1, 0); // new center pixel
float4 ln = Texture.SampleLevel(Sampler, p_t0 + lofs, 0); // new low pixel
float4 ho = Texture.Sample(Sampler, p_t2 - lofs); // old high pixel
float4 co = Texture.Sample(Sampler, p_t3); // old center pixel
float4 lo = Texture.Sample(Sampler, p_t2 + lofs); // old low pixel
float4 ho = Texture.SampleLevel(Sampler, p_t2 - lofs, 0); // old high pixel
float4 co = Texture.SampleLevel(Sampler, p_t3, 0); // old center pixel
float4 lo = Texture.SampleLevel(Sampler, p_t2 + lofs, 0); // old low pixel
float3 mh = hn.rgb - ho.rgb; // high pixel motion
float3 mc = cn.rgb - co.rgb; // center pixel motion
@@ -164,7 +160,7 @@ float4 ps_main4(PS_INPUT input) : SV_Target0
if ((vpos & 1) == field)
{
// output coordinate present on current field
return Texture.Sample(Sampler, p_t0);
return Texture.SampleLevel(Sampler, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{

View File

@@ -29,7 +29,6 @@ cbuffer cb0 : register(b0)
float2 u_source_resolution;
float2 u_rcp_source_resolution; // 1 / u_source_resolution
float u_time;
float3 cb0_pad0;
};
Texture2D Texture;

View File

@@ -1,5 +1,3 @@
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
#define FMT_32 0
#define FMT_24 1
#define FMT_16 2
@@ -30,21 +28,23 @@
#define PS_ATST 1
#define PS_FOG 0
#define PS_IIP 0
#define PS_CLR_HW 0
#define PS_BLEND_HW 0
#define PS_A_MASKED 0
#define PS_FBA 0
#define PS_FBMASK 0
#define PS_LTF 1
#define PS_TCOFFSETHACK 0
#define PS_POINT_SAMPLER 0
#define PS_REGION_RECT 0
#define PS_SHUFFLE 0
#define PS_READ_BA 0
#define PS_READ16_SRC 0
#define PS_DFMT 0
#define PS_DEPTH_FMT 0
#define PS_PAL_FMT 0
#define PS_CHANNEL_FETCH 0
#define PS_TALES_OF_ABYSS_HLE 0
#define PS_URBAN_CHAOS_HLE 0
#define PS_SCALE_FACTOR 1.0
#define PS_HDR 0
#define PS_COLCLIP 0
#define PS_BLEND_A 0
@@ -52,6 +52,7 @@
#define PS_BLEND_C 0
#define PS_BLEND_D 0
#define PS_BLEND_MIX 0
#define PS_ROUND_INV 0
#define PS_FIXED_ONE_A 0
#define PS_PABE 0
#define PS_DITHER 0
@@ -69,6 +70,7 @@
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
struct VS_INPUT
{
@@ -109,6 +111,8 @@ struct PS_INPUT
#endif
};
#ifdef PIXEL_SHADER
struct PS_OUTPUT
{
#if !PS_NO_COLOR
@@ -132,21 +136,6 @@ Texture2D<float4> RtTexture : register(t2);
Texture2D<float> PrimMinTexture : register(t3);
SamplerState TextureSampler : register(s0);
#ifdef DX12
cbuffer cb0 : register(b0)
#else
cbuffer cb0
#endif
{
float2 VertexScale;
float2 VertexOffset;
float2 TextureScale;
float2 TextureOffset;
float2 PointSize;
uint MaxDepth;
uint pad_cb0;
};
#ifdef DX12
cbuffer cb1 : register(b1)
#else
@@ -167,12 +156,16 @@ cbuffer cb1
float2 TC_OffsetHack;
float2 STScale;
float4x4 DitherMatrix;
float ScaledScaleFactor;
float RcpScaleFactor;
};
float4 sample_c(float2 uv, float uv_w)
{
#if PS_TEX_IS_FB == 1
return RtTexture.Load(int3(int2(uv * WH.zw), 0));
#elif PS_REGION_RECT == 1
return Texture.Load(int3(int2(uv), 0));
#else
if (PS_POINT_SAMPLER)
{
@@ -236,7 +229,15 @@ float4 clamp_wrap_uv(float4 uv)
if(PS_WMS == PS_WMT)
{
if(PS_WMS == 2)
if(PS_REGION_RECT != 0 && PS_WMS == 0)
{
uv = frac(uv);
}
else if(PS_REGION_RECT != 0 && PS_WMS == 1)
{
uv = saturate(uv);
}
else if(PS_WMS == 2)
{
uv = clamp(uv, MinMax.xyxy, MinMax.zwzw);
}
@@ -252,7 +253,15 @@ float4 clamp_wrap_uv(float4 uv)
}
else
{
if(PS_WMS == 2)
if(PS_REGION_RECT != 0 && PS_WMS == 0)
{
uv.xz = frac(uv.xz);
}
else if(PS_REGION_RECT != 0 && PS_WMS == 1)
{
uv.xz = saturate(uv.xz);
}
else if(PS_WMS == 2)
{
uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz);
}
@@ -263,7 +272,15 @@ float4 clamp_wrap_uv(float4 uv)
#endif
uv.xz = (float2)(((uint2)(uv.xz * tex_size.xx) & asuint(MinMax.xx)) | asuint(MinMax.zz)) / tex_size.xx;
}
if(PS_WMT == 2)
if(PS_REGION_RECT != 0 && PS_WMT == 0)
{
uv.yw = frac(uv.yw);
}
else if(PS_REGION_RECT != 0 && PS_WMT == 1)
{
uv.yw = saturate(uv.yw);
}
else if(PS_WMT == 2)
{
uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww);
}
@@ -276,6 +293,12 @@ float4 clamp_wrap_uv(float4 uv)
}
}
if(PS_REGION_RECT != 0)
{
// Normalized -> Integer Coordinates.
uv = clamp(uv * WH.zwzw + STRange.xyxy, STRange.xyxy, STRange.zwzw);
}
return uv;
}
@@ -398,9 +421,13 @@ int2 clamp_wrap_uv_depth(int2 uv)
float4 sample_depth(float2 st, float2 pos)
{
float2 uv_f = (float2)clamp_wrap_uv_depth(int2(st)) * (float2)PS_SCALE_FACTOR * (float2)(1.0f / 16.0f);
int2 uv = (int2)uv_f;
float2 uv_f = (float2)clamp_wrap_uv_depth(int2(st)) * (float2)ScaledScaleFactor;
#if PS_REGION_RECT == 1
uv_f = clamp(uv_f + STRange.xy, STRange.xy, STRange.zw);
#endif
int2 uv = (int2)uv_f;
float4 t = (float4)(0.0f);
if (PS_TALES_OF_ABYSS_HLE == 1)
@@ -559,7 +586,7 @@ float4 sample_color(float2 st, float uv_w)
float4x4 c;
float2 dd;
if (PS_LTF == 0 && PS_AEM_FMT == FMT_32 && PS_PAL_FMT == 0 && PS_WMS < 2 && PS_WMT < 2)
if (PS_LTF == 0 && PS_AEM_FMT == FMT_32 && PS_PAL_FMT == 0 && PS_REGION_RECT == 0 && PS_WMS < 2 && PS_WMT < 2)
{
c[0] = sample_c(st, uv_w);
}
@@ -738,9 +765,13 @@ void ps_dither(inout float3 C, float2 pos_xy)
if (PS_DITHER == 2)
fpos = int2(pos_xy);
else
fpos = int2(pos_xy / (float)PS_SCALE_FACTOR);
fpos = int2(pos_xy * RcpScaleFactor);
C += DitherMatrix[fpos.x & 3][fpos.y & 3];
float value = DitherMatrix[fpos.x & 3][fpos.y & 3];
if (PS_ROUND_INV)
C -= value;
else
C += value;
}
}
@@ -750,6 +781,9 @@ void ps_color_clamp_wrap(inout float3 C)
// so we need to limit the color depth on dithered items
if (SW_BLEND || PS_DITHER || PS_FBMASK)
{
if (PS_DFMT == FMT_16 && PS_BLEND_MIX == 0 && PS_ROUND_INV)
C += 7.0f; // Need to round up, not down since the shader will invert
// Standard Clamp
if (PS_COLCLIP == 0 && PS_HDR == 0)
C = clamp(C, (float3)0.0f, (float3)255.0f);
@@ -762,8 +796,10 @@ void ps_color_clamp_wrap(inout float3 C)
}
}
void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy)
{
float As = As_rgba.a;
if (SW_BLEND)
{
// PABE
@@ -787,9 +823,9 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
float3 D = (PS_BLEND_D == 0) ? Cs : ((PS_BLEND_D == 1) ? Cd : (float3)0.0f);
// As/Af clamp alpha for Blend mix
// We shouldn't clamp blend mix with clr1 as we want alpha higher
// We shouldn't clamp blend mix with blend hw 1 as we want alpha higher
float C_clamped = C;
if (PS_BLEND_MIX > 0 && PS_CLR_HW != 1)
if (PS_BLEND_MIX > 0 && PS_BLEND_HW != 1)
C_clamped = min(C_clamped, 1.0f);
if (PS_BLEND_A == PS_BLEND_B)
@@ -808,21 +844,19 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
else
Color.rgb = trunc(((A - B) * C) + D);
if (PS_CLR_HW == 1)
if (PS_BLEND_HW == 1)
{
// Replace Af with As so we can do proper compensation for Alpha.
if (PS_BLEND_C == 2)
As = Af;
// As or Af
As_rgba.rgb = (float3)C;
// Subtract 1 for alpha to compensate for the changed equation,
// if c.rgb > 255.0f then we further need to adjust alpha accordingly,
// we pick the lowest overflow from all colors because it's the safest,
// we divide by 255 the color because we don't know Cd value,
// changed alpha should only be done for hw blend.
float min_color = min(min(Color.r, Color.g), Color.b);
float alpha_compensate = max(1.0f, min_color / 255.0f);
As -= alpha_compensate;
float3 alpha_compensate = max((float3)1.0f, Color.rgb / (float3)255.0f);
As_rgba.rgb -= alpha_compensate;
}
else if (PS_CLR_HW == 2)
else if (PS_BLEND_HW == 2)
{
// Compensate slightly for Cd*(As + 1) - Cs*As.
// The initial factor we chose is 1 (0.00392)
@@ -832,16 +866,26 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
float color_compensate = 1.0f * (C + 1.0f);
Color.rgb -= (float3)color_compensate;
}
else if (PS_BLEND_HW == 3)
{
// As, Ad or Af clamped.
As_rgba.rgb = (float3)C_clamped;
// Cs*(Alpha + 1) might overflow, if it does then adjust alpha value
// that is sent on second output to compensate.
float3 overflow_check = (Color.rgb - (float3)255.0f) / 255.0f;
float3 alpha_compensate = max((float3)0.0f, overflow_check);
As_rgba.rgb -= alpha_compensate;
}
}
else
{
if (PS_CLR_HW == 1 || PS_CLR_HW == 5)
if (PS_BLEND_HW == 1)
{
// Needed for Cd * (As/Ad/F + 1) blending modes
Color.rgb = (float3)255.0f;
}
else if (PS_CLR_HW == 2 || PS_CLR_HW == 4)
else if (PS_BLEND_HW == 2)
{
// Cd*As,Cd*Ad or Cd*F
@@ -850,12 +894,16 @@ void ps_blend(inout float4 Color, inout float As, float2 pos_xy)
Color.rgb = max((float3)0.0f, (Alpha - (float3)1.0f));
Color.rgb *= (float3)255.0f;
}
else if (PS_CLR_HW == 3)
else if (PS_BLEND_HW == 3)
{
// Needed for Cs*Ad, Cs*Ad + Cd, Cd - Cs*Ad
// Multiply Color.rgb by (255/128) to compensate for wrong Ad/255 value
Color.rgb *= (255.0f / 128.0f);
// Multiply Color.rgb by (255/128) to compensate for wrong Ad/255 value when rgb are below 128.
// When any color channel is higher than 128 then adjust the compensation automatically
// to give us more accurate colors, otherwise they will be wrong.
// The higher the value (>128) the lower the compensation will be.
float max_color = max(max(Color.r, Color.g), Color.b);
float color_compensate = 255.0f / max(128.0f, max_color);
Color.rgb *= (float3)color_compensate;
}
}
}
@@ -877,26 +925,37 @@ PS_OUTPUT ps_main(PS_INPUT input)
{
uint4 denorm_c = uint4(C);
uint2 denorm_TA = uint2(float2(TA.xy) * 255.0f + 0.5f);
// Mask will take care of the correct destination
if (PS_READ_BA)
C.rb = C.bb;
else
C.rb = C.rr;
if (PS_READ_BA)
if (PS_READ16_SRC)
{
C.rb = (float2)float((denorm_c.r >> 3) | (((denorm_c.g >> 3) & 0x7u) << 5));
if (denorm_c.a & 0x80u)
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
C.ga = (float2)float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.y & 0x80u));
else
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
C.ga = (float2)float((denorm_c.g >> 6) | ((denorm_c.b >> 3) << 2) | (denorm_TA.x & 0x80u));
}
else
{
if (denorm_c.g & 0x80u)
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
// Mask will take care of the correct destination
if (PS_READ_BA)
C.rb = C.bb;
else
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
C.rb = C.rr;
if (PS_READ_BA)
{
if (denorm_c.a & 0x80u)
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.a & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
else
{
if (denorm_c.g & 0x80u)
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.y & 0x80u)));
else
C.ga = (float2)(float((denorm_c.g & 0x7Fu) | (denorm_TA.x & 0x80u)));
}
}
}
@@ -908,15 +967,15 @@ PS_OUTPUT ps_main(PS_INPUT input)
C.a = 128.0f;
}
float alpha_blend;
if (PS_BLEND_C == 1 && PS_CLR_HW > 3)
float4 alpha_blend;
if (SW_AD_TO_HW)
{
float4 RT = trunc(RtTexture.Load(int3(input.p.xy, 0)) * 255.0f + 0.1f);
alpha_blend = RT.a / 128.0f;
alpha_blend = (float4)(RT.a / 128.0f);
}
else
{
alpha_blend = C.a / 128.0f;
alpha_blend = (float4)(C.a / 128.0f);
}
// Alpha correction
@@ -966,12 +1025,12 @@ PS_OUTPUT ps_main(PS_INPUT input)
#if !PS_NO_COLOR
output.c0 = PS_HDR ? float4(C.rgb / 65535.0f, C.a / 255.0f) : C / 255.0f;
#if !PS_NO_COLOR1
output.c1 = (float4)(alpha_blend);
output.c1 = alpha_blend;
#endif
#if PS_NO_ABLEND
// write alpha blend factor into col0
output.c0.a = alpha_blend;
output.c0.a = alpha_blend.a;
#endif
#if PS_ONLY_ALPHA
// rgb isn't used
@@ -988,10 +1047,29 @@ PS_OUTPUT ps_main(PS_INPUT input)
return output;
}
#endif // PIXEL_SHADER
//////////////////////////////////////////////////////////////////////
// Vertex Shader
//////////////////////////////////////////////////////////////////////
#ifdef VERTEX_SHADER
#ifdef DX12
cbuffer cb0 : register(b0)
#else
cbuffer cb0
#endif
{
float2 VertexScale;
float2 VertexOffset;
float2 TextureScale;
float2 TextureOffset;
float2 PointSize;
uint MaxDepth;
uint BaseVertex; // Only used in DX11.
};
VS_OUTPUT vs_main(VS_INPUT input)
{
// Clamp to max depth, gs doesn't wrap
@@ -1044,156 +1122,101 @@ VS_OUTPUT vs_main(VS_INPUT input)
return output;
}
//////////////////////////////////////////////////////////////////////
// Geometry Shader
//////////////////////////////////////////////////////////////////////
#if VS_EXPAND != 0
#if GS_FORWARD_PRIMID
#define PRIMID_IN , uint primid : SV_PrimitiveID
#define VS2PS(x) vs2ps_impl(x, primid)
PS_INPUT vs2ps_impl(VS_OUTPUT vs, uint primid)
struct VS_RAW_INPUT
{
PS_INPUT o;
o.p = vs.p;
o.t = vs.t;
o.ti = vs.ti;
o.c = vs.c;
o.primid = primid;
return o;
}
float2 ST;
uint RGBA;
float Q;
uint XY;
uint Z;
uint UV;
uint FOG;
};
StructuredBuffer<VS_RAW_INPUT> vertices : register(t0);
VS_INPUT load_vertex(uint index)
{
#ifdef DX12
VS_RAW_INPUT raw = vertices.Load(index);
#else
#define PRIMID_IN
#define VS2PS(x) vs2ps_impl(x)
PS_INPUT vs2ps_impl(VS_OUTPUT vs)
{
PS_INPUT o;
o.p = vs.p;
o.t = vs.t;
o.ti = vs.ti;
o.c = vs.c;
return o;
}
VS_RAW_INPUT raw = vertices.Load(BaseVertex + index);
#endif
#if GS_PRIM == 0
[maxvertexcount(6)]
void gs_main(point VS_OUTPUT input[1], inout TriangleStream<PS_INPUT> stream PRIMID_IN)
{
// Transform a point to a NxN sprite
PS_INPUT Point = VS2PS(input[0]);
// Get new position
float4 lt_p = input[0].p;
float4 rb_p = input[0].p + float4(PointSize.x, PointSize.y, 0.0f, 0.0f);
float4 lb_p = rb_p;
float4 rt_p = rb_p;
lb_p.x = lt_p.x;
rt_p.y = lt_p.y;
// Triangle 1
Point.p = lt_p;
stream.Append(Point);
Point.p = lb_p;
stream.Append(Point);
Point.p = rt_p;
stream.Append(Point);
// Triangle 2
Point.p = lb_p;
stream.Append(Point);
Point.p = rt_p;
stream.Append(Point);
Point.p = rb_p;
stream.Append(Point);
VS_INPUT vert;
vert.st = raw.ST;
vert.c = uint4(raw.RGBA & 0xFFu, (raw.RGBA >> 8) & 0xFFu, (raw.RGBA >> 16) & 0xFFu, raw.RGBA >> 24);
vert.q = raw.Q;
vert.p = uint2(raw.XY & 0xFFFFu, raw.XY >> 16);
vert.z = raw.Z;
vert.uv = uint2(raw.UV & 0xFFFFu, raw.UV >> 16);
vert.f = float4(float(raw.FOG & 0xFFu), float((raw.FOG >> 8) & 0xFFu), float((raw.FOG >> 16) & 0xFFu), float(raw.FOG >> 24)) / 255.0f;
return vert;
}
#elif GS_PRIM == 1
[maxvertexcount(6)]
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<PS_INPUT> stream PRIMID_IN)
VS_OUTPUT vs_main_expand(uint vid : SV_VertexID)
{
// Transform a line to a thick line-sprite
PS_INPUT left = VS2PS(input[0]);
PS_INPUT right = VS2PS(input[1]);
float2 lt_p = input[0].p.xy;
float2 rt_p = input[1].p.xy;
#if VS_EXPAND == 1 // Point
// Potentially there is faster math
float2 line_vector = normalize(rt_p.xy - lt_p.xy);
VS_OUTPUT vtx = vs_main(load_vertex(vid >> 2));
vtx.p.x += ((vid & 1u) != 0u) ? PointSize.x : 0.0f;
vtx.p.y += ((vid & 2u) != 0u) ? PointSize.y : 0.0f;
return vtx;
#elif VS_EXPAND == 2 // Line
uint vid_base = vid >> 2;
bool is_bottom = vid & 2;
bool is_right = vid & 1;
// All lines will be a pair of vertices next to each other
// Since DirectX uses provoking vertex first, the bottom point will be the lower of the two
uint vid_other = is_bottom ? vid_base + 1 : vid_base - 1;
VS_OUTPUT vtx = vs_main(load_vertex(vid_base));
VS_OUTPUT other = vs_main(load_vertex(vid_other));
float2 line_vector = normalize(vtx.p.xy - other.p.xy);
float2 line_normal = float2(line_vector.y, -line_vector.x);
float2 line_width = (line_normal * PointSize) / 2;
// line_normal is inverted for bottom point
float2 offset = (is_bottom ^ is_right) ? line_width : -line_width;
vtx.p.xy += offset;
lt_p -= line_width;
rt_p -= line_width;
float2 lb_p = input[0].p.xy + line_width;
float2 rb_p = input[1].p.xy + line_width;
// Lines will be run as (0 1 2) (1 2 3)
// This means that both triangles will have a point based off the top line point as their first point
// So we don't have to do anything for !IIP
#if GS_IIP == 0
left.c = right.c;
#endif
return vtx;
// Triangle 1
left.p.xy = lt_p;
stream.Append(left);
#elif VS_EXPAND == 3 // Sprite
left.p.xy = lb_p;
stream.Append(left);
// Sprite points are always in pairs
uint vid_base = vid >> 1;
uint vid_lt = vid_base & ~1u;
uint vid_rb = vid_base | 1u;
right.p.xy = rt_p;
stream.Append(right);
stream.RestartStrip();
VS_OUTPUT lt = vs_main(load_vertex(vid_lt));
VS_OUTPUT rb = vs_main(load_vertex(vid_rb));
VS_OUTPUT vtx = rb;
// Triangle 2
left.p.xy = lb_p;
stream.Append(left);
bool is_right = ((vid & 1u) != 0u);
vtx.p.x = is_right ? lt.p.x : vtx.p.x;
vtx.t.x = is_right ? lt.t.x : vtx.t.x;
vtx.ti.xz = is_right ? lt.ti.xz : vtx.ti.xz;
right.p.xy = rt_p;
stream.Append(right);
bool is_bottom = ((vid & 2u) != 0u);
vtx.p.y = is_bottom ? lt.p.y : vtx.p.y;
vtx.t.y = is_bottom ? lt.t.y : vtx.t.y;
vtx.ti.yw = is_bottom ? lt.ti.yw : vtx.ti.yw;
right.p.xy = rb_p;
stream.Append(right);
stream.RestartStrip();
}
#elif GS_PRIM == 3
[maxvertexcount(4)]
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<PS_INPUT> stream PRIMID_IN)
{
PS_INPUT lt = VS2PS(input[0]);
PS_INPUT rb = VS2PS(input[1]);
// flat depth
lt.p.z = rb.p.z;
// flat fog and texture perspective
lt.t.zw = rb.t.zw;
// flat color
lt.c = rb.c;
// Swap texture and position coordinate
PS_INPUT lb = rb;
lb.p.x = lt.p.x;
lb.t.x = lt.t.x;
lb.ti.x = lt.ti.x;
lb.ti.z = lt.ti.z;
PS_INPUT rt = rb;
rt.p.y = lt.p.y;
rt.t.y = lt.t.y;
rt.ti.y = lt.ti.y;
rt.ti.w = lt.ti.w;
stream.Append(lt);
stream.Append(lb);
stream.Append(rt);
stream.Append(rb);
}
return vtx;
#endif
#endif
}
#endif // VS_EXPAND
#endif // VERTEX_SHADER

View File

@@ -30,7 +30,7 @@ layout(binding=0, rgba8) uniform writeonly image2D imgDst;
AF3 CasLoad(ASU2 p)
{
return texelFetch(imgSrc, srcOffset + ivec2(p), 0).rgb;
return texelFetch(imgSrc, srcOffset + ivec2(p), 0).rgb;
}
// Lets you transform input from the load into a linear color space between 0 and 1. See ffx_cas.h
@@ -42,23 +42,23 @@ void CasInput(inout AF1 r, inout AF1 g, inout AF1 b) {}
layout(local_size_x=64) in;
void main()
{
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
AU2 gxy = ARmp8x8(gl_LocalInvocationID.x)+AU2(gl_WorkGroupID.x<<4u,gl_WorkGroupID.y<<4u);
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
AU2 gxy = ARmp8x8(gl_LocalInvocationID.x)+AU2(gl_WorkGroupID.x<<4u,gl_WorkGroupID.y<<4u);
// Filter.
AF4 c;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
gxy.x += 8u;
// Filter.
AF4 c;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
gxy.x += 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
gxy.y += 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
gxy.y += 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
gxy.x -= 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
gxy.x -= 8u;
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
CasFilter(c.r, c.g, c.b, gxy, const0, const1, CAS_SHARPEN_ONLY);
imageStore(imgDst, ASU2(gxy), c);
}

View File

@@ -1,101 +0,0 @@
//#version 420 // Keep it for editor detection
//////////////////////////////////////////////////////////////////////
// Common Interface Definition
//////////////////////////////////////////////////////////////////////
#ifdef VERTEX_SHADER
#if !pGL_ES
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
#if !pGL_ES
float gl_ClipDistance[1];
#endif
};
#endif
#endif
#ifdef GEOMETRY_SHADER
#if !pGL_ES
in gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
#if !pGL_ES
float gl_ClipDistance[1];
#endif
} gl_in[];
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
#if !pGL_ES
float gl_ClipDistance[1];
#endif
};
#endif
#endif
//////////////////////////////////////////////////////////////////////
// Constant Buffer Definition
//////////////////////////////////////////////////////////////////////
// Performance note, some drivers (nouveau) will validate all Constant Buffers
// even if only one was updated.
#if defined(VERTEX_SHADER) || defined(GEOMETRY_SHADER)
layout(std140, binding = 1) uniform cb20
{
vec2 VertexScale;
vec2 VertexOffset;
vec2 TextureScale;
vec2 TextureOffset;
vec2 PointSize;
uint MaxDepth;
uint pad_cb20;
};
#endif
#if defined(VERTEX_SHADER) || defined(FRAGMENT_SHADER)
layout(std140, binding = 0) uniform cb21
{
vec3 FogColor;
float AREF;
vec4 WH;
vec2 TA;
float MaxDepthPS;
float Af;
uvec4 FbMask;
vec4 HalfTexel;
vec4 MinMax;
vec4 STRange;
ivec4 ChannelShuffle;
vec2 TC_OffsetHack;
vec2 STScale;
mat4 DitherMatrix;
};
#endif
//////////////////////////////////////////////////////////////////////
// Default Sampler
//////////////////////////////////////////////////////////////////////
#ifdef FRAGMENT_SHADER
layout(binding = 0) uniform sampler2D TextureSampler;
#endif

View File

@@ -21,10 +21,10 @@ out vec4 PSin_c;
void vs_main()
{
PSin_p = vec4(POSITION, 0.5f, 1.0f);
PSin_t = TEXCOORD0;
PSin_c = COLOR;
gl_Position = vec4(POSITION, 0.5f, 1.0f); // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
PSin_p = vec4(POSITION, 0.5f, 1.0f);
PSin_t = TEXCOORD0;
PSin_c = COLOR;
gl_Position = vec4(POSITION, 0.5f, 1.0f); // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
}
#endif
@@ -35,6 +35,8 @@ in vec4 PSin_p;
in vec2 PSin_t;
in vec4 PSin_c;
layout(binding = 0) uniform sampler2D TextureSampler;
// Give a different name so I remember there is a special case!
#if defined(ps_convert_rgba8_16bits) || defined(ps_convert_float32_32bits)
layout(location = 0) out uint SV_Target1;
@@ -44,13 +46,13 @@ layout(location = 0) out vec4 SV_Target0;
vec4 sample_c()
{
return texture(TextureSampler, PSin_t);
return texture(TextureSampler, PSin_t);
}
#ifdef ps_copy
void ps_copy()
{
SV_Target0 = sample_c();
SV_Target0 = sample_c();
}
#endif
@@ -65,20 +67,20 @@ void ps_depth_copy()
// Need to be careful with precision here, it can break games like Spider-Man 3 and Dogs Life
void ps_convert_rgba8_16bits()
{
highp uvec4 i = uvec4(sample_c() * vec4(255.5f, 255.5f, 255.5f, 255.5f));
highp uvec4 i = uvec4(sample_c() * vec4(255.5f, 255.5f, 255.5f, 255.5f));
SV_Target1 = ((i.x & 0x00F8u) >> 3) | ((i.y & 0x00F8u) << 2) | ((i.z & 0x00f8u) << 7) | ((i.w & 0x80u) << 8);
SV_Target1 = ((i.x & 0x00F8u) >> 3) | ((i.y & 0x00F8u) << 2) | ((i.z & 0x00f8u) << 7) | ((i.w & 0x80u) << 8);
}
#endif
#ifdef ps_convert_float32_32bits
void ps_convert_float32_32bits()
{
// Convert a GL_FLOAT32 depth texture into a 32 bits UINT texture
// Convert a GL_FLOAT32 depth texture into a 32 bits UINT texture
#if HAS_CLIP_CONTROL
SV_Target1 = uint(exp2(32.0f) * sample_c().r);
SV_Target1 = uint(exp2(32.0f) * sample_c().r);
#else
SV_Target1 = uint(exp2(24.0f) * sample_c().r);
SV_Target1 = uint(exp2(24.0f) * sample_c().r);
#endif
}
#endif
@@ -86,195 +88,205 @@ void ps_convert_float32_32bits()
#ifdef ps_convert_float32_rgba8
void ps_convert_float32_rgba8()
{
// Convert a GL_FLOAT32 depth texture into a RGBA color texture
// Convert a GL_FLOAT32 depth texture into a RGBA color texture
#if HAS_CLIP_CONTROL
uint d = uint(sample_c().r * exp2(32.0f));
uint d = uint(sample_c().r * exp2(32.0f));
#else
uint d = uint(sample_c().r * exp2(24.0f));
uint d = uint(sample_c().r * exp2(24.0f));
#endif
SV_Target0 = vec4(uvec4((d & 0xFFu), ((d >> 8) & 0xFFu), ((d >> 16) & 0xFFu), (d >> 24))) / vec4(255.0);
SV_Target0 = vec4(uvec4((d & 0xFFu), ((d >> 8) & 0xFFu), ((d >> 16) & 0xFFu), (d >> 24))) / vec4(255.0);
}
#endif
#ifdef ps_convert_float16_rgb5a1
void ps_convert_float16_rgb5a1()
{
// Convert a GL_FLOAT32 (only 16 lsb) depth into a RGB5A1 color texture
// Convert a GL_FLOAT32 (only 16 lsb) depth into a RGB5A1 color texture
#if HAS_CLIP_CONTROL
uint d = uint(sample_c().r * exp2(32.0f));
uint d = uint(sample_c().r * exp2(32.0f));
#else
uint d = uint(sample_c().r * exp2(24.0f));
uint d = uint(sample_c().r * exp2(24.0f));
#endif
SV_Target0 = vec4(uvec4((d & 0x1Fu), ((d >> 5) & 0x1Fu), ((d >> 10) & 0x1Fu), (d >> 15) & 0x01u)) / vec4(32.0f, 32.0f, 32.0f, 1.0f);
SV_Target0 = vec4(uvec4((d & 0x1Fu), ((d >> 5) & 0x1Fu), ((d >> 10) & 0x1Fu), (d >> 15) & 0x01u)) / vec4(32.0f, 32.0f, 32.0f, 1.0f);
}
#endif
float rgba8_to_depth32(vec4 unorm)
{
uvec4 c = uvec4(unorm * vec4(255.5f));
uvec4 c = uvec4(unorm * vec4(255.5f));
#if HAS_CLIP_CONTROL
return float(c.r | (c.g << 8) | (c.b << 16) | (c.a << 24)) * exp2(-32.0f);
return float(c.r | (c.g << 8) | (c.b << 16) | (c.a << 24)) * exp2(-32.0f);
#else
return float(c.r | (c.g << 8) | (c.b << 16) | (c.a << 24)) * exp2(-24.0f);
return float(c.r | (c.g << 8) | (c.b << 16) | (c.a << 24)) * exp2(-24.0f);
#endif
}
float rgba8_to_depth24(vec4 unorm)
{
uvec3 c = uvec3(unorm.rgb * vec3(255.5f));
uvec3 c = uvec3(unorm.rgb * vec3(255.5f));
#if HAS_CLIP_CONTROL
return float(c.r | (c.g << 8) | (c.b << 16)) * exp2(-32.0f);
return float(c.r | (c.g << 8) | (c.b << 16)) * exp2(-32.0f);
#else
return float(c.r | (c.g << 8) | (c.b << 16)) * exp2(-24.0f);
return float(c.r | (c.g << 8) | (c.b << 16)) * exp2(-24.0f);
#endif
}
float rgba8_to_depth16(vec4 unorm)
{
uvec2 c = uvec2(unorm.rg * vec2(255.5f));
uvec2 c = uvec2(unorm.rg * vec2(255.5f));
#if HAS_CLIP_CONTROL
return float(c.r | (c.g << 8)) * exp2(-32.0f);
return float(c.r | (c.g << 8)) * exp2(-32.0f);
#else
return float(c.r | (c.g << 8)) * exp2(-24.0f);
return float(c.r | (c.g << 8)) * exp2(-24.0f);
#endif
}
float rgb5a1_to_depth16(vec4 unorm)
{
uvec4 c = uvec4(unorm * vec4(255.5f));
uvec4 c = uvec4(unorm * vec4(255.5f));
#if HAS_CLIP_CONTROL
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f);
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f);
#else
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-24.0f);
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-24.0f);
#endif
}
#ifdef ps_convert_rgba8_float32
void ps_convert_rgba8_float32()
{
// Convert an RGBA texture into a float depth texture
gl_FragDepth = rgba8_to_depth32(sample_c());
// Convert an RGBA texture into a float depth texture
gl_FragDepth = rgba8_to_depth32(sample_c());
}
#endif
#ifdef ps_convert_rgba8_float24
void ps_convert_rgba8_float24()
{
// Same as above but without the alpha channel (24 bits Z)
// Same as above but without the alpha channel (24 bits Z)
// Convert an RGBA texture into a float depth texture
gl_FragDepth = rgba8_to_depth24(sample_c());
// Convert an RGBA texture into a float depth texture
gl_FragDepth = rgba8_to_depth24(sample_c());
}
#endif
#ifdef ps_convert_rgba8_float16
void ps_convert_rgba8_float16()
{
// Same as above but without the A/B channels (16 bits Z)
// Same as above but without the A/B channels (16 bits Z)
// Convert an RGBA texture into a float depth texture
gl_FragDepth = rgba8_to_depth16(sample_c());
// Convert an RGBA texture into a float depth texture
gl_FragDepth = rgba8_to_depth16(sample_c());
}
#endif
#ifdef ps_convert_rgb5a1_float16
void ps_convert_rgb5a1_float16()
{
// Convert an RGB5A1 (saved as RGBA8) color to a 16 bit Z
gl_FragDepth = rgb5a1_to_depth16(sample_c());
// Convert an RGB5A1 (saved as RGBA8) color to a 16 bit Z
gl_FragDepth = rgb5a1_to_depth16(sample_c());
}
#endif
#define SAMPLE_RGBA_DEPTH_BILN(CONVERT_FN) \
ivec2 dims = textureSize(TextureSampler, 0); \
vec2 top_left_f = PSin_t * vec2(dims) - 0.5f; \
ivec2 top_left = ivec2(floor(top_left_f)); \
ivec4 coords = clamp(ivec4(top_left, top_left + 1), ivec4(0), dims.xyxy - 1); \
vec2 mix_vals = fract(top_left_f); \
float depthTL = CONVERT_FN(texelFetch(TextureSampler, coords.xy, 0)); \
float depthTR = CONVERT_FN(texelFetch(TextureSampler, coords.zy, 0)); \
float depthBL = CONVERT_FN(texelFetch(TextureSampler, coords.xw, 0)); \
float depthBR = CONVERT_FN(texelFetch(TextureSampler, coords.zw, 0)); \
gl_FragDepth = mix(mix(depthTL, depthTR, mix_vals.x), mix(depthBL, depthBR, mix_vals.x), mix_vals.y);
ivec2 dims = textureSize(TextureSampler, 0); \
vec2 top_left_f = PSin_t * vec2(dims) - 0.5f; \
ivec2 top_left = ivec2(floor(top_left_f)); \
ivec4 coords = clamp(ivec4(top_left, top_left + 1), ivec4(0), dims.xyxy - 1); \
vec2 mix_vals = fract(top_left_f); \
float depthTL = CONVERT_FN(texelFetch(TextureSampler, coords.xy, 0)); \
float depthTR = CONVERT_FN(texelFetch(TextureSampler, coords.zy, 0)); \
float depthBL = CONVERT_FN(texelFetch(TextureSampler, coords.xw, 0)); \
float depthBR = CONVERT_FN(texelFetch(TextureSampler, coords.zw, 0)); \
gl_FragDepth = mix(mix(depthTL, depthTR, mix_vals.x), mix(depthBL, depthBR, mix_vals.x), mix_vals.y);
#ifdef ps_convert_rgba8_float32_biln
void ps_convert_rgba8_float32_biln()
{
// Convert an RGBA texture into a float depth texture
SAMPLE_RGBA_DEPTH_BILN(rgba8_to_depth32);
// Convert an RGBA texture into a float depth texture
SAMPLE_RGBA_DEPTH_BILN(rgba8_to_depth32);
}
#endif
#ifdef ps_convert_rgba8_float24_biln
void ps_convert_rgba8_float24_biln()
{
// Same as above but without the alpha channel (24 bits Z)
// Same as above but without the alpha channel (24 bits Z)
// Convert an RGBA texture into a float depth texture
SAMPLE_RGBA_DEPTH_BILN(rgba8_to_depth24);
// Convert an RGBA texture into a float depth texture
SAMPLE_RGBA_DEPTH_BILN(rgba8_to_depth24);
}
#endif
#ifdef ps_convert_rgba8_float16_biln
void ps_convert_rgba8_float16_biln()
{
// Same as above but without the A/B channels (16 bits Z)
// Same as above but without the A/B channels (16 bits Z)
// Convert an RGBA texture into a float depth texture
SAMPLE_RGBA_DEPTH_BILN(rgba8_to_depth16);
// Convert an RGBA texture into a float depth texture
SAMPLE_RGBA_DEPTH_BILN(rgba8_to_depth16);
}
#endif
#ifdef ps_convert_rgb5a1_float16_biln
void ps_convert_rgb5a1_float16_biln()
{
// Convert an RGB5A1 (saved as RGBA8) color to a 16 bit Z
SAMPLE_RGBA_DEPTH_BILN(rgb5a1_to_depth16);
// Convert an RGB5A1 (saved as RGBA8) color to a 16 bit Z
SAMPLE_RGBA_DEPTH_BILN(rgb5a1_to_depth16);
}
#endif
#ifdef ps_convert_rgba_8i
uniform uint SBW;
uniform uint DBW;
uniform float ScaleFactor;
void ps_convert_rgba_8i()
{
// Convert a RGBA texture into a 8 bits packed texture
// Input column: 8x2 RGBA pixels
// 0: 8 RGBA
// 1: 8 RGBA
// Output column: 16x4 Index pixels
// 0: 8 R | 8 B
// 1: 8 R | 8 B
// 2: 8 G | 8 A
// 3: 8 G | 8 A
uvec2 pos = uvec2(gl_FragCoord.xy);
// Convert a RGBA texture into a 8 bits packed texture
// Input column: 8x2 RGBA pixels
// 0: 8 RGBA
// 1: 8 RGBA
// Output column: 16x4 Index pixels
// 0: 8 R | 8 B
// 1: 8 R | 8 B
// 2: 8 G | 8 A
// 3: 8 G | 8 A
uvec2 pos = uvec2(gl_FragCoord.xy);
// Collapse separate R G B A areas into their base pixel
uvec2 block = (pos & ~uvec2(15u, 3u)) >> 1;
uvec2 subblock = pos & uvec2(7u, 1u);
uvec2 coord = block | subblock;
// Collapse separate R G B A areas into their base pixel
uvec2 block = (pos & ~uvec2(15u, 3u)) >> 1;
uvec2 subblock = pos & uvec2(7u, 1u);
uvec2 coord = block | subblock;
// Apply offset to cols 1 and 2
uint is_col23 = pos.y & 4u;
uint is_col13 = pos.y & 2u;
uint is_col12 = is_col23 ^ (is_col13 << 1);
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
// Compensate for potentially differing page pitch.
uvec2 block_xy = coord / uvec2(64u, 32u);
uint block_num = (block_xy.y * (DBW / 128u)) + block_xy.x;
uvec2 block_offset = uvec2((block_num % (SBW / 64u)) * 64u, (block_num / (SBW / 64u)) * 32u);
coord = (coord % uvec2(64u, 32u)) + block_offset;
if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR)
coord = uvec2(vec2(coord) * PS_SCALE_FACTOR);
else
coord *= uvec2(PS_SCALE_FACTOR);
// Apply offset to cols 1 and 2
uint is_col23 = pos.y & 4u;
uint is_col13 = pos.y & 2u;
uint is_col12 = is_col23 ^ (is_col13 << 1);
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
vec4 pixel = texelFetch(TextureSampler, ivec2(coord), 0);
vec2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga;
float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y;
SV_Target0 = vec4(sel1);
if (floor(ScaleFactor) != ScaleFactor)
coord = uvec2(vec2(coord) * ScaleFactor);
else
coord *= uvec2(ScaleFactor);
vec4 pixel = texelFetch(TextureSampler, ivec2(coord), 0);
vec2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga;
float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y;
SV_Target0 = vec4(sel1);
}
#endif
#ifdef ps_filter_transparency
void ps_filter_transparency()
{
vec4 c = sample_c();
SV_Target0 = vec4(c.rgb, 1.0);
vec4 c = sample_c();
SV_Target0 = vec4(c.rgb, 1.0);
}
#endif
@@ -283,8 +295,8 @@ void ps_filter_transparency()
#ifdef ps_datm1
void ps_datm1()
{
if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass
discard;
if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass
discard;
}
#endif
@@ -293,30 +305,30 @@ void ps_datm1()
#ifdef ps_datm0
void ps_datm0()
{
if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
discard;
if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
discard;
}
#endif
#ifdef ps_hdr_init
void ps_hdr_init()
{
vec4 value = sample_c();
SV_Target0 = vec4(round(value.rgb * 255.0f) / 65535.0f, value.a);
vec4 value = sample_c();
SV_Target0 = vec4(round(value.rgb * 255.0f) / 65535.0f, value.a);
}
#endif
#ifdef ps_hdr_resolve
void ps_hdr_resolve()
{
vec4 value = sample_c();
SV_Target0 = vec4(vec3(uvec3(value.rgb * 65535.0f) & 255u) / 255.0f, value.a);
vec4 value = sample_c();
SV_Target0 = vec4(vec3(uvec3(value.rgb * 65535.0f) & 255u) / 255.0f, value.a);
}
#endif
#ifdef ps_convert_clut_4
uniform uvec3 offset;
uniform vec2 scale;
uniform float scale;
void ps_convert_clut_4()
{
@@ -324,14 +336,14 @@ void ps_convert_clut_4()
uint index = uint(gl_FragCoord.x) + offset.z;
uvec2 pos = uvec2(index % 8u, index / 8u);
ivec2 final = ivec2(floor(vec2(offset.xy + pos) * scale));
ivec2 final = ivec2(floor(vec2(offset.xy + pos) * vec2(scale)));
SV_Target0 = texelFetch(TextureSampler, final, 0);
}
#endif
#ifdef ps_convert_clut_8
uniform uvec3 offset;
uniform vec2 scale;
uniform float scale;
void ps_convert_clut_8()
{
@@ -344,7 +356,7 @@ void ps_convert_clut_8()
pos.x = (index % 8u) + ((subgroup >= 2u) ? 8u : 0u);
pos.y = ((index / 32u) * 2u) + (subgroup % 2u);
ivec2 final = ivec2(floor(vec2(offset.xy + pos) * scale));
ivec2 final = ivec2(floor(vec2(offset.xy + pos) * vec2(scale)));
SV_Target0 = texelFetch(TextureSampler, final, 0);
}
#endif
@@ -354,51 +366,51 @@ uniform ivec2 EMOD;
void ps_yuv()
{
vec4 i = sample_c();
vec4 o;
vec4 i = sample_c();
vec4 o;
mat3 rgb2yuv; // Value from GS manual
rgb2yuv[0] = vec3(0.587, -0.311, -0.419);
rgb2yuv[1] = vec3(0.114, 0.500, -0.081);
rgb2yuv[2] = vec3(0.299, -0.169, 0.500);
mat3 rgb2yuv; // Value from GS manual
rgb2yuv[0] = vec3(0.587, -0.311, -0.419);
rgb2yuv[1] = vec3(0.114, 0.500, -0.081);
rgb2yuv[2] = vec3(0.299, -0.169, 0.500);
vec3 yuv = rgb2yuv * i.gbr;
vec3 yuv = rgb2yuv * i.gbr;
float Y = float(0xDB)/255.0f * yuv.x + float(0x10)/255.0f;
float Cr = float(0xE0)/255.0f * yuv.y + float(0x80)/255.0f;
float Cb = float(0xE0)/255.0f * yuv.z + float(0x80)/255.0f;
float Y = float(0xDB)/255.0f * yuv.x + float(0x10)/255.0f;
float Cr = float(0xE0)/255.0f * yuv.y + float(0x80)/255.0f;
float Cb = float(0xE0)/255.0f * yuv.z + float(0x80)/255.0f;
switch(EMOD.x) {
case 0:
o.a = i.a;
break;
case 1:
o.a = Y;
break;
case 2:
o.a = Y/2.0f;
break;
case 3:
o.a = 0.0f;
break;
}
switch(EMOD.x) {
case 0:
o.a = i.a;
break;
case 1:
o.a = Y;
break;
case 2:
o.a = Y/2.0f;
break;
case 3:
o.a = 0.0f;
break;
}
switch(EMOD.y) {
case 0:
o.rgb = i.rgb;
break;
case 1:
o.rgb = vec3(Y);
break;
case 2:
o.rgb = vec3(Y, Cb, Cr);
break;
case 3:
o.rgb = vec3(i.a);
break;
}
switch(EMOD.y) {
case 0:
o.rgb = i.rgb;
break;
case 1:
o.rgb = vec3(Y);
break;
case 2:
o.rgb = vec3(Y, Cb, Cr);
break;
case 3:
o.rgb = vec3(i.a);
break;
}
SV_Target0 = o;
SV_Target0 = o;
}
#endif
@@ -406,16 +418,16 @@ void ps_yuv()
void main()
{
SV_Target0 = vec4(0x7FFFFFFF);
SV_Target0 = vec4(0x7FFFFFFF);
#ifdef ps_stencil_image_init_0
if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
SV_Target0 = vec4(-1);
#endif
#ifdef ps_stencil_image_init_1
if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass
SV_Target0 = vec4(-1);
#endif
#ifdef ps_stencil_image_init_0
if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
SV_Target0 = vec4(-1);
#endif
#ifdef ps_stencil_image_init_1
if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass
SV_Target0 = vec4(-1);
#endif
}
#endif

View File

@@ -0,0 +1,35 @@
#ifdef VERTEX_SHADER
layout(location = 0) in vec2 Position;
layout(location = 1) in vec2 UV;
layout(location = 2) in vec4 Color;
uniform mat4 ProjMtx;
out vec2 Frag_UV;
out vec4 Frag_Color;
void vs_main()
{
Frag_UV = UV;
Frag_Color = Color;
gl_Position = ProjMtx * vec4(Position.xy, 0.0, 1.0);
}
#endif
#ifdef FRAGMENT_SHADER
layout(binding = 0) uniform sampler2D Texture;
in vec2 Frag_UV;
in vec4 Frag_Color;
layout(location = 0) out vec4 Out_Color;
void ps_main()
{
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
}
#endif

View File

@@ -8,6 +8,8 @@ in vec4 PSin_c;
uniform vec4 ZrH;
layout(binding = 0) uniform sampler2D TextureSampler;
layout(location = 0) out vec4 SV_Target0;
@@ -19,7 +21,7 @@ void ps_main0()
int vpos = int(gl_FragCoord.y); // vertical position of destination texture
if ((vpos & 1) == field)
SV_Target0 = texture(TextureSampler, PSin_t);
SV_Target0 = textureLod(TextureSampler, PSin_t, 0);
else
discard;
}
@@ -28,7 +30,7 @@ void ps_main0()
// Bob shader
void ps_main1()
{
SV_Target0 = texture(TextureSampler, PSin_t);
SV_Target0 = textureLod(TextureSampler, PSin_t, 0);
}
@@ -36,9 +38,9 @@ void ps_main1()
void ps_main2()
{
vec2 vstep = vec2(0.0f, ZrH.y);
vec4 c0 = texture(TextureSampler, PSin_t - vstep);
vec4 c1 = texture(TextureSampler, PSin_t);
vec4 c2 = texture(TextureSampler, PSin_t + vstep);
vec4 c0 = textureLod(TextureSampler, PSin_t - vstep, 0);
vec4 c1 = textureLod(TextureSampler, PSin_t, 0);
vec4 c2 = textureLod(TextureSampler, PSin_t + vstep, 0);
SV_Target0 = (c0 + c1 * 2.0f + c2) / 4.0f;
}
@@ -60,15 +62,11 @@ void ps_main3()
int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
int vpos = int(gl_FragCoord.y) + lofs; // vertical position of destination texture
vec2 bofs = vec2(0.0f, 0.5f * float(bank)); // vertical offset of the current bank relative to source texture size
vec2 vscale = vec2(1.0f, 2.0f); // scaling factor from source to destination texture
vec2 optr = PSin_t - bofs; // used to check if the current destination line is within the current bank
vec2 iptr = optr * vscale; // pointer to the current pixel in the source texture
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
SV_Target0 = texture(TextureSampler, iptr);
if ((vpos & 1) == field)
SV_Target0 = textureLod(TextureSampler, PSin_t, 0);
else
discard;
}
@@ -126,13 +124,13 @@ void ps_main4()
// calculating motion, only relevant for missing lines where the "center line" is pointed
// by p_t1
vec4 hn = texture(TextureSampler, p_t0 - lofs); // new high pixel
vec4 cn = texture(TextureSampler, p_t1); // new center pixel
vec4 ln = texture(TextureSampler, p_t0 + lofs); // new low pixel
vec4 hn = textureLod(TextureSampler, p_t0 - lofs, 0); // new high pixel
vec4 cn = textureLod(TextureSampler, p_t1, 0); // new center pixel
vec4 ln = textureLod(TextureSampler, p_t0 + lofs, 0); // new low pixel
vec4 ho = texture(TextureSampler, p_t2 - lofs); // old high pixel
vec4 co = texture(TextureSampler, p_t3); // old center pixel
vec4 lo = texture(TextureSampler, p_t2 + lofs); // old low pixel
vec4 ho = textureLod(TextureSampler, p_t2 - lofs, 0); // old high pixel
vec4 co = textureLod(TextureSampler, p_t3, 0); // old center pixel
vec4 lo = textureLod(TextureSampler, p_t2 + lofs, 0); // old low pixel
vec3 mh = hn.rgb - ho.rgb; // high pixel motion
vec3 mc = cn.rgb - co.rgb; // center pixel motion
@@ -158,7 +156,7 @@ void ps_main4()
if ((vpos & 1) == field)
{
// output coordinate present on current field
SV_Target0 = texture(TextureSampler, p_t0);
SV_Target0 = textureLod(TextureSampler, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{

View File

@@ -8,21 +8,23 @@ in vec4 PSin_c;
uniform vec4 BGColor;
layout(binding = 0) uniform sampler2D TextureSampler;
layout(location = 0) out vec4 SV_Target0;
void ps_main0()
{
vec4 c = texture(TextureSampler, PSin_t);
// Note: clamping will be done by fixed unit
c.a *= 2.0f;
SV_Target0 = c;
vec4 c = texture(TextureSampler, PSin_t);
// Note: clamping will be done by fixed unit
c.a *= 2.0f;
SV_Target0 = c;
}
void ps_main1()
{
vec4 c = texture(TextureSampler, PSin_t);
c.a = BGColor.a;
SV_Target0 = c;
vec4 c = texture(TextureSampler, PSin_t);
c.a = BGColor.a;
SV_Target0 = c;
}
#endif

View File

@@ -40,12 +40,13 @@ uniform vec2 u_rcp_target_resolution; // 1 / u_target_resolution
uniform vec2 u_source_resolution;
uniform vec2 u_rcp_source_resolution; // 1 / u_source_resolution
uniform float u_time;
uniform vec3 cb0_pad0;
in vec4 PSin_p;
in vec2 PSin_t;
in vec4 PSin_c;
layout(binding = 0) uniform sampler2D TextureSampler;
layout(location = 0) out vec4 SV_Target0;
vec4 sample_c()
@@ -117,10 +118,10 @@ void ps_filter_triangular() // triangular
#ifdef ps_filter_complex
void ps_filter_complex()
{
const float PI = 3.14159265359f;
vec2 texdim = vec2(textureSize(TextureSampler, 0));
float factor = (0.9f - 0.4f * cos(2.0f * PI * PSin_t.y * texdim.y));
vec4 c = factor * texture(TextureSampler, vec2(PSin_t.x, (floor(PSin_t.y * texdim.y) + 0.5f) / texdim.y));
const float PI = 3.14159265359f;
vec2 texdim = vec2(textureSize(TextureSampler, 0));
float factor = (0.9f - 0.4f * cos(2.0f * PI * PSin_t.y * texdim.y));
vec4 c = factor * texture(TextureSampler, vec2(PSin_t.x, (floor(PSin_t.y * texdim.y) + 0.5f) / texdim.y));
SV_Target0 = c;
}

View File

@@ -17,38 +17,40 @@ in vec4 PSin_p;
in vec2 PSin_t;
in vec4 PSin_c;
layout(binding = 0) uniform sampler2D TextureSampler;
layout(location = 0) out vec4 SV_Target0;
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
vec4 ContrastSaturationBrightness(vec4 color)
{
float brt = params.x;
float con = params.y;
float sat = params.z;
float brt = params.x;
float con = params.y;
float sat = params.z;
// Increase or decrease these values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
// Increase or decrease these values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color.rgb * brt;
float dot_intensity = dot(brtColor, LumCoeff);
vec3 intensity = vec3(dot_intensity, dot_intensity, dot_intensity);
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color.rgb * brt;
float dot_intensity = dot(brtColor, LumCoeff);
vec3 intensity = vec3(dot_intensity, dot_intensity, dot_intensity);
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
color.rgb = conColor;
return color;
color.rgb = conColor;
return color;
}
void ps_main()
{
vec4 c = texture(TextureSampler, PSin_t);
SV_Target0 = ContrastSaturationBrightness(c);
vec4 c = texture(TextureSampler, PSin_t);
SV_Target0 = ContrastSaturationBrightness(c);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,35 @@
//#version 420 // Keep it for text editor detection
layout(std140, binding = 1) uniform cb20
{
vec2 VertexScale;
vec2 VertexOffset;
vec2 TextureScale;
vec2 TextureOffset;
vec2 PointSize;
uint MaxDepth;
uint pad_cb20;
};
#ifdef VERTEX_SHADER
out SHADER
{
vec4 t_float;
vec4 t_int;
#if VS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} VSout;
const float exp_min32 = exp2(-32.0f);
#if VS_EXPAND == 0
layout(location = 0) in vec2 i_st;
layout(location = 2) in vec4 i_c;
layout(location = 3) in float i_q;
@@ -9,241 +38,202 @@ layout(location = 5) in uint i_z;
layout(location = 6) in uvec2 i_uv;
layout(location = 7) in vec4 i_f;
#if !defined(BROKEN_DRIVER) && (pGL_ES || defined(GL_ARB_enhanced_layouts) && GL_ARB_enhanced_layouts)
layout(location = 0)
#endif
out SHADER
{
vec4 t_float;
vec4 t_int;
#if VS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} VSout;
const float exp_min32 = exp2(-32.0f);
void texture_coord()
{
vec2 uv = vec2(i_uv) - TextureOffset;
vec2 st = i_st - TextureOffset;
vec2 uv = vec2(i_uv) - TextureOffset;
vec2 st = i_st - TextureOffset;
// Float coordinate
VSout.t_float.xy = st;
VSout.t_float.w = i_q;
// Float coordinate
VSout.t_float.xy = st;
VSout.t_float.w = i_q;
// Integer coordinate => normalized
VSout.t_int.xy = uv * TextureScale;
#if VS_INT_FST == 1
// Some games uses float coordinate for post-processing effect
VSout.t_int.zw = st / TextureScale;
// Integer coordinate => normalized
VSout.t_int.xy = uv * TextureScale;
#if VS_FST
// Integer coordinate => integral
VSout.t_int.zw = uv;
#else
// Integer coordinate => integral
VSout.t_int.zw = uv;
// Some games uses float coordinate for post-processing effect
VSout.t_int.zw = st / TextureScale;
#endif
}
void vs_main()
{
// Clamp to max depth, gs doesn't wrap
highp uint z = min(i_z, MaxDepth);
// Clamp to max depth, gs doesn't wrap
highp uint z = min(i_z, MaxDepth);
// pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go)
// example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty
// input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
vec4 p;
// pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go)
// example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty
// input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
vec4 p;
p.xy = vec2(i_p) - vec2(0.05f, 0.05f);
p.xy = p.xy * VertexScale - VertexOffset;
p.w = 1.0f;
p.xy = vec2(i_p) - vec2(0.05f, 0.05f);
p.xy = p.xy * VertexScale - VertexOffset;
p.w = 1.0f;
#if HAS_CLIP_CONTROL
p.z = float(z) * exp_min32;
p.z = float(z) * exp_min32;
#else
// GLES doesn't support ARB_clip_control, so remap it to -1..1. We also reduce the range from 32 bits
// to 24 bits, which means some games with very large depth ranges will not render correctly. But,
// for most, it's okay, and really, the best we can do.
p.z = min(float(z) * exp2(-23.0f), 2.0f) - 1.0f;
// GLES doesn't support ARB_clip_control, so remap it to -1..1. We also reduce the range from 32 bits
// to 24 bits, which means some games with very large depth ranges will not render correctly. But,
// for most, it's okay, and really, the best we can do.
p.z = min(float(z) * exp2(-23.0f), 2.0f) - 1.0f;
#endif
gl_Position = p;
gl_Position = p;
texture_coord();
texture_coord();
VSout.c = i_c;
VSout.t_float.z = i_f.x; // pack for with texture
VSout.c = i_c;
VSout.t_float.z = i_f.x; // pack for with texture
#if VS_POINT_SIZE
gl_PointSize = float(VS_POINT_SIZE_VALUE);
#endif
#if VS_POINT_SIZE
gl_PointSize = PointSize.x;
#endif
}
#endif
#else // VS_EXPAND
#ifdef GEOMETRY_SHADER
#if !defined(BROKEN_DRIVER) && (pGL_ES || defined(GL_ARB_enhanced_layouts) && GL_ARB_enhanced_layouts)
layout(location = 0)
#endif
in SHADER
struct RawVertex
{
vec4 t_float;
vec4 t_int;
#if GS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} GSin[];
#if !defined(BROKEN_DRIVER) && (pGL_ES || defined(GL_ARB_enhanced_layouts) && GL_ARB_enhanced_layouts)
layout(location = 0)
#endif
out SHADER
{
vec4 t_float;
vec4 t_int;
#if GS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} GSout;
struct vertex
{
vec4 t_float;
vec4 t_int;
vec4 c;
vec2 ST;
uint RGBA;
float Q;
uint XY;
uint Z;
uint UV;
uint FOG;
};
void out_vertex(in vec4 position, in vertex v)
layout(std140, binding = 2) readonly buffer VertexBuffer {
RawVertex vertex_buffer[];
};
struct ProcessedVertex
{
GSout.t_float = v.t_float;
GSout.t_int = v.t_int;
// Flat output
#if GS_POINT == 1
GSout.c = GSin[0].c;
vec4 p;
vec4 t_float;
vec4 t_int;
vec4 c;
};
ProcessedVertex load_vertex(uint index)
{
#if defined(GL_ARB_shader_draw_parameters) && GL_ARB_shader_draw_parameters
RawVertex rvtx = vertex_buffer[index + gl_BaseVertexARB];
#else
GSout.c = GSin[1].c;
RawVertex rvtx = vertex_buffer[index];
#endif
gl_Position = position;
gl_PrimitiveID = gl_PrimitiveIDIn;
EmitVertex();
}
#if GS_POINT == 1
layout(points) in;
vec2 i_st = rvtx.ST;
vec4 i_c = vec4(uvec4(bitfieldExtract(rvtx.RGBA, 0, 8), bitfieldExtract(rvtx.RGBA, 8, 8),
bitfieldExtract(rvtx.RGBA, 16, 8), bitfieldExtract(rvtx.RGBA, 24, 8)));
float i_q = rvtx.Q;
uvec2 i_p = uvec2(bitfieldExtract(rvtx.XY, 0, 16), bitfieldExtract(rvtx.XY, 16, 16));
uint i_z = rvtx.Z;
uvec2 i_uv = uvec2(bitfieldExtract(rvtx.UV, 0, 16), bitfieldExtract(rvtx.UV, 16, 16));
vec4 i_f = unpackUnorm4x8(rvtx.FOG);
ProcessedVertex vtx;
uint z = min(i_z, MaxDepth);
vtx.p.xy = vec2(i_p) - vec2(0.05f, 0.05f);
vtx.p.xy = vtx.p.xy * VertexScale - VertexOffset;
vtx.p.w = 1.0f;
#if HAS_CLIP_CONTROL
vtx.p.z = float(z) * exp_min32;
#else
layout(lines) in;
vtx.p.z = min(float(z) * exp2(-23.0f), 2.0f) - 1.0f;
#endif
layout(triangle_strip, max_vertices = 4) out;
#if GS_POINT == 1
vec2 uv = vec2(i_uv) - TextureOffset;
vec2 st = i_st - TextureOffset;
void gs_main()
{
// Transform a point to a NxN sprite
vertex point = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);
// Get new position
vec4 lt_p = gl_in[0].gl_Position;
vec4 rb_p = gl_in[0].gl_Position + vec4(PointSize.x, PointSize.y, 0.0f, 0.0f);
vec4 lb_p = rb_p;
vec4 rt_p = rb_p;
lb_p.x = lt_p.x;
rt_p.y = lt_p.y;
out_vertex(lt_p, point);
out_vertex(lb_p, point);
out_vertex(rt_p, point);
out_vertex(rb_p, point);
EndPrimitive();
}
#elif GS_LINE == 1
void gs_main()
{
// Transform a line to a thick line-sprite
vertex left = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);
vertex right = vertex(GSin[1].t_float, GSin[1].t_int, GSin[1].c);
vec4 lt_p = gl_in[0].gl_Position;
vec4 rt_p = gl_in[1].gl_Position;
// Potentially there is faster math
vec2 line_vector = normalize(rt_p.xy - lt_p.xy);
vec2 line_normal = vec2(line_vector.y, -line_vector.x);
vec2 line_width = (line_normal * PointSize) / 2.0f;
lt_p.xy -= line_width;
rt_p.xy -= line_width;
vec4 lb_p = gl_in[0].gl_Position + vec4(line_width, 0.0f, 0.0f);
vec4 rb_p = gl_in[1].gl_Position + vec4(line_width, 0.0f, 0.0f);
out_vertex(lt_p, left);
out_vertex(lb_p, left);
out_vertex(rt_p, right);
out_vertex(rb_p, right);
EndPrimitive();
}
vtx.t_float.xy = st;
vtx.t_float.w = i_q;
vtx.t_int.xy = uv * TextureScale;
#if VS_FST
vtx.t_int.zw = uv;
#else
vtx.t_int.zw = st / TextureScale;
#endif
void gs_main()
{
// left top => GSin[0];
// right bottom => GSin[1];
vertex rb = vertex(GSin[1].t_float, GSin[1].t_int, GSin[1].c);
vertex lt = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);
vtx.c = i_c;
vtx.t_float.z = i_f.x;
vec4 rb_p = gl_in[1].gl_Position;
vec4 lb_p = rb_p;
vec4 rt_p = rb_p;
vec4 lt_p = gl_in[0].gl_Position;
// flat depth
lt_p.z = rb_p.z;
// flat fog and texture perspective
lt.t_float.zw = rb.t_float.zw;
// flat color
lt.c = rb.c;
// Swap texture and position coordinate
vertex lb = rb;
lb.t_float.x = lt.t_float.x;
lb.t_int.x = lt.t_int.x;
lb.t_int.z = lt.t_int.z;
lb_p.x = lt_p.x;
vertex rt = rb;
rt_p.y = lt_p.y;
rt.t_float.y = lt.t_float.y;
rt.t_int.y = lt.t_int.y;
rt.t_int.w = lt.t_int.w;
out_vertex(lt_p, lt);
out_vertex(lb_p, lb);
out_vertex(rt_p, rt);
out_vertex(rb_p, rb);
EndPrimitive();
return vtx;
}
void main()
{
ProcessedVertex vtx;
#if defined(GL_ARB_shader_draw_parameters) && GL_ARB_shader_draw_parameters
uint vid = uint(gl_VertexID - gl_BaseVertexARB);
#else
uint vid = uint(gl_VertexID);
#endif
#if VS_EXPAND == 1 // Point
vtx = load_vertex(vid >> 2);
vtx.p.x += ((vid & 1u) != 0u) ? PointSize.x : 0.0f;
vtx.p.y += ((vid & 2u) != 0u) ? PointSize.y : 0.0f;
#elif VS_EXPAND == 2 // Line
uint vid_base = vid >> 2;
bool is_bottom = (vid & 2u) != 0u;
bool is_right = (vid & 1u) != 0u;
uint vid_other = is_bottom ? vid_base - 1 : vid_base + 1;
vtx = load_vertex(vid_base);
ProcessedVertex other = load_vertex(vid_other);
vec2 line_vector = normalize(vtx.p.xy - other.p.xy);
vec2 line_normal = vec2(line_vector.y, -line_vector.x);
vec2 line_width = (line_normal * PointSize) / 2;
// line_normal is inverted for bottom point
vec2 offset = ((uint(is_bottom) ^ uint(is_right)) != 0u) ? line_width : -line_width;
vtx.p.xy += offset;
// Lines will be run as (0 1 2) (1 2 3)
// This means that both triangles will have a point based off the top line point as their first point
// So we don't have to do anything for !IIP
#elif VS_EXPAND == 3 // Sprite
// Sprite points are always in pairs
uint vid_base = vid >> 1;
uint vid_lt = vid_base & ~1u;
uint vid_rb = vid_base | 1u;
ProcessedVertex lt = load_vertex(vid_lt);
ProcessedVertex rb = load_vertex(vid_rb);
vtx = rb;
bool is_right = ((vid & 1u) != 0u);
vtx.p.x = is_right ? lt.p.x : vtx.p.x;
vtx.t_float.x = is_right ? lt.t_float.x : vtx.t_float.x;
vtx.t_int.xz = is_right ? lt.t_int.xz : vtx.t_int.xz;
bool is_bottom = ((vid & 2u) != 0u);
vtx.p.y = is_bottom ? lt.p.y : vtx.p.y;
vtx.t_float.y = is_bottom ? lt.t_float.y : vtx.t_float.y;
vtx.t_int.yw = is_bottom ? lt.t_int.yw : vtx.t_int.yw;
#endif
gl_Position = vtx.p;
VSout.t_float = vtx.t_float;
VSout.t_int = vtx.t_int;
VSout.c = vtx.c;
}
#endif // VS_EXPAND
#endif // VERTEX_SHADER

View File

@@ -1,7 +1,3 @@
#ifndef PS_SCALE_FACTOR
#define PS_SCALE_FACTOR 1.0
#endif
#ifdef VERTEX_SHADER
layout(location = 0) in vec4 a_pos;
@@ -23,7 +19,17 @@ layout(location = 0) in vec2 v_tex;
#if defined(ps_convert_rgba8_16bits) || defined(ps_convert_float32_32bits)
layout(location = 0) out uint o_col0;
#else
#elif !defined(ps_datm1) && \
!defined(ps_datm0) && \
!defined(ps_convert_rgba8_float32) && \
!defined(ps_convert_rgba8_float24) && \
!defined(ps_convert_rgba8_float16) && \
!defined(ps_convert_rgb5a1_float16) && \
!defined(ps_convert_rgba8_float32_biln) && \
!defined(ps_convert_rgba8_float24_biln) && \
!defined(ps_convert_rgba8_float16_biln) && \
!defined(ps_convert_rgb5a1_float16_biln) && \
!defined(ps_depth_copy)
layout(location = 0) out vec4 o_col0;
#endif
@@ -69,8 +75,6 @@ void ps_convert_rgba8_16bits()
#ifdef ps_datm1
void ps_datm1()
{
o_col0 = vec4(0, 0, 0, 0);
if(sample_c(v_tex).a < (127.5f / 255.0f)) // >= 0x80 pass
discard;
@@ -80,8 +84,6 @@ void ps_datm1()
#ifdef ps_datm0
void ps_datm0()
{
o_col0 = vec4(0, 0, 0, 0);
if((127.5f / 255.0f) < sample_c(v_tex).a) // < 0x80 pass (== 0x80 should not pass)
discard;
}
@@ -238,6 +240,15 @@ void ps_convert_rgb5a1_float16_biln()
#endif
#ifdef ps_convert_rgba_8i
layout(push_constant) uniform cb10
{
uint SBW;
uint DBW;
uvec2 cb_pad1;
float ScaleFactor;
vec3 cb_pad2;
};
void ps_convert_rgba_8i()
{
// Convert a RGBA texture into a 8 bits packed texture
@@ -249,37 +260,45 @@ void ps_convert_rgba_8i()
// 1: 8 R | 8 B
// 2: 8 G | 8 A
// 3: 8 G | 8 A
uvec2 pos = uvec2(gl_FragCoord.xy);
uvec2 pos = uvec2(gl_FragCoord.xy);
// Collapse separate R G B A areas into their base pixel
uvec2 block = (pos & ~uvec2(15u, 3u)) >> 1;
uvec2 subblock = pos & uvec2(7u, 1u);
uvec2 coord = block | subblock;
// Collapse separate R G B A areas into their base pixel
uvec2 block = (pos & ~uvec2(15u, 3u)) >> 1;
uvec2 subblock = pos & uvec2(7u, 1u);
uvec2 coord = block | subblock;
// Apply offset to cols 1 and 2
uint is_col23 = pos.y & 4u;
uint is_col13 = pos.y & 2u;
uint is_col12 = is_col23 ^ (is_col13 << 1);
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
// Compensate for potentially differing page pitch.
uvec2 block_xy = coord / uvec2(64u, 32u);
uint block_num = (block_xy.y * (DBW / 128u)) + block_xy.x;
uvec2 block_offset = uvec2((block_num % (SBW / 64u)) * 64u, (block_num / (SBW / 64u)) * 32u);
coord = (coord % uvec2(64u, 32u)) + block_offset;
if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR)
coord = uvec2(vec2(coord) * PS_SCALE_FACTOR);
else
coord *= uvec2(PS_SCALE_FACTOR);
// Apply offset to cols 1 and 2
uint is_col23 = pos.y & 4u;
uint is_col13 = pos.y & 2u;
uint is_col12 = is_col23 ^ (is_col13 << 1);
coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x
vec4 pixel = texelFetch(samp0, ivec2(coord), 0);
vec2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga;
float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y;
o_col0 = vec4(sel1); // Divide by something here?
if (floor(ScaleFactor) != ScaleFactor)
coord = uvec2(vec2(coord) * ScaleFactor);
else
coord *= uvec2(ScaleFactor);
vec4 pixel = texelFetch(samp0, ivec2(coord), 0);
vec2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga;
float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y;
o_col0 = vec4(sel1); // Divide by something here?
}
#endif
#ifdef ps_convert_clut_4
layout(push_constant) uniform cb10
{
vec2 scale;
uvec2 offset;
uint doffset;
uint cb_pad1;
float scale;
vec3 cb_pad2;
};
void ps_convert_clut_4()
@@ -288,7 +307,7 @@ void ps_convert_clut_4()
uint index = uint(gl_FragCoord.x) + doffset;
uvec2 pos = uvec2(index % 8u, index / 8u);
ivec2 final = ivec2(floor(vec2(offset + pos) * scale));
ivec2 final = ivec2(floor(vec2(offset + pos) * vec2(scale)));
o_col0 = texelFetch(samp0, final, 0);
}
#endif
@@ -296,9 +315,11 @@ void ps_convert_clut_4()
#ifdef ps_convert_clut_8
layout(push_constant) uniform cb10
{
vec2 scale;
uvec2 offset;
uint doffset;
uint cb_pad1;
float scale;
vec3 cb_pad2;
};
void ps_convert_clut_8()
@@ -312,7 +333,7 @@ void ps_convert_clut_8()
pos.x = (index % 8u) + ((subgroup >= 2u) ? 8u : 0u);
pos.y = ((index / 32u) * 2u) + (subgroup % 2u);
ivec2 final = ivec2(floor(vec2(offset + pos) * scale));
ivec2 final = ivec2(floor(vec2(offset + pos) * vec2(scale)));
o_col0 = texelFetch(samp0, final, 0);
}
#endif

View File

@@ -0,0 +1,39 @@
#ifdef VERTEX_SHADER
layout(location = 0) in vec2 Position;
layout(location = 1) in vec2 UV;
layout(location = 2) in vec4 Color;
layout(push_constant) uniform PushConstants
{
vec2 uScale;
vec2 uTranslate;
};
layout(location = 0) out vec2 Frag_UV;
layout(location = 1) out vec4 Frag_Color;
void vs_main()
{
Frag_UV = UV;
Frag_Color = Color;
gl_Position = vec4(Position * uScale + uTranslate, 0.0f, 1.0f);
}
#endif
#ifdef FRAGMENT_SHADER
layout(binding = 0) uniform sampler2D Texture;
layout(location = 0) in vec2 Frag_UV;
layout(location = 1) in vec4 Frag_Color;
layout(location = 0) out vec4 Out_Color;
void ps_main()
{
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
}
#endif

View File

@@ -35,7 +35,7 @@ void ps_main0()
const int vpos = int(gl_FragCoord.y); // vertical position of destination texture
if ((vpos & 1) == field)
o_col0 = texture(samp0, v_tex);
o_col0 = textureLod(samp0, v_tex, 0);
else
discard;
}
@@ -46,7 +46,7 @@ void ps_main0()
#ifdef ps_main1
void ps_main1()
{
o_col0 = texture(samp0, v_tex);
o_col0 = textureLod(samp0, v_tex, 0);
}
#endif
@@ -56,9 +56,9 @@ void ps_main1()
void ps_main2()
{
vec2 vstep = vec2(0.0f, ZrH.y);
vec4 c0 = texture(samp0, v_tex - vstep);
vec4 c1 = texture(samp0, v_tex);
vec4 c2 = texture(samp0, v_tex + vstep);
vec4 c0 = textureLod(samp0, v_tex - vstep, 0);
vec4 c1 = textureLod(samp0, v_tex, 0);
vec4 c2 = textureLod(samp0, v_tex + vstep, 0);
o_col0 = (c0 + c1 * 2.0f + c2) / 4.0f;
}
@@ -82,15 +82,11 @@ void ps_main3()
const int vres = int(ZrH.z) >> 1; // vertical resolution of source texture
const int lofs = ((((vres + 1) >> 1) << 1) - vres) & bank; // line alignment offset for bank 1
const int vpos = int(gl_FragCoord.y) + lofs; // vertical position of destination texture
const vec2 bofs = vec2(0.0f, 0.5f * bank); // vertical offset of the current bank relative to source texture size
const vec2 vscale = vec2(1.0f, 2.0f); // scaling factor from source to destination texture
const vec2 optr = v_tex - bofs; // used to check if the current destination line is within the current bank
const vec2 iptr = optr * vscale; // pointer to the current pixel in the source texture
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
o_col0 = texture(samp0, iptr);
if ((vpos & 1) == field)
o_col0 = textureLod(samp0, v_tex, 0);
else
discard;
}
@@ -150,13 +146,13 @@ void ps_main4()
// calculating motion, only relevant for missing lines where the "center line" is pointed by p_t1
vec4 hn = texture(samp0, p_t0 - lofs); // new high pixel
vec4 cn = texture(samp0, p_t1); // new center pixel
vec4 ln = texture(samp0, p_t0 + lofs); // new low pixel
vec4 hn = textureLod(samp0, p_t0 - lofs, 0); // new high pixel
vec4 cn = textureLod(samp0, p_t1, 0); // new center pixel
vec4 ln = textureLod(samp0, p_t0 + lofs, 0); // new low pixel
vec4 ho = texture(samp0, p_t2 - lofs); // old high pixel
vec4 co = texture(samp0, p_t3); // old center pixel
vec4 lo = texture(samp0, p_t2 + lofs); // old low pixel
vec4 ho = textureLod(samp0, p_t2 - lofs, 0); // old high pixel
vec4 co = textureLod(samp0, p_t3, 0); // old center pixel
vec4 lo = textureLod(samp0, p_t2 + lofs, 0); // old low pixel
vec3 mh = hn.rgb - ho.rgb; // high pixel motion
vec3 mc = cn.rgb - co.rgb; // center pixel motion
@@ -181,7 +177,7 @@ void ps_main4()
if ((vpos & 1) == field) // output coordinate present on current field
{
// output coordinate present on current field
o_col0 = texture(samp0, p_t0);
o_col0 = textureLod(samp0, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{

View File

@@ -26,7 +26,6 @@ layout(push_constant) uniform cb10
vec2 u_source_resolution;
vec2 u_rcp_source_resolution; // 1 / u_source_resolution
float u_time;
vec3 cb0_pad0;
};
layout(location = 0) in vec2 v_tex;

File diff suppressed because it is too large Load Diff

View File

@@ -1,113 +0,0 @@
set(wx_sdl_c_code "
#include <wx/setup.h>
#if (wxUSE_LIBSDL == 0)
#error cmake_WX_SDL
#endif
int main()
{
return 0;
}
")
set(gcc7_mmx_code "
#include <stdio.h>
#include <stdint.h>
#include <xmmintrin.h>
#include <emmintrin.h>
class alignas(16) GSVector4i
{
public:
__m128i m;
explicit GSVector4i(__m128i m)
{
this->m = m;
}
static void storel(void* p, const GSVector4i& v)
{
_mm_storel_epi64((__m128i*)p, v.m);
}
static GSVector4i loadl(const void* p)
{
return GSVector4i(_mm_loadl_epi64((__m128i*)p));
}
bool eq(const GSVector4i& v) const
{
return _mm_movemask_epi8(_mm_cmpeq_epi32(m, v.m)) == 0xffff;
}
};
union GIFRegTRXPOS
{
unsigned long long u64;
void operator = (const GSVector4i& v) {GSVector4i::storel(this, v);}
bool operator != (const union GIFRegTRXPOS& r) const {return !((GSVector4i)r).eq(*this);}
operator GSVector4i() const {return GSVector4i::loadl(this);}
};
extern GIFRegTRXPOS TRXPOS;
GIFRegTRXPOS TRXPOS = {};
void GIFRegHandlerTRXPOS(const GIFRegTRXPOS& p)
{
if(p != TRXPOS)
{
printf(\"foo\");
}
TRXPOS = (GSVector4i)p;
}
int main()
{
GIFRegTRXPOS r = {};
GIFRegHandlerTRXPOS(r);
uint16_t fpu[16] = {0};
__asm__ __volatile__(\"fstenv %0\" : \"=m\"(fpu));
bool ok = fpu[4] == 0xFFFF;
if (!ok) {
printf(\"Wrong MMX state !\");
exit(1);
}
return 0;
}
")
function(GCC7_BUG)
# try_run doesn't work when cross-compiling is enabled. It is completely silly in our case
# as i386 binaries are 100% fine on x64.
set(OLD_CMAKE_CROSSCOMPILING ${CMAKE_CROSSCOMPILING})
set(CMAKE_CROSSCOMPILING 0)
set(IN "${CMAKE_BINARY_DIR}/gcc7_mmx.cpp")
file(WRITE "${IN}" "${gcc7_mmx_code}")
enable_language(CXX)
try_run(
run_result
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${IN}"
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=-msse -msse2 -O2 -m32 -march=i686"
)
if (${run_result})
message(FATAL_ERROR "GCC 7.0/7.1 generates invalid code => https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80799\n"
"You can either backport the fix or swith to another version of GCC.")
endif()
set(CMAKE_CROSSCOMPILING ${OLD_CMAKE_CROSSCOMPILING})
endfunction()

View File

@@ -7,6 +7,7 @@ set(PCSX2_DEFS "")
option(DISABLE_BUILD_DATE "Disable including the binary compile date")
option(ENABLE_TESTS "Enables building the unit tests" ON)
set(USE_SYSTEM_LIBS "AUTO" CACHE STRING "Use system libraries instead of bundled libraries. ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled. Default is AUTO")
set(DEFAULT_USE_SYSTEM_RYML OFF) # System rapidyaml causes a lot of problems
optional_system_library(fmt)
optional_system_library(ryml)
optional_system_library(zstd)
@@ -34,6 +35,8 @@ if(UNIX AND NOT APPLE)
option(USE_LEGACY_USER_DIRECTORY "Use legacy home/PCSX2 user directory instead of XDG standard" OFF)
option(X11_API "Enable X11 support" ON)
option(WAYLAND_API "Enable Wayland support" ON)
option(DBUS_API "Enable DBus support for screensaver inhibiting" ON)
option(USE_LINKED_FFMPEG "Links with ffmpeg instead of using dynamic loading" OFF)
endif()
if(APPLE)
@@ -46,12 +49,12 @@ endif()
#-------------------------------------------------------------------------------
option(USE_ASAN "Enable address sanitizer")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(USE_CLANG_CL TRUE)
message(STATUS "Building with Clang-CL.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
set(USE_CLANG TRUE)
message(STATUS "Building with Clang/LLVM.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(USE_ICC TRUE)
message(STATUS "Building with Intel's ICC.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(USE_GCC TRUE)
message(STATUS "Building with GNU GCC")
@@ -103,33 +106,23 @@ include(TargetArch)
target_architecture(PCSX2_TARGET_ARCHITECTURES)
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
message(STATUS "Compiling a ${PCSX2_TARGET_ARCHITECTURES} build on a ${CMAKE_HOST_SYSTEM_PROCESSOR} host.")
else()
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
endif()
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
# x86_64 requires -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(NOT DEFINED ARCH_FLAG AND NOT MSVC)
if (DISABLE_ADVANCE_SIMD)
if (USE_ICC)
set(ARCH_FLAG "-msse2 -msse4.1")
else()
set(ARCH_FLAG "-msse -msse2 -msse4.1 -mfxsr")
endif()
set(ARCH_FLAG "-msse -msse2 -msse4.1 -mfxsr")
else()
#set(ARCH_FLAG "-march=native -fabi-version=6")
set(ARCH_FLAG "-march=native")
endif()
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()
# All but i386 requires -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
endif()
string(REPLACE " " ";" ARCH_FLAG_LIST "${ARCH_FLAG}")
@@ -143,13 +136,16 @@ 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)
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>")
else()
if(MSVC AND NOT USE_CLANG_CL)
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>>)
@@ -164,6 +160,12 @@ if(WIN32)
list(APPEND PCSX2_DEFS TIXML_USE_STL _SCL_SECURE_NO_WARNINGS _UNICODE UNICODE)
endif()
# Enable debug information in release builds for Linux.
# Makes the backtrace actually meaningful.
if(UNIX AND NOT APPLE)
add_compile_options($<$<CONFIG:Release>:-g1>)
endif()
if(MSVC)
# Enable PDB generation in release builds
add_compile_options(
@@ -209,24 +211,13 @@ endif()
if (MSVC)
set(DEFAULT_WARNINGS)
else()
set(DEFAULT_WARNINGS -Wall -Wextra -Wno-attributes -Wno-unused-function -Wno-unused-parameter -Wno-missing-field-initializers -Wno-format -Wno-format-security)
if (NOT USE_ICC)
list(APPEND DEFAULT_WARNINGS -Wno-unused-value)
endif()
set(DEFAULT_WARNINGS -Wall -Wextra -Wno-attributes -Wno-unused-function -Wno-unused-parameter -Wno-missing-field-initializers -Wno-format -Wno-format-security -Wno-unused-value)
endif()
if (USE_GCC)
list(APPEND DEFAULT_WARNINGS -Wno-stringop-truncation -Wno-stringop-overflow -Wno-maybe-uninitialized )
endif()
# -Wstrict-aliasing=n: to fix one day aliasing issue. n=1/2/3
if (USE_ICC)
set(AGGRESSIVE_WARNING -Wstrict-aliasing)
elseif(NOT MSVC)
set(AGGRESSIVE_WARNING -Wstrict-aliasing -Wstrict-overflow=1)
endif()
if (USE_PGO_GENERATE OR USE_PGO_OPTIMIZE)
add_compile_options("-fprofile-dir=${CMAKE_SOURCE_DIR}/profile")
endif()
@@ -253,7 +244,7 @@ if(USE_CLANG AND TIMETRACE)
add_compile_options(-ftime-trace)
endif()
set(PCSX2_WARNINGS ${DEFAULT_WARNINGS} ${AGGRESSIVE_WARNING})
set(PCSX2_WARNINGS ${DEFAULT_WARNINGS})
if(DISABLE_BUILD_DATE)
message(STATUS "Disabling the inclusion of the binary compile date.")

View File

@@ -0,0 +1,31 @@
# - Try to find libbacktrace
# Once done this will define
# LIBBACKTRACE_FOUND - System has libbacktrace
# LIBBACKTRACE_INCLUDE_DIRS - The libbacktrace include directories
# LIBBACKTRACE_LIBRARIES - The libraries needed to use libbacktrace
FIND_PATH(
LIBBACKTRACE_INCLUDE_DIR backtrace.h
HINTS /usr/include /usr/local/include
${LIBBACKTRACE_PATH_INCLUDES}
)
FIND_LIBRARY(
LIBBACKTRACE_LIBRARY
NAMES backtrace
PATHS ${ADDITIONAL_LIBRARY_PATHS} ${LIBBACKTRACE_PATH_LIB}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libbacktrace DEFAULT_MSG
LIBBACKTRACE_LIBRARY LIBBACKTRACE_INCLUDE_DIR)
if(LIBBACKTRACE_FOUND)
add_library(libbacktrace::libbacktrace UNKNOWN IMPORTED)
set_target_properties(libbacktrace::libbacktrace PROPERTIES
IMPORTED_LOCATION ${LIBBACKTRACE_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${LIBBACKTRACE_INCLUDE_DIR}
)
endif()
mark_as_advanced(LIBBACKTRACE_INCLUDE_DIR LIBBACKTRACE_LIBRARY)

View File

@@ -5,28 +5,21 @@
# VTUNE_INCLUDE_DIRS include path to jitprofiling.h
# VTUNE_LIBRARIES path to vtune libs
find_path(VTUNE_INCLUDE_DIRS NAMES jitprofiling.h PATHS
/opt/intel/oneapi/vtune/latest/include
/opt/intel/vtune_amplifier_xe_2018/include
/opt/intel/vtune_amplifier_xe_2017/include
/opt/intel/vtune_amplifier_xe_2016/include
set(VTUNE_PATHS
/opt/intel/oneapi/vtune/latest
/opt/intel/vtune_amplifier_xe_2018
/opt/intel/vtune_amplifier_xe_2017
/opt/intel/vtune_amplifier_xe_2016
"C:\\Program Files (x86)\\Intel\\oneAPI\\vtune\\latest"
)
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
find_library(VTUNE_LIBRARIES NAMES libjitprofiling.a PATHS
/opt/intel/oneapi/vtune/latest/lib32
/opt/intel/vtune_amplifier_xe_2018/lib32
/opt/intel/vtune_amplifier_xe_2017/lib32
/opt/intel/vtune_amplifier_xe_2016/lib32
)
else()
find_library(VTUNE_LIBRARIES NAMES libjitprofiling.a PATHS
/opt/intel/oneapi/vtune/latest/lib64
/opt/intel/vtune_amplifier_xe_2018/lib64
/opt/intel/vtune_amplifier_xe_2017/lib64
/opt/intel/vtune_amplifier_xe_2016/lib64
)
endif()
find_path(VTUNE_INCLUDE_DIRS NAMES jitprofiling.h PATHS ${VTUNE_PATHS} PATH_SUFFIXES include)
find_library(VTUNE_LIBRARIES
NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}jitprofiling${CMAKE_STATIC_LIBRARY_SUFFIX}
PATHS ${VTUNE_PATHS}
PATH_SUFFIXES lib64
)
# handle the QUIETLY and REQUIRED arguments and set VTUNE_FOUND to TRUE if
# all listed variables are TRUE
@@ -41,4 +34,3 @@ if(VTUNE_LIBRARIES AND NOT TARGET Vtune::Vtune)
endif()
mark_as_advanced(VTUNE_FOUND VTUNE_INCLUDE_DIRS VTUNE_LIBRARIES)

View File

@@ -10,8 +10,9 @@ function(detectOperatingSystem)
if(WIN32)
set(Windows TRUE PARENT_SCOPE)
elseif(UNIX AND APPLE)
# No easy way to filter out iOS.
message(WARNING "OS X/iOS isn't supported, the build will most likely fail")
if(IOS)
message(WARNING "iOS isn't supported, the build will most likely fail")
endif()
set(MacOSX TRUE PARENT_SCOPE)
elseif(UNIX)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -198,9 +199,18 @@ endfunction()
function(optional_system_library library)
string(TOUPPER ${library} upperlib)
set(USE_SYSTEM_${upperlib} "" CACHE STRING "Use system ${library} instead of bundled. ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled, blank - Delegate to USE_SYSTEM_LIBS. Default is blank.")
if (DEFINED DEFAULT_USE_SYSTEM_${upperlib})
set(extra " with extra override to ${DEFAULT_USE_SYSTEM_${upperlib}} on fully default builds")
else()
set(extra)
endif()
set(USE_SYSTEM_${upperlib} "" CACHE STRING "Use system ${library} instead of bundled. ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled, blank - Delegate to USE_SYSTEM_LIBS${extra}. Default is blank.")
if ("${USE_SYSTEM_${upperlib}}" STREQUAL "")
set(RESOLVED_USE_SYSTEM_${upperlib} ${USE_SYSTEM_LIBS} PARENT_SCOPE)
if(${USE_SYSTEM_LIBS} STREQUAL "AUTO" AND DEFINED DEFAULT_USE_SYSTEM_${upperlib})
set(RESOLVED_USE_SYSTEM_${upperlib} ${DEFAULT_USE_SYSTEM_${upperlib}} PARENT_SCOPE)
else()
set(RESOLVED_USE_SYSTEM_${upperlib} ${USE_SYSTEM_LIBS} PARENT_SCOPE)
endif()
else()
set(RESOLVED_USE_SYSTEM_${upperlib} ${USE_SYSTEM_${upperlib}} PARENT_SCOPE)
endif()

View File

@@ -14,6 +14,7 @@ if (WIN32)
add_subdirectory(3rdparty/xz EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/D3D12MemAlloc EXCLUDE_FROM_ALL)
set(FFMPEG_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/3rdparty/ffmpeg/include")
find_package(Vtune)
else()
find_package(PCAP REQUIRED)
find_package(LibLZMA REQUIRED)
@@ -86,6 +87,8 @@ else()
if(WAYLAND_API)
find_package(Wayland REQUIRED)
endif()
find_package(Libbacktrace)
endif()
endif(WIN32)
@@ -100,18 +103,7 @@ if(ENABLE_TESTS)
endif()
endif()
#----------------------------------------
# Check correctness of the parameter
# Note: wxWidgets_INCLUDE_DIRS must be defined
#----------------------------------------
include(ApiValidation)
# Blacklist bad GCC
if(GCC_VERSION VERSION_EQUAL "7.0" OR GCC_VERSION VERSION_EQUAL "7.1")
GCC7_BUG()
endif()
if((GCC_VERSION VERSION_EQUAL "9.0" OR GCC_VERSION VERSION_GREATER "9.0") AND GCC_VERSION LESS "9.2")
if(GCC_VERSION VERSION_GREATER_EQUAL "9.0" AND GCC_VERSION VERSION_LESS "9.2")
message(WARNING "
It looks like you are compiling with 9.0.x or 9.1.x. Using these versions is not recommended,
as there is a bug known to cause the compiler to segfault while compiling. See patch
@@ -132,7 +124,7 @@ find_optional_system_library(libzip 3rdparty/libzip 1.8.0)
if(QT_BUILD)
# Default to bundled Qt6 for Windows.
if(WIN32 AND NOT DEFINED Qt6_DIR)
set(Qt6_DIR ${CMAKE_SOURCE_DIR}/3rdparty/qt/6.4.0/msvc2022_64/lib/cmake/Qt6)
set(Qt6_DIR ${CMAKE_SOURCE_DIR}/3rdparty/qt/6.5.0/msvc2022_64/lib/cmake/Qt6)
endif()
# Find the Qt components that we need.
@@ -152,6 +144,9 @@ if(QT_BUILD)
# rcheevos backend for RetroAchievements.
if(USE_ACHIEVEMENTS)
add_subdirectory(3rdparty/rcheevos EXCLUDE_FROM_ALL)
if(WIN32)
add_subdirectory(3rdparty/rainterface EXCLUDE_FROM_ALL)
endif()
endif()
# Discord-RPC library for rich presence.

56
common/ByteSwap.h Normal file
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
}
}

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
@@ -126,52 +127,9 @@ target_sources(common PRIVATE
emitter/tools.h
emitter/x86emitter.h
emitter/x86types.h
Darwin/DarwinMisc.h
)
if(USE_OPENGL)
target_sources(common PRIVATE
GL/Context.cpp
GL/Program.cpp
GL/ShaderCache.cpp
GL/StreamBuffer.cpp
)
target_sources(common PRIVATE
GL/Context.h
GL/Program.h
GL/ShaderCache.h
GL/StreamBuffer.h
)
target_link_libraries(common PUBLIC glad)
endif()
if(USE_VULKAN)
target_link_libraries(common PUBLIC
Vulkan-Headers glslang
)
target_sources(common PRIVATE
Vulkan/ShaderCache.cpp
Vulkan/Texture.cpp
Vulkan/Loader.cpp
Vulkan/ShaderCompiler.cpp
Vulkan/Util.cpp
Vulkan/SwapChain.cpp
Vulkan/StreamBuffer.cpp
Vulkan/Context.cpp
Vulkan/Builders.cpp
Vulkan/vk_mem_alloc.cpp
Vulkan/Context.h
Vulkan/Texture.h
Vulkan/ShaderCompiler.h
Vulkan/SwapChain.h
Vulkan/Builders.h
Vulkan/StreamBuffer.h
Vulkan/ShaderCache.h
Vulkan/EntryPoints.h
Vulkan/Loader.h
Vulkan/Util.h
)
endif()
if(USE_VTUNE)
target_link_libraries(common PUBLIC Vtune::Vtune)
endif()
@@ -179,7 +137,7 @@ endif()
if(WIN32)
enable_language(ASM_MASM)
target_sources(common PRIVATE FastJmp.asm)
target_link_libraries(common PUBLIC WIL::WIL D3D12MemAlloc winmm)
target_link_libraries(common PUBLIC WIL::WIL winmm)
target_sources(common PRIVATE
CrashHandler.cpp
CrashHandler.h
@@ -188,24 +146,6 @@ if(WIN32)
HTTPDownloaderWinHTTP.h
StackWalker.cpp
StackWalker.h
D3D11/ShaderCache.cpp
D3D11/ShaderCache.h
D3D11/ShaderCompiler.cpp
D3D11/ShaderCompiler.h
D3D12/Builders.cpp
D3D12/Builders.h
D3D12/Context.cpp
D3D12/Context.h
D3D12/DescriptorHeapManager.cpp
D3D12/DescriptorHeapManager.h
D3D12/ShaderCache.cpp
D3D12/ShaderCache.h
D3D12/StreamBuffer.cpp
D3D12/StreamBuffer.h
D3D12/Texture.cpp
D3D12/Texture.h
D3D12/Util.cpp
D3D12/Util.h
)
endif()
@@ -216,62 +156,23 @@ 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(USE_OPENGL)
if(WIN32)
target_sources(common PRIVATE
GL/ContextWGL.cpp
GL/ContextWGL.h
)
target_link_libraries(common PUBLIC opengl32.lib)
elseif(APPLE)
target_sources(common PRIVATE
GL/ContextAGL.mm
GL/ContextAGL.h
)
else()
if(X11_API OR WAYLAND_API)
target_sources(common PRIVATE
GL/ContextEGL.cpp
GL/ContextEGL.h
)
target_link_libraries(common PRIVATE PkgConfig::EGL)
endif()
if(X11_API)
target_sources(common PRIVATE
GL/ContextEGLX11.cpp
GL/ContextEGLX11.h
)
if(TARGET PkgConfig::XRANDR)
target_link_libraries(common PRIVATE PkgConfig::XRANDR)
target_compile_definitions(common PRIVATE "HAS_XRANDR=1")
endif()
endif()
if(WAYLAND_API)
target_sources(common PRIVATE
GL/ContextEGLWayland.cpp
GL/ContextEGLWayland.h
)
endif()
endif()
if(DBUS_API)
target_compile_definitions(common PRIVATE DBUS_API)
find_package(PkgConfig REQUIRED)
pkg_check_modules(DBUS REQUIRED dbus-1)
target_include_directories(common PRIVATE ${DBUS_INCLUDE_DIRS})
target_link_libraries(common PRIVATE ${DBUS_LINK_LIBRARIES})
endif()
if(USE_VULKAN)
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()
if(X11_API AND TARGET PkgConfig::XRANDR)
target_link_libraries(common PRIVATE PkgConfig::XRANDR)
target_compile_definitions(common PRIVATE "HAS_XRANDR=1")
endif()
if (USE_GCC AND CMAKE_INTERPROCEDURAL_OPTIMIZATION)
@@ -288,6 +189,11 @@ if(NOT WIN32 AND (QT_BUILD OR NOGUI_BUILD))
target_link_libraries(common PRIVATE CURL::libcurl)
endif()
if(UNIX AND NOT APPLE AND TARGET libbacktrace::libbacktrace)
target_compile_definitions(common PRIVATE "HAS_LIBBACKTRACE=1")
target_link_libraries(common PRIVATE libbacktrace::libbacktrace)
endif()
target_link_libraries(common PRIVATE
${LIBC_LIBRARIES}
PNG::PNG

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-
@@ -215,6 +215,199 @@ void CrashHandler::Uninstall()
}
}
#elif defined(HAS_LIBBACKTRACE)
#include "FileSystem.h"
#include <backtrace.h>
#include <signal.h>
#include <sys/mman.h>
#include <unistd.h>
#include <cstdarg>
#include <cstdio>
#include <mutex>
namespace CrashHandler
{
struct BacktraceBuffer
{
char* buffer;
size_t used;
size_t size;
};
static const char* GetSignalName(int signal_no);
static void AllocateBuffer(BacktraceBuffer* buf);
static void FreeBuffer(BacktraceBuffer* buf);
static void AppendToBuffer(BacktraceBuffer* buf, const char* format, ...);
static int BacktraceFullCallback(void* data, uintptr_t pc, const char* filename, int lineno, const char* function);
static void CallExistingSignalHandler(int signal, siginfo_t* siginfo, void* ctx);
static void CrashSignalHandler(int signal, siginfo_t* siginfo, void* ctx);
static std::recursive_mutex s_crash_mutex;
static bool s_in_signal_handler = false;
static backtrace_state* s_backtrace_state = nullptr;
static struct sigaction s_old_sigbus_action;
static struct sigaction s_old_sigsegv_action;
}
const char* CrashHandler::GetSignalName(int signal_no)
{
switch (signal_no)
{
// Don't need to list all of them, there's only a couple we register.
// clang-format off
case SIGSEGV: return "SIGSEGV";
case SIGBUS: return "SIGBUS";
default: return "UNKNOWN";
// clang-format on
}
}
void CrashHandler::AllocateBuffer(BacktraceBuffer* buf)
{
buf->used = 0;
buf->size = __pagesize;
buf->buffer = static_cast<char*>(mmap(nullptr, buf->size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
if (buf->buffer == static_cast<char*>(MAP_FAILED))
{
buf->buffer = nullptr;
buf->size = 0;
}
}
void CrashHandler::FreeBuffer(BacktraceBuffer* buf)
{
if (buf->buffer)
munmap(buf->buffer, buf->size);
}
void CrashHandler::AppendToBuffer(BacktraceBuffer* buf, const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
// Hope this doesn't allocate memory... it *can*, but hopefully unlikely since
// it won't be the first call, and we're providing the buffer.
if (buf->size > 0 && buf->used < (buf->size - 1))
{
const int written = std::vsnprintf(buf->buffer + buf->used, buf->size - buf->used, format, ap);
if (written > 0)
buf->used += static_cast<size_t>(written);
}
va_end(ap);
}
int CrashHandler::BacktraceFullCallback(void* data, uintptr_t pc, const char* filename, int lineno, const char* function)
{
BacktraceBuffer* buf = static_cast<BacktraceBuffer*>(data);
AppendToBuffer(buf, " %016p", pc);
if (function)
AppendToBuffer(buf, " %s", function);
if (filename)
AppendToBuffer(buf, " [%s:%d]", filename, lineno);
AppendToBuffer(buf, "\n");
return 0;
}
void CrashHandler::CallExistingSignalHandler(int signal, siginfo_t* siginfo, void* ctx)
{
const struct sigaction& sa = (signal == SIGBUS) ? s_old_sigbus_action : s_old_sigsegv_action;
if (sa.sa_flags & SA_SIGINFO)
{
sa.sa_sigaction(signal, siginfo, ctx);
}
else if (sa.sa_handler == SIG_DFL)
{
// Re-raising the signal would just queue it, and since we'd restore the handler back to us,
// we'd end up right back here again. So just abort, because that's probably what it'd do anyway.
abort();
}
else if (sa.sa_handler != SIG_IGN)
{
sa.sa_handler(signal);
}
}
void CrashHandler::CrashSignalHandler(int signal, siginfo_t* siginfo, void* ctx)
{
std::unique_lock lock(s_crash_mutex);
// If we crash somewhere in libbacktrace, don't bother trying again.
if (!s_in_signal_handler)
{
s_in_signal_handler = true;
#if defined(__APPLE__) && defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext->__ss.__rip);
#elif defined(__FreeBSD__) && defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext.mc_rip);
#elif defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext.gregs[REG_RIP]);
#else
void* const exception_pc = nullptr;
#endif
BacktraceBuffer buf;
AllocateBuffer(&buf);
AppendToBuffer(&buf, "*************** Unhandled %s at %p ***************\n", GetSignalName(signal), exception_pc);
const int rc = backtrace_full(s_backtrace_state, 0, BacktraceFullCallback, nullptr, &buf);
if (rc != 0)
AppendToBuffer(&buf, " backtrace_full() failed: %d\n");
AppendToBuffer(&buf, "*******************************************************************\n");
if (buf.used > 0)
write(STDERR_FILENO, buf.buffer, buf.used);
FreeBuffer(&buf);
s_in_signal_handler = false;
}
// Chances are we're not going to have anything else to call, but just in case.
lock.unlock();
CallExistingSignalHandler(signal, siginfo, ctx);
}
bool CrashHandler::Install()
{
const std::string progpath = FileSystem::GetProgramPath();
s_backtrace_state = backtrace_create_state(progpath.empty() ? nullptr : progpath.c_str(), 0, nullptr, nullptr);
if (!s_backtrace_state)
return false;
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO | SA_NODEFER;
sa.sa_sigaction = CrashSignalHandler;
if (sigaction(SIGBUS, &sa, &s_old_sigbus_action) != 0)
return false;
if (sigaction(SIGSEGV, &sa, &s_old_sigsegv_action) != 0)
return false;
return true;
}
void CrashHandler::SetWriteDirectory(const std::string_view& dump_directory)
{
}
void CrashHandler::WriteDumpForCaller()
{
}
void CrashHandler::Uninstall()
{
// We can't really unchain the signal handlers... so, YOLO.
}
#else
bool CrashHandler::Install()

View File

@@ -1,120 +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 "common/HashCombine.h"
#include "common/RedtapeWindows.h"
#include "common/RedtapeWilCom.h"
#include "common/D3D11/ShaderCompiler.h"
#include <cstdio>
#include <d3d11.h>
#include <string_view>
#include <unordered_map>
#include <vector>
namespace D3D11
{
class ShaderCache
{
public:
ShaderCache();
~ShaderCache();
D3D_FEATURE_LEVEL GetFeatureLevel() const { return m_feature_level; }
bool UsingDebugShaders() const { return m_debug; }
bool Open(std::string_view base_path, D3D_FEATURE_LEVEL feature_level, u32 version, bool debug);
wil::com_ptr_nothrow<ID3DBlob> GetShaderBlob(ShaderCompiler::Type type, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11VertexShader> GetVertexShader(ID3D11Device* device, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
bool GetVertexShaderAndInputLayout(ID3D11Device* device,
ID3D11VertexShader** vs, ID3D11InputLayout** il,
const D3D11_INPUT_ELEMENT_DESC* layout, size_t layout_size,
const std::string_view& shader_code, const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11GeometryShader> GetGeometryShader(ID3D11Device* device, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11PixelShader> GetPixelShader(ID3D11Device* device, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11ComputeShader> GetComputeShader(ID3D11Device* device, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
private:
static constexpr u32 FILE_VERSION = 1;
struct CacheIndexKey
{
u64 source_hash_low;
u64 source_hash_high;
u64 macro_hash_low;
u64 macro_hash_high;
u64 entry_point_low;
u64 entry_point_high;
u32 source_length;
ShaderCompiler::Type shader_type;
bool operator==(const CacheIndexKey& key) const;
bool operator!=(const CacheIndexKey& key) const;
};
struct CacheIndexEntryHasher
{
std::size_t operator()(const CacheIndexKey& e) const noexcept
{
std::size_t h = 0;
HashCombine(h, e.entry_point_low, e.entry_point_high, e.macro_hash_low, e.macro_hash_high,
e.source_hash_low, e.source_hash_high, e.source_length, e.shader_type);
return h;
}
};
struct CacheIndexData
{
u32 file_offset;
u32 blob_size;
};
using CacheIndex = std::unordered_map<CacheIndexKey, CacheIndexData, CacheIndexEntryHasher>;
static std::string GetCacheBaseFileName(const std::string_view& base_path, D3D_FEATURE_LEVEL feature_level,
bool debug);
static CacheIndexKey GetCacheKey(ShaderCompiler::Type type, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros, const char* entry_point);
bool CreateNew(const std::string& index_filename, const std::string& blob_filename);
bool ReadExisting(const std::string& index_filename, const std::string& blob_filename);
void Close();
wil::com_ptr_nothrow<ID3DBlob> CompileAndAddShaderBlob(const CacheIndexKey& key, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros, const char* entry_point);
std::FILE* m_index_file = nullptr;
std::FILE* m_blob_file = nullptr;
CacheIndex m_index;
D3D_FEATURE_LEVEL m_feature_level = D3D_FEATURE_LEVEL_11_0;
u32 m_version = 0;
bool m_debug = false;
};
} // namespace D3D11

View File

@@ -1,215 +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 "common/PrecompiledHeader.h"
#include "common/D3D11/ShaderCompiler.h"
#include "common/Console.h"
#include "common/StringUtil.h"
#include <array>
#include <d3dcompiler.h>
#include <fstream>
static unsigned s_next_bad_shader_id = 1;
wil::com_ptr_nothrow<ID3DBlob> D3D11::ShaderCompiler::CompileShader(Type type, D3D_FEATURE_LEVEL feature_level, bool debug,
const std::string_view& code, const D3D_SHADER_MACRO* macros /* = nullptr */, const char* entry_point /* = "main" */)
{
const char* target;
switch (feature_level)
{
case D3D_FEATURE_LEVEL_10_0:
{
static constexpr std::array<const char*, 4> targets = {{"vs_4_0", "gs_4_0", "ps_4_0", "cs_4_0"}};
target = targets[static_cast<int>(type)];
}
break;
case D3D_FEATURE_LEVEL_10_1:
{
static constexpr std::array<const char*, 4> targets = {{"vs_4_1", "gs_4_1", "ps_4_1", "cs_4_1"}};
target = targets[static_cast<int>(type)];
}
break;
case D3D_FEATURE_LEVEL_11_0:
{
static constexpr std::array<const char*, 4> targets = {{"vs_5_0", "gs_5_0", "ps_5_0", "cs_5_0"}};
target = targets[static_cast<int>(type)];
}
break;
case D3D_FEATURE_LEVEL_11_1:
default:
{
static constexpr std::array<const char*, 4> targets = {{"vs_5_1", "gs_5_1", "ps_5_1", "cs_5_1"}};
target = targets[static_cast<int>(type)];
}
break;
}
static constexpr UINT flags_non_debug = D3DCOMPILE_OPTIMIZATION_LEVEL3;
static constexpr UINT flags_debug = D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_DEBUG;
wil::com_ptr_nothrow<ID3DBlob> blob;
wil::com_ptr_nothrow<ID3DBlob> error_blob;
const HRESULT hr =
D3DCompile(code.data(), code.size(), "0", macros, nullptr, entry_point, target, debug ? flags_debug : flags_non_debug,
0, blob.put(), error_blob.put());
std::string error_string;
if (error_blob)
{
error_string.append(static_cast<const char*>(error_blob->GetBufferPointer()), error_blob->GetBufferSize());
error_blob.reset();
}
if (FAILED(hr))
{
Console.WriteLn("Failed to compile '%s':\n%s", target, error_string.c_str());
std::ofstream ofs(StringUtil::StdStringFromFormat("bad_shader_%u.txt", s_next_bad_shader_id++).c_str(),
std::ofstream::out | std::ofstream::binary);
if (ofs.is_open())
{
ofs << code;
ofs << "\n\nCompile as " << target << " failed: " << hr << "\n";
ofs.write(error_string.c_str(), error_string.size());
ofs.close();
}
return {};
}
if (!error_string.empty())
Console.Warning("'%s' compiled with warnings:\n%s", target, error_string.c_str());
return blob;
}
wil::com_ptr_nothrow<ID3D11VertexShader> D3D11::ShaderCompiler::CompileAndCreateVertexShader(ID3D11Device* device, bool debug,
const std::string_view& code, const D3D_SHADER_MACRO* macros /* = nullptr */, const char* entry_point /* = "main" */)
{
wil::com_ptr_nothrow<ID3DBlob> blob = CompileShader(Type::Vertex, device->GetFeatureLevel(), debug, code, macros, entry_point);
if (!blob)
return {};
return CreateVertexShader(device, blob.get());
}
wil::com_ptr_nothrow<ID3D11GeometryShader> D3D11::ShaderCompiler::CompileAndCreateGeometryShader(ID3D11Device* device, bool debug,
const std::string_view& code, const D3D_SHADER_MACRO* macros /* = nullptr */, const char* entry_point /* = "main" */)
{
wil::com_ptr_nothrow<ID3DBlob> blob = CompileShader(Type::Geometry, device->GetFeatureLevel(), debug, code, macros, entry_point);
if (!blob)
return {};
return CreateGeometryShader(device, blob.get());
}
wil::com_ptr_nothrow<ID3D11PixelShader> D3D11::ShaderCompiler::CompileAndCreatePixelShader(ID3D11Device* device, bool debug,
const std::string_view& code, const D3D_SHADER_MACRO* macros /* = nullptr */, const char* entry_point /* = "main" */)
{
wil::com_ptr_nothrow<ID3DBlob> blob = CompileShader(Type::Pixel, device->GetFeatureLevel(), debug, code, macros, entry_point);
if (!blob)
return {};
return CreatePixelShader(device, blob.get());
}
wil::com_ptr_nothrow<ID3D11ComputeShader> D3D11::ShaderCompiler::CompileAndCreateComputeShader(ID3D11Device* device, bool debug,
const std::string_view& code, const D3D_SHADER_MACRO* macros /* = nullptr */, const char* entry_point /* = "main" */)
{
wil::com_ptr_nothrow<ID3DBlob> blob = CompileShader(Type::Compute, device->GetFeatureLevel(), debug, code, macros, entry_point);
if (!blob)
return {};
return CreateComputeShader(device, blob.get());
}
wil::com_ptr_nothrow<ID3D11VertexShader> D3D11::ShaderCompiler::CreateVertexShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length)
{
wil::com_ptr_nothrow<ID3D11VertexShader> shader;
const HRESULT hr = device->CreateVertexShader(bytecode, bytecode_length, nullptr, shader.put());
if (FAILED(hr))
{
Console.Error("Failed to create vertex shader: 0x%08X", hr);
return {};
}
return shader;
}
wil::com_ptr_nothrow<ID3D11VertexShader> D3D11::ShaderCompiler::CreateVertexShader(ID3D11Device* device, const ID3DBlob* blob)
{
return CreateVertexShader(device, const_cast<ID3DBlob*>(blob)->GetBufferPointer(),
const_cast<ID3DBlob*>(blob)->GetBufferSize());
}
wil::com_ptr_nothrow<ID3D11GeometryShader> D3D11::ShaderCompiler::CreateGeometryShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length)
{
wil::com_ptr_nothrow<ID3D11GeometryShader> shader;
const HRESULT hr = device->CreateGeometryShader(bytecode, bytecode_length, nullptr, shader.put());
if (FAILED(hr))
{
Console.Error("Failed to create geometry shader: 0x%08X", hr);
return {};
}
return shader;
}
wil::com_ptr_nothrow<ID3D11GeometryShader> D3D11::ShaderCompiler::CreateGeometryShader(ID3D11Device* device, const ID3DBlob* blob)
{
return CreateGeometryShader(device, const_cast<ID3DBlob*>(blob)->GetBufferPointer(),
const_cast<ID3DBlob*>(blob)->GetBufferSize());
}
wil::com_ptr_nothrow<ID3D11PixelShader> D3D11::ShaderCompiler::CreatePixelShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length)
{
wil::com_ptr_nothrow<ID3D11PixelShader> shader;
const HRESULT hr = device->CreatePixelShader(bytecode, bytecode_length, nullptr, shader.put());
if (FAILED(hr))
{
Console.Error("Failed to create pixel shader: 0x%08X", hr);
return {};
}
return shader;
}
wil::com_ptr_nothrow<ID3D11PixelShader> D3D11::ShaderCompiler::CreatePixelShader(ID3D11Device* device, const ID3DBlob* blob)
{
return CreatePixelShader(device, const_cast<ID3DBlob*>(blob)->GetBufferPointer(),
const_cast<ID3DBlob*>(blob)->GetBufferSize());
}
wil::com_ptr_nothrow<ID3D11ComputeShader> D3D11::ShaderCompiler::CreateComputeShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length)
{
wil::com_ptr_nothrow<ID3D11ComputeShader> shader;
const HRESULT hr = device->CreateComputeShader(bytecode, bytecode_length, nullptr, shader.put());
if (FAILED(hr))
{
Console.Error("Failed to create compute shader: 0x%08X", hr);
return {};
}
return shader;
}
wil::com_ptr_nothrow<ID3D11ComputeShader> D3D11::ShaderCompiler::CreateComputeShader(ID3D11Device* device, const ID3DBlob* blob)
{
return CreateComputeShader(device, const_cast<ID3DBlob*>(blob)->GetBufferPointer(),
const_cast<ID3DBlob*>(blob)->GetBufferSize());
}

View File

@@ -1,55 +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/RedtapeWindows.h"
#include "common/RedtapeWilCom.h"
#include <d3d11.h>
#include <string_view>
#include <type_traits>
namespace D3D11::ShaderCompiler
{
enum class Type
{
Vertex,
Geometry,
Pixel,
Compute
};
wil::com_ptr_nothrow<ID3DBlob> CompileShader(Type type, D3D_FEATURE_LEVEL feature_level, bool debug, const std::string_view& code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11VertexShader> CompileAndCreateVertexShader(ID3D11Device* device, bool debug, const std::string_view& code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11GeometryShader> CompileAndCreateGeometryShader(ID3D11Device* device, bool debug, const std::string_view& code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11PixelShader> CompileAndCreatePixelShader(ID3D11Device* device, bool debug, const std::string_view& code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11ComputeShader> CompileAndCreateComputeShader(ID3D11Device* device, bool debug, const std::string_view& code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
wil::com_ptr_nothrow<ID3D11VertexShader> CreateVertexShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length);
wil::com_ptr_nothrow<ID3D11VertexShader> CreateVertexShader(ID3D11Device* device, const ID3DBlob* blob);
wil::com_ptr_nothrow<ID3D11GeometryShader> CreateGeometryShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length);
wil::com_ptr_nothrow<ID3D11GeometryShader> CreateGeometryShader(ID3D11Device* device, const ID3DBlob* blob);
wil::com_ptr_nothrow<ID3D11PixelShader> CreatePixelShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length);
wil::com_ptr_nothrow<ID3D11PixelShader> CreatePixelShader(ID3D11Device* device, const ID3DBlob* blob);
wil::com_ptr_nothrow<ID3D11ComputeShader> CreateComputeShader(ID3D11Device* device, const void* bytecode, size_t bytecode_length);
wil::com_ptr_nothrow<ID3D11ComputeShader> CreateComputeShader(ID3D11Device* device, const ID3DBlob* blob);
}; // namespace D3D11::ShaderCompiler

View File

@@ -1,214 +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 "common/RedtapeWindows.h"
#include "common/D3D12/DescriptorHeapManager.h"
#include "common/D3D12/StreamBuffer.h"
#include <array>
#include <d3d12.h>
#include <memory>
#include <vector>
#include <wil/com.h>
struct IDXGIAdapter;
struct IDXGIFactory;
namespace D3D12MA
{
class Allocator;
class Allocation;
} // namespace D3D12MA
namespace D3D12
{
class Context
{
public:
template <typename T>
using ComPtr = wil::com_ptr_nothrow<T>;
enum : u32
{
/// Number of command lists. One is being built while the other(s) are executed.
NUM_COMMAND_LISTS = 3,
/// Textures that don't fit into this buffer will be uploaded with a staging buffer.
TEXTURE_UPLOAD_BUFFER_SIZE = 64 * 1024 * 1024,
/// Maximum number of samples in a single allocation group.
SAMPLER_GROUP_SIZE = 2,
/// Start/End timestamp queries.
NUM_TIMESTAMP_QUERIES_PER_CMDLIST = 2,
};
~Context();
/// Creates new device and context.
static bool Create(IDXGIFactory* dxgi_factory, u32 adapter_index, bool enable_debug_layer);
/// Destroys active context.
static void Destroy();
__fi IDXGIAdapter* GetAdapter() const { return m_adapter.get(); }
__fi ID3D12Device* GetDevice() const { return m_device.get(); }
__fi ID3D12CommandQueue* GetCommandQueue() const { return m_command_queue.get(); }
__fi D3D12MA::Allocator* GetAllocator() const { return m_allocator.get(); }
/// Returns the PCI vendor ID of the device, if known.
u32 GetAdapterVendorID() const;
/// Returns the current command list, commands can be recorded directly.
ID3D12GraphicsCommandList4* GetCommandList() const
{
return m_command_lists[m_current_command_list].command_lists[1].get();
}
/// Returns the init command list for uploading.
ID3D12GraphicsCommandList4* GetInitCommandList();
/// Returns the per-frame SRV/CBV/UAV allocator.
DescriptorAllocator& GetDescriptorAllocator()
{
return m_command_lists[m_current_command_list].descriptor_allocator;
}
/// Returns the per-frame sampler allocator.
GroupedSamplerAllocator<SAMPLER_GROUP_SIZE>& GetSamplerAllocator()
{
return m_command_lists[m_current_command_list].sampler_allocator;
}
/// Invalidates GPU-side sampler caches for all command lists. Call after you've freed samplers,
/// and are going to re-use the handles from GetSamplerHeapManager().
void InvalidateSamplerGroups();
// Descriptor manager access.
DescriptorHeapManager& GetDescriptorHeapManager() { return m_descriptor_heap_manager; }
DescriptorHeapManager& GetRTVHeapManager() { return m_rtv_heap_manager; }
DescriptorHeapManager& GetDSVHeapManager() { return m_dsv_heap_manager; }
DescriptorHeapManager& GetSamplerHeapManager() { return m_sampler_heap_manager; }
const DescriptorHandle& GetNullSRVDescriptor() const { return m_null_srv_descriptor; }
StreamBuffer& GetTextureStreamBuffer() { return m_texture_stream_buffer; }
// Root signature access.
ComPtr<ID3DBlob> SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc);
ComPtr<ID3D12RootSignature> CreateRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc);
/// Fence value for current command list.
u64 GetCurrentFenceValue() const { return m_current_fence_value; }
/// Last "completed" fence.
u64 GetCompletedFenceValue() const { return m_completed_fence_value; }
/// Feature level to use when compiling shaders.
D3D_FEATURE_LEVEL GetFeatureLevel() const { return m_feature_level; }
/// Test for support for the specified texture format.
bool SupportsTextureFormat(DXGI_FORMAT format);
enum class WaitType
{
None, ///< Don't wait (async)
Sleep, ///< Wait normally
Spin, ///< Wait by spinning
};
/// Executes the current command list.
void ExecuteCommandList(WaitType wait_for_completion);
/// Waits for a specific fence.
void WaitForFence(u64 fence, bool spin);
/// Waits for any in-flight command buffers to complete.
void WaitForGPUIdle();
/// Defers destruction of a D3D resource (associates it with the current list).
void DeferObjectDestruction(ID3D12DeviceChild* resource);
/// Defers destruction of a D3D resource (associates it with the current list).
void DeferResourceDestruction(D3D12MA::Allocation* allocation, ID3D12Resource* resource);
/// Defers destruction of a descriptor handle (associates it with the current list).
void DeferDescriptorDestruction(DescriptorHeapManager& manager, u32 index);
void DeferDescriptorDestruction(DescriptorHeapManager& manager, DescriptorHandle* handle);
float GetAndResetAccumulatedGPUTime();
void SetEnableGPUTiming(bool enabled);
private:
struct CommandListResources
{
std::array<ComPtr<ID3D12CommandAllocator>, 2> command_allocators;
std::array<ComPtr<ID3D12GraphicsCommandList4>, 2> command_lists;
DescriptorAllocator descriptor_allocator;
GroupedSamplerAllocator<SAMPLER_GROUP_SIZE> sampler_allocator;
std::vector<std::pair<D3D12MA::Allocation*, ID3D12DeviceChild*>> pending_resources;
std::vector<std::pair<DescriptorHeapManager&, u32>> pending_descriptors;
u64 ready_fence_value = 0;
bool init_command_list_used = false;
bool has_timestamp_query = false;
};
Context();
bool CreateDevice(IDXGIFactory* dxgi_factory, u32 adapter_index, bool enable_debug_layer);
bool CreateCommandQueue();
bool CreateAllocator();
bool CreateFence();
bool CreateDescriptorHeaps();
bool CreateCommandLists();
bool CreateTextureStreamBuffer();
bool CreateTimestampQuery();
void MoveToNextCommandList();
void DestroyPendingResources(CommandListResources& cmdlist);
void DestroyResources();
ComPtr<IDXGIAdapter> m_adapter;
ComPtr<ID3D12Debug> m_debug_interface;
ComPtr<ID3D12Device> m_device;
ComPtr<ID3D12CommandQueue> m_command_queue;
ComPtr<D3D12MA::Allocator> m_allocator;
ComPtr<ID3D12Fence> m_fence;
HANDLE m_fence_event = {};
u32 m_current_fence_value = 0;
u64 m_completed_fence_value = 0;
std::array<CommandListResources, NUM_COMMAND_LISTS> m_command_lists;
u32 m_current_command_list = NUM_COMMAND_LISTS - 1;
ComPtr<ID3D12QueryHeap> m_timestamp_query_heap;
ComPtr<ID3D12Resource> m_timestamp_query_buffer;
ComPtr<D3D12MA::Allocation> m_timestamp_query_allocation;
double m_timestamp_frequency = 0.0;
float m_accumulated_gpu_time = 0.0f;
bool m_gpu_timing_enabled = false;
DescriptorHeapManager m_descriptor_heap_manager;
DescriptorHeapManager m_rtv_heap_manager;
DescriptorHeapManager m_dsv_heap_manager;
DescriptorHeapManager m_sampler_heap_manager;
DescriptorHandle m_null_srv_descriptor;
StreamBuffer m_texture_stream_buffer;
D3D_FEATURE_LEVEL m_feature_level = D3D_FEATURE_LEVEL_11_0;
};
} // namespace D3D12
extern std::unique_ptr<D3D12::Context> g_d3d12_context;

View File

@@ -1,269 +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 "common/HashCombine.h"
#include "common/RedtapeWindows.h"
#include "common/RedtapeWilCom.h"
#include <bitset>
#include <cstring>
#include <d3d12.h>
#include <unordered_map>
#include <vector>
namespace D3D12
{
// This class provides an abstraction for D3D12 descriptor heaps.
struct DescriptorHandle final
{
enum : u32
{
INVALID_INDEX = 0xFFFFFFFF
};
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle{};
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle{};
u32 index = INVALID_INDEX;
__fi operator bool() const { return index != INVALID_INDEX; }
__fi operator D3D12_CPU_DESCRIPTOR_HANDLE() const { return cpu_handle; }
__fi operator D3D12_GPU_DESCRIPTOR_HANDLE() const { return gpu_handle; }
__fi bool operator==(const DescriptorHandle& rhs) const { return (index == rhs.index); }
__fi bool operator!=(const DescriptorHandle& rhs) const { return (index != rhs.index); }
__fi bool operator<(const DescriptorHandle& rhs) const { return (index < rhs.index); }
__fi bool operator<=(const DescriptorHandle& rhs) const { return (index <= rhs.index); }
__fi bool operator>(const DescriptorHandle& rhs) const { return (index > rhs.index); }
__fi bool operator>=(const DescriptorHandle& rhs) const { return (index >= rhs.index); }
__fi void Clear()
{
cpu_handle = {};
gpu_handle = {};
index = INVALID_INDEX;
}
};
class DescriptorHeapManager final
{
public:
DescriptorHeapManager();
~DescriptorHeapManager();
ID3D12DescriptorHeap* GetDescriptorHeap() const { return m_descriptor_heap.get(); }
u32 GetDescriptorIncrementSize() const { return m_descriptor_increment_size; }
bool Create(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE type, u32 num_descriptors, bool shader_visible);
void Destroy();
bool Allocate(DescriptorHandle* handle);
void Free(DescriptorHandle* handle);
void Free(u32 index);
private:
wil::com_ptr_nothrow<ID3D12DescriptorHeap> m_descriptor_heap;
u32 m_num_descriptors = 0;
u32 m_descriptor_increment_size = 0;
bool m_shader_visible = false;
D3D12_CPU_DESCRIPTOR_HANDLE m_heap_base_cpu = {};
D3D12_GPU_DESCRIPTOR_HANDLE m_heap_base_gpu = {};
static constexpr u32 BITSET_SIZE = 1024;
using BitSetType = std::bitset<BITSET_SIZE>;
std::vector<BitSetType> m_free_slots = {};
};
class DescriptorAllocator
{
public:
DescriptorAllocator();
~DescriptorAllocator();
__fi ID3D12DescriptorHeap* GetDescriptorHeap() const { return m_descriptor_heap.get(); }
__fi u32 GetDescriptorIncrementSize() const { return m_descriptor_increment_size; }
bool Create(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE type, u32 num_descriptors);
void Destroy();
bool Allocate(u32 num_handles, DescriptorHandle* out_base_handle);
void Reset();
private:
wil::com_ptr_nothrow<ID3D12DescriptorHeap> m_descriptor_heap;
u32 m_descriptor_increment_size = 0;
u32 m_num_descriptors = 0;
u32 m_current_offset = 0;
D3D12_CPU_DESCRIPTOR_HANDLE m_heap_base_cpu = {};
D3D12_GPU_DESCRIPTOR_HANDLE m_heap_base_gpu = {};
};
template <u32 NumSamplers>
class GroupedSamplerAllocator : private DescriptorAllocator
{
struct Key
{
u32 idx[NumSamplers];
__fi bool operator==(const Key& rhs) const
{
return (std::memcmp(idx, rhs.idx, sizeof(idx)) == 0);
}
__fi bool operator!=(const Key& rhs) const
{
return (std::memcmp(idx, rhs.idx, sizeof(idx)) != 0);
}
};
struct KeyHash
{
__fi std::size_t operator()(const Key& key) const
{
size_t seed = 0;
for (u32 key : key.idx)
HashCombine(seed, key);
return seed;
}
};
public:
GroupedSamplerAllocator();
~GroupedSamplerAllocator();
using DescriptorAllocator::GetDescriptorHeap;
using DescriptorAllocator::GetDescriptorIncrementSize;
bool Create(ID3D12Device* device, u32 num_descriptors);
void Destroy();
bool LookupSingle(DescriptorHandle* gpu_handle, const DescriptorHandle& cpu_handle);
bool LookupGroup(DescriptorHandle* gpu_handle, const DescriptorHandle* cpu_handles);
// Clears cache but doesn't reset allocator.
void InvalidateCache();
void Reset();
bool ShouldReset() const;
private:
wil::com_ptr_nothrow<ID3D12Device> m_device;
std::unordered_map<Key, D3D12::DescriptorHandle, KeyHash> m_groups;
};
template <u32 NumSamplers>
GroupedSamplerAllocator<NumSamplers>::GroupedSamplerAllocator() = default;
template <u32 NumSamplers>
GroupedSamplerAllocator<NumSamplers>::~GroupedSamplerAllocator() = default;
template <u32 NumSamplers>
bool GroupedSamplerAllocator<NumSamplers>::Create(ID3D12Device* device, u32 num_descriptors)
{
if (!DescriptorAllocator::Create(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, num_descriptors))
return false;
m_device = device;
return true;
}
template <u32 NumSamplers>
void GroupedSamplerAllocator<NumSamplers>::Destroy()
{
DescriptorAllocator::Destroy();
m_device.reset();
}
template <u32 NumSamplers>
void GroupedSamplerAllocator<NumSamplers>::Reset()
{
m_groups.clear();
DescriptorAllocator::Reset();
}
template <u32 NumSamplers>
void GroupedSamplerAllocator<NumSamplers>::InvalidateCache()
{
m_groups.clear();
}
template <u32 NumSamplers>
bool GroupedSamplerAllocator<NumSamplers>::LookupSingle(DescriptorHandle* gpu_handle, const DescriptorHandle& cpu_handle)
{
Key key;
key.idx[0] = cpu_handle.index;
for (u32 i = 1; i < NumSamplers; i++)
key.idx[i] = 0;
auto it = m_groups.find(key);
if (it != m_groups.end())
{
*gpu_handle = it->second;
return true;
}
if (!Allocate(1, gpu_handle))
return false;
m_device->CopyDescriptorsSimple(1, *gpu_handle, cpu_handle, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
m_groups.emplace(key, *gpu_handle);
return true;
}
template <u32 NumSamplers>
bool GroupedSamplerAllocator<NumSamplers>::LookupGroup(DescriptorHandle* gpu_handle, const DescriptorHandle* cpu_handles)
{
Key key;
for (u32 i = 0; i < NumSamplers; i++)
key.idx[i] = cpu_handles[i].index;
auto it = m_groups.find(key);
if (it != m_groups.end())
{
*gpu_handle = it->second;
return true;
}
if (!Allocate(NumSamplers, gpu_handle))
return false;
D3D12_CPU_DESCRIPTOR_HANDLE dst_handle = *gpu_handle;
UINT dst_size = NumSamplers;
D3D12_CPU_DESCRIPTOR_HANDLE src_handles[NumSamplers];
UINT src_sizes[NumSamplers];
for (u32 i = 0; i < NumSamplers; i++)
{
src_handles[i] = cpu_handles[i];
src_sizes[i] = 1;
}
m_device->CopyDescriptors(1, &dst_handle, &dst_size, NumSamplers, src_handles, src_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
m_groups.emplace(key, *gpu_handle);
return true;
}
template <u32 NumSamplers>
bool GroupedSamplerAllocator<NumSamplers>::ShouldReset() const
{
// We only reset the sampler heap if more than half of the descriptors are used.
// This saves descriptor copying when there isn't a large number of sampler configs per frame.
return m_groups.size() >= (D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE / 2);
}
} // namespace D3D12

View File

@@ -1,156 +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 "common/HashCombine.h"
#include "common/RedtapeWindows.h"
#include "common/RedtapeWilCom.h"
#include <cstdio>
#include <d3d12.h>
#include <string_view>
#include <unordered_map>
#include <vector>
namespace D3D12
{
class ShaderCache
{
public:
template <typename T>
using ComPtr = wil::com_ptr_nothrow<T>;
enum class EntryType
{
VertexShader,
GeometryShader,
PixelShader,
ComputeShader,
GraphicsPipeline,
ComputePipeline,
};
ShaderCache();
~ShaderCache();
__fi D3D_FEATURE_LEVEL GetFeatureLevel() const { return m_feature_level; }
__fi u32 GetDataVersion() const { return m_data_version; }
__fi bool UsingDebugShaders() const { return m_debug; }
bool Open(std::string_view base_path, D3D_FEATURE_LEVEL feature_level, u32 version, bool debug);
__fi ComPtr<ID3DBlob> GetVertexShader(std::string_view shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main")
{
return GetShaderBlob(EntryType::VertexShader, shader_code, macros, entry_point);
}
__fi ComPtr<ID3DBlob> GetGeometryShader(std::string_view shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main")
{
return GetShaderBlob(EntryType::GeometryShader, shader_code, macros, entry_point);
}
__fi ComPtr<ID3DBlob> GetPixelShader(std::string_view shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main")
{
return GetShaderBlob(EntryType::PixelShader, shader_code, macros, entry_point);
}
__fi ComPtr<ID3DBlob> GetComputeShader(std::string_view shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main")
{
return GetShaderBlob(EntryType::ComputeShader, shader_code, macros, entry_point);
}
ComPtr<ID3DBlob> GetShaderBlob(EntryType type, std::string_view shader_code,
const D3D_SHADER_MACRO* macros = nullptr, const char* entry_point = "main");
ComPtr<ID3D12PipelineState> GetPipelineState(ID3D12Device* device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& desc);
ComPtr<ID3D12PipelineState> GetPipelineState(ID3D12Device* device, const D3D12_COMPUTE_PIPELINE_STATE_DESC& desc);
private:
static constexpr u32 FILE_VERSION = 1;
struct CacheIndexKey
{
u64 source_hash_low;
u64 source_hash_high;
u64 macro_hash_low;
u64 macro_hash_high;
u64 entry_point_low;
u64 entry_point_high;
u32 source_length;
EntryType type;
bool operator==(const CacheIndexKey& key) const;
bool operator!=(const CacheIndexKey& key) const;
};
struct CacheIndexEntryHasher
{
std::size_t operator()(const CacheIndexKey& e) const noexcept
{
std::size_t h = 0;
HashCombine(h, e.entry_point_low, e.entry_point_high, e.macro_hash_low, e.macro_hash_high,
e.source_hash_low, e.source_hash_high, e.source_length, e.type);
return h;
}
};
struct CacheIndexData
{
u32 file_offset;
u32 blob_size;
};
using CacheIndex = std::unordered_map<CacheIndexKey, CacheIndexData, CacheIndexEntryHasher>;
static std::string GetCacheBaseFileName(const std::string_view& base_path, const std::string_view& type,
D3D_FEATURE_LEVEL feature_level, bool debug);
static CacheIndexKey GetShaderCacheKey(EntryType type, const std::string_view& shader_code,
const D3D_SHADER_MACRO* macros, const char* entry_point);
static CacheIndexKey GetPipelineCacheKey(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& gpdesc);
static CacheIndexKey GetPipelineCacheKey(const D3D12_COMPUTE_PIPELINE_STATE_DESC& gpdesc);
bool CreateNew(const std::string& index_filename, const std::string& blob_filename, std::FILE*& index_file,
std::FILE*& blob_file);
bool ReadExisting(const std::string& index_filename, const std::string& blob_filename, std::FILE*& index_file,
std::FILE*& blob_file, CacheIndex& index);
void InvalidatePipelineCache();
void Close();
ComPtr<ID3DBlob> CompileAndAddShaderBlob(const CacheIndexKey& key, std::string_view shader_code,
const D3D_SHADER_MACRO* macros, const char* entry_point);
ComPtr<ID3D12PipelineState> CompileAndAddPipeline(ID3D12Device* device, const CacheIndexKey& key,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC& gpdesc);
ComPtr<ID3D12PipelineState> CompileAndAddPipeline(ID3D12Device* device, const CacheIndexKey& key,
const D3D12_COMPUTE_PIPELINE_STATE_DESC& gpdesc);
bool AddPipelineToBlob(const CacheIndexKey& key, ID3D12PipelineState* pso);
std::string m_base_path;
std::FILE* m_shader_index_file = nullptr;
std::FILE* m_shader_blob_file = nullptr;
CacheIndex m_shader_index;
std::FILE* m_pipeline_index_file = nullptr;
std::FILE* m_pipeline_blob_file = nullptr;
CacheIndex m_pipeline_index;
D3D_FEATURE_LEVEL m_feature_level = D3D_FEATURE_LEVEL_11_0;
u32 m_data_version = 0;
bool m_debug = false;
};
} // namespace D3D12

View File

@@ -1,77 +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 "common/RedtapeWindows.h"
#include "common/RedtapeWilCom.h"
#include <d3d12.h>
#include <deque>
#include <utility>
namespace D3D12MA
{
class Allocation;
}
namespace D3D12
{
class StreamBuffer
{
public:
StreamBuffer();
~StreamBuffer();
bool Create(u32 size);
__fi bool IsValid() const { return static_cast<bool>(m_buffer); }
__fi ID3D12Resource* GetBuffer() const { return m_buffer.get(); }
__fi D3D12_GPU_VIRTUAL_ADDRESS GetGPUPointer() const { return m_gpu_pointer; }
__fi void* GetHostPointer() const { return m_host_pointer; }
__fi void* GetCurrentHostPointer() const { return m_host_pointer + m_current_offset; }
__fi D3D12_GPU_VIRTUAL_ADDRESS GetCurrentGPUPointer() const { return m_gpu_pointer + m_current_offset; }
__fi u32 GetSize() const { return m_size; }
__fi u32 GetCurrentOffset() const { return m_current_offset; }
__fi u32 GetCurrentSpace() const { return m_current_space; }
bool ReserveMemory(u32 num_bytes, u32 alignment);
void CommitMemory(u32 final_num_bytes);
void Destroy(bool defer = true);
private:
void UpdateCurrentFencePosition();
void UpdateGPUPosition();
// Waits for as many fences as needed to allocate num_bytes bytes from the buffer.
bool WaitForClearSpace(u32 num_bytes);
u32 m_size = 0;
u32 m_current_offset = 0;
u32 m_current_space = 0;
u32 m_current_gpu_position = 0;
wil::com_ptr_nothrow<ID3D12Resource> m_buffer;
wil::com_ptr_nothrow<D3D12MA::Allocation> m_allocation;
D3D12_GPU_VIRTUAL_ADDRESS m_gpu_pointer = {};
u8* m_host_pointer = nullptr;
// List of fences and the corresponding positions in the buffer
std::deque<std::pair<u64, u32>> m_tracked_fences;
};
} // namespace D3D12

View File

@@ -1,506 +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 "common/PrecompiledHeader.h"
#include "common/D3D12/Texture.h"
#include "common/D3D12/Context.h"
#include "common/D3D12/Util.h"
#include "common/Align.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/StringUtil.h"
#include "D3D12MemAlloc.h"
using namespace D3D12;
Texture::Texture() = default;
Texture::Texture(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;
}
Texture::Texture(Texture&& 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;
}
Texture::~Texture()
{
Destroy();
}
Texture& Texture::operator=(Texture&& 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 Texture::GetDesc() const
{
return m_resource->GetDesc();
}
bool Texture::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;
}
DescriptorHandle 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 = Texture::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 = Texture::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 = Texture::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 Texture::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());
DescriptorHandle 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 = Texture::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 = Texture::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 = Texture::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 Texture::Destroy(bool defer /* = true */)
{
if (defer)
{
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_srv_descriptor);
switch (m_write_descriptor_type)
{
case Texture::WriteDescriptorType::RTV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetRTVHeapManager(), &m_write_descriptor);
break;
case Texture::WriteDescriptorType::DSV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDSVHeapManager(), &m_write_descriptor);
break;
case Texture::WriteDescriptorType::UAV:
g_d3d12_context->DeferDescriptorDestruction(g_d3d12_context->GetDescriptorHeapManager(), &m_write_descriptor);
break;
case Texture::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 Texture::WriteDescriptorType::RTV:
g_d3d12_context->GetRTVHeapManager().Free(&m_write_descriptor);
break;
case Texture::WriteDescriptorType::DSV:
g_d3d12_context->GetDSVHeapManager().Free(&m_write_descriptor);
break;
case Texture::WriteDescriptorType::UAV:
g_d3d12_context->GetDescriptorHeapManager().Free(&m_write_descriptor);
break;
case Texture::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 Texture::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RESOURCE_STATES state)
{
if (m_state == state)
return;
ResourceBarrier(cmdlist, m_resource.get(), m_state, state);
m_state = state;
}
void Texture::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* Texture::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 * 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(Context::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 Texture::EndStreamUpdate(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height)
{
const u32 copy_pitch = Common::AlignUpPow2(width * GetTexelSize(m_format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
const u32 upload_size = copy_pitch * height;
StreamBuffer& 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 Texture::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 Texture::LoadData(ID3D12GraphicsCommandList* cmdlist, u32 level, u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch)
{
const u32 texel_size = 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 Texture::CreateSRVDescriptor(ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, DescriptorHandle* 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 Texture::CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, DescriptorHandle* 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 Texture::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, DescriptorHandle* 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 Texture::CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, DescriptorHandle* 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;
}

View File

@@ -1,109 +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 "common/RedtapeWindows.h"
#include "common/D3D12/DescriptorHeapManager.h"
#include <d3d12.h>
#include <wil/com.h>
namespace D3D12MA
{
class Allocation;
}
namespace D3D12
{
class StreamBuffer;
class Texture final
{
public:
template <typename T>
using ComPtr = wil::com_ptr_nothrow<T>;
Texture();
Texture(ID3D12Resource* resource, D3D12_RESOURCE_STATES state);
Texture(Texture&& texture);
Texture(const Texture&) = delete;
~Texture();
__fi ID3D12Resource* GetResource() const { return m_resource.get(); }
__fi D3D12MA::Allocation* GetAllocation() const { return m_allocation.get(); }
__fi const DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
__fi const DescriptorHandle& 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;
Texture& operator=(const Texture&) = delete;
Texture& operator=(Texture&& 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, DescriptorHandle* dh);
static bool CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, DescriptorHandle* dh);
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, DescriptorHandle* dh);
static bool CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, DescriptorHandle* dh);
enum class WriteDescriptorType : u8
{
None,
RTV,
DSV,
UAV
};
ComPtr<ID3D12Resource> m_resource;
ComPtr<D3D12MA::Allocation> m_allocation;
DescriptorHandle m_srv_descriptor = {};
DescriptorHandle 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;
};
} // namespace D3D12

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/>.
*/
#include "common/PrecompiledHeader.h"
#include "common/D3D12/Util.h"
#include "common/Assertions.h"
#include "common/StringUtil.h"
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;
}
}
void D3D12::SetDefaultSampler(D3D12_SAMPLER_DESC* desc)
{
desc->Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
desc->AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
desc->AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
desc->AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
desc->MipLODBias = 0;
desc->MaxAnisotropy = 1;
desc->ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
desc->BorderColor[0] = 1.0f;
desc->BorderColor[1] = 1.0f;
desc->BorderColor[2] = 1.0f;
desc->BorderColor[3] = 1.0f;
desc->MinLOD = -3.402823466e+38F; // -FLT_MAX
desc->MaxLOD = 3.402823466e+38F; // FLT_MAX
}
#ifdef _DEBUG
void D3D12::SetObjectName(ID3D12Object* object, const char* name)
{
object->SetName(StringUtil::UTF8StringToWideString(name).c_str());
}
void D3D12::SetObjectNameFormatted(ID3D12Object* object, const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
SetObjectName(object, StringUtil::StdStringFromFormatV(format, ap).c_str());
va_end(ap);
}
#endif

View File

@@ -1,77 +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 "common/RedtapeWindows.h"
#include <array>
#include <d3d12.h>
namespace D3D12
{
static inline void ResourceBarrier(ID3D12GraphicsCommandList* cmdlist, ID3D12Resource* resource,
D3D12_RESOURCE_STATES from_state, D3D12_RESOURCE_STATES to_state)
{
const D3D12_RESOURCE_BARRIER barrier = {D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{resource, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, from_state, to_state}}};
cmdlist->ResourceBarrier(1, &barrier);
}
static inline void SetViewport(ID3D12GraphicsCommandList* cmdlist, int x, int y, int width, int height,
float min_depth = 0.0f, float max_depth = 1.0f)
{
const D3D12_VIEWPORT vp{static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(width),
static_cast<float>(height),
min_depth,
max_depth};
cmdlist->RSSetViewports(1, &vp);
}
static inline void SetScissor(ID3D12GraphicsCommandList* cmdlist, int x, int y, int width, int height)
{
const D3D12_RECT r{x, y, x + width, y + height};
cmdlist->RSSetScissorRects(1, &r);
}
static inline void SetViewportAndScissor(ID3D12GraphicsCommandList* cmdlist, int x, int y, int width, int height,
float min_depth = 0.0f, float max_depth = 1.0f)
{
SetViewport(cmdlist, x, y, width, height, min_depth, max_depth);
SetScissor(cmdlist, x, y, width, height);
}
u32 GetTexelSize(DXGI_FORMAT format);
void SetDefaultSampler(D3D12_SAMPLER_DESC* desc);
#ifdef _DEBUG
void SetObjectName(ID3D12Object* object, const char* name);
void SetObjectNameFormatted(ID3D12Object* object, const char* format, ...);
#else
static inline void SetObjectName(ID3D12Object* object, const char* name)
{
}
static inline void SetObjectNameFormatted(ID3D12Object* object, const char* format, ...) {}
#endif
} // namespace D3D12

View File

@@ -15,8 +15,11 @@
#if defined(__APPLE__)
#include "common/Darwin/DarwinMisc.h"
#include <cstring>
#include <cstdlib>
#include <optional>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <time.h>
@@ -24,6 +27,7 @@
#include <IOKit/pwr_mgt/IOPMLib.h>
#include "common/Pcsx2Types.h"
#include "common/Console.h"
#include "common/General.h"
#include "common/Threading.h"
#include "common/WindowInfo.h"
@@ -89,6 +93,20 @@ static std::string sysctl_str(int category, int name)
return std::string(buf, len > 0 ? len - 1 : 0);
}
static std::optional<u32> sysctlbyname_u32(const char* name)
{
u32 output;
size_t output_size = sizeof(output);
if (0 != sysctlbyname(name, &output, &output_size, nullptr, 0))
return std::nullopt;
if (output_size != sizeof(output))
{
DevCon.WriteLn("(DarwinMisc) sysctl %s gave unexpected size %zd", name, output_size);
return std::nullopt;
}
return output;
}
std::string GetOSVersionString()
{
std::string type = sysctl_str(CTL_KERN, KERN_OSTYPE);
@@ -135,4 +153,46 @@ void Threading::SleepUntil(u64 ticks)
nanosleep(&ts, nullptr);
}
std::vector<DarwinMisc::CPUClass> DarwinMisc::GetCPUClasses()
{
std::vector<CPUClass> out;
if (std::optional<u32> nperflevels = sysctlbyname_u32("hw.nperflevels"))
{
char name[64];
for (u32 i = 0; i < *nperflevels; i++)
{
snprintf(name, sizeof(name), "hw.perflevel%u.physicalcpu", i);
std::optional<u32> physicalcpu = sysctlbyname_u32(name);
snprintf(name, sizeof(name), "hw.perflevel%u.logicalcpu", i);
std::optional<u32> logicalcpu = sysctlbyname_u32(name);
char levelname[64];
size_t levelname_size = sizeof(levelname);
snprintf(name, sizeof(name), "hw.perflevel%u.name", i);
if (0 != sysctlbyname(name, levelname, &levelname_size, nullptr, 0))
strcpy(levelname, "???");
if (!physicalcpu.has_value() || !logicalcpu.has_value())
{
Console.Warning("(DarwinMisc) Perf level %u is missing data on %s cpus!",
i, !physicalcpu.has_value() ? "physical" : "logical");
continue;
}
out.push_back({levelname, *physicalcpu, *logicalcpu});
}
}
else if (std::optional<u32> physcpu = sysctlbyname_u32("hw.physicalcpu"))
{
out.push_back({"Default", *physcpu, sysctlbyname_u32("hw.logicalcpu").value_or(0)});
}
else
{
Console.Warning("(DarwinMisc) Couldn't get cpu core count!");
}
return out;
}
#endif

View File

@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* 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-
@@ -13,10 +13,24 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "GSDeviceNull.h"
#pragma once
#ifdef __APPLE__
#include <string>
#include <vector>
#include "common/Pcsx2Types.h"
namespace DarwinMisc {
struct CPUClass {
std::string name;
u32 num_physical;
u32 num_logical;
};
std::vector<CPUClass> GetCPUClasses();
GSTexture* GSDeviceNull::CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format)
{
return new GSTextureNull(type, width, height, levels, format);
}
#endif

View File

@@ -1,184 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/PrecompiledHeader.h"
#include "common/Console.h"
#include "common/GL/Context.h"
#include "glad.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#ifdef __APPLE__
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#if defined(_WIN32) && !defined(_M_ARM64)
#include "common/GL/ContextWGL.h"
#elif defined(__APPLE__)
#include "common/GL/ContextAGL.h"
#else
#ifdef X11_API
#include "common/GL/ContextEGLX11.h"
#endif
#ifdef WAYLAND_API
#include "common/GL/ContextEGLWayland.h"
#endif
#endif
namespace GL
{
static bool ShouldPreferESContext()
{
#ifndef _MSC_VER
const char* value = std::getenv("PREFER_GLES_CONTEXT");
return (value && std::strcmp(value, "1") == 0);
#else
char buffer[2] = {};
size_t buffer_size = sizeof(buffer);
getenv_s(&buffer_size, buffer, "PREFER_GLES_CONTEXT");
return (std::strcmp(buffer, "1") == 0);
#endif
}
static void DisableBrokenExtensions(const char* gl_vendor, const char* gl_renderer)
{
if (std::strstr(gl_vendor, "ARM"))
{
// GL_{EXT,OES}_copy_image seem to be implemented on the CPU in the Mali drivers...
Console.Warning("Mali driver detected, disabling GL_{EXT,OES}_copy_image");
GLAD_GL_EXT_copy_image = 0;
GLAD_GL_OES_copy_image = 0;
}
}
Context::Context(const WindowInfo& wi)
: m_wi(wi)
{
}
Context::~Context() = default;
std::vector<Context::FullscreenModeInfo> Context::EnumerateFullscreenModes()
{
return {};
}
std::unique_ptr<GL::Context> Context::Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try)
{
if (ShouldPreferESContext())
{
// move ES versions to the front
Version* new_versions_to_try = static_cast<Version*>(alloca(sizeof(Version) * versions_to_try.size()));
size_t count = 0;
for (size_t i = 0; i < versions_to_try.size(); i++)
{
if (versions_to_try[i].profile == Profile::ES)
new_versions_to_try[count++] = versions_to_try[i];
}
for (size_t i = 0; i < versions_to_try.size(); i++)
{
if (versions_to_try[i].profile != Profile::ES)
new_versions_to_try[count++] = versions_to_try[i];
}
versions_to_try = gsl::span<const Version>(new_versions_to_try, versions_to_try.size());
}
std::unique_ptr<Context> context;
#if defined(_WIN32) && !defined(_M_ARM64)
context = ContextWGL::Create(wi, versions_to_try);
#elif defined(__APPLE__)
context = ContextAGL::Create(wi, versions_to_try);
#endif
#if defined(X11_API)
if (wi.type == WindowInfo::Type::X11)
context = ContextEGLX11::Create(wi, versions_to_try);
#endif
#if defined(WAYLAND_API)
if (wi.type == WindowInfo::Type::Wayland)
context = ContextEGLWayland::Create(wi, versions_to_try);
#endif
if (!context)
return nullptr;
Console.WriteLn("Created a %s context", context->IsGLES() ? "OpenGL ES" : "OpenGL");
// NOTE: Not thread-safe. But this is okay, since we're not going to be creating more than one context at a time.
static Context* context_being_created;
context_being_created = context.get();
// load up glad
if (!context->IsGLES())
{
if (!gladLoadGLLoader([](const char* name) { return context_being_created->GetProcAddress(name); }))
{
Console.Error("Failed to load GL functions for GLAD");
return nullptr;
}
}
else
{
if (!gladLoadGLES2Loader([](const char* name) { return context_being_created->GetProcAddress(name); }))
{
Console.Error("Failed to load GLES functions for GLAD");
return nullptr;
}
}
context_being_created = nullptr;
const char* gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
const char* gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
const char* gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
const char* gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
DevCon.WriteLn(Color_Magenta, "GL_VENDOR: %s", gl_vendor);
DevCon.WriteLn(Color_Magenta, "GL_RENDERER: %s", gl_renderer);
DevCon.WriteLn(Color_Magenta, "GL_VERSION: %s", gl_version);
DevCon.WriteLn(Color_Magenta, "GL_SHADING_LANGUAGE_VERSION: %s", gl_shading_language_version);
DisableBrokenExtensions(gl_vendor, gl_renderer);
return context;
}
gsl::span<const Context::Version> Context::GetAllVersionsList()
{
static constexpr Version vlist[] = {
{Profile::Core, 4, 6},
{Profile::Core, 4, 5},
{Profile::Core, 4, 4},
{Profile::Core, 4, 3},
{Profile::Core, 4, 2},
{Profile::Core, 4, 1},
{Profile::Core, 4, 0},
{Profile::Core, 3, 3},
{Profile::Core, 3, 2},
{Profile::Core, 3, 1},
{Profile::Core, 3, 0},
{Profile::ES, 3, 2},
{Profile::ES, 3, 1},
{Profile::ES, 3, 0},
{Profile::ES, 2, 0},
{Profile::NoProfile, 0, 0}
};
return vlist;
}
} // namespace GL

View File

@@ -1,80 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/WindowInfo.h"
#include <gsl/span>
#include <array>
#include <memory>
#include <vector>
namespace GL {
class Context
{
public:
Context(const WindowInfo& wi);
virtual ~Context();
enum class Profile
{
NoProfile,
Core,
ES
};
struct Version
{
Profile profile;
int major_version;
int minor_version;
};
struct FullscreenModeInfo
{
u32 width;
u32 height;
float refresh_rate;
};
__fi const WindowInfo& GetWindowInfo() const { return m_wi; }
__fi bool IsGLES() const { return (m_version.profile == Profile::ES); }
__fi u32 GetSurfaceWidth() const { return m_wi.surface_width; }
__fi u32 GetSurfaceHeight() const { return m_wi.surface_height; }
virtual void* GetProcAddress(const char* name) = 0;
virtual bool ChangeSurface(const WindowInfo& new_wi) = 0;
virtual void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) = 0;
virtual bool SwapBuffers() = 0;
virtual bool MakeCurrent() = 0;
virtual bool DoneCurrent() = 0;
virtual bool SetSwapInterval(s32 interval) = 0;
virtual std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) = 0;
virtual std::vector<FullscreenModeInfo> EnumerateFullscreenModes();
static std::unique_ptr<Context> Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try);
static std::unique_ptr<Context> Create(const WindowInfo& wi) { return Create(wi, GetAllVersionsList()); }
static gsl::span<const Version> GetAllVersionsList();
protected:
WindowInfo m_wi;
Version m_version = {};
};
} // namespace GL

View File

@@ -1,62 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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/GL/Context.h"
#include "glad.h"
#if defined(__APPLE__) && defined(__OBJC__)
#import <AppKit/AppKit.h>
#else
struct NSView;
struct NSOpenGLContext;
struct NSOpenGLPixelFormat;
#endif
namespace GL
{
class ContextAGL final : public Context
{
public:
ContextAGL(const WindowInfo& wi);
~ContextAGL() override;
static std::unique_ptr<Context> Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try);
void* GetProcAddress(const char* name) override;
bool ChangeSurface(const WindowInfo& new_wi) override;
void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override;
bool SwapBuffers() override;
bool MakeCurrent() override;
bool DoneCurrent() override;
bool SetSwapInterval(s32 interval) override;
std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
private:
bool Initialize(gsl::span<const Version> versions_to_try);
bool CreateContext(NSOpenGLContext* share_context, int profile, bool make_current);
void BindContextToView();
void CleanupView();
// returns true if dimensions have changed
bool UpdateDimensions();
NSView* m_view = nullptr;
NSOpenGLContext* m_context = nullptr;
NSOpenGLPixelFormat* m_pixel_format = nullptr;
void* m_opengl_module_handle = nullptr;
};
} // namespace GL

View File

@@ -1,243 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/GL/ContextAGL.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "glad.h"
#include <dlfcn.h>
#if ! __has_feature(objc_arc)
#error "Compile this with -fobjc-arc"
#endif
namespace GL
{
ContextAGL::ContextAGL(const WindowInfo& wi)
: Context(wi)
{
m_opengl_module_handle = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_NOW);
if (!m_opengl_module_handle)
Console.Error("Could not open OpenGL.framework, function lookups will probably fail");
}
ContextAGL::~ContextAGL()
{
if ([NSOpenGLContext currentContext] == m_context)
[NSOpenGLContext clearCurrentContext];
CleanupView();
if (m_opengl_module_handle)
dlclose(m_opengl_module_handle);
}
std::unique_ptr<Context> ContextAGL::Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try)
{
std::unique_ptr<ContextAGL> context = std::make_unique<ContextAGL>(wi);
if (!context->Initialize(versions_to_try))
return nullptr;
return context;
}
bool ContextAGL::Initialize(gsl::span<const Version> versions_to_try)
{
for (const Version& cv : versions_to_try)
{
if (cv.profile == Profile::NoProfile && CreateContext(nullptr, NSOpenGLProfileVersionLegacy, true))
{
// we already have the dummy context, so just use that
m_version = cv;
return true;
}
else if (cv.profile == Profile::Core)
{
if (cv.major_version > 4 || cv.minor_version > 1)
continue;
const NSOpenGLPixelFormatAttribute profile = (cv.major_version > 3 || cv.minor_version > 2) ? NSOpenGLProfileVersion4_1Core : NSOpenGLProfileVersion3_2Core;
if (CreateContext(nullptr, static_cast<int>(profile), true))
{
m_version = cv;
return true;
}
}
}
return false;
}
void* ContextAGL::GetProcAddress(const char* name)
{
void* addr = m_opengl_module_handle ? dlsym(m_opengl_module_handle, name) : nullptr;
if (addr)
return addr;
return dlsym(RTLD_NEXT, name);
}
bool ContextAGL::ChangeSurface(const WindowInfo& new_wi)
{
m_wi = new_wi;
BindContextToView();
return true;
}
void ContextAGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/)
{
UpdateDimensions();
}
bool ContextAGL::UpdateDimensions()
{
if (![NSThread isMainThread])
{
bool ret;
dispatch_sync(dispatch_get_main_queue(), [this, &ret]{ ret = UpdateDimensions(); });
return ret;
}
const NSSize window_size = [m_view frame].size;
const CGFloat window_scale = [[m_view window] backingScaleFactor];
const u32 new_width = static_cast<u32>(window_size.width * window_scale);
const u32 new_height = static_cast<u32>(window_size.height * window_scale);
if (m_wi.surface_width == new_width && m_wi.surface_height == new_height)
return false;
m_wi.surface_width = new_width;
m_wi.surface_height = new_height;
[m_context update];
return true;
}
bool ContextAGL::SwapBuffers()
{
[m_context flushBuffer];
return true;
}
bool ContextAGL::MakeCurrent()
{
[m_context makeCurrentContext];
return true;
}
bool ContextAGL::DoneCurrent()
{
[NSOpenGLContext clearCurrentContext];
return true;
}
bool ContextAGL::SetSwapInterval(s32 interval)
{
GLint gl_interval = static_cast<GLint>(interval);
[m_context setValues:&gl_interval forParameter:NSOpenGLCPSwapInterval];
return true;
}
std::unique_ptr<Context> ContextAGL::CreateSharedContext(const WindowInfo& wi)
{
std::unique_ptr<ContextAGL> context = std::make_unique<ContextAGL>(wi);
context->m_context = [[NSOpenGLContext alloc] initWithFormat:m_pixel_format shareContext:m_context];
if (context->m_context == nil)
return nullptr;
context->m_version = m_version;
context->m_pixel_format = m_pixel_format;
if (wi.type == WindowInfo::Type::MacOS)
context->BindContextToView();
return context;
}
bool ContextAGL::CreateContext(NSOpenGLContext* share_context, int profile, bool make_current)
{
if (m_context)
m_context = nullptr;
const NSOpenGLPixelFormatAttribute attribs[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAOpenGLProfile, static_cast<NSOpenGLPixelFormatAttribute>(profile),
NSOpenGLPFAAccelerated,
0
};
m_pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (m_pixel_format == nil)
{
Console.Error("(ContextAGL) Failed to initialize pixel format");
return false;
}
m_context = [[NSOpenGLContext alloc] initWithFormat:m_pixel_format shareContext:nil];
if (m_context == nil)
return false;
if (m_wi.type == WindowInfo::Type::MacOS)
BindContextToView();
if (make_current)
[m_context makeCurrentContext];
return true;
}
void ContextAGL::BindContextToView()
{
if (![NSThread isMainThread])
{
dispatch_sync(dispatch_get_main_queue(), [this]{ BindContextToView(); });
return;
}
#ifdef PCSX2_CORE
m_view = (__bridge NSView*)m_wi.window_handle;
#else
// Drawing to wx's wxView somehow causes fighting between us and wx, resulting in massive CPU usage on the main thread and no image
// Avoid that by adding our own subview
CleanupView();
NSView* const superview = (__bridge NSView*)m_wi.window_handle;
m_view = [[NSView alloc] initWithFrame:[superview frame]];
[superview addSubview:m_view];
[m_view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
#endif
[m_view setWantsBestResolutionOpenGLSurface:YES];
UpdateDimensions();
[m_context setView:m_view];
}
void ContextAGL::CleanupView()
{
#ifndef PCSX2_CORE
if (![NSThread isMainThread])
{
dispatch_sync(dispatch_get_main_queue(), [this]{ CleanupView(); });
return;
}
if (m_view)
[m_view removeFromSuperview];
#endif
m_view = nullptr;
}
} // namespace GL

View File

@@ -1,391 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/PrecompiledHeader.h"
#include "common/Console.h"
#include "ContextEGL.h"
#include <algorithm>
#include <cstring>
#include <optional>
#include <vector>
namespace GL
{
ContextEGL::ContextEGL(const WindowInfo& wi)
: Context(wi)
{
}
ContextEGL::~ContextEGL()
{
DestroySurface();
DestroyContext();
}
std::unique_ptr<Context> ContextEGL::Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try)
{
std::unique_ptr<ContextEGL> context = std::make_unique<ContextEGL>(wi);
if (!context->Initialize(versions_to_try))
return nullptr;
return context;
}
bool ContextEGL::Initialize(gsl::span<const Version> versions_to_try)
{
if (!gladLoadEGL())
{
Console.Error("Loading GLAD EGL functions failed");
return false;
}
if (!SetDisplay())
return false;
int egl_major, egl_minor;
if (!eglInitialize(m_display, &egl_major, &egl_minor))
{
Console.Error("eglInitialize() failed: %d", eglGetError());
return false;
}
Console.WriteLn("EGL Version: %d.%d", egl_major, egl_minor);
const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS);
if (extensions)
{
Console.WriteLn("EGL Extensions: %s", extensions);
m_supports_surfaceless = std::strstr(extensions, "EGL_KHR_surfaceless_context") != nullptr;
}
if (!m_supports_surfaceless)
Console.Warning("EGL implementation does not support surfaceless contexts, emulating with pbuffers");
for (const Version& version : versions_to_try)
{
if (CreateContextAndSurface(version, nullptr, true))
return true;
}
return false;
}
bool ContextEGL::SetDisplay()
{
m_display = eglGetDisplay(static_cast<EGLNativeDisplayType>(m_wi.display_connection));
if (!m_display)
{
Console.Error("eglGetDisplay() failed: %d", eglGetError());
return false;
}
return true;
}
void* ContextEGL::GetProcAddress(const char* name)
{
return reinterpret_cast<void*>(eglGetProcAddress(name));
}
bool ContextEGL::ChangeSurface(const WindowInfo& new_wi)
{
const bool was_current = (eglGetCurrentContext() == m_context);
if (was_current)
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_surface != EGL_NO_SURFACE)
{
eglDestroySurface(m_display, m_surface);
m_surface = EGL_NO_SURFACE;
}
m_wi = new_wi;
if (!CreateSurface())
return false;
if (was_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context))
{
Console.Error("Failed to make context current again after surface change");
return false;
}
return true;
}
void ContextEGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/)
{
if (new_surface_width == 0 && new_surface_height == 0)
{
EGLint surface_width, surface_height;
if (eglQuerySurface(m_display, m_surface, EGL_WIDTH, &surface_width) &&
eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &surface_height))
{
m_wi.surface_width = static_cast<u32>(surface_width);
m_wi.surface_height = static_cast<u32>(surface_height);
return;
}
else
{
Console.Error("eglQuerySurface() failed: %d", eglGetError());
}
}
m_wi.surface_width = new_surface_width;
m_wi.surface_height = new_surface_height;
}
bool ContextEGL::SwapBuffers()
{
return eglSwapBuffers(m_display, m_surface);
}
bool ContextEGL::MakeCurrent()
{
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context))
{
Console.Error("eglMakeCurrent() failed: %d", eglGetError());
return false;
}
return true;
}
bool ContextEGL::DoneCurrent()
{
return eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
bool ContextEGL::SetSwapInterval(s32 interval)
{
return eglSwapInterval(m_display, interval);
}
std::unique_ptr<Context> ContextEGL::CreateSharedContext(const WindowInfo& wi)
{
std::unique_ptr<ContextEGL> context = std::make_unique<ContextEGL>(wi);
context->m_display = m_display;
context->m_supports_surfaceless = m_supports_surfaceless;
if (!context->CreateContextAndSurface(m_version, m_context, false))
return nullptr;
return context;
}
EGLNativeWindowType ContextEGL::GetNativeWindow(EGLConfig config)
{
return {};
}
bool ContextEGL::CreateSurface()
{
if (m_wi.type == WindowInfo::Type::Surfaceless)
{
if (m_supports_surfaceless)
return true;
else
return CreatePBufferSurface();
}
EGLNativeWindowType native_window = GetNativeWindow(m_config);
m_surface = eglCreateWindowSurface(m_display, m_config, native_window, nullptr);
if (!m_surface)
{
Console.Error("eglCreateWindowSurface() failed: %d", eglGetError());
return false;
}
// Some implementations may require the size to be queried at runtime.
EGLint surface_width, surface_height;
if (eglQuerySurface(m_display, m_surface, EGL_WIDTH, &surface_width) &&
eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &surface_height))
{
m_wi.surface_width = static_cast<u32>(surface_width);
m_wi.surface_height = static_cast<u32>(surface_height);
}
else
{
Console.Error("eglQuerySurface() failed: %d", eglGetError());
}
return true;
}
bool ContextEGL::CreatePBufferSurface()
{
const u32 width = std::max<u32>(m_wi.surface_width, 1);
const u32 height = std::max<u32>(m_wi.surface_height, 1);
EGLint attrib_list[] = {
EGL_WIDTH, static_cast<EGLint>(width),
EGL_HEIGHT, static_cast<EGLint>(height),
EGL_NONE,
};
m_surface = eglCreatePbufferSurface(m_display, m_config, attrib_list);
if (!m_surface)
{
Console.Error("eglCreatePbufferSurface() failed: %d", eglGetError());
return false;
}
Console.WriteLn("Created %ux%u pbuffer surface", width, height);
return true;
}
bool ContextEGL::CheckConfigSurfaceFormat(EGLConfig config) const
{
int red_size, green_size, blue_size;
if (!eglGetConfigAttrib(m_display, config, EGL_RED_SIZE, &red_size) ||
!eglGetConfigAttrib(m_display, config, EGL_GREEN_SIZE, &green_size) ||
!eglGetConfigAttrib(m_display, config, EGL_BLUE_SIZE, &blue_size))
{
return false;
}
return (red_size == 8 && green_size == 8 && blue_size == 8);
}
void ContextEGL::DestroyContext()
{
if (eglGetCurrentContext() == m_context)
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_context != EGL_NO_CONTEXT)
{
eglDestroyContext(m_display, m_context);
m_context = EGL_NO_CONTEXT;
}
}
void ContextEGL::DestroySurface()
{
if (eglGetCurrentSurface(EGL_DRAW) == m_surface)
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_surface != EGL_NO_SURFACE)
{
eglDestroySurface(m_display, m_surface);
m_surface = EGL_NO_SURFACE;
}
}
bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
{
Console.WriteLn(
"Trying version %u.%u (%s)", version.major_version, version.minor_version,
version.profile == Context::Profile::ES ? "ES" : (version.profile == Context::Profile::Core ? "Core" : "None"));
const int renderable_type = version.profile == Profile::ES
? ((version.major_version >= 3) ? EGL_OPENGL_ES3_BIT : ((version.major_version == 2) ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_ES_BIT))
: EGL_OPENGL_BIT;
const int surface_attribs[] = {
EGL_RENDERABLE_TYPE, renderable_type,
EGL_SURFACE_TYPE, (m_wi.type != WindowInfo::Type::Surfaceless) ? EGL_WINDOW_BIT : 0,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_NONE
};
EGLint num_configs;
if (!eglChooseConfig(m_display, surface_attribs, nullptr, 0, &num_configs) || num_configs == 0)
{
Console.Error("eglChooseConfig() failed: %d", eglGetError());
return false;
}
std::vector<EGLConfig> configs(static_cast<u32>(num_configs));
if (!eglChooseConfig(m_display, surface_attribs, configs.data(), num_configs, &num_configs))
{
Console.Error("eglChooseConfig() failed: %d", eglGetError());
return false;
}
configs.resize(static_cast<u32>(num_configs));
m_config = [this, &configs]() {
const auto found_config = std::find_if(std::begin(configs), std::end(configs), [&](const auto& check_config) {
return CheckConfigSurfaceFormat(check_config);
});
if (found_config == std::end(configs))
{
Console.Warning("No EGL configs matched exactly, using first.");
return configs.front();
}
else
{
return *found_config;
}
}();
const auto attribs = [version]() -> std::array<int, 8> {
if (version.profile != Profile::NoProfile)
return {
EGL_CONTEXT_MAJOR_VERSION, version.major_version,
EGL_CONTEXT_MINOR_VERSION, version.minor_version,
EGL_NONE
};
return {EGL_NONE};
}();
if (!eglBindAPI((version.profile == Profile::ES) ? EGL_OPENGL_ES_API : EGL_OPENGL_API))
{
Console.Error("eglBindAPI(%s) failed", (version.profile == Profile::ES) ? "EGL_OPENGL_ES_API" : "EGL_OPENGL_API");
return false;
}
m_context = eglCreateContext(m_display, m_config, share_context, attribs.data());
if (!m_context)
{
Console.Error("eglCreateContext() failed: %d", eglGetError());
return false;
}
Console.WriteLn(
"Got version %u.%u (%s)", version.major_version, version.minor_version,
version.profile == Context::Profile::ES ? "ES" : (version.profile == Context::Profile::Core ? "Core" : "None"));
m_version = version;
return true;
}
bool ContextEGL::CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current)
{
if (!CreateContext(version, share_context))
return false;
if (!CreateSurface())
{
Console.Error("Failed to create surface for context");
eglDestroyContext(m_display, m_context);
m_context = EGL_NO_CONTEXT;
return false;
}
if (make_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context))
{
Console.Error("eglMakeCurrent() failed: %d", eglGetError());
if (m_surface != EGL_NO_SURFACE)
{
eglDestroySurface(m_display, m_surface);
m_surface = EGL_NO_SURFACE;
}
eglDestroyContext(m_display, m_context);
m_context = EGL_NO_CONTEXT;
return false;
}
return true;
}
} // namespace GL

View File

@@ -1,63 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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/GL/Context.h"
#include "glad_egl.h"
namespace GL
{
class ContextEGL : public Context
{
public:
ContextEGL(const WindowInfo& wi);
~ContextEGL() override;
static std::unique_ptr<Context> Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try);
void* GetProcAddress(const char* name) override;
virtual bool ChangeSurface(const WindowInfo& new_wi) override;
virtual void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override;
bool SwapBuffers() override;
bool MakeCurrent() override;
bool DoneCurrent() override;
bool SetSwapInterval(s32 interval) override;
virtual std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
protected:
virtual bool SetDisplay();
virtual EGLNativeWindowType GetNativeWindow(EGLConfig config);
bool Initialize(gsl::span<const Version> versions_to_try);
bool CreateDisplay();
bool CreateContext(const Version& version, EGLContext share_context);
bool CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current);
bool CreateSurface();
bool CreatePBufferSurface();
bool CheckConfigSurfaceFormat(EGLConfig config) const;
void DestroyContext();
void DestroySurface();
EGLDisplay m_display = EGL_NO_DISPLAY;
EGLSurface m_surface = EGL_NO_SURFACE;
EGLContext m_context = EGL_NO_CONTEXT;
EGLConfig m_config = {};
bool m_supports_surfaceless = false;
};
} // namespace GL

View File

@@ -1,104 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/PrecompiledHeader.h"
#include "common/Console.h"
#include "ContextEGLWayland.h"
#include <dlfcn.h>
namespace GL
{
static const char* WAYLAND_EGL_MODNAME = "libwayland-egl.so.1";
ContextEGLWayland::ContextEGLWayland(const WindowInfo& wi)
: ContextEGL(wi)
{
}
ContextEGLWayland::~ContextEGLWayland()
{
if (m_wl_window)
m_wl_egl_window_destroy(m_wl_window);
if (m_wl_module)
dlclose(m_wl_module);
}
std::unique_ptr<Context> ContextEGLWayland::Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try)
{
std::unique_ptr<ContextEGLWayland> context = std::make_unique<ContextEGLWayland>(wi);
if (!context->LoadModule() || !context->Initialize(versions_to_try))
return nullptr;
return context;
}
std::unique_ptr<Context> ContextEGLWayland::CreateSharedContext(const WindowInfo& wi)
{
std::unique_ptr<ContextEGLWayland> context = std::make_unique<ContextEGLWayland>(wi);
context->m_display = m_display;
if (!context->LoadModule() || !context->CreateContextAndSurface(m_version, m_context, false))
return nullptr;
return context;
}
void ContextEGLWayland::ResizeSurface(u32 new_surface_width, u32 new_surface_height)
{
if (m_wl_window)
m_wl_egl_window_resize(m_wl_window, new_surface_width, new_surface_height, 0, 0);
ContextEGL::ResizeSurface(new_surface_width, new_surface_height);
}
EGLNativeWindowType ContextEGLWayland::GetNativeWindow(EGLConfig config)
{
if (m_wl_window)
{
m_wl_egl_window_destroy(m_wl_window);
m_wl_window = nullptr;
}
m_wl_window =
m_wl_egl_window_create(static_cast<wl_surface*>(m_wi.window_handle), m_wi.surface_width, m_wi.surface_height);
if (!m_wl_window)
return {};
return reinterpret_cast<EGLNativeWindowType>(m_wl_window);
}
bool ContextEGLWayland::LoadModule()
{
m_wl_module = dlopen(WAYLAND_EGL_MODNAME, RTLD_NOW | RTLD_GLOBAL);
if (!m_wl_module)
{
Console.Error("Failed to load %s.", WAYLAND_EGL_MODNAME);
return false;
}
m_wl_egl_window_create = reinterpret_cast<decltype(m_wl_egl_window_create)>(dlsym(m_wl_module, "wl_egl_window_create"));
m_wl_egl_window_destroy = reinterpret_cast<decltype(m_wl_egl_window_destroy)>(dlsym(m_wl_module, "wl_egl_window_destroy"));
m_wl_egl_window_resize = reinterpret_cast<decltype(m_wl_egl_window_resize)>(dlsym(m_wl_module, "wl_egl_window_resize"));
if (!m_wl_egl_window_create || !m_wl_egl_window_destroy || !m_wl_egl_window_resize)
{
Console.Error("Failed to load one or more functions from %s.", WAYLAND_EGL_MODNAME);
return false;
}
return true;
}
} // namespace GL

View File

@@ -1,49 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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/GL/ContextEGL.h"
struct wl_egl_window;
struct wl_surface;
namespace GL
{
class ContextEGLWayland final : public ContextEGL
{
public:
ContextEGLWayland(const WindowInfo& wi);
~ContextEGLWayland() override;
static std::unique_ptr<Context> Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try);
std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override;
protected:
EGLNativeWindowType GetNativeWindow(EGLConfig config) override;
private:
bool LoadModule();
wl_egl_window* m_wl_window = nullptr;
void* m_wl_module = nullptr;
wl_egl_window* (*m_wl_egl_window_create)(struct wl_surface* surface, int width, int height);
void (*m_wl_egl_window_destroy)(struct wl_egl_window* egl_window);
void (*m_wl_egl_window_resize)(struct wl_egl_window* egl_window, int width, int height, int dx, int dy);
};
} // namespace GL

View File

@@ -1,59 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/PrecompiledHeader.h"
#include "common/GL/ContextEGLX11.h"
#include <X11/Xlib.h>
namespace GL
{
ContextEGLX11::ContextEGLX11(const WindowInfo& wi)
: ContextEGL(wi)
{
}
ContextEGLX11::~ContextEGLX11() = default;
std::unique_ptr<Context> ContextEGLX11::Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try)
{
std::unique_ptr<ContextEGLX11> context = std::make_unique<ContextEGLX11>(wi);
if (!context->Initialize(versions_to_try))
return nullptr;
return context;
}
std::unique_ptr<Context> ContextEGLX11::CreateSharedContext(const WindowInfo& wi)
{
std::unique_ptr<ContextEGLX11> context = std::make_unique<ContextEGLX11>(wi);
context->m_display = m_display;
if (!context->CreateContextAndSurface(m_version, m_context, false))
return nullptr;
return context;
}
void ContextEGLX11::ResizeSurface(u32 new_surface_width, u32 new_surface_height)
{
ContextEGL::ResizeSurface(new_surface_width, new_surface_height);
}
EGLNativeWindowType ContextEGLX11::GetNativeWindow(EGLConfig config)
{
return (EGLNativeWindowType)reinterpret_cast<Window>(m_wi.window_handle);
}
} // namespace GL

View File

@@ -1,487 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/GL/ContextWGL.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/ScopedGuard.h"
static void* GetProcAddressCallback(const char* name)
{
void* addr = reinterpret_cast<void*>(wglGetProcAddress(name));
if (addr)
return addr;
// try opengl32.dll
return reinterpret_cast<void*>(::GetProcAddress(GetModuleHandleA("opengl32.dll"), name));
}
static bool ReloadWGL(HDC dc)
{
if (!gladLoadWGLLoader([](const char* name) -> void* { return reinterpret_cast<void*>(wglGetProcAddress(name)); }, dc))
{
Console.Error("Loading GLAD WGL functions failed");
return false;
}
return true;
}
namespace GL
{
ContextWGL::ContextWGL(const WindowInfo& wi)
: Context(wi)
{
}
ContextWGL::~ContextWGL()
{
if (wglGetCurrentContext() == m_rc)
wglMakeCurrent(m_dc, nullptr);
if (m_rc)
wglDeleteContext(m_rc);
ReleaseDC();
}
std::unique_ptr<Context> ContextWGL::Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try)
{
std::unique_ptr<ContextWGL> context = std::make_unique<ContextWGL>(wi);
if (!context->Initialize(versions_to_try))
return nullptr;
return context;
}
bool ContextWGL::Initialize(gsl::span<const Version> versions_to_try)
{
if (m_wi.type == WindowInfo::Type::Win32)
{
if (!InitializeDC())
return false;
}
else
{
if (!CreatePBuffer())
return false;
}
// Everything including core/ES requires a dummy profile to load the WGL extensions.
if (!CreateAnyContext(nullptr, true))
return false;
for (const Version& cv : versions_to_try)
{
if (cv.profile == Profile::NoProfile)
{
// we already have the dummy context, so just use that
m_version = cv;
return true;
}
else if (CreateVersionContext(cv, nullptr, true))
{
m_version = cv;
return true;
}
}
return false;
}
void* ContextWGL::GetProcAddress(const char* name)
{
return GetProcAddressCallback(name);
}
bool ContextWGL::ChangeSurface(const WindowInfo& new_wi)
{
const bool was_current = (wglGetCurrentContext() == m_rc);
ReleaseDC();
m_wi = new_wi;
if (!InitializeDC())
return false;
if (was_current && !wglMakeCurrent(m_dc, m_rc))
{
Console.Error("Failed to make context current again after surface change: 0x%08X", GetLastError());
return false;
}
return true;
}
void ContextWGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/)
{
RECT client_rc = {};
GetClientRect(GetHWND(), &client_rc);
m_wi.surface_width = static_cast<u32>(client_rc.right - client_rc.left);
m_wi.surface_height = static_cast<u32>(client_rc.bottom - client_rc.top);
}
bool ContextWGL::SwapBuffers()
{
return ::SwapBuffers(m_dc);
}
bool ContextWGL::MakeCurrent()
{
if (!wglMakeCurrent(m_dc, m_rc))
{
Console.Error("wglMakeCurrent() failed: 0x%08X", GetLastError());
return false;
}
return true;
}
bool ContextWGL::DoneCurrent()
{
return wglMakeCurrent(m_dc, nullptr);
}
bool ContextWGL::SetSwapInterval(s32 interval)
{
if (!GLAD_WGL_EXT_swap_control)
return false;
return wglSwapIntervalEXT(interval);
}
std::unique_ptr<Context> ContextWGL::CreateSharedContext(const WindowInfo& wi)
{
std::unique_ptr<ContextWGL> context = std::make_unique<ContextWGL>(wi);
if (wi.type == WindowInfo::Type::Win32)
{
if (!context->InitializeDC())
return nullptr;
}
else
{
if (!context->CreatePBuffer())
return nullptr;
}
if (m_version.profile == Profile::NoProfile)
{
if (!context->CreateAnyContext(m_rc, false))
return nullptr;
}
else
{
if (!context->CreateVersionContext(m_version, m_rc, false))
return nullptr;
}
context->m_version = m_version;
return context;
}
HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd)
{
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.dwLayerMask = PFD_MAIN_PLANE;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
pfd.cColorBits = 24;
HDC hDC = ::GetDC(hwnd);
if (!hDC)
{
Console.Error("GetDC() failed: 0x%08X", GetLastError());
return {};
}
if (!m_pixel_format.has_value())
{
const int pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0)
{
Console.Error("ChoosePixelFormat() failed: 0x%08X", GetLastError());
::ReleaseDC(hwnd, hDC);
return {};
}
m_pixel_format = pf;
}
if (!SetPixelFormat(hDC, m_pixel_format.value(), &pfd))
{
Console.Error("SetPixelFormat() failed: 0x%08X", GetLastError());
::ReleaseDC(hwnd, hDC);
return {};
}
return hDC;
}
bool ContextWGL::InitializeDC()
{
if (m_wi.type == WindowInfo::Type::Win32)
{
m_dc = GetDCAndSetPixelFormat(GetHWND());
if (!m_dc)
{
Console.Error("Failed to get DC for window");
return false;
}
return true;
}
else if (m_wi.type == WindowInfo::Type::Surfaceless)
{
return CreatePBuffer();
}
else
{
Console.Error("Unknown window info type %u", static_cast<unsigned>(m_wi.type));
return false;
}
}
void ContextWGL::ReleaseDC()
{
if (m_pbuffer)
{
wglReleasePbufferDCARB(m_pbuffer, m_dc);
m_dc = {};
wglDestroyPbufferARB(m_pbuffer);
m_pbuffer = {};
::ReleaseDC(m_dummy_window, m_dummy_dc);
m_dummy_dc = {};
DestroyWindow(m_dummy_window);
m_dummy_window = {};
}
else if (m_dc)
{
::ReleaseDC(GetHWND(), m_dc);
m_dc = {};
}
}
bool ContextWGL::CreatePBuffer()
{
static bool window_class_registered = false;
static const wchar_t* window_class_name = L"ContextWGLPBuffer";
if (!window_class_registered)
{
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = 0;
wc.lpfnWndProc = DefWindowProcW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(nullptr);
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = window_class_name;
wc.hIconSm = NULL;
if (!RegisterClassExW(&wc))
{
Console.Error("(ContextWGL::CreatePBuffer) RegisterClassExW() failed");
return false;
}
window_class_registered = true;
}
HWND hwnd = CreateWindowExW(0, window_class_name, window_class_name, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
if (!hwnd)
{
Console.Error("(ContextWGL::CreatePBuffer) CreateWindowEx() failed");
return false;
}
ScopedGuard hwnd_guard([hwnd]() { DestroyWindow(hwnd); });
HDC hdc = GetDCAndSetPixelFormat(hwnd);
if (!hdc)
return false;
ScopedGuard hdc_guard([hdc, hwnd]() { ::ReleaseDC(hwnd, hdc); });
static constexpr const int pb_attribs[] = {0, 0};
HGLRC temp_rc = nullptr;
ScopedGuard temp_rc_guard([&temp_rc, hdc]() { if (temp_rc) {
wglMakeCurrent(hdc, nullptr);
wglDeleteContext(temp_rc);
} });
if (!GLAD_WGL_ARB_pbuffer)
{
// we're probably running completely surfaceless... need a temporary context.
temp_rc = wglCreateContext(hdc);
if (!temp_rc || !wglMakeCurrent(hdc, temp_rc))
{
Console.Error("Failed to create temporary context to load WGL for pbuffer.");
return false;
}
if (!ReloadWGL(hdc) || !GLAD_WGL_ARB_pbuffer)
{
Console.Error("Missing WGL_ARB_pbuffer");
return false;
}
}
pxAssertRel(m_pixel_format.has_value(), "Has pixel format for pbuffer");
HPBUFFERARB pbuffer = wglCreatePbufferARB(hdc, m_pixel_format.value(), 1, 1, pb_attribs);
if (!pbuffer)
{
Console.Error("(ContextWGL::CreatePBuffer) wglCreatePbufferARB() failed");
return false;
}
ScopedGuard pbuffer_guard([pbuffer]() { wglDestroyPbufferARB(pbuffer); });
m_dc = wglGetPbufferDCARB(pbuffer);
if (!m_dc)
{
Console.Error("(ContextWGL::CreatePbuffer) wglGetPbufferDCARB() failed");
return false;
}
m_dummy_window = hwnd;
m_dummy_dc = hdc;
m_pbuffer = pbuffer;
temp_rc_guard.Run();
pbuffer_guard.Cancel();
hdc_guard.Cancel();
hwnd_guard.Cancel();
return true;
}
bool ContextWGL::CreateAnyContext(HGLRC share_context, bool make_current)
{
m_rc = wglCreateContext(m_dc);
if (!m_rc)
{
Console.Error("wglCreateContext() failed: 0x%08X", GetLastError());
return false;
}
if (make_current)
{
if (!wglMakeCurrent(m_dc, m_rc))
{
Console.Error("wglMakeCurrent() failed: 0x%08X", GetLastError());
return false;
}
// re-init glad-wgl
if (!gladLoadWGLLoader([](const char* name) -> void* { return reinterpret_cast<void*>(wglGetProcAddress(name)); }, m_dc))
{
Console.Error("Loading GLAD WGL functions failed");
return false;
}
}
if (share_context && !wglShareLists(share_context, m_rc))
{
Console.Error("wglShareLists() failed: 0x%08X", GetLastError());
return false;
}
return true;
}
bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_context, bool make_current)
{
// we need create context attribs
if (!GLAD_WGL_ARB_create_context)
{
Console.Error("Missing GLAD_WGL_ARB_create_context.");
return false;
}
HGLRC new_rc;
if (version.profile == Profile::Core)
{
const int attribs[] = {
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_MAJOR_VERSION_ARB, version.major_version,
WGL_CONTEXT_MINOR_VERSION_ARB, version.minor_version,
#ifdef _DEBUG
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB,
#else
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
#endif
0, 0};
new_rc = wglCreateContextAttribsARB(m_dc, share_context, attribs);
}
else if (version.profile == Profile::ES)
{
if ((version.major_version >= 2 && !GLAD_WGL_EXT_create_context_es2_profile) ||
(version.major_version < 2 && !GLAD_WGL_EXT_create_context_es_profile))
{
Console.Error("WGL_EXT_create_context_es_profile not supported");
return false;
}
const int attribs[] = {
WGL_CONTEXT_PROFILE_MASK_ARB, ((version.major_version >= 2) ? WGL_CONTEXT_ES2_PROFILE_BIT_EXT : WGL_CONTEXT_ES_PROFILE_BIT_EXT),
WGL_CONTEXT_MAJOR_VERSION_ARB, version.major_version,
WGL_CONTEXT_MINOR_VERSION_ARB, version.minor_version,
0, 0};
new_rc = wglCreateContextAttribsARB(m_dc, share_context, attribs);
}
else
{
Console.Error("Unknown profile");
return false;
}
if (!new_rc)
return false;
// destroy and swap contexts
if (m_rc)
{
if (!wglMakeCurrent(m_dc, make_current ? new_rc : nullptr))
{
Console.Error("wglMakeCurrent() failed: 0x%08X", GetLastError());
wglDeleteContext(new_rc);
return false;
}
// re-init glad-wgl
if (make_current && !ReloadWGL(m_dc))
return false;
wglDeleteContext(m_rc);
}
m_rc = new_rc;
return true;
}
} // namespace GL

View File

@@ -1,71 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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/GL/Context.h"
#include "glad_wgl.h"
#include "glad.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <optional>
namespace GL
{
class ContextWGL final : public Context
{
public:
ContextWGL(const WindowInfo& wi);
~ContextWGL() override;
static std::unique_ptr<Context> Create(const WindowInfo& wi, gsl::span<const Version> versions_to_try);
void* GetProcAddress(const char* name) override;
bool ChangeSurface(const WindowInfo& new_wi) override;
void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override;
bool SwapBuffers() override;
bool MakeCurrent() override;
bool DoneCurrent() override;
bool SetSwapInterval(s32 interval) override;
std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
private:
__fi HWND GetHWND() const { return static_cast<HWND>(m_wi.window_handle); }
HDC GetDCAndSetPixelFormat(HWND hwnd);
bool Initialize(gsl::span<const Version> versions_to_try);
bool InitializeDC();
void ReleaseDC();
bool CreatePBuffer();
bool CreateAnyContext(HGLRC share_context, bool make_current);
bool CreateVersionContext(const Version& version, HGLRC share_context, bool make_current);
HDC m_dc = {};
HGLRC m_rc = {};
// Can't change pixel format once it's set for a RC.
std::optional<int> m_pixel_format;
// Dummy window for creating a PBuffer off when we're surfaceless.
HWND m_dummy_window = {};
HDC m_dummy_dc = {};
HPBUFFERARB m_pbuffer = {};
};
} // namespace GL

View File

@@ -1,673 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/PrecompiledHeader.h"
#include "common/GL/Program.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/StringUtil.h"
#include <array>
#include <fstream>
namespace GL
{
GLuint Program::s_last_program_id = 0;
static GLuint s_next_bad_shader_id = 1;
Program::Program() = default;
Program::Program(Program&& prog)
{
m_program_id = prog.m_program_id;
prog.m_program_id = 0;
m_vertex_shader_id = prog.m_vertex_shader_id;
prog.m_vertex_shader_id = 0;
m_fragment_shader_id = prog.m_fragment_shader_id;
prog.m_fragment_shader_id = 0;
m_uniform_locations = std::move(prog.m_uniform_locations);
}
Program::~Program()
{
Destroy();
}
GLuint Program::CompileShader(GLenum type, const std::string_view source)
{
GLuint id = glCreateShader(type);
std::array<const GLchar*, 1> sources = {{source.data()}};
std::array<GLint, 1> source_lengths = {{static_cast<GLint>(source.size())}};
glShaderSource(id, static_cast<GLsizei>(sources.size()), sources.data(), source_lengths.data());
glCompileShader(id);
GLint status = GL_FALSE;
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
GLint info_log_length = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
// Log will create a new line when there are no warnings so let's set a minimum log length of 1.
constexpr int info_log_min_length = 1;
if (status == GL_FALSE || info_log_length > info_log_min_length)
{
std::string info_log;
info_log.resize(info_log_length + 1);
glGetShaderInfoLog(id, info_log_length, &info_log_length, &info_log[0]);
if (status == GL_TRUE)
{
Console.Warning("Shader compiled with warnings:\n%s", info_log.c_str());
}
else
{
Console.Error("Shader failed to compile:\n%s", info_log.c_str());
std::ofstream ofs(StringUtil::StdStringFromFormat("bad_shader_%u.txt", s_next_bad_shader_id++).c_str(),
std::ofstream::out | std::ofstream::binary);
if (ofs.is_open())
{
ofs.write(sources[0], source_lengths[0]);
ofs << "\n\nCompile failed, info log:\n";
ofs << info_log;
ofs.close();
}
glDeleteShader(id);
return 0;
}
}
return id;
}
void Program::ResetLastProgram()
{
s_last_program_id = 0;
}
bool Program::Compile(const std::string_view vertex_shader, const std::string_view geometry_shader,
const std::string_view fragment_shader)
{
GLuint vertex_shader_id = 0;
if (!vertex_shader.empty())
{
vertex_shader_id = CompileShader(GL_VERTEX_SHADER, vertex_shader);
if (vertex_shader_id == 0)
return false;
}
GLuint geometry_shader_id = 0;
if (!geometry_shader.empty())
{
geometry_shader_id = CompileShader(GL_GEOMETRY_SHADER, geometry_shader);
if (geometry_shader_id == 0)
return false;
}
GLuint fragment_shader_id = 0;
if (!fragment_shader.empty())
{
fragment_shader_id = CompileShader(GL_FRAGMENT_SHADER, fragment_shader);
if (fragment_shader_id == 0)
{
glDeleteShader(vertex_shader_id);
return false;
}
}
m_program_id = glCreateProgram();
if (vertex_shader_id != 0)
glAttachShader(m_program_id, vertex_shader_id);
if (geometry_shader_id != 0)
glAttachShader(m_program_id, geometry_shader_id);
if (fragment_shader_id != 0)
glAttachShader(m_program_id, fragment_shader_id);
return true;
}
bool Program::CompileCompute(const std::string_view glsl)
{
GLuint id = CompileShader(GL_COMPUTE_SHADER, glsl);
if (id == 0)
return false;
m_program_id = glCreateProgram();
glAttachShader(m_program_id, id);
return true;
}
bool Program::CreateFromBinary(const void* data, u32 data_length, u32 data_format)
{
GLuint prog = glCreateProgram();
glProgramBinary(prog, static_cast<GLenum>(data_format), data, data_length);
GLint link_status;
glGetProgramiv(prog, GL_LINK_STATUS, &link_status);
if (link_status != GL_TRUE)
{
Console.Error("Failed to create GL program from binary: status %d", link_status);
glDeleteProgram(prog);
return false;
}
m_program_id = prog;
return true;
}
bool Program::GetBinary(std::vector<u8>* out_data, u32* out_data_format)
{
GLint binary_size = 0;
glGetProgramiv(m_program_id, GL_PROGRAM_BINARY_LENGTH, &binary_size);
if (binary_size == 0)
{
Console.Warning("glGetProgramiv(GL_PROGRAM_BINARY_LENGTH) returned 0");
return false;
}
GLenum format = 0;
out_data->resize(static_cast<size_t>(binary_size));
glGetProgramBinary(m_program_id, binary_size, &binary_size, &format, out_data->data());
if (binary_size == 0)
{
Console.Warning("glGetProgramBinary() failed");
return false;
}
else if (static_cast<size_t>(binary_size) != out_data->size())
{
Console.Warning("Size changed from %zu to %d after glGetProgramBinary()", out_data->size(), binary_size);
out_data->resize(static_cast<size_t>(binary_size));
}
*out_data_format = static_cast<u32>(format);
DevCon.WriteLn("Program binary retrieved, %zu bytes, format %u", out_data->size(), *out_data_format);
return true;
}
void Program::SetBinaryRetrievableHint()
{
glProgramParameteri(m_program_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
}
void Program::BindAttribute(GLuint index, const char* name)
{
glBindAttribLocation(m_program_id, index, name);
}
void Program::BindDefaultAttributes()
{
BindAttribute(0, "a_position");
BindAttribute(1, "a_texcoord");
BindAttribute(2, "a_color");
}
void Program::BindFragData(GLuint index /*= 0*/, const char* name /*= "o_col0"*/)
{
glBindFragDataLocation(m_program_id, index, name);
}
void Program::BindFragDataIndexed(GLuint color_number /*= 0*/, const char* name /*= "o_col0"*/)
{
if (GLAD_GL_VERSION_3_3 || GLAD_GL_ARB_blend_func_extended)
{
glBindFragDataLocationIndexed(m_program_id, color_number, 0, name);
return;
}
else if (GLAD_GL_EXT_blend_func_extended)
{
glBindFragDataLocationIndexedEXT(m_program_id, color_number, 0, name);
return;
}
Console.Error("BindFragDataIndexed() called without ARB or EXT extension, we'll probably crash.");
glBindFragDataLocationIndexed(m_program_id, color_number, 0, name);
}
bool Program::Link()
{
glLinkProgram(m_program_id);
if (m_vertex_shader_id != 0)
glDeleteShader(m_vertex_shader_id);
m_vertex_shader_id = 0;
if (m_fragment_shader_id != 0)
glDeleteShader(m_fragment_shader_id);
m_fragment_shader_id = 0;
GLint status = GL_FALSE;
glGetProgramiv(m_program_id, GL_LINK_STATUS, &status);
GLint info_log_length = 0;
// Log will create a new line when there are no warnings so let's set a minimum log length of 1.
constexpr int info_log_min_length = 1;
glGetProgramiv(m_program_id, GL_INFO_LOG_LENGTH, &info_log_length);
if (status == GL_FALSE || info_log_length > info_log_min_length)
{
std::string info_log;
info_log.resize(info_log_length + 1);
glGetProgramInfoLog(m_program_id, info_log_length, &info_log_length, &info_log[0]);
if (status == GL_TRUE)
{
Console.Error("Program linked with warnings:\n%s", info_log.c_str());
}
else
{
Console.Error("Program failed to link:\n%s", info_log.c_str());
glDeleteProgram(m_program_id);
m_program_id = 0;
return false;
}
}
return true;
}
void Program::Bind() const
{
if (s_last_program_id == m_program_id)
return;
glUseProgram(m_program_id);
s_last_program_id = m_program_id;
}
void Program::Destroy()
{
if (m_vertex_shader_id != 0)
{
glDeleteShader(m_vertex_shader_id);
m_vertex_shader_id = 0;
}
if (m_fragment_shader_id != 0)
{
glDeleteShader(m_fragment_shader_id);
m_fragment_shader_id = 0;
}
if (m_program_id != 0)
{
glDeleteProgram(m_program_id);
m_program_id = 0;
}
m_uniform_locations.clear();
}
int Program::RegisterUniform(const char* name)
{
int id = static_cast<int>(m_uniform_locations.size());
m_uniform_locations.push_back(glGetUniformLocation(m_program_id, name));
return id;
}
void Program::Uniform1ui(int index, u32 x) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform1ui(location, x);
}
void Program::Uniform2ui(int index, u32 x, u32 y) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform2ui(location, x, y);
}
void Program::Uniform3ui(int index, u32 x, u32 y, u32 z) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform3ui(location, x, y, z);
}
void Program::Uniform4ui(int index, u32 x, u32 y, u32 z, u32 w) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform4ui(location, x, y, z, w);
}
void Program::Uniform1i(int index, s32 x) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform1i(location, x);
}
void Program::Uniform2i(int index, s32 x, s32 y) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform2i(location, x, y);
}
void Program::Uniform3i(int index, s32 x, s32 y, s32 z) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform3i(location, x, y, z);
}
void Program::Uniform4i(int index, s32 x, s32 y, s32 z, s32 w) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform4i(location, x, y, z, w);
}
void Program::Uniform1f(int index, float x) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform1f(location, x);
}
void Program::Uniform2f(int index, float x, float y) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform2f(location, x, y);
}
void Program::Uniform3f(int index, float x, float y, float z) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform3f(location, x, y, z);
}
void Program::Uniform4f(int index, float x, float y, float z, float w) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform4f(location, x, y, z, w);
}
void Program::Uniform2uiv(int index, const u32* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform2uiv(location, 1, v);
}
void Program::Uniform3uiv(int index, const u32* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform3uiv(location, 1, v);
}
void Program::Uniform4uiv(int index, const u32* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform4uiv(location, 1, v);
}
void Program::Uniform2iv(int index, const s32* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform2iv(location, 1, v);
}
void Program::Uniform3iv(int index, const s32* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform3iv(location, 1, v);
}
void Program::Uniform4iv(int index, const s32* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform4iv(location, 1, v);
}
void Program::Uniform2fv(int index, const float* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform2fv(location, 1, v);
}
void Program::Uniform3fv(int index, const float* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform3fv(location, 1, v);
}
void Program::Uniform4fv(int index, const float* v) const
{
pxAssert(static_cast<size_t>(index) < m_uniform_locations.size());
const GLint location = m_uniform_locations[index];
if (location >= 0)
glUniform4fv(location, 1, v);
}
void Program::Uniform1ui(const char* name, u32 x) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform1ui(location, x);
}
void Program::Uniform2ui(const char* name, u32 x, u32 y) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform2ui(location, x, y);
}
void Program::Uniform3ui(const char* name, u32 x, u32 y, u32 z) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform3ui(location, x, y, z);
}
void Program::Uniform4ui(const char* name, u32 x, u32 y, u32 z, u32 w) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform4ui(location, x, y, z, w);
}
void Program::Uniform1i(const char* name, s32 x) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform1i(location, x);
}
void Program::Uniform2i(const char* name, s32 x, s32 y) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform2i(location, x, y);
}
void Program::Uniform3i(const char* name, s32 x, s32 y, s32 z) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform3i(location, x, y, z);
}
void Program::Uniform4i(const char* name, s32 x, s32 y, s32 z, s32 w) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform4i(location, x, y, z, w);
}
void Program::Uniform1f(const char* name, float x) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform1f(location, x);
}
void Program::Uniform2f(const char* name, float x, float y) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform2f(location, x, y);
}
void Program::Uniform3f(const char* name, float x, float y, float z) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform3f(location, x, y, z);
}
void Program::Uniform4f(const char* name, float x, float y, float z, float w) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform4f(location, x, y, z, w);
}
void Program::Uniform2uiv(const char* name, const u32* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform2uiv(location, 1, v);
}
void Program::Uniform3uiv(const char* name, const u32* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform3uiv(location, 1, v);
}
void Program::Uniform4uiv(const char* name, const u32* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform4uiv(location, 1, v);
}
void Program::Uniform2iv(const char* name, const s32* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform2iv(location, 1, v);
}
void Program::Uniform3iv(const char* name, const s32* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform3iv(location, 1, v);
}
void Program::Uniform4iv(const char* name, const s32* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform4iv(location, 1, v);
}
void Program::Uniform2fv(const char* name, const float* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform2fv(location, 1, v);
}
void Program::Uniform3fv(const char* name, const float* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform3fv(location, 1, v);
}
void Program::Uniform4fv(const char* name, const float* v) const
{
const GLint location = glGetUniformLocation(m_program_id, name);
if (location >= 0)
glUniform4fv(location, 1, v);
}
void Program::BindUniformBlock(const char* name, u32 index)
{
const GLint location = glGetUniformBlockIndex(m_program_id, name);
if (location >= 0)
glUniformBlockBinding(m_program_id, location, index);
}
void Program::SetName(const std::string_view& name)
{
if (name.empty())
return;
#ifdef _DEBUG
glObjectLabel(GL_PROGRAM, m_program_id, name.length(), name.data());
#endif
}
void Program::SetFormattedName(const char* format, ...)
{
va_list ap;
va_start(ap, format);
std::string n = StringUtil::StdStringFromFormatV(format, ap);
va_end(ap);
SetName(n);
}
Program& Program::operator=(Program&& prog)
{
Destroy();
m_program_id = prog.m_program_id;
prog.m_program_id = 0;
m_vertex_shader_id = prog.m_vertex_shader_id;
prog.m_vertex_shader_id = 0;
m_fragment_shader_id = prog.m_fragment_shader_id;
prog.m_fragment_shader_id = 0;
m_uniform_locations = std::move(prog.m_uniform_locations);
return *this;
}
} // namespace GL

View File

@@ -1,124 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "../Pcsx2Defs.h"
#include "glad.h"
#include <string_view>
#include <vector>
namespace GL
{
class Program
{
public:
Program();
Program(const Program&) = delete;
Program(Program&& prog);
~Program();
static GLuint CompileShader(GLenum type, const std::string_view source);
static void ResetLastProgram();
bool IsValid() const { return m_program_id != 0; }
bool Compile(const std::string_view vertex_shader, const std::string_view geometry_shader,
const std::string_view fragment_shader);
bool CompileCompute(const std::string_view glsl);
bool CreateFromBinary(const void* data, u32 data_length, u32 data_format);
bool GetBinary(std::vector<u8>* out_data, u32* out_data_format);
void SetBinaryRetrievableHint();
void BindAttribute(GLuint index, const char* name);
void BindDefaultAttributes();
void BindFragData(GLuint index = 0, const char* name = "o_col0");
void BindFragDataIndexed(GLuint color_number = 0, const char* name = "o_col0");
bool Link();
void Bind() const;
void Destroy();
int RegisterUniform(const char* name);
void Uniform1ui(int index, u32 x) const;
void Uniform2ui(int index, u32 x, u32 y) const;
void Uniform3ui(int index, u32 x, u32 y, u32 z) const;
void Uniform4ui(int index, u32 x, u32 y, u32 z, u32 w) const;
void Uniform1i(int index, s32 x) const;
void Uniform2i(int index, s32 x, s32 y) const;
void Uniform3i(int index, s32 x, s32 y, s32 z) const;
void Uniform4i(int index, s32 x, s32 y, s32 z, s32 w) const;
void Uniform1f(int index, float x) const;
void Uniform2f(int index, float x, float y) const;
void Uniform3f(int index, float x, float y, float z) const;
void Uniform4f(int index, float x, float y, float z, float w) const;
void Uniform2uiv(int index, const u32* v) const;
void Uniform3uiv(int index, const u32* v) const;
void Uniform4uiv(int index, const u32* v) const;
void Uniform2iv(int index, const s32* v) const;
void Uniform3iv(int index, const s32* v) const;
void Uniform4iv(int index, const s32* v) const;
void Uniform2fv(int index, const float* v) const;
void Uniform3fv(int index, const float* v) const;
void Uniform4fv(int index, const float* v) const;
void Uniform1ui(const char* name, u32 x) const;
void Uniform2ui(const char* name, u32 x, u32 y) const;
void Uniform3ui(const char* name, u32 x, u32 y, u32 z) const;
void Uniform4ui(const char* name, u32 x, u32 y, u32 z, u32 w) const;
void Uniform1i(const char* name, s32 x) const;
void Uniform2i(const char* name, s32 x, s32 y) const;
void Uniform3i(const char* name, s32 x, s32 y, s32 z) const;
void Uniform4i(const char* name, s32 x, s32 y, s32 z, s32 w) const;
void Uniform1f(const char* name, float x) const;
void Uniform2f(const char* name, float x, float y) const;
void Uniform3f(const char* name, float x, float y, float z) const;
void Uniform4f(const char* name, float x, float y, float z, float w) const;
void Uniform2uiv(const char* name, const u32* v) const;
void Uniform3uiv(const char* name, const u32* v) const;
void Uniform4uiv(const char* name, const u32* v) const;
void Uniform2iv(const char* name, const s32* v) const;
void Uniform3iv(const char* name, const s32* v) const;
void Uniform4iv(const char* name, const s32* v) const;
void Uniform2fv(const char* name, const float* v) const;
void Uniform3fv(const char* name, const float* v) const;
void Uniform4fv(const char* name, const float* v) const;
void BindUniformBlock(const char* name, u32 index);
void SetName(const std::string_view& name);
void SetFormattedName(const char* format, ...);
Program& operator=(const Program&) = delete;
Program& operator=(Program&& prog);
__fi bool operator==(const Program& rhs) const { return m_program_id == rhs.m_program_id; }
__fi bool operator!=(const Program& rhs) const { return m_program_id != rhs.m_program_id; }
private:
static u32 s_last_program_id;
GLuint m_program_id = 0;
GLuint m_vertex_shader_id = 0;
GLuint m_fragment_shader_id = 0;
std::vector<GLint> m_uniform_locations;
};
} // namespace GL

View File

@@ -1,566 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/GL/ShaderCache.h"
#include "common/FileSystem.h"
#include "common/Console.h"
#include "common/MD5Digest.h"
#include "common/StringUtil.h"
#include "common/Timer.h"
namespace GL
{
#pragma pack(push, 1)
struct CacheIndexEntry
{
u64 vertex_source_hash_low;
u64 vertex_source_hash_high;
u32 vertex_source_length;
u64 geometry_source_hash_low;
u64 geometry_source_hash_high;
u32 geometry_source_length;
u64 fragment_source_hash_low;
u64 fragment_source_hash_high;
u32 fragment_source_length;
u32 file_offset;
u32 blob_size;
u32 blob_format;
};
#pragma pack(pop)
ShaderCache::ShaderCache() = default;
ShaderCache::~ShaderCache()
{
Close();
}
bool ShaderCache::CacheIndexKey::operator==(const CacheIndexKey& key) const
{
return (
vertex_source_hash_low == key.vertex_source_hash_low && vertex_source_hash_high == key.vertex_source_hash_high &&
vertex_source_length == key.vertex_source_length && geometry_source_hash_low == key.geometry_source_hash_low &&
geometry_source_hash_high == key.geometry_source_hash_high &&
geometry_source_length == key.geometry_source_length && fragment_source_hash_low == key.fragment_source_hash_low &&
fragment_source_hash_high == key.fragment_source_hash_high && fragment_source_length == key.fragment_source_length);
}
bool ShaderCache::CacheIndexKey::operator!=(const CacheIndexKey& key) const
{
return (
vertex_source_hash_low != key.vertex_source_hash_low || vertex_source_hash_high != key.vertex_source_hash_high ||
vertex_source_length != key.vertex_source_length || geometry_source_hash_low != key.geometry_source_hash_low ||
geometry_source_hash_high != key.geometry_source_hash_high ||
geometry_source_length != key.geometry_source_length || fragment_source_hash_low != key.fragment_source_hash_low ||
fragment_source_hash_high != key.fragment_source_hash_high || fragment_source_length != key.fragment_source_length);
}
bool ShaderCache::Open(bool is_gles, std::string_view base_path, u32 version)
{
m_base_path = base_path;
m_version = version;
m_program_binary_supported = is_gles || GLAD_GL_ARB_get_program_binary;
if (m_program_binary_supported)
{
// check that there's at least one format and the extension isn't being "faked"
GLint num_formats = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_formats);
Console.WriteLn("%u program binary formats supported by driver", num_formats);
m_program_binary_supported = (num_formats > 0);
}
if (!m_program_binary_supported)
{
Console.Warning("Your GL driver does not support program binaries. Hopefully it has a built-in cache.");
return true;
}
if (!base_path.empty())
{
const std::string index_filename = GetIndexFileName();
const std::string blob_filename = GetBlobFileName();
if (ReadExisting(index_filename, blob_filename))
return true;
return CreateNew(index_filename, blob_filename);
}
return true;
}
bool ShaderCache::CreateNew(const std::string& index_filename, const std::string& blob_filename)
{
if (FileSystem::FileExists(index_filename.c_str()))
{
Console.Warning("Removing existing index file '%s'", index_filename.c_str());
FileSystem::DeleteFilePath(index_filename.c_str());
}
if (FileSystem::FileExists(blob_filename.c_str()))
{
Console.Warning("Removing existing blob file '%s'", blob_filename.c_str());
FileSystem::DeleteFilePath(blob_filename.c_str());
}
m_index_file = FileSystem::OpenCFile(index_filename.c_str(), "wb");
if (!m_index_file)
{
Console.Error("Failed to open index file '%s' for writing", index_filename.c_str());
return false;
}
const u32 index_version = FILE_VERSION;
if (std::fwrite(&index_version, sizeof(index_version), 1, m_index_file) != 1 ||
std::fwrite(&m_version, sizeof(m_version), 1, m_index_file) != 1)
{
Console.Error("Failed to write version to index file '%s'", index_filename.c_str());
std::fclose(m_index_file);
m_index_file = nullptr;
FileSystem::DeleteFilePath(index_filename.c_str());
return false;
}
m_blob_file = FileSystem::OpenCFile(blob_filename.c_str(), "w+b");
if (!m_blob_file)
{
Console.Error("Failed to open blob file '%s' for writing", blob_filename.c_str());
std::fclose(m_index_file);
m_index_file = nullptr;
FileSystem::DeleteFilePath(index_filename.c_str());
return false;
}
return true;
}
bool ShaderCache::ReadExisting(const std::string& index_filename, const std::string& blob_filename)
{
m_index_file = FileSystem::OpenCFile(index_filename.c_str(), "r+b");
if (!m_index_file)
{
// special case here: when there's a sharing violation (i.e. two instances running),
// we don't want to blow away the cache. so just continue without a cache.
if (errno == EACCES)
{
Console.WriteLn("Failed to open shader cache index with EACCES, are you running two instances?");
return true;
}
return false;
}
u32 file_version = 0;
u32 data_version = 0;
if (std::fread(&file_version, sizeof(file_version), 1, m_index_file) != 1 || file_version != FILE_VERSION ||
std::fread(&data_version, sizeof(data_version), 1, m_index_file) != 1 || data_version != m_version)
{
Console.Error("Bad file/data version in '%s'", index_filename.c_str());
std::fclose(m_index_file);
m_index_file = nullptr;
return false;
}
m_blob_file = FileSystem::OpenCFile(blob_filename.c_str(), "a+b");
if (!m_blob_file)
{
Console.Error("Blob file '%s' is missing", blob_filename.c_str());
std::fclose(m_index_file);
m_index_file = nullptr;
return false;
}
std::fseek(m_blob_file, 0, SEEK_END);
const u32 blob_file_size = static_cast<u32>(std::ftell(m_blob_file));
for (;;)
{
CacheIndexEntry entry;
if (std::fread(&entry, sizeof(entry), 1, m_index_file) != 1 ||
(entry.file_offset + entry.blob_size) > blob_file_size)
{
if (std::feof(m_index_file))
break;
Console.Error("Failed to read entry from '%s', corrupt file?", index_filename.c_str());
m_index.clear();
std::fclose(m_blob_file);
m_blob_file = nullptr;
std::fclose(m_index_file);
m_index_file = nullptr;
return false;
}
const CacheIndexKey key{
entry.vertex_source_hash_low, entry.vertex_source_hash_high, entry.vertex_source_length,
entry.geometry_source_hash_low, entry.geometry_source_hash_high, entry.geometry_source_length,
entry.fragment_source_hash_low, entry.fragment_source_hash_high, entry.fragment_source_length};
const CacheIndexData data{entry.file_offset, entry.blob_size, entry.blob_format};
m_index.emplace(key, data);
}
Console.WriteLn("Read %zu entries from '%s'", m_index.size(), index_filename.c_str());
return true;
}
void ShaderCache::Close()
{
m_index.clear();
if (m_index_file)
std::fclose(m_index_file);
if (m_blob_file)
std::fclose(m_blob_file);
}
bool ShaderCache::Recreate()
{
Close();
const std::string index_filename = GetIndexFileName();
const std::string blob_filename = GetBlobFileName();
return CreateNew(index_filename, blob_filename);
}
ShaderCache::CacheIndexKey ShaderCache::GetCacheKey(const std::string_view& vertex_shader,
const std::string_view& geometry_shader,
const std::string_view& fragment_shader)
{
union ShaderHash
{
struct
{
u64 low;
u64 high;
};
u8 bytes[16];
};
ShaderHash vertex_hash = {};
ShaderHash geometry_hash = {};
ShaderHash fragment_hash = {};
MD5Digest digest;
if (!vertex_shader.empty())
{
digest.Update(vertex_shader.data(), static_cast<u32>(vertex_shader.length()));
digest.Final(vertex_hash.bytes);
}
if (!geometry_shader.empty())
{
digest.Reset();
digest.Update(geometry_shader.data(), static_cast<u32>(geometry_shader.length()));
digest.Final(geometry_hash.bytes);
}
if (!fragment_shader.empty())
{
digest.Reset();
digest.Update(fragment_shader.data(), static_cast<u32>(fragment_shader.length()));
digest.Final(fragment_hash.bytes);
}
return CacheIndexKey{vertex_hash.low, vertex_hash.high, static_cast<u32>(vertex_shader.length()),
geometry_hash.low, geometry_hash.high, static_cast<u32>(geometry_shader.length()),
fragment_hash.low, fragment_hash.high, static_cast<u32>(fragment_shader.length())};
}
std::string ShaderCache::GetIndexFileName() const
{
return StringUtil::StdStringFromFormat("%s/gl_programs.idx", m_base_path.c_str());
}
std::string ShaderCache::GetBlobFileName() const
{
return StringUtil::StdStringFromFormat("%s/gl_programs.bin", m_base_path.c_str());
}
std::optional<Program> ShaderCache::GetProgram(const std::string_view vertex_shader,
const std::string_view geometry_shader,
const std::string_view fragment_shader, const PreLinkCallback& callback)
{
if (!m_program_binary_supported || !m_blob_file)
{
#ifdef PCSX2_DEVBUILD
Common::Timer timer;
#endif
std::optional<Program> res = CompileProgram(vertex_shader, geometry_shader, fragment_shader, callback, false);
#ifdef PCSX2_DEVBUILD
Console.WriteLn("Time to compile shader without caching: %.2fms", timer.GetTimeMilliseconds());
#endif
return res;
}
const auto key = GetCacheKey(vertex_shader, geometry_shader, fragment_shader);
auto iter = m_index.find(key);
if (iter == m_index.end())
return CompileAndAddProgram(key, vertex_shader, geometry_shader, fragment_shader, callback);
std::vector<u8> data(iter->second.blob_size);
if (std::fseek(m_blob_file, iter->second.file_offset, SEEK_SET) != 0 ||
std::fread(data.data(), 1, iter->second.blob_size, m_blob_file) != iter->second.blob_size)
{
Console.Error("Read blob from file failed");
return {};
}
#ifdef PCSX2_DEVBUILD
Common::Timer timer;
#endif
Program prog;
if (prog.CreateFromBinary(data.data(), static_cast<u32>(data.size()), iter->second.blob_format))
{
#ifdef PCSX2_DEVBUILD
Console.WriteLn("Time to create program from binary: %.2fms", timer.GetTimeMilliseconds());
#endif
return std::optional<Program>(std::move(prog));
}
Console.Warning(
"Failed to create program from binary, this may be due to a driver or GPU Change. Recreating cache.");
if (!Recreate())
return CompileProgram(vertex_shader, geometry_shader, fragment_shader, callback, false);
else
return CompileAndAddProgram(key, vertex_shader, geometry_shader, fragment_shader, callback);
}
bool ShaderCache::GetProgram(Program* out_program, const std::string_view vertex_shader,
const std::string_view geometry_shader, const std::string_view fragment_shader,
const PreLinkCallback& callback /* = */)
{
auto prog = GetProgram(vertex_shader, geometry_shader, fragment_shader, callback);
if (!prog)
return false;
*out_program = std::move(*prog);
return true;
}
bool ShaderCache::WriteToBlobFile(const CacheIndexKey& key, const std::vector<u8>& prog_data, u32 prog_format)
{
if (!m_blob_file || std::fseek(m_blob_file, 0, SEEK_END) != 0)
return false;
CacheIndexData data;
data.file_offset = static_cast<u32>(std::ftell(m_blob_file));
data.blob_size = static_cast<u32>(prog_data.size());
data.blob_format = prog_format;
CacheIndexEntry entry = {};
entry.vertex_source_hash_low = key.vertex_source_hash_low;
entry.vertex_source_hash_high = key.vertex_source_hash_high;
entry.vertex_source_length = key.vertex_source_length;
entry.geometry_source_hash_low = key.geometry_source_hash_low;
entry.geometry_source_hash_high = key.geometry_source_hash_high;
entry.geometry_source_length = key.geometry_source_length;
entry.fragment_source_hash_low = key.fragment_source_hash_low;
entry.fragment_source_hash_high = key.fragment_source_hash_high;
entry.fragment_source_length = key.fragment_source_length;
entry.file_offset = data.file_offset;
entry.blob_size = data.blob_size;
entry.blob_format = data.blob_format;
if (std::fwrite(prog_data.data(), 1, entry.blob_size, m_blob_file) != entry.blob_size ||
std::fflush(m_blob_file) != 0 || std::fwrite(&entry, sizeof(entry), 1, m_index_file) != 1 ||
std::fflush(m_index_file) != 0)
{
Console.Error("Failed to write shader blob to file");
return false;
}
m_index.emplace(key, data);
return true;
}
std::optional<Program> ShaderCache::CompileProgram(const std::string_view& vertex_shader,
const std::string_view& geometry_shader,
const std::string_view& fragment_shader,
const PreLinkCallback& callback, bool set_retrievable)
{
Program prog;
if (!prog.Compile(vertex_shader, geometry_shader, fragment_shader))
return std::nullopt;
if (callback)
callback(prog);
if (set_retrievable)
prog.SetBinaryRetrievableHint();
if (!prog.Link())
return std::nullopt;
return std::optional<Program>(std::move(prog));
}
std::optional<Program> ShaderCache::CompileComputeProgram(const std::string_view& glsl,
const PreLinkCallback& callback, bool set_retrievable)
{
Program prog;
if (!prog.CompileCompute(glsl))
return std::nullopt;
if (callback)
callback(prog);
if (set_retrievable)
prog.SetBinaryRetrievableHint();
if (!prog.Link())
return std::nullopt;
return std::optional<Program>(std::move(prog));
}
std::optional<Program> ShaderCache::CompileAndAddProgram(const CacheIndexKey& key,
const std::string_view& vertex_shader,
const std::string_view& geometry_shader,
const std::string_view& fragment_shader,
const PreLinkCallback& callback)
{
#ifdef PCSX2_DEVBUILD
Common::Timer timer;
#endif
std::optional<Program> prog = CompileProgram(vertex_shader, geometry_shader, fragment_shader, callback, true);
if (!prog)
return std::nullopt;
#ifdef PCSX2_DEVBUILD
const float compile_time = timer.GetTimeMilliseconds();
timer.Reset();
#endif
std::vector<u8> prog_data;
u32 prog_format = 0;
if (!prog->GetBinary(&prog_data, &prog_format))
return std::nullopt;
#ifdef PCSX2_DEVBUILD
const float binary_time = timer.GetTimeMilliseconds();
timer.Reset();
#endif
WriteToBlobFile(key, prog_data, prog_format);
#ifdef PCSX2_DEVBUILD
const float write_time = timer.GetTimeMilliseconds();
Console.WriteLn("Compiled and cached shader: Compile: %.2fms, Binary: %.2fms, Write: %.2fms", compile_time, binary_time, write_time);
#endif
return prog;
}
std::optional<Program> ShaderCache::GetComputeProgram(const std::string_view glsl, const PreLinkCallback& callback)
{
if (!m_program_binary_supported || !m_blob_file)
{
#ifdef PCSX2_DEVBUILD
Common::Timer timer;
#endif
std::optional<Program> res = CompileComputeProgram(glsl, callback, false);
#ifdef PCSX2_DEVBUILD
Console.WriteLn("Time to compile shader without caching: %.2fms", timer.GetTimeMilliseconds());
#endif
return res;
}
const auto key = GetCacheKey(glsl, std::string_view(), std::string_view());
auto iter = m_index.find(key);
if (iter == m_index.end())
return CompileAndAddComputeProgram(key, glsl, callback);
std::vector<u8> data(iter->second.blob_size);
if (std::fseek(m_blob_file, iter->second.file_offset, SEEK_SET) != 0 ||
std::fread(data.data(), 1, iter->second.blob_size, m_blob_file) != iter->second.blob_size)
{
Console.Error("Read blob from file failed");
return {};
}
#ifdef PCSX2_DEVBUILD
Common::Timer timer;
#endif
Program prog;
if (prog.CreateFromBinary(data.data(), static_cast<u32>(data.size()), iter->second.blob_format))
{
#ifdef PCSX2_DEVBUILD
Console.WriteLn("Time to create program from binary: %.2fms", timer.GetTimeMilliseconds());
#endif
return std::optional<Program>(std::move(prog));
}
Console.Warning(
"Failed to create program from binary, this may be due to a driver or GPU Change. Recreating cache.");
if (!Recreate())
return CompileComputeProgram(glsl, callback, false);
else
return CompileAndAddComputeProgram(key, glsl, callback);
}
bool ShaderCache::GetComputeProgram(Program* out_program, const std::string_view glsl, const PreLinkCallback& callback)
{
auto prog = GetComputeProgram(glsl, callback);
if (!prog)
return false;
*out_program = std::move(*prog);
return true;
}
std::optional<Program> ShaderCache::CompileAndAddComputeProgram(
const CacheIndexKey& key, const std::string_view& glsl, const PreLinkCallback& callback)
{
#ifdef PCSX2_DEVBUILD
Common::Timer timer;
#endif
std::optional<Program> prog = CompileComputeProgram(glsl, callback, true);
if (!prog)
return std::nullopt;
#ifdef PCSX2_DEVBUILD
const float compile_time = timer.GetTimeMilliseconds();
timer.Reset();
#endif
std::vector<u8> prog_data;
u32 prog_format = 0;
if (!prog->GetBinary(&prog_data, &prog_format))
return std::nullopt;
#ifdef PCSX2_DEVBUILD
const float binary_time = timer.GetTimeMilliseconds();
timer.Reset();
#endif
WriteToBlobFile(key, prog_data, prog_format);
#ifdef PCSX2_DEVBUILD
const float write_time = timer.GetTimeMilliseconds();
Console.WriteLn("Compiled and cached compute shader: Compile: %.2fms, Binary: %.2fms, Write: %.2fms", compile_time, binary_time, write_time);
#endif
return prog;
}
} // namespace GL

View File

@@ -1,120 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "common/HashCombine.h"
#include "common/GL/Program.h"
#include <cstdio>
#include <functional>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
namespace GL
{
class ShaderCache
{
public:
using PreLinkCallback = std::function<void(Program&)>;
ShaderCache();
~ShaderCache();
bool Open(bool is_gles, std::string_view base_path, u32 version);
std::optional<Program> GetProgram(const std::string_view vertex_shader, const std::string_view geometry_shader,
const std::string_view fragment_shader, const PreLinkCallback& callback = {});
bool GetProgram(Program* out_program, const std::string_view vertex_shader, const std::string_view geometry_shader,
const std::string_view fragment_shader, const PreLinkCallback& callback = {});
std::optional<Program> GetComputeProgram(const std::string_view glsl, const PreLinkCallback& callback = {});
bool GetComputeProgram(Program* out_program, const std::string_view glsl, const PreLinkCallback& callback = {});
private:
static constexpr u32 FILE_VERSION = 1;
struct CacheIndexKey
{
u64 vertex_source_hash_low;
u64 vertex_source_hash_high;
u32 vertex_source_length;
u64 geometry_source_hash_low;
u64 geometry_source_hash_high;
u32 geometry_source_length;
u64 fragment_source_hash_low;
u64 fragment_source_hash_high;
u32 fragment_source_length;
bool operator==(const CacheIndexKey& key) const;
bool operator!=(const CacheIndexKey& key) const;
};
struct CacheIndexEntryHasher
{
std::size_t operator()(const CacheIndexKey& e) const noexcept
{
std::size_t h = 0;
HashCombine(h,
e.vertex_source_hash_low, e.vertex_source_hash_high, e.vertex_source_length,
e.geometry_source_hash_low, e.geometry_source_hash_high, e.geometry_source_length,
e.fragment_source_hash_low, e.fragment_source_hash_high, e.fragment_source_length);
return h;
}
};
struct CacheIndexData
{
u32 file_offset;
u32 blob_size;
u32 blob_format;
};
using CacheIndex = std::unordered_map<CacheIndexKey, CacheIndexData, CacheIndexEntryHasher>;
static CacheIndexKey GetCacheKey(const std::string_view& vertex_shader, const std::string_view& geometry_shader,
const std::string_view& fragment_shader);
std::string GetIndexFileName() const;
std::string GetBlobFileName() const;
bool CreateNew(const std::string& index_filename, const std::string& blob_filename);
bool ReadExisting(const std::string& index_filename, const std::string& blob_filename);
void Close();
bool Recreate();
bool WriteToBlobFile(const CacheIndexKey& key, const std::vector<u8>& prog_data, u32 prog_format);
std::optional<Program> CompileProgram(const std::string_view& vertex_shader, const std::string_view& geometry_shader,
const std::string_view& fragment_shader, const PreLinkCallback& callback,
bool set_retrievable);
std::optional<Program> CompileAndAddProgram(const CacheIndexKey& key, const std::string_view& vertex_shader,
const std::string_view& geometry_shader,
const std::string_view& fragment_shader, const PreLinkCallback& callback);
std::optional<Program> CompileComputeProgram(const std::string_view& glsl, const PreLinkCallback& callback, bool set_retrievable);
std::optional<Program> CompileAndAddComputeProgram(const CacheIndexKey& key, const std::string_view& glsl, const PreLinkCallback& callback);
std::string m_base_path;
std::FILE* m_index_file = nullptr;
std::FILE* m_blob_file = nullptr;
CacheIndex m_index;
u32 m_version = 0;
bool m_program_binary_supported = false;
};
} // namespace GL

View File

@@ -1,346 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "StreamBuffer.h"
#include "common/Align.h"
#include "common/Assertions.h"
#include <array>
#include <cstring>
namespace GL
{
StreamBuffer::StreamBuffer(GLenum target, GLuint buffer_id, u32 size)
: m_target(target)
, m_buffer_id(buffer_id)
, m_size(size)
{
}
StreamBuffer::~StreamBuffer()
{
glDeleteBuffers(1, &m_buffer_id);
}
void StreamBuffer::Bind()
{
glBindBuffer(m_target, m_buffer_id);
}
void StreamBuffer::Unbind()
{
glBindBuffer(m_target, 0);
}
namespace detail
{
// Uses glBufferSubData() to update. Preferred for drivers which don't support {ARB,EXT}_buffer_storage.
class BufferSubDataStreamBuffer final : public StreamBuffer
{
public:
~BufferSubDataStreamBuffer() override = default;
MappingResult Map(u32 alignment, u32 min_size) override
{
return MappingResult{static_cast<void*>(m_cpu_buffer.data()), 0, 0, m_size / alignment};
}
void Unmap(u32 used_size) override
{
if (used_size == 0)
return;
glBindBuffer(m_target, m_buffer_id);
glBufferSubData(m_target, 0, used_size, m_cpu_buffer.data());
}
u32 GetChunkSize() const override
{
return m_size;
}
static std::unique_ptr<StreamBuffer> Create(GLenum target, u32 size)
{
glGetError();
GLuint buffer_id;
glGenBuffers(1, &buffer_id);
glBindBuffer(target, buffer_id);
glBufferData(target, size, nullptr, GL_STREAM_DRAW);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
glBindBuffer(target, 0);
glDeleteBuffers(1, &buffer_id);
return {};
}
return std::unique_ptr<StreamBuffer>(new BufferSubDataStreamBuffer(target, buffer_id, size));
}
private:
BufferSubDataStreamBuffer(GLenum target, GLuint buffer_id, u32 size)
: StreamBuffer(target, buffer_id, size)
, m_cpu_buffer(size)
{
}
std::vector<u8> m_cpu_buffer;
};
// Uses BufferData() to orphan the buffer after every update. Used on Mali where BufferSubData forces a sync.
class BufferDataStreamBuffer final : public StreamBuffer
{
public:
~BufferDataStreamBuffer() override = default;
MappingResult Map(u32 alignment, u32 min_size) override
{
return MappingResult{static_cast<void*>(m_cpu_buffer.data()), 0, 0, m_size / alignment};
}
void Unmap(u32 used_size) override
{
if (used_size == 0)
return;
glBindBuffer(m_target, m_buffer_id);
glBufferData(m_target, used_size, m_cpu_buffer.data(), GL_STREAM_DRAW);
}
u32 GetChunkSize() const override
{
return m_size;
}
static std::unique_ptr<StreamBuffer> Create(GLenum target, u32 size)
{
glGetError();
GLuint buffer_id;
glGenBuffers(1, &buffer_id);
glBindBuffer(target, buffer_id);
glBufferData(target, size, nullptr, GL_STREAM_DRAW);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
glBindBuffer(target, 0);
glDeleteBuffers(1, &buffer_id);
return {};
}
return std::unique_ptr<StreamBuffer>(new BufferDataStreamBuffer(target, buffer_id, size));
}
private:
BufferDataStreamBuffer(GLenum target, GLuint buffer_id, u32 size)
: StreamBuffer(target, buffer_id, size)
, m_cpu_buffer(size)
{
}
std::vector<u8> m_cpu_buffer;
};
// Base class for implementations which require syncing.
class SyncingStreamBuffer : public StreamBuffer
{
public:
enum : u32
{
NUM_SYNC_POINTS = 16
};
virtual ~SyncingStreamBuffer() override
{
for (u32 i = m_available_block_index; i <= m_used_block_index; i++)
{
pxAssert(m_sync_objects[i]);
glDeleteSync(m_sync_objects[i]);
}
}
protected:
SyncingStreamBuffer(GLenum target, GLuint buffer_id, u32 size)
: StreamBuffer(target, buffer_id, size)
, m_bytes_per_block((size + (NUM_SYNC_POINTS)-1) / NUM_SYNC_POINTS)
{
}
__fi u32 GetSyncIndexForOffset(u32 offset) { return offset / m_bytes_per_block; }
__fi void AddSyncsForOffset(u32 offset)
{
const u32 end = GetSyncIndexForOffset(offset);
for (; m_used_block_index < end; m_used_block_index++)
{
pxAssert(!m_sync_objects[m_used_block_index]);
m_sync_objects[m_used_block_index] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
}
__fi void WaitForSync(GLsync& sync)
{
glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
glDeleteSync(sync);
sync = nullptr;
}
__fi void EnsureSyncsWaitedForOffset(u32 offset)
{
const u32 end = std::min<u32>(GetSyncIndexForOffset(offset) + 1, NUM_SYNC_POINTS);
for (; m_available_block_index < end; m_available_block_index++)
{
pxAssert(m_sync_objects[m_available_block_index]);
WaitForSync(m_sync_objects[m_available_block_index]);
}
}
void AllocateSpace(u32 size)
{
// add sync objects for writes since the last allocation
AddSyncsForOffset(m_position);
// wait for sync objects for the space we want to use
EnsureSyncsWaitedForOffset(m_position + size);
// wrap-around?
if ((m_position + size) > m_size)
{
// current position ... buffer end
AddSyncsForOffset(m_size);
// rewind, and try again
m_position = 0;
// wait for the sync at the start of the buffer
WaitForSync(m_sync_objects[0]);
m_available_block_index = 1;
// and however much more we need to satisfy the allocation
EnsureSyncsWaitedForOffset(size);
m_used_block_index = 0;
}
}
u32 GetChunkSize() const override
{
return m_size / NUM_SYNC_POINTS;
}
u32 m_position = 0;
u32 m_used_block_index = 0;
u32 m_available_block_index = NUM_SYNC_POINTS;
u32 m_bytes_per_block;
std::array<GLsync, NUM_SYNC_POINTS> m_sync_objects{};
};
class BufferStorageStreamBuffer : public SyncingStreamBuffer
{
public:
~BufferStorageStreamBuffer() override
{
glBindBuffer(m_target, m_buffer_id);
glUnmapBuffer(m_target);
glBindBuffer(m_target, 0);
}
MappingResult Map(u32 alignment, u32 min_size) override
{
if (m_position > 0)
m_position = Common::AlignUp(m_position, alignment);
AllocateSpace(min_size);
pxAssert((m_position + min_size) <= (m_available_block_index * m_bytes_per_block));
const u32 free_space_in_block = ((m_available_block_index * m_bytes_per_block) - m_position);
return MappingResult{static_cast<void*>(m_mapped_ptr + m_position), m_position, m_position / alignment,
free_space_in_block / alignment};
}
void Unmap(u32 used_size) override
{
pxAssert((m_position + used_size) <= m_size);
if (!m_coherent)
{
Bind();
glFlushMappedBufferRange(m_target, m_position, used_size);
}
m_position += used_size;
}
static std::unique_ptr<StreamBuffer> Create(GLenum target, u32 size, bool coherent = true)
{
glGetError();
GLuint buffer_id;
glGenBuffers(1, &buffer_id);
glBindBuffer(target, buffer_id);
const u32 flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0);
const u32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT);
if (GLAD_GL_VERSION_4_4 || GLAD_GL_ARB_buffer_storage)
glBufferStorage(target, size, nullptr, flags);
else if (GLAD_GL_EXT_buffer_storage)
glBufferStorageEXT(target, size, nullptr, flags);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
glBindBuffer(target, 0);
glDeleteBuffers(1, &buffer_id);
return {};
}
u8* mapped_ptr = static_cast<u8*>(glMapBufferRange(target, 0, size, map_flags));
pxAssertRel(mapped_ptr, "Persistent buffer was mapped");
return std::unique_ptr<StreamBuffer>(new BufferStorageStreamBuffer(target, buffer_id, size, mapped_ptr, coherent));
}
private:
BufferStorageStreamBuffer(GLenum target, GLuint buffer_id, u32 size, u8* mapped_ptr, bool coherent)
: SyncingStreamBuffer(target, buffer_id, size)
, m_mapped_ptr(mapped_ptr)
, m_coherent(coherent)
{
}
u8* m_mapped_ptr;
bool m_coherent;
};
} // namespace detail
std::unique_ptr<StreamBuffer> StreamBuffer::Create(GLenum target, u32 size)
{
std::unique_ptr<StreamBuffer> buf;
if (GLAD_GL_VERSION_4_4 || GLAD_GL_ARB_buffer_storage || GLAD_GL_EXT_buffer_storage)
{
buf = detail::BufferStorageStreamBuffer::Create(target, size);
if (buf)
return buf;
}
// BufferSubData is slower on all drivers except NVIDIA...
const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
if (std::strstr(vendor, "NVIDIA"))
return detail::BufferSubDataStreamBuffer::Create(target, size);
else
return detail::BufferDataStreamBuffer::Create(target, size);
}
} // namespace GL

View File

@@ -1,61 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 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 "glad.h"
#include <memory>
#include <tuple>
#include <vector>
namespace GL
{
/// Provides a buffer for streaming data to the GPU, ideally in write-combined memory.
class StreamBuffer
{
public:
virtual ~StreamBuffer();
__fi GLuint GetGLBufferId() const { return m_buffer_id; }
__fi GLenum GetGLTarget() const { return m_target; }
__fi u32 GetSize() const { return m_size; }
void Bind();
void Unbind();
struct MappingResult
{
void* pointer;
u32 buffer_offset;
u32 index_aligned; // offset / alignment, suitable for base vertex
u32 space_aligned; // remaining space / alignment
};
virtual MappingResult Map(u32 alignment, u32 min_size) = 0;
virtual void Unmap(u32 used_size) = 0;
/// Returns the minimum granularity of blocks which sync objects will be created around.
virtual u32 GetChunkSize() const = 0;
static std::unique_ptr<StreamBuffer> Create(GLenum target, u32 size);
protected:
StreamBuffer(GLenum target, GLuint buffer_id, u32 size);
GLenum m_target;
GLuint m_buffer_id;
u32 m_size;
};
} // namespace GL

View File

@@ -89,6 +89,7 @@ static void SysPageFaultSignalFilter(int signal, siginfo_t* siginfo, void* ctx)
// Prevent recursive exception filtering.
if (s_in_exception_handler)
{
lock.unlock();
CallExistingSignalHandler(signal, siginfo, ctx);
return;
}
@@ -100,6 +101,8 @@ static void SysPageFaultSignalFilter(int signal, siginfo_t* siginfo, void* ctx)
#if defined(__APPLE__) && defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext->__ss.__rip);
#elif defined(__FreeBSD__) && defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext.mc_rip);
#elif defined(__x86_64__)
void* const exception_pc = reinterpret_cast<void*>(static_cast<ucontext_t*>(ctx)->uc_mcontext.gregs[REG_RIP]);
#else
@@ -119,6 +122,7 @@ static void SysPageFaultSignalFilter(int signal, siginfo_t* siginfo, void* ctx)
return;
// Call old signal handler, which will likely dump core.
lock.unlock();
CallExistingSignalHandler(signal, siginfo, ctx);
}
@@ -133,6 +137,10 @@ bool HostSys::InstallPageFaultHandler(PageFaultHandler handler)
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = SysPageFaultSignalFilter;
#ifdef __linux__
// Don't block the signal from executing recursively, we want to fire the original handler.
sa.sa_flags |= SA_NODEFER;
#endif
#ifdef __APPLE__
// MacOS uses SIGBUS for memory permission violations
if (sigaction(SIGBUS, &sa, &s_old_sigbus_action) != 0)

View File

@@ -31,6 +31,10 @@
#include "common/Threading.h"
#include "common/WindowInfo.h"
#ifdef DBUS_API
#include <dbus/dbus.h>
#endif
// Returns 0 on failure (not supported by the operating system).
u64 GetPhysicalMemory()
{
@@ -69,11 +73,77 @@ std::string GetOSVersionString()
#endif
}
#ifdef X11_API
#ifdef DBUS_API
bool ChangeScreenSaverStateDBus(const bool inhibit_requested, const char* program_name, const char* reason)
{
static dbus_uint32_t s_cookie;
// "error_dbus" doesn't need to be cleared in the end with "dbus_message_unref" at least if there is
// no error set, since calling "dbus_error_free" reinitializes it like "dbus_error_init" after freeing.
DBusError error_dbus;
dbus_error_init(&error_dbus);
DBusConnection* connection = nullptr;
DBusMessage* message = nullptr;
DBusMessage* response = nullptr;
// Initialized here because initializations should be before "goto" statements.
const char* bus_method = (inhibit_requested) ? "Inhibit" : "UnInhibit";
// "dbus_bus_get" gets a pointer to the same connection in libdbus, if exists, without creating a new connection.
// this doesn't need to be deleted, except if there's an error then calling "dbus_connection_unref", to free it,
// might be better so a new connection is established on the next try.
if (!(connection = dbus_bus_get(DBUS_BUS_SESSION, &error_dbus)) || (dbus_error_is_set(&error_dbus)))
goto cleanup;
if (!(message = dbus_message_new_method_call("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver", bus_method)))
goto cleanup;
// Initialize an append iterator for the message, gets freed with the message.
DBusMessageIter message_itr;
dbus_message_iter_init_append(message, &message_itr);
if (inhibit_requested)
{
// Append process/window name.
if (!dbus_message_iter_append_basic(&message_itr, DBUS_TYPE_STRING, &program_name))
goto cleanup;
// Append reason for inhibiting the screensaver.
if (!dbus_message_iter_append_basic(&message_itr, DBUS_TYPE_STRING, &reason))
goto cleanup;
}
else
{
// Only Append the cookie.
if (!dbus_message_iter_append_basic(&message_itr, DBUS_TYPE_UINT32, &s_cookie))
goto cleanup;
}
// Send message and get response.
if (!(response = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error_dbus))
|| dbus_error_is_set(&error_dbus))
goto cleanup;
if (inhibit_requested)
{
// Get the cookie from the response message.
if (!dbus_message_get_args(response, &error_dbus, DBUS_TYPE_UINT32, &s_cookie, DBUS_TYPE_INVALID))
goto cleanup;
}
dbus_message_unref(message);
dbus_message_unref(response);
return true;
cleanup:
if (dbus_error_is_set(&error_dbus))
dbus_error_free(&error_dbus);
if (connection)
dbus_connection_unref(connection);
if (message)
dbus_message_unref(message);
if (response)
dbus_message_unref(response);
return false;
}
#endif
#if !defined(DBUS_API) && defined(X11_API)
static bool SetScreensaverInhibitX11(const WindowInfo& wi, bool inhibit)
{
extern char **environ;
extern char** environ;
const char* command = "xdg-screensaver";
const char* operation = inhibit ? "suspend" : "resume";
@@ -88,8 +158,6 @@ static bool SetScreensaverInhibitX11(const WindowInfo& wi, bool inhibit)
return (res == 0);
}
#endif
static bool SetScreensaverInhibit(const WindowInfo& wi, bool inhibit)
{
switch (wi.type)
@@ -106,8 +174,18 @@ static bool SetScreensaverInhibit(const WindowInfo& wi, bool inhibit)
static std::optional<WindowInfo> s_inhibit_window_info;
#endif
bool WindowInfo::InhibitScreensaver(const WindowInfo& wi, bool inhibit)
{
#ifdef DBUS_API
return ChangeScreenSaverStateDBus(inhibit, "PCSX2", "PCSX2 VM is running.");
#else
//ChangeScreenSaverStateDBus
if (s_inhibit_window_info.has_value())
{
// Bit of extra logic here, because wx spams it and we don't want to
@@ -132,6 +210,9 @@ bool WindowInfo::InhibitScreensaver(const WindowInfo& wi, bool inhibit)
s_inhibit_window_info = wi;
return true;
#endif
}
bool Common::PlaySoundAsync(const char* path)

View File

@@ -15,197 +15,207 @@
#include "common/Perf.h"
#include "common/Pcsx2Defs.h"
#ifdef __unix__
#include <unistd.h>
#endif
#include "common/Assertions.h"
#include "common/StringUtil.h"
#ifdef ENABLE_VTUNE
#include "jitprofiling.h"
#endif
#include <string> // std::string
#include <cstring> // strncpy
#include <algorithm> // std::remove_if
#include <array>
#include <cstring>
#ifdef __linux__
#include <atomic>
#include <ctime>
#include <mutex>
#include <elf.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#endif
//#define ProfileWithPerf
#define MERGE_BLOCK_RESULT
//#define ProfileWithPerfJitDump
#ifdef ENABLE_VTUNE
#ifdef _WIN32
#if defined(ENABLE_VTUNE) && defined(_WIN32)
#pragma comment(lib, "jitprofiling.lib")
#endif
#endif
namespace Perf
{
// Warning object aren't thread safe
InfoVector any("");
InfoVector ee("EE");
InfoVector iop("IOP");
InfoVector vu("VU");
InfoVector vif("VIF");
Group any("");
Group ee("EE");
Group iop("IOP");
Group vu0("VU0");
Group vu1("VU1");
Group vif("VIF");
// Perf is only supported on linux
#if defined(__linux__) && (defined(ProfileWithPerf) || defined(ENABLE_VTUNE))
////////////////////////////////////////////////////////////////////////////////
// Implementation of the Info object
////////////////////////////////////////////////////////////////////////////////
Info::Info(uptr x86, u32 size, const char* symbol)
: m_x86(x86)
, m_size(size)
, m_dynamic(false)
#if defined(__linux__) && defined(ProfileWithPerf)
static std::FILE* s_map_file = nullptr;
static bool s_map_file_opened = false;
static std::mutex s_mutex;
static void RegisterMethod(const void* ptr, size_t size, const char* symbol)
{
strncpy(m_symbol, symbol, sizeof(m_symbol));
}
std::unique_lock lock(s_mutex);
Info::Info(uptr x86, u32 size, const char* symbol, u32 pc)
: m_x86(x86)
, m_size(size)
, m_dynamic(true)
{
snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc);
}
void Info::Print(FILE* fp)
{
fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol);
}
////////////////////////////////////////////////////////////////////////////////
// Implementation of the InfoVector object
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char* prefix)
{
strncpy(m_prefix, prefix, sizeof(m_prefix));
#ifdef ENABLE_VTUNE
m_vtune_id = iJIT_GetNewMethodID();
#else
m_vtune_id = 0;
#endif
}
void InfoVector::print(FILE* fp)
{
for (auto&& it : m_v)
it.Print(fp);
}
void InfoVector::map(uptr x86, u32 size, const char* symbol)
{
// This function is typically used for dispatcher and recompiler.
// Dispatchers are on a page and must always be kept.
// Recompilers are much bigger (TODO check VIF) and are only
// useful when MERGE_BLOCK_RESULT is defined
#if defined(ENABLE_VTUNE) || !defined(MERGE_BLOCK_RESULT)
u32 max_code_size = 16 * _1kb;
#else
u32 max_code_size = _1gb;
#endif
if (size < max_code_size)
if (!s_map_file)
{
m_v.emplace_back(x86, size, symbol);
if (s_map_file_opened)
return;
#ifdef ENABLE_VTUNE
std::string name = std::string(symbol);
iJIT_Method_Load ml;
memset(&ml, 0, sizeof(ml));
ml.method_id = iJIT_GetNewMethodID();
ml.method_name = (char*)name.c_str();
ml.method_load_address = (void*)x86;
ml.method_size = size;
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml);
//fprintf(stderr, "mapF %s: %p size %dKB\n", ml.method_name, ml.method_load_address, ml.method_size / 1024u);
#endif
char file[256];
snprintf(file, std::size(file), "/tmp/perf-%d.map", getpid());
s_map_file = std::fopen(file, "wb");
s_map_file_opened = true;
if (!s_map_file)
return;
}
std::fprintf(s_map_file, "%" PRIx64 " %zx %s\n", static_cast<u64>(reinterpret_cast<uintptr_t>(ptr)), size, symbol);
std::fflush(s_map_file);
}
#elif defined(__linux__) && defined(ProfileWithPerfJitDump)
enum : u32
{
JIT_CODE_LOAD = 0,
JIT_CODE_MOVE = 1,
JIT_CODE_DEBUG_INFO = 2,
JIT_CODE_CLOSE = 3,
JIT_CODE_UNWINDING_INFO = 4
};
#pragma pack(push, 1)
struct JITDUMP_HEADER
{
u32 magic = 0x4A695444; // JiTD
u32 version = 1;
u32 header_size = sizeof(JITDUMP_HEADER);
u32 elf_mach;
u32 pad1 = 0;
u32 pid;
u64 timestamp;
u64 flags = 0;
};
struct JITDUMP_RECORD_HEADER
{
u32 id;
u32 total_size;
u64 timestamp;
};
struct JITDUMP_CODE_LOAD
{
JITDUMP_RECORD_HEADER header;
u32 pid;
u32 tid;
u64 vma;
u64 code_addr;
u64 code_size;
u64 code_index;
// name
};
#pragma pack(pop)
static u64 JitDumpTimestamp()
{
struct timespec ts = {};
clock_gettime(CLOCK_MONOTONIC, &ts);
return (static_cast<u64>(ts.tv_sec) * 1000000000ULL) + static_cast<u64>(ts.tv_nsec);
}
void InfoVector::map(uptr x86, u32 size, u32 pc)
static FILE* s_jitdump_file = nullptr;
static bool s_jitdump_file_opened = false;
static std::mutex s_jitdump_mutex;
static u32 s_jitdump_record_id;
static void RegisterMethod(const void* ptr, size_t size, const char* symbol)
{
#ifndef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, m_prefix, pc);
#endif
const u32 namelen = std::strlen(symbol) + 1;
#ifdef ENABLE_VTUNE
iJIT_Method_Load_V2 ml;
std::unique_lock lock(s_jitdump_mutex);
if (!s_jitdump_file)
{
if (!s_jitdump_file_opened)
{
char file[256];
snprintf(file, std::size(file), "jit-%d.dump", getpid());
s_jitdump_file = fopen(file, "w+b");
s_jitdump_file_opened = true;
if (!s_jitdump_file)
return;
}
memset(&ml, 0, sizeof(ml));
void* perf_marker = mmap(nullptr, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, fileno(s_jitdump_file), 0);
pxAssertRel(perf_marker != MAP_FAILED, "Map perf marker");
#ifdef MERGE_BLOCK_RESULT
ml.method_id = m_vtune_id;
ml.method_name = m_prefix;
#else
std::string name = std::string(m_prefix) + "_" + std::to_string(pc);
JITDUMP_HEADER jh = {};
jh.elf_mach = EM_X86_64;
jh.pid = getpid();
jh.timestamp = JitDumpTimestamp();
std::fwrite(&jh, sizeof(jh), 1, s_jitdump_file);
}
JITDUMP_CODE_LOAD cl = {};
cl.header.id = JIT_CODE_LOAD;
cl.header.total_size = sizeof(cl) + namelen + static_cast<u32>(size);
cl.header.timestamp = JitDumpTimestamp();
cl.pid = getpid();
cl.tid = syscall(SYS_gettid);
cl.vma = 0;
cl.code_addr = static_cast<u64>(reinterpret_cast<uintptr_t>(ptr));
cl.code_size = static_cast<u64>(size);
cl.code_index = s_jitdump_record_id++;
std::fwrite(&cl, sizeof(cl), 1, s_jitdump_file);
std::fwrite(symbol, namelen, 1, s_jitdump_file);
std::fwrite(ptr, size, 1, s_jitdump_file);
std::fflush(s_jitdump_file);
}
#elif defined(ENABLE_VTUNE)
static void RegisterMethod(const void* ptr, size_t size, const char* symbol)
{
iJIT_Method_Load_V2 ml = {};
ml.method_id = iJIT_GetNewMethodID();
ml.method_name = (char*)name.c_str();
#endif
ml.method_load_address = (void*)x86;
ml.method_size = size;
ml.method_name = const_cast<char*>(symbol);
ml.method_load_address = const_cast<void*>(ptr);
ml.method_size = static_cast<unsigned int>(size);
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml);
//fprintf(stderr, "mapB %s: %p size %d\n", ml.method_name, ml.method_load_address, ml.method_size);
}
#endif
}
void InfoVector::reset()
#if (defined(__linux__) && (defined(ProfileWithPerf) || defined(ProfileWithPerfJitDump))) || defined(ENABLE_VTUNE)
void Group::Register(const void* ptr, size_t size, const char* symbol)
{
auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; });
m_v.erase(dynamic, m_v.end());
char full_symbol[128];
if (HasPrefix())
std::snprintf(full_symbol, std::size(full_symbol), "%s_%s", m_prefix, symbol);
else
StringUtil::Strlcpy(full_symbol, symbol, std::size(full_symbol));
RegisterMethod(ptr, size, full_symbol);
}
////////////////////////////////////////////////////////////////////////////////
// Global function
////////////////////////////////////////////////////////////////////////////////
void dump()
void Group::RegisterPC(const void* ptr, size_t size, u32 pc)
{
char file[256];
snprintf(file, 250, "/tmp/perf-%d.map", getpid());
FILE* fp = fopen(file, "w");
any.print(fp);
ee.print(fp);
iop.print(fp);
vu.print(fp);
if (fp)
fclose(fp);
char full_symbol[128];
if (HasPrefix())
std::snprintf(full_symbol, std::size(full_symbol), "%s_%08X", m_prefix, pc);
else
std::snprintf(full_symbol, std::size(full_symbol), "%08X", pc);
RegisterMethod(ptr, size, full_symbol);
}
void dump_and_reset()
void Group::RegisterKey(const void* ptr, size_t size, const char* prefix, u64 key)
{
dump();
any.reset();
ee.reset();
iop.reset();
vu.reset();
char full_symbol[128];
if (HasPrefix())
std::snprintf(full_symbol, std::size(full_symbol), "%s_%s%016" PRIX64, m_prefix, prefix, key);
else
std::snprintf(full_symbol, std::size(full_symbol), "%s%016" PRIX64, prefix, key);
RegisterMethod(ptr, size, full_symbol);
}
#else
////////////////////////////////////////////////////////////////////////////////
// Dummy implementation
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char* prefix)
: m_vtune_id(0)
{
}
void InfoVector::map(uptr x86, u32 size, const char* symbol) {}
void InfoVector::map(uptr x86, u32 size, u32 pc) {}
void InfoVector::reset() {}
void dump() {}
void dump_and_reset() {}
void Group::Register(const void* ptr, size_t size, const char* symbol) {}
void Group::RegisterPC(const void* ptr, size_t size, u32 pc) {}
void Group::RegisterKey(const void* ptr, size_t size, const char* prefix, u64 key) {}
#endif
} // namespace Perf

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