Compare commits

...
15 Commits
Author SHA1 Message Date
JordanTheToaster 1810140d1d Core: Split frame limiter in to two wait points 2026-09-09 04:14:30 +02:00
JordanTheToaster 7676b1f73e Counters: Add new Advanced Frame Display setting 2026-09-09 04:14:30 +02:00
TJnotJT bbc57ec622 GS:HW: Fix bpp assertion in GetConvertShader(). 2026-09-09 03:08:21 +02:00
PCSX2 Bot 98697735f1 [ci skip] PAD: Update to latest controller database. 2026-09-07 18:09:09 +02:00
refractionpcsx2 4102a0bd2c VU-JIT: Correct mask for ignoring mac flags on non exact matches 2026-09-07 02:35:34 +02:00
refractionpcsx2 cb3c60557e Build: add hyphens to commit checker 2026-09-07 02:35:34 +02:00
PCSX2 Bot c62d29e6a1 [ci skip] Qt: Update Base Translation. 2026-09-06 20:23:41 -04:00
TJnotJT ac24959c4a GS: Use "coords" in rewrite large ST hack for clarity. 2026-09-07 01:06:22 +02:00
TellowKrinkle 236f67a82f CMake: Minimum Qt is 6.10 2026-09-05 23:14:42 -04:00
JordanTheToaster 4e9c5dcc88 Flatpak: Update KDE runtime to 6.11 2026-09-05 19:53:07 +02:00
PCSX2 Bot 450a39a37c [ci skip] Qt: Update Base Translation. 2026-09-05 02:08:01 +02:00
Tundrak ca0145e6aa InputRecording: Reset controller state after input playback 2026-09-04 11:20:01 -04:00
Tundrak 20c51dd80e Pad: Add functions to reset controller inputs 2026-09-04 11:20:01 -04:00
lightningterror aaf03c18b6 GS/TC: Fix -Wsign-compare warning. 2026-09-04 13:35:32 +02:00
TJnotJT 77bec5e0f5 GS/HW: Rewrite vertices if large ST.
Adds vertex rewriting functionality to both HW/SW. Aggressive version is user hack. Adds a GameDB hack for Ridge Racer V and Destruction Derby Arena. For SW, a less aggressive version is used if the hack is not enabled.
2026-09-04 12:05:30 +02:00
33 changed files with 1937 additions and 1737 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
uses: gsactions/commit-message-checker@16fa2d5de096ae0d35626443bcd24f1e756cafee
with:
accessToken: ${{ secrets.GITHUB_TOKEN }}
pattern: '^[A-Z0-9][A-Za-z0-9 \["\/\\]+:.+'
pattern: '^[A-Z0-9][A-Za-z0-9 \["\/\\-]+:.+'
excludeTitle: true
excludeDescription: true
checkAllCommitMessages: true
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.9
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.10
options: --privileged
timeout-minutes: 60
@@ -1,15 +1,15 @@
{
"app-id": "net.pcsx2.PCSX2",
"runtime": "org.kde.Platform",
"runtime-version": "6.10",
"runtime-version": "6.11",
"sdk": "org.kde.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.llvm20"
"org.freedesktop.Sdk.Extension.llvm22"
],
"add-extensions": {
"org.freedesktop.Platform.ffmpeg-full": {
"directory": "lib/ffmpeg",
"version": "25.08",
"version": "26.08",
"add-ld-path": ".",
"autodownload": true
}
@@ -52,8 +52,8 @@
"-DCMAKE_PREFIX_PATH=\"${FLATPAK_DEST}\"",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON",
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm20/bin/clang",
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm20/bin/clang++",
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm22/bin/clang",
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm22/bin/clang++",
"-DCMAKE_EXE_LINKER_FLAGS_INIT=-fuse-ld=lld",
"-DCMAKE_MODULE_LINKER_FLAGS_INIT=-fuse-ld=lld",
"-DCMAKE_SHARED_LINKER_FLAGS_INIT=-fuse-ld=lld",
+5
View File
@@ -4706,6 +4706,7 @@ SCES-50000:
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
cpuSpriteRenderBW: 1 # Fixes car textures.
cpuSpriteRenderLevel: 1 # Needed for above.
rewriteLargeSTCoords: 1 # Fix reflections on cars.
SCES-50001:
name: "Tekken Tag Tournament"
region: "PAL-M5"
@@ -35387,6 +35388,7 @@ SLPM-60109:
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
cpuSpriteRenderBW: 1 # Fixes car textures.
cpuSpriteRenderLevel: 1 # Needed for above.
rewriteLargeSTCoords: 1 # Fix reflections on cars.
SLPM-60112:
name: "フレースヴェルグ [体験版]"
name-sort: "ふれーすヴぇるぐ [たいけんばん]"
@@ -54809,6 +54811,7 @@ SLPS-20001:
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
cpuSpriteRenderBW: 1 # Fixes car textures.
cpuSpriteRenderLevel: 1 # Needed for above.
rewriteLargeSTCoords: 1 # Fix reflections on cars.
SLPS-20002:
name: "撞球 ビリヤードマスター2"
name-sort: "どうきゅう びりやーどますたー2"
@@ -63501,6 +63504,7 @@ SLPS-71502:
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
cpuSpriteRenderBW: 1 # Fixes car textures.
cpuSpriteRenderLevel: 1 # Needed for above.
rewriteLargeSTCoords: 1 # Fix reflections on cars.
SLPS-72501:
name: "ファイナルファンタジーⅩ [MEGA HITS!]"
name-sort: "ふぁいなるふぁんたじー10 [MEGA HITS!]"
@@ -64503,6 +64507,7 @@ SLUS-20002:
gpuPaletteConversion: 2 # Lots of CLUTs in large textures.
cpuSpriteRenderBW: 1 # Fixes car textures.
cpuSpriteRenderLevel: 1 # Needed for above.
rewriteLargeSTCoords: 1 # Fix reflections on cars.
SLUS-20003:
name: "Portal Runner"
region: "NTSC-U"
+6 -1
View File
@@ -403,6 +403,7 @@
030000006d04000011c2000000000000,Logitech WingMan Cordless,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Windows,
030000004e3700001101000000000000,M64 Pro Controller,a:b0,x:b1,start:b9,leftshoulder:b3,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,-rightx:b7,+rightx:b8,-righty:b5,+righty:b6,lefttrigger:b2,platform:Windows,
03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,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,
03000000380700003888000000000000,Mad Catz Arcade Fightstick TE S Plus PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008532000000000000,Mad Catz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -550,7 +551,7 @@
03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,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:b0,y:b3,platform:Windows,
030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,
030000004f1f00000800000000000000,PS3 Controller,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,
03000000632500007505000000000000,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,
03000000632500007505000000000000,PS3 Controller,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:Windows,
03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows,
03000000888800000804000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,
030000008f0e00000300000000000000,PS3 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:a5,start:b9,x:b3,y:b0,platform:Windows,
@@ -1023,6 +1024,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006d0400001fc2000000000000,Logitech F710,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,
030000006d0400001ac2000004000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000018c2000000010000,Logitech RumblePad 2,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,
030000004e3700001101000000020000,M64 Pro Controller,a:b0,x:b1,start:b9,leftshoulder:b3,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,-rightx:b7,+rightx:b8,-righty:b5,+righty:b6,lefttrigger:b2,platform:Mac OS X,
03000000380700005032000000010000,Mad Catz PS3 Fightpad 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,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000380700008433000000010000,Mad Catz PS3 Fightstick TE S Plus,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,
03000000380700005082000000010000,Mad Catz PS4 Fightpad 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
@@ -1357,6 +1359,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00008001000011010000,Faceoff Pro Nintendo Switch 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000852100000201000010010000,FF GP1,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,
05000000b40400001224000001010000,Flydigi APEX 4,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b20,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000d73700001424000004010000,Flydigi Direwolf 4,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,paddle1:b12,paddle2:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,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,
@@ -1437,6 +1440,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000341a000005f7000010010000,HuiJia GameCube 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,
03000000790000004e95000010010000,Hyperkin N64 Adapter,a:b1,b:b2,start:b9,leftshoulder:b7,rightshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightx:a5,righty:a2,dpup:b12,dpdown:b14,dpleft:b15,dpright:b13,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,
@@ -1483,6 +1487,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006d04000019c2000010010000,Logitech RumblePad 2,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,
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
030000006d04000011c2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
050000004e3700001101000000020000,M64 Pro Controller,a:b0,x:b1,start:b9,leftshoulder:b3,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,-rightx:b7,+rightx:b8,-righty:b5,+righty:b6,lefttrigger:b2,platform:Linux,
05000000380700006652000025010000,Mad Catz CTRLR,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,
03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000380700005032000011010000,Mad Catz Fightpad Pro 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,
+1 -1
View File
@@ -104,7 +104,7 @@ disable_compiler_warnings_for_target(speex)
# Find the Qt components that we need.
if(ENABLE_QT_UI)
find_package(Qt6 6.10.1 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
find_package(Qt6 6.10 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
if(NOT WIN32 AND NOT APPLE)
if (Qt6_VERSION VERSION_GREATER_EQUAL 6.10.0)
@@ -33,6 +33,7 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* settings_dialog
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.syncToHostRefreshRate, "EmuCore/GS", "SyncToHostRefreshRate", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useVSyncForTiming, "EmuCore/GS", "UseVSyncForTiming", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.skipPresentingDuplicateFrames, "EmuCore/GS", "SkipDuplicateFrames", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.advancedFrameDisplay, "EmuCore/GS", "AdvancedFrameDisplay", false);
connect(m_ui.optimalFramePacing, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::onOptimalFramePacingChanged);
connect(m_ui.vsync, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::updateUseVSyncForTimingEnabled);
connect(m_ui.syncToHostRefreshRate, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::updateUseVSyncForTimingEnabled);
@@ -155,6 +156,11 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* settings_dialog
"rendered, it just means the GPU has more time to complete it (this is NOT frame skipping). Can smooth out frame time "
"fluctuations when the CPU/GPU are near maximum utilization, but makes frame pacing more inconsistent and can increase "
"input lag. Helps when using frame generation on 25/30fps games."));
dialog()->registerWidgetHelp(m_ui.advancedFrameDisplay, tr("Advanced Frame Display"), tr("Unchecked"),
tr("Displays the newest frame immediately at the beginning of the "
"frame raster time, instead of at the end. Can reduce perceived "
"input lag, but may cause problems with some games, such as "
"Soulcalibur II and Baldur's Gate Dark Alliance II."));
dialog()->registerWidgetHelp(m_ui.manuallySetRealTimeClock, tr("Manually Set Real-Time Clock"), tr("Unchecked"),
tr("Manually set a real-time clock to use for the virtual PlayStation 2 instead of using your OS' system clock."));
dialog()->registerWidgetHelp(m_ui.rtcDateTime, tr("Real-Time Clock"), tr("Current date and time"),
@@ -263,6 +263,13 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="advancedFrameDisplay">
<property name="text">
<string>Advanced Frame Display</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@@ -271,6 +271,13 @@
</item>
<item row="7" column="0" colspan="2">
<layout class="QGridLayout" name="hwFixesLayout">
<item row="5" column="0">
<widget class="QCheckBox" name="rewriteLargeSTCoords">
<property name="text">
<string>Rewrite Large ST</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="drawBuffering">
<property name="text">
@@ -389,6 +396,7 @@
<tabstop>disableRenderFixes</tabstop>
<tabstop>readTCOnClose</tabstop>
<tabstop>estimateTextureRegion</tabstop>
<tabstop>rewriteLargeSTCoords</tabstop>
</tabstops>
<resources/>
<connections/>
@@ -155,6 +155,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.readTCOnClose, "EmuCore/GS", "UserHacks_ReadTCOnClose", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.estimateTextureRegion, "EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.drawBuffering, "EmuCore/GS", "UserHacks_DrawBuffering", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.rewriteLargeSTCoords, "EmuCore/GS", "UserHacks_RewriteLargeSTCoords", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_fixes.gpuPaletteConversion, "EmuCore/GS", "paltex", false);
connect(m_fixes.cpuSpriteRenderBW, &QComboBox::currentIndexChanged, this,
&GraphicsSettingsWidget::onCPUSpriteRenderBWChanged);
@@ -636,6 +637,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
dialog()->registerWidgetHelp(m_fixes.drawBuffering, tr("Draw Buffering"), tr("Unchecked"),
tr("Attempts to reduce draw calls in games which do heavy context switching for blending purposes."));
dialog()->registerWidgetHelp(m_fixes.rewriteLargeSTCoords, tr("Rewrite Large ST"), tr("Unchecked"),
tr("Rewrite large ST coordinates and clamp the values (mainly for Ridge Racer V and Destruction Derby Arena)."));
}
// Upscaling Fixes tab
File diff suppressed because it is too large Load Diff
+2
View File
@@ -766,6 +766,7 @@ struct Pcsx2Config
DisableFramebufferFetch : 1,
DisableVertexShaderExpand : 1,
SkipDuplicateFrames : 1,
AdvancedFrameDisplay : 1,
OsdShowSpeed : 1,
OsdShowFPS : 1,
OsdShowVPS : 1,
@@ -811,6 +812,7 @@ struct Pcsx2Config
UserHacks_NativePaletteDraw : 1,
UserHacks_EstimateTextureRegion : 1,
UserHacks_DrawBuffering : 1,
UserHacks_RewriteLargeSTCoords : 1,
FXAA : 1,
ShadeBoost : 1,
DumpGSData : 1,
+11 -2
View File
@@ -494,9 +494,12 @@ static __fi void VSyncStart(u64 sCycle)
// Don't bother throttling if we're going to pause.
if (!VMManager::Internal::IsExecutionInterrupted())
VMManager::Internal::Throttle();
VMManager::Internal::Throttle(true);
gsPostVsyncStart(); // MUST be after framelimit; doing so before causes funk with frame times!
if (!EmuConfig.GS.AdvancedFrameDisplay)
{
gsPostVsyncStart(); // MUST be after framelimit; doing so before causes funk with frame times!
}
// Poll input after MTGS frame push, just in case it has to stall to catch up.
VMManager::Internal::PollInputOnCPUThread();
@@ -566,6 +569,12 @@ static __fi void GSVSync()
static __fi void VSyncEnd(u64 sCycle)
{
EECNT_LOG(" ================ EE COUNTER VSYNC END (frame: %d) ================", g_FrameCount);
VMManager::Internal::Throttle(false);
if (EmuConfig.GS.AdvancedFrameDisplay)
{
gsPostVsyncStart();
}
g_FrameCount++;
if (!GSSMODE1reg.SINT)
+2 -1
View File
@@ -174,7 +174,8 @@ The clamp modes are also numerically based.
* cpuSpriteRenderBW [Value between `0` to `10`] {Disabled, 1 (64), 2 (128), 3 (192), 4 (256), 5 (320), 6 (384), 7 (448), 8 (512), 9 (576), 10 (640)} Default: Off (`0`)
* cpuSpriteRenderLevel [`0` or `1` or `2`] {Sprites only, Sprites/Triangles, Blended Sprites/Triangles} Default: Off unless cpuSpriteRenderBW has value other than Off then it is 'Sprites only' (`0`)
* estimateTextureRegion [`0` or `1`] {Off, On} Default: Off (`0`)
* drawBuffering [`0` or `1`] {Off, On} Default: Off (`0`)
* drawBuffering [`0` or `1`] {Off, On} Default: Off (`0`)
* rewriteLargeSTCoords [`0` or `1`] {Off, On} Default: Off (`0`)
* getSkipCount {`GSC` with suffix } {None unless specific game GSC} Default: Disabled (`0`) unless valid variable name (ex. GSC_PolyphonyDigitalGames, GSC_UrbanReign, ...)
* gpuPaletteConversion [`0` or `1`] {Off, On} Default: Off (`0`)
* gpuTargetCLUT [`0` or `1` or `2`] {Disabled, Enabled (Exact Match), Enabled (Check Inside Target)} Default: Disabled (`0`)
+6 -1
View File
@@ -204,7 +204,12 @@
"minimum": 0,
"maximum": 1
},
"drawBuffering": {
"drawBuffering": {
"type": "integer",
"minimum": 0,
"maximum": 1
},
"rewriteLargeSTCoords": {
"type": "integer",
"minimum": 0,
"maximum": 1
+153
View File
@@ -6838,6 +6838,159 @@ GIFRegTEX0 GSState::GetTex0Layer(u32 lod)
return TEX0;
}
// Fix large ST coorindates that may cause graphical glitches.
template <u32 primclass>
void GSState::RewriteVerticesIfLargeSTImpl(const GSVector4& large_val, bool check_clamp_mode)
{
// Need to be texture mapping with ST and not have so many vertices that rewritten indices will overflow.
if (PRIM->TME && PRIM->FST == 0)
{
const float tw = static_cast<float>(1 << m_context->TEX0.TW);
const float th = static_cast<float>(1 << m_context->TEX0.TH);
const GSVector4 tsize = GSVector4(tw, th, 1.0f, 1.0f);
// Only rewrite big/small S or T when the clamping mode is CLAMP or REGION_CLAMP (if requested).
const GIFRegCLAMP& clamp = m_context->CLAMP;
const GSVector4 clamp_mask =
check_clamp_mode ?
GSVector4::cast(GSVector4i(
(clamp.WMS == CLAMP_CLAMP || clamp.WMS == CLAMP_REGION_CLAMP) ? 0xFFFFFFFF : 0,
(clamp.WMT == CLAMP_CLAMP || clamp.WMT == CLAMP_REGION_CLAMP) ? 0xFFFFFFFF : 0,
0,
0)) :
GSVector4::cast(GSVector4i::cxpr(0xFFFFFFFF));
const GSVector4 tex_bbox = m_vt.m_min.t.xyxy(m_vt.m_max.t) / tsize.xyxy();
const bool large_st = ((tex_bbox.abs() >= large_val) & clamp_mask).mask() || m_vt.nan.value;
if (large_st)
{
GL_PUSH("Large ST detected, rewriting vertices.");
if (m_index->tail > UINT16_MAX)
{
GL_INS("Too many vertices to rewrite safely, exiting.");
DevCon.Warning("Large ST detected but too many vertices to rewrite safely.");
return;
}
constexpr int n = GSUtil::GetClassVertexCount(primclass);
// Make sure the copy buffer is large enough.
while (m_max_vertex_count < m_index->tail)
GrowVertexBuffer();
GSVertex* RESTRICT vertex = m_vertex->buff;
GSVertex* RESTRICT vertex_copy = m_vertex->buff_copy;
u16* RESTRICT index = m_index->buff;
const int count = static_cast<int>(m_index->tail);
for (int i = 0; i < count; i += n)
{
GSVector4 stcq[n];
// Load STQ for this primitive.
for (int j = 0; j < n; j++)
stcq[j] = GSVector4::cast(GSVector4i(vertex[index[i + j]].m[0]));
// Perform Q division and see which values need to be rewritten.
GSVector4 uv[n];
GSVector4 small{}, big{}, nan{};
for (int j = 0; j < n; j++)
{
// For sprites always use Q of second vertex.
const GSVector4 q = primclass == GS_SPRITE_CLASS ? stcq[1].wwww() : stcq[j].wwww();
uv[j] = (stcq[j] / q).xyzw(GSVector4::zero());
small |= (uv[j] <= -large_val);
big |= (uv[j] >= large_val);
nan |= (uv[j] != uv[j]);
}
// Get the new values for fields that will be rewritten.
// The follows rules are used:
// 1. If there are small values but not big or nans, make all vertices small.
// 2. If there are big values but not small or nans, make all vertices big.
// 3. If there are both big and small values, or nans, make all vertices zero.
GSVector4 uv_new = GSVector4::zero();
uv_new = uv_new.blend32(-large_val, small);
uv_new = uv_new.blend32(large_val, big);
uv_new = uv_new.blend32(GSVector4::zero(), (small & big) | nan);
const GSVector4 rewrite = (((small | big) & clamp_mask) | nan).xyxy(GSVector4::zero());
// If both S and T are rewritten, no point in keeping Q. Just set it to 1.0f;
if ((rewrite.mask() & 3) == 3)
{
for (int j = 0; j < n; j++)
stcq[j] = stcq[j].template insert32<0, 3>(GSVector4::m_one);
}
// Rewrite the fields that require it and write to the copy buffer.
for (int j = 0; j < n; j++)
{
// For sprites always use Q of second vertex.
const GSVector4 q = (primclass == GS_SPRITE_CLASS) ? stcq[1].wwww() : stcq[j].wwww();
stcq[j] = stcq[j].blend32(uv_new * q, rewrite);
vertex_copy[i + j].m[0] = GSVector4i::cast(stcq[j]);
vertex_copy[i + j].m[1] = vertex[index[i + j]].m[1];
index[i + j] = i + j;
}
}
// Swap the buffers and fix the counts.
std::swap(m_vertex->buff, m_vertex->buff_copy);
m_vertex->head = m_vertex->next = m_vertex->tail = m_index->tail;
// Recalculate ST min/max/eq in the vertex trace.
GSVector4 tmin = GSVector4::cxpr(FLT_MAX);
GSVector4 tmax = GSVector4::cxpr(-FLT_MAX);
for (int i = 0; i < count; i += n)
{
for (int j = 0; j < n; j++)
{
GSVector4 stcq = GSVector4::cast(GSVector4i(m_vertex->buff[i + j].m[0]));
const float q = (primclass == GS_SPRITE_CLASS) ? m_vertex->buff[i + 1].RGBAQ.Q : stcq.w;
stcq = (stcq / q).xyzw(stcq);
tmin = tmin.min(stcq);
tmax = tmax.max(stcq);
}
}
m_vt.m_min.t = tmin.xyww() * tsize;
m_vt.m_max.t = tmax.xyww() * tsize;
m_vt.m_eq.stq = (m_vt.m_min.t == m_vt.m_max.t).mask();
// Dump vertices if needed.
if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()) && GSConfig.SaveInfo)
{
DumpVertices(GetDrawDumpPath("%05d_vertices_st_rewrite.txt", s_n));
}
}
}
}
void GSState::RewriteVerticesIfLargeST(const GSVector4& large_val, bool check_clamp_mode)
{
switch (m_vt.m_primclass)
{
case GS_POINT_CLASS:
RewriteVerticesIfLargeSTImpl<GS_POINT_CLASS>(large_val, check_clamp_mode);
break;
case GS_LINE_CLASS:
RewriteVerticesIfLargeSTImpl<GS_LINE_CLASS>(large_val, check_clamp_mode);
break;
case GS_SPRITE_CLASS:
RewriteVerticesIfLargeSTImpl<GS_SPRITE_CLASS>(large_val, check_clamp_mode);
break;
case GS_TRIANGLE_CLASS:
RewriteVerticesIfLargeSTImpl<GS_TRIANGLE_CLASS>(large_val, check_clamp_mode);
break;
default:
pxFail("Invalid primclass"); // Impossible
break;
}
}
// GSTransferBuffer
GSState::GSTransferBuffer::GSTransferBuffer()
+3
View File
@@ -541,6 +541,9 @@ public:
bool SpriteDrawWithoutGaps();
void CalculatePrimitiveCoversWithoutGaps();
GIFRegTEX0 GetTex0Layer(u32 lod);
template <u32 primclass>
void RewriteVerticesIfLargeSTImpl(const GSVector4& large_val, bool check_clamp_mode);
void RewriteVerticesIfLargeST(const GSVector4& large_val, bool check_clamp_mode);
};
// We put this in the header because of Multi-ISA.
+1 -1
View File
@@ -465,7 +465,7 @@ static inline ShaderConvertSelector GetConvertShader(GSTexture::Format src, GSTe
switch (dst)
{
case GSTexture::Format::Color:
pxAssert(src_bpp == 32 && dst_bpp == 32);
pxAssert(src_bpp == dst_bpp);
shader = ShaderConvert::COPY; // bpp is handled by mask
break;
case GSTexture::Format::DepthColor:
+9
View File
@@ -2901,6 +2901,15 @@ void GSRendererHW::Draw()
// First pass texture shuffle detection using context/vertices.
DetectTextureShuffle();
// Ridge Racer V and Destruction Derby Arena have large ST coordinates in reflection map draws that cause
// speckled artifacts on cars. Detect and rewrite such vertices here.
if (GSConfig.UserHacks_RewriteLargeSTCoords)
{
// The threshold is chosen to be low enough to fix the artifacts in Ridge Racer V and Destruction Derby Arena
// while not breaking anything.
RewriteVerticesIfLargeST(GSVector4::cxpr(16.0f), false);
}
// When the format is 24bit (Z or C), DATE ceases to function.
// It was believed that in 24bit mode all pixels pass because alpha doesn't exist
+2 -2
View File
@@ -1735,8 +1735,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
match = false;
// Situations where font has been uploaded to the alpha channel and they use a different buffer width, this can't currently be translated correctly.
GSLocalMemory::psm_t req_psm = GSLocalMemory::m_psm[psm];
if (!possible_shuffle && req_psm.trbpp <= 8 && req_psm.bpp == 32 && t->m_TEX0.TBW != bw && (bw * 64) != t->m_valid.z && r.w > req_psm.pgs.y)
const GSLocalMemory::psm_t req_psm = GSLocalMemory::m_psm[psm];
if (!possible_shuffle && req_psm.trbpp <= 8 && req_psm.bpp == 32 && t->m_TEX0.TBW != bw && static_cast<int>(bw * 64) != t->m_valid.z && r.w > req_psm.pgs.y)
match = false;
// Different swizzle, different width, and dirty, so probably not what we want.
+18 -136
View File
@@ -287,125 +287,6 @@ void ConvertVertexBuffer(const GSDrawingContext* RESTRICT ctx, GSVertexSW* RESTR
}
}
// Fix ST coordinates that would overflow the rasterizer fixed point format by rewriting the vertices.
template <u32 primclass>
void GSRendererSW::RewriteVerticesIfSTOverflow()
{
if (PRIM->TME && PRIM->FST == 0)
{
const GSVector4 tsize = GSVector4(
static_cast<float>(1 << m_context->TEX0.TW),
static_cast<float>(1 << m_context->TEX0.TH),
1.0f,
1.0f);
// SW rasterizer stores UV in 1.15.16 format so clamp to +/- (2^15 - 2) (-2 so bilinear doesn't overflow).
// Do the division by texture size here to avoid divisions for each vertex.
const GSVector4 OVERFLOW_VAL = GSVector4::cxpr(static_cast<float>((1 << 15) - 2)) / tsize;
// Only rewrite big/small S or T when the clamping mode is CLAMP or REGION_CLAMP.
const GSVector4i clamp_mode = GSVector4i(
(m_context->CLAMP.WMS == CLAMP_CLAMP || m_context->CLAMP.WMS == CLAMP_REGION_CLAMP) ? 0xFFFFFFFF : 0,
(m_context->CLAMP.WMT == CLAMP_CLAMP || m_context->CLAMP.WMT == CLAMP_REGION_CLAMP) ? 0xFFFFFFFF : 0,
0,
0);
const bool st_overflow =
((GSVector4i::cast(m_vt.m_min.t <= -OVERFLOW_VAL * tsize) & clamp_mode).mask() & 3) ||
((GSVector4i::cast(m_vt.m_max.t >= OVERFLOW_VAL * tsize) & clamp_mode).mask() & 3) ||
m_vt.nan.value;
if (st_overflow)
{
constexpr int n = GSUtil::GetClassVertexCount(primclass);
// Make sure the copy buffer is large enough.
while (m_max_vertex_count < m_index->tail)
GrowVertexBuffer();
GSVertex* RESTRICT vertex = m_vertex->buff;
GSVertex* RESTRICT vertex_copy = m_vertex->buff_copy;
u16* RESTRICT index = m_index->buff;
for (int i = 0; i < static_cast<int>(m_index->tail); i += n)
{
GSVector4 stcq[n];
// Load STQ for this primitive.
for (int j = 0; j < n; j++)
stcq[j] = GSVector4::cast(GSVector4i(vertex[index[i + j]].m[0]));
// Perform Q division and see which values need to be rewritten.
GSVector4 uv[n];
GSVector4i small{}, big{}, nan{};
for (int j = 0; j < n; j++)
{
// For sprites always use Q of second vertex.
const GSVector4 q = primclass == GS_SPRITE_CLASS ? stcq[1].wwww() : stcq[j].wwww();
uv[j] = (stcq[j] / q).xyzw(GSVector4::zero());
small |= GSVector4i::cast(uv[j] <= -OVERFLOW_VAL);
big |= GSVector4i::cast(uv[j] >= OVERFLOW_VAL);
nan |= GSVector4i::cast(uv[j] != uv[j]);
}
// Get the new values for fields that will be rewritten.
// The follows rules are used:
// 1. If there are small values but not big or nans, make all vertices small.
// 2. If there are big values but not small or nans, make all vertices big.
// 3. If there are both big and small values, or nans, make all vertices zero.
GSVector4 uv_new = GSVector4::zero();
uv_new = uv_new.blend32(-OVERFLOW_VAL, GSVector4::cast(small));
uv_new = uv_new.blend32(OVERFLOW_VAL, GSVector4::cast(big));
uv_new = uv_new.blend32(GSVector4::zero(), GSVector4::cast((small & big) | nan));
const GSVector4i rewrite = (((small | big) & clamp_mode) | nan).upl64(GSVector4i::zero());
// If both S and T are rewritten, no point in keeping Q. Just set it to 1.0f;
if ((GSVector4::cast(rewrite).mask() & 3) == 3)
{
for (int j = 0; j < n; j++)
stcq[j] = stcq[j].template insert32<0, 3>(GSVector4::m_one);
}
// Rewrite the fields that require it and write to the copy buffer.
for (int j = 0; j < n; j++)
{
// For sprites always use Q of second vertex.
const GSVector4 q = (primclass == GS_SPRITE_CLASS) ? stcq[1].wwww() : stcq[j].wwww();
stcq[j] = stcq[j].blend32(uv_new * q, GSVector4::cast(rewrite));
vertex_copy[i + j].m[0] = GSVector4i::cast(stcq[j]);
vertex_copy[i + j].m[1] = vertex[index[i + j]].m[1];
index[i + j] = i + j;
}
}
// Swap the buffers and fix the counts.
std::swap(m_vertex->buff, m_vertex->buff_copy);
m_vertex->head = m_vertex->next = m_vertex->tail = m_index->tail;
// Recalculate ST min/max/eq in the vertex trace.
GSVector4 tmin = GSVector4::cxpr(FLT_MAX);
GSVector4 tmax = GSVector4::cxpr(-FLT_MAX);
for (int i = 0; i < static_cast<int>(m_index->tail); i += n)
{
for (int j = 0; j < n; j++)
{
GSVector4 stcq = GSVector4::cast(GSVector4i(m_vertex->buff[i + j].m[0]));
const float Q = (primclass == GS_SPRITE_CLASS) ? stcq.w : m_vertex->buff[i + 1].RGBAQ.Q;
stcq = (stcq / Q).xyzw(stcq);
tmin = tmin.min(stcq);
tmax = tmax.max(stcq);
}
}
m_vt.m_min.t = tmin.xyww() * tsize;
m_vt.m_max.t = tmax.xyww() * tsize;
m_vt.m_eq.stq = (m_vt.m_min.t == m_vt.m_max.t).mask();
}
}
}
void GSVertexSWInitStatic()
{
#define InitCVB4(P, T, F, Q) GSVertexSW::s_cvb[P][T][F][Q] = ConvertVertexBuffer<P, T, F, Q>;
@@ -427,24 +308,25 @@ MULTI_ISA_UNSHARED_END
void GSRendererSW::Draw()
{
const GSDrawingContext* context = m_context;
switch (m_vt.m_primclass)
if (!GSConfig.UserHacks_RewriteLargeSTCoords)
{
case GS_POINT_CLASS:
RewriteVerticesIfSTOverflow<GS_POINT_CLASS>();
break;
case GS_LINE_CLASS:
RewriteVerticesIfSTOverflow<GS_LINE_CLASS>();
break;
case GS_TRIANGLE_CLASS:
RewriteVerticesIfSTOverflow<GS_TRIANGLE_CLASS>();
break;
case GS_SPRITE_CLASS:
RewriteVerticesIfSTOverflow<GS_SPRITE_CLASS>();
break;
default:
pxFailRel("Unknown primitive class.");
break;
// SW rasterizer stores UV in 1.15.16 format so clamp to +/- (2^15 - 2) (-2 so bilinear doesn't overflow).
// Also only do this for CLAMP and CLAMP_REGION modes to reduce the performance impact.
const GSVector4 tsize = GSVector4(
static_cast<float>(1 << m_context->TEX0.TW),
static_cast<float>(1 << m_context->TEX0.TH),
1.0f,
1.0f);
// Large value is given in terms of normalized ST / Q coordinates.
const GSVector4 large_val = GSVector4::cxpr(static_cast<float>((1 << 15) - 2)) / tsize;
RewriteVerticesIfLargeST(large_val, true);
}
else
{
// More sensitive as the rewrite threshold is lower and we do it for all clamp mode.
// The performance cost will also be higher.
RewriteVerticesIfLargeST(GSVector4::cxpr(16.0f), false);
}
auto data = m_vertex_heap.make_shared<SharedData>().cast<GSRasterizerData>();
+8
View File
@@ -376,6 +376,7 @@ static const char* s_gs_hw_fix_names[] = {
"nativePaletteDraw",
"estimateTextureRegion",
"drawBuffering",
"rewriteLargeSTCoords",
"PCRTCOffsets",
"PCRTCOverscan",
"trilinearFiltering",
@@ -622,6 +623,9 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
case GSHWFixId::DrawBuffering:
return (static_cast<int>(config.UserHacks_DrawBuffering) == value);
case GSHWFixId::RewriteLargeSTCoords:
return (static_cast<int>(config.UserHacks_RewriteLargeSTCoords) == value);
case GSHWFixId::PCRTCOffsets:
return (static_cast<int>(config.PCRTCOffsets) == value);
@@ -793,6 +797,10 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
config.UserHacks_DrawBuffering = (value > 0);
break;
case GSHWFixId::RewriteLargeSTCoords:
config.UserHacks_RewriteLargeSTCoords = (value > 0);
break;
case GSHWFixId::PCRTCOffsets:
config.PCRTCOffsets = (value > 0);
break;
+1
View File
@@ -61,6 +61,7 @@ namespace GameDatabaseSchema
NativePaletteDraw,
EstimateTextureRegion,
DrawBuffering,
RewriteLargeSTCoords,
PCRTCOffsets,
PCRTCOverscan,
+12
View File
@@ -2658,6 +2658,13 @@ void FullscreenUI::DrawEmulationSettingsPage()
SetSettingsChanged(bsi);
}
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_ANGLES_RIGHT, "Advanced Frame Display"),
FSUI_CSTR("Displays the newest frame immediately at the beginning of the "
"frame raster time, instead of at the end. Can reduce perceived "
"input lag, but may cause problems with some games, such as "
"Soulcalibur II and Baldur's Gate Dark Alliance II. "),
"EmuCore/GS", "AdvancedFrameDisplay", false);
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_SPIN, "Vertical Sync (VSync)"), FSUI_CSTR("Synchronizes frame presentation with host refresh."),
"EmuCore/GS", "VsyncEnable", false);
@@ -3236,6 +3243,9 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_CROP, "Estimate Texture Region"),
FSUI_CSTR("Attempts to reduce the texture size when games do not set it themselves (e.g. Snowblind games)."), "EmuCore/GS",
"UserHacks_EstimateTextureRegion", false, manual_hw_fixes);
DrawToggleSetting(bsi, FSUI_CSTR("Rewrite Large ST"),
FSUI_CSTR("Rewrite large ST coordinates and clamp the values."), "EmuCore/GS",
"UserHacks_RewriteLargeSTCoords", false, manual_hw_fixes);
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_PALETTE, "GPU Palette Conversion"),
FSUI_CSTR("When enabled GPU converts colormap-textures, otherwise the CPU will. It is a trade-off between GPU and CPU."),
"EmuCore/GS", "paltex", false, manual_hw_fixes);
@@ -6014,6 +6024,8 @@ TRANSLATE_NOOP("FullscreenUI", "Removes texture cache entries when there is any
TRANSLATE_NOOP("FullscreenUI", "Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer.");
TRANSLATE_NOOP("FullscreenUI", "Flushes all targets in the texture cache back to local memory when shutting down.");
TRANSLATE_NOOP("FullscreenUI", "Attempts to reduce the texture size when games do not set it themselves (e.g. Snowblind games).");
TRANSLATE_NOOP("FullscreenUI", "Rewrite Large ST");
TRANSLATE_NOOP("FullscreenUI", "Rewrite large ST coordinates and clamp the values.");
TRANSLATE_NOOP("FullscreenUI", "When enabled GPU converts colormap-textures, otherwise the CPU will. It is a trade-off between GPU and CPU.");
TRANSLATE_NOOP("FullscreenUI", "Attempts to reduce draw calls in games which do heavy context switching for blending purposes.");
TRANSLATE_NOOP("FullscreenUI", "Truncate 32-bit depth values to 24 bits. Helps games struggling with Z-fighting.");
+4
View File
@@ -928,6 +928,8 @@ __ri void ImGuiManager::DrawSettingsOverlay(float scale, float margin, float spa
APPEND("MTVU ");
if (EmuConfig.GS.VsyncEnable)
APPEND("VSYNC ");
if (EmuConfig.GS.AdvancedFrameDisplay)
APPEND("AFD ");
APPEND("EER={} EEC={} VUR={} VUC={} VQS={} ", static_cast<unsigned>(EmuConfig.Cpu.FPUFPCR.GetRoundMode()),
EmuConfig.Cpu.Recompiler.GetEEClampMode(), static_cast<unsigned>(EmuConfig.Cpu.VU0FPCR.GetRoundMode()),
@@ -1021,6 +1023,8 @@ __ri void ImGuiManager::DrawSettingsOverlay(float scale, float margin, float spa
APPEND("ETR ");
if (GSConfig.UserHacks_DrawBuffering)
APPEND("DRWB ");
if (GSConfig.UserHacks_RewriteLargeSTCoords)
APPEND("RWST ");
if (GSConfig.HWSpinGPUForReadbacks)
APPEND("RBSG ");
if (GSConfig.HWSpinCPUForReadbacks)
+4
View File
@@ -723,6 +723,7 @@ Pcsx2Config::GSOptions::GSOptions()
DisableFramebufferFetch = false;
DisableVertexShaderExpand = false;
SkipDuplicateFrames = true;
AdvancedFrameDisplay = false;
OsdMessagesPos = OsdOverlayPos::TopLeft;
OsdPerformancePos = OsdOverlayPos::TopRight;
OsdShowSpeed = false;
@@ -961,6 +962,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBool(DisableFramebufferFetch);
SettingsWrapBitBool(DisableVertexShaderExpand);
SettingsWrapBitBool(SkipDuplicateFrames);
SettingsWrapBitBool(AdvancedFrameDisplay);
SettingsWrapBitBool(OsdShowSpeed);
SettingsWrapBitBool(OsdShowFPS);
SettingsWrapBitBool(OsdShowVPS);
@@ -1005,6 +1007,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapIntEnumEx(UserHacks_Limit24BitDepth, "UserHacks_Limit24BitDepth");
SettingsWrapBitBoolEx(UserHacks_EstimateTextureRegion, "UserHacks_EstimateTextureRegion");
SettingsWrapBitBoolEx(UserHacks_DrawBuffering, "UserHacks_DrawBuffering");
SettingsWrapBitBoolEx(UserHacks_RewriteLargeSTCoords, "UserHacks_RewriteLargeSTCoords");
SettingsWrapBitBoolEx(FXAA, "fxaa");
SettingsWrapBitBool(ShadeBoost);
SettingsWrapBitBoolEx(DumpGSData, "DumpGSData");
@@ -1145,6 +1148,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
UserHacks_Limit24BitDepth = GSLimit24BitDepth::Disabled;
UserHacks_EstimateTextureRegion = false;
UserHacks_DrawBuffering = false;
UserHacks_RewriteLargeSTCoords = false;
UserHacks_TCOffsetX = 0;
UserHacks_TCOffsetY = 0;
UserHacks_CPUSpriteRenderBW = 0;
+2 -3
View File
@@ -23,8 +23,6 @@ bool SaveStateBase::InputRecordingFreeze()
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "Counters.h"
#include "SaveState.h"
#include "VMManager.h"
#include "Host.h"
#include "ImGui/ImGuiOverlays.h"
@@ -32,7 +30,7 @@ bool SaveStateBase::InputRecordingFreeze()
#include "GameDatabase.h"
#include "fmt/format.h"
#include "GS.h"
#include "Host.h"
#include "SIO/Pad/Pad.h"
InputRecording g_InputRecording;
@@ -139,6 +137,7 @@ void InputRecording::closeActiveFile()
if (m_file.close())
{
m_is_active = false;
Pad::ResetAllControllerInputs();
InputRec::log(TRANSLATE_STR("InputRecording", "Input recording stopped"), Host::OSD_ERROR_DURATION);
MTGS::PresentCurrentFrame();
}
@@ -7,6 +7,7 @@
#include "InputRecording.h"
#include "InputRecordingControls.h"
#include "Utilities/InputRecordingLogger.h"
#include "SIO/Pad/Pad.h"
#include "Host.h"
#include "MTGS.h"
@@ -29,6 +30,7 @@ void InputRecordingControls::setRecordMode(bool waitForFrameToEnd)
if (!waitForFrameToEnd || VMManager::GetState() == VMState::Paused)
{
m_state = Mode::Recording;
Pad::ResetAllControllerInputs();
InputRec::log(TRANSLATE("InputRecordingControls","Record Mode Enabled"), Host::OSD_INFO_DURATION);
MTGS::PresentCurrentFrame();
}
@@ -36,6 +38,7 @@ void InputRecordingControls::setRecordMode(bool waitForFrameToEnd)
{
m_controlQueue.push([&]() {
m_state = Mode::Recording;
Pad::ResetAllControllerInputs();
InputRec::log(TRANSLATE("InputRecordingControls","Record Mode Enabled"), Host::OSD_INFO_DURATION);
});
}
+26
View File
@@ -554,6 +554,32 @@ void Pad::SetControllerState(u32 controller, u32 bind, float value)
s_controllers[controller]->Set(bind, value);
}
void Pad::ResetControllerInputs(u32 controller)
{
if (controller >= NUM_CONTROLLER_PORTS || !HasConnectedPad(controller))
return;
for (InputBindingInfo binding : s_controllers[controller]->GetInfo().bindings)
{
switch (binding.bind_type)
{
case InputBindingInfo::Type::Button:
case InputBindingInfo::Type::Axis:
case InputBindingInfo::Type::HalfAxis:
s_controllers[controller]->Set(binding.bind_index, 0);
break;
default:
break;
}
}
}
void Pad::ResetAllControllerInputs()
{
for (u32 port = 0; port < NUM_CONTROLLER_PORTS; port++)
ResetControllerInputs(port);
}
bool Pad::Freeze(StateWrapper& sw)
{
if (sw.IsReading())
+4
View File
@@ -66,6 +66,10 @@ namespace Pad
// Sets the specified bind on a controller to the specified pressure (normalized to 0..1).
void SetControllerState(u32 controller, u32 bind, float value);
// Resets all input binds on a controller to their default state.
void ResetControllerInputs(u32 controller);
void ResetAllControllerInputs();
bool Freeze(StateWrapper& sw);
// Sets the state of the specified macro button.
+12 -4
View File
@@ -2272,14 +2272,14 @@ void VMManager::ResetFrameLimiter()
s_limiter_frame_start = GetCPUTicks();
}
void VMManager::Internal::Throttle()
void VMManager::Internal::Throttle(bool vsync_start)
{
if (s_target_speed == 0.0f || s_use_vsync_for_timing)
return;
const u64 uExpectedEnd =
s_limiter_frame_start +
s_limiter_ticks_per_frame; // Compute when we would expect this frame to end, assuming everything goes perfectly perfect.
(vsync_start ? (s_limiter_ticks_per_frame * 0.9) : s_limiter_ticks_per_frame); // Compute when we would expect this frame to end, assuming everything goes perfectly perfect.
const u64 iEnd = GetCPUTicks(); // The current tick we actually stopped on.
const s64 sDeltaTime = iEnd - uExpectedEnd; // The diff between when we stopped and when we expected to.
@@ -2308,8 +2308,11 @@ void VMManager::Internal::Throttle()
{
}
// Finally, set our next frame start to when this one ends
s_limiter_frame_start = uExpectedEnd;
if (!vsync_start)
{
// Finally, set our next frame start to when this one ends
s_limiter_frame_start = uExpectedEnd;
}
}
void VMManager::Internal::FrameRateChanged()
@@ -3279,6 +3282,11 @@ void VMManager::WarnAboutUnsafeSettings()
append(ICON_FA_CIRCLE_EXCLAMATION,
TRANSLATE_SV("VMManager", "Draw Buffering is enabled, this may result in graphical errors."));
}
if (EmuConfig.GS.UserHacks_RewriteLargeSTCoords)
{
append(ICON_FA_CIRCLE_EXCLAMATION,
TRANSLATE_SV("VMManager", "Rewrite large ST is enabled, this may reduce performance."));
}
if (EmuConfig.GS.DumpReplaceableTextures)
{
append(ICON_FA_CIRCLE_EXCLAMATION,
+1 -1
View File
@@ -322,7 +322,7 @@ namespace VMManager
void FrameRateChanged();
/// Throttles execution, or limits the frame rate.
void Throttle();
void Throttle(bool vsync_start);
/// Resets/clears all execution/code caches.
void ClearCPUExecutionCaches();
+2 -1
View File
@@ -237,7 +237,8 @@ public:
// if we're using the flag hack, ignore the mac flags going in to the new block too if an exact match wasn't requested.
if (mVUsFlagHack)
{
if ((ref.quick & ~0x0C04) != (quick64 & ~0x0C04)) continue;
if ((ref.quick & ~0x3002) != (quick64 & ~0x3002))
continue;
}
else if (ref.quick != quick64) continue;