mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e971a9ebf5 | ||
|
|
19f85713ce | ||
|
|
4c41de6013 | ||
|
|
96f9cde1bc | ||
|
|
3feef0824c | ||
|
|
5f2ab55c93 | ||
|
|
0f75bfe17d | ||
|
|
7faa132622 | ||
|
|
b69e6da105 | ||
|
|
11edb128e9 | ||
|
|
fc4407aaef | ||
|
|
2a418e3282 | ||
|
|
59415542ff |
@@ -22205,18 +22205,28 @@ SLES-53142:
|
||||
SLES-53143:
|
||||
name: "Fantastic 4"
|
||||
region: "PAL-E"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLES-53144:
|
||||
name: "4 Fantastiques, Les"
|
||||
region: "PAL-F"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLES-53145:
|
||||
name: "Fantastic 4"
|
||||
region: "PAL-G"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLES-53146:
|
||||
name: "I Fantastici Quattro"
|
||||
region: "PAL-I"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLES-53147:
|
||||
name: "4 Fantásticos, Los"
|
||||
region: "PAL-S"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLES-53148:
|
||||
name: "Fruitfall"
|
||||
region: "PAL-E"
|
||||
@@ -22461,6 +22471,8 @@ SLES-53280:
|
||||
SLES-53281:
|
||||
name: "Fantastic 4"
|
||||
region: "PAL-NL"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLES-53282:
|
||||
name: "Harvest Fishing"
|
||||
region: "PAL-E"
|
||||
@@ -35029,6 +35041,9 @@ SLPM-60279:
|
||||
name-en: "Kamen Rider Kabuto [Trial]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes post-processing alignment.
|
||||
nativeScaling: 1 # Fixes post-processing alignment.
|
||||
textureInsideRT: 1 # Fixes garbage and missing effects.
|
||||
autoFlush: 1 # Fixes garbage corruptions on the bottom of the screen.
|
||||
SLPM-60280:
|
||||
name: "電撃PS2 PlayStation 2 SAVE DATA COLLECTION 2007"
|
||||
@@ -55672,6 +55687,9 @@ SLPS-20483:
|
||||
name-en: "Kamen Rider Kabuto"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes post-processing alignment.
|
||||
nativeScaling: 1 # Fixes post-processing alignment.
|
||||
textureInsideRT: 1 # Fixes garbage and missing effects.
|
||||
autoFlush: 1 # Fixes garbage corruptions on the bottom of the screen.
|
||||
SLPS-20484:
|
||||
name: "SIMPLE2000シリーズ Ultimate Vol.34 魁!!男塾"
|
||||
@@ -65659,6 +65677,8 @@ SLUS-20615:
|
||||
name: "Fantastic 4"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 5 # Fixes large depth line.
|
||||
SLUS-20616:
|
||||
name: "Virtua Fighter 4 - Evolution"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -262,6 +262,8 @@
|
||||
030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
|
||||
03000000ac0500006b05000000000000,GT2a,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,
|
||||
03000000341a00000302000000000000,Hama Scorpad,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,
|
||||
030000008a2e0000dd10000000000000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Windows,
|
||||
030000008a2e0000df10000000000000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Windows,
|
||||
030000000d0f00004900000000000000,Hatsune Miku Sho 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,
|
||||
030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
|
||||
030000000d0f00000c00000000000000,HEXT,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,
|
||||
@@ -1130,6 +1132,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000005e040000e302000000000000,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,
|
||||
030000005e040000ea02000000000000,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,
|
||||
030000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b16,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,
|
||||
030000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000c62400003a54000000000000,Xbox One PowerA 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,
|
||||
030000005e040000130b000001050000,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:Mac OS X,
|
||||
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:Mac OS X,
|
||||
@@ -1329,6 +1332,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,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:b2,y:b3,platform:Linux,
|
||||
0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,
|
||||
03000000f0250000c383000010010000,GT VX2,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:Linux,
|
||||
030000008a2e0000dd10000011010000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Linux,
|
||||
030000008a2e0000df10000011010000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Linux,
|
||||
06000000adde0000efbe000002010000,Hidromancer 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,
|
||||
03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
|
||||
03000000c9110000f055000011010000,HJC 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,
|
||||
@@ -1793,10 +1798,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
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,
|
||||
030000005e040000ea02000011050000,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,
|
||||
030000005e040000ea02000015050000,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,
|
||||
030000005e040000ea02000017050000,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,
|
||||
060000005e040000ea0200000b050000,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,
|
||||
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,
|
||||
060000005e040000ea02000016050000,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,
|
||||
030000005e040000ea02000017050000,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,
|
||||
@@ -1822,8 +1827,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000005e040000130b000022050000,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,
|
||||
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,
|
||||
050000005e040000200b000017050000,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,
|
||||
050000005e040000220b000017050000,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,
|
||||
050000005e040000200b000023050000,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,
|
||||
050000005e040000220b000017050000,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,
|
||||
03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
|
||||
|
||||
@@ -1301,9 +1301,7 @@ VS_OUTPUT vs_main_expand(uint vid : SV_VertexID)
|
||||
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;
|
||||
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));
|
||||
|
||||
|
||||
@@ -174,11 +174,7 @@ void main()
|
||||
|
||||
bool is_bottom = (vid & 2u) != 0u;
|
||||
bool is_right = (vid & 1u) != 0u;
|
||||
#ifdef VS_PROVOKING_VERTEX_LAST
|
||||
uint vid_other = is_bottom ? vid_base - 1 : vid_base + 1;
|
||||
#else
|
||||
uint vid_other = is_bottom ? vid_base + 1 : vid_base - 1;
|
||||
#endif
|
||||
|
||||
vtx = load_vertex(vid_base);
|
||||
ProcessedVertex other = load_vertex(vid_other);
|
||||
|
||||
@@ -599,6 +599,7 @@ void MemorySearchView::onSearchButtonClicked()
|
||||
connect(workerWatcher, &QFutureWatcher<std::vector<u32>>::finished, onSearchFinished);
|
||||
|
||||
m_ui.btnSearch->setDisabled(true);
|
||||
m_ui.btnFilterSearch->setDisabled(true);
|
||||
if (!isFilterSearch)
|
||||
{
|
||||
m_searchResults.clear();
|
||||
|
||||
@@ -34,10 +34,12 @@
|
||||
#include "pcsx2/Recording/InputRecording.h"
|
||||
#include "pcsx2/Recording/InputRecordingControls.h"
|
||||
#include "pcsx2/SIO/Sio.h"
|
||||
#include "pcsx2/GS/GSExtra.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CocoaTools.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QDir>
|
||||
@@ -1454,6 +1456,8 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point)
|
||||
connect(menu.addAction(tr("Check Wiki Page")), &QAction::triggered, [this, entry]() { goToWikiPage(entry); });
|
||||
}
|
||||
|
||||
action = menu.addAction(tr("Open Screenshots Folder"));
|
||||
connect(action, &QAction::triggered, [this, entry]() { openScreenshotsFolderForGame(entry); });
|
||||
menu.addSeparator();
|
||||
|
||||
if (!s_vm_valid)
|
||||
@@ -2905,6 +2909,39 @@ void MainWindow::goToWikiPage(const GameList::Entry* entry)
|
||||
QtUtils::OpenURL(this, fmt::format("https://wiki.pcsx2.net/{}", entry->serial).c_str());
|
||||
}
|
||||
|
||||
void MainWindow::openScreenshotsFolderForGame(const GameList::Entry* entry)
|
||||
{
|
||||
if (!entry || entry->title.empty())
|
||||
return;
|
||||
|
||||
// if disabled open the snapshots folder
|
||||
if (!EmuConfig.GS.OrganizeScreenshotsByGame)
|
||||
{
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(QString::fromStdString(EmuFolders::Snapshots)));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string game_name = entry->title;
|
||||
Path::SanitizeFileName(&game_name);
|
||||
if (game_name.length() > 219)
|
||||
{
|
||||
game_name.resize(219);
|
||||
}
|
||||
const std::string game_dir = Path::Combine(EmuFolders::Snapshots, game_name);
|
||||
|
||||
if (!FileSystem::DirectoryExists(game_dir.c_str()))
|
||||
{
|
||||
if (!FileSystem::CreateDirectoryPath(game_dir.c_str(), false))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to create screenshots directory '%1'.").arg(QString::fromStdString(game_dir)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const QFileInfo fi(QString::fromStdString(game_dir));
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(fi.absoluteFilePath()));
|
||||
}
|
||||
|
||||
std::optional<bool> MainWindow::promptForResumeState(const QString& save_state_path)
|
||||
{
|
||||
if (save_state_path.isEmpty())
|
||||
|
||||
@@ -274,6 +274,7 @@ private:
|
||||
void setGameListEntryCoverImage(const GameList::Entry* entry);
|
||||
void clearGameListEntryPlayTime(const GameList::Entry* entry);
|
||||
void goToWikiPage(const GameList::Entry* entry);
|
||||
void openScreenshotsFolderForGame(const GameList::Entry* entry);
|
||||
|
||||
std::optional<bool> promptForResumeState(const QString& save_state_path);
|
||||
void loadSaveStateSlot(s32 slot, bool load_backup = false);
|
||||
|
||||
@@ -53,9 +53,6 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.gameFixes, "EmuCore", "EnableGameFixes", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.patches, "EmuCore", "EnablePatches", true);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.ntscFrameRate, "EmuCore/GS", "FramerateNTSC", 59.94f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.palFrameRate, "EmuCore/GS", "FrameratePAL", 50.00f);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.savestateSelector, tr("Use Save State Selector"), tr("Checked"),
|
||||
tr("Show a save state selector UI when switching slots instead of showing a notification bubble."));
|
||||
|
||||
|
||||
@@ -508,61 +508,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="framerateControlSettings">
|
||||
<property name="title">
|
||||
<string>Frame Rate Control</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="framerateControlLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="palFrameRate">
|
||||
<property name="suffix">
|
||||
<string extracomment="hz=Hertz, as in the measuring unit. Shown after the corresponding number. Those languages who'd need to remove the space or do something in between should do so."> hz</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>300.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="ntscFrameRate">
|
||||
<property name="suffix">
|
||||
<string> hz</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>300.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="palLabel">
|
||||
<property name="text">
|
||||
<string>PAL Frame Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="ntscLabel">
|
||||
<property name="text">
|
||||
<string>NTSC Frame Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="pineSettings">
|
||||
<property name="title">
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <algorithm>
|
||||
|
||||
#include "FolderSettingsWidget.h"
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsWindow.h"
|
||||
|
||||
@@ -18,8 +20,14 @@ FolderSettingsWidget::FolderSettingsWidget(SettingsWindow* dialog, QWidget* pare
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.cheats, m_ui.cheatsBrowse, m_ui.cheatsOpen, m_ui.cheatsReset, "Folders", "Cheats", Path::Combine(EmuFolders::DataRoot, "cheats"));
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.covers, m_ui.coversBrowse, m_ui.coversOpen, m_ui.coversReset, "Folders", "Covers", Path::Combine(EmuFolders::DataRoot, "covers"));
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.snapshots, m_ui.snapshotsBrowse, m_ui.snapshotsOpen, m_ui.snapshotsReset, "Folders", "Snapshots", Path::Combine(EmuFolders::DataRoot, "snaps"));
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.organizeScreenshotsByGame, "EmuCore/GS", "OrganizeScreenshotsByGame", false);
|
||||
connect(m_ui.organizeScreenshotsByGame, &QCheckBox::checkStateChanged, this, [](int state) {
|
||||
GSConfig.OrganizeScreenshotsByGame = (state == Qt::Checked);
|
||||
});
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.saveStates, m_ui.saveStatesBrowse, m_ui.saveStatesOpen, m_ui.saveStatesReset, "Folders", "SaveStates", Path::Combine(EmuFolders::DataRoot, "sstates"));
|
||||
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.videoDumpingDirectory, m_ui.videoDumpingDirectoryBrowse, m_ui.videoDumpingDirectoryOpen, m_ui.videoDumpingDirectoryReset, "Folders", "Videos", Path::Combine(EmuFolders::DataRoot, "videos"));
|
||||
dialog->registerWidgetHelp(m_ui.organizeScreenshotsByGame, tr("Organize Screenshots by Game"), tr("Unchecked"),
|
||||
tr("When enabled, screenshots will be saved in a folder with the game's name, instead of all being saved in the Snapshots folder"));
|
||||
}
|
||||
|
||||
FolderSettingsWidget::~FolderSettingsWidget() = default;
|
||||
|
||||
@@ -175,12 +175,19 @@
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="snaphotsLabel">
|
||||
<property name="text">
|
||||
<string>Used for screenshots and saving GS dumps.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<property name="text">
|
||||
<string>Used for screenshots and saving GS dumps.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QCheckBox" name="organizeScreenshotsByGame">
|
||||
<property name="text">
|
||||
<string>Save Screenshots in Game-Specific Folders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
|
||||
@@ -130,7 +130,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowHardwareInfo, "EmuCore/GS", "OsdShowHardwareInfo", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowVideoCapture, "EmuCore/GS", "OsdShowVideoCapture", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowInputRec, "EmuCore/GS", "OsdShowInputRec", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdWarnAboutUnsafeSettings, "EmuCore", "osdWarnAboutUnsafeSettings", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdWarnAboutUnsafeSettings, "EmuCore", "OsdWarnAboutUnsafeSettings", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fxaa, "EmuCore/GS", "fxaa", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.shadeBoost, "EmuCore/GS", "ShadeBoost", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.shadeBoostBrightness, "EmuCore/GS", "ShadeBoost_Brightness", false);
|
||||
@@ -254,6 +254,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableVertexShaderExpand, "EmuCore/GS", "DisableVertexShaderExpand", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
sif, m_ui.gsDownloadMode, "EmuCore/GS", "HWDownloadMode", static_cast<int>(GSHardwareDownloadMode::Enabled));
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.ntscFrameRate, "EmuCore/GS", "FrameRateNTSC", 59.94f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.palFrameRate, "EmuCore/GS", "FrameRatePAL", 50.00f);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SW Settings
|
||||
@@ -392,6 +394,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||
m_ui.useBlitSwapChain = nullptr;
|
||||
m_ui.disableMailboxPresentation = nullptr;
|
||||
m_ui.extendedUpscales = nullptr;
|
||||
m_ui.ntscFrameRate = nullptr;
|
||||
m_ui.palFrameRate = nullptr;
|
||||
m_ui.spinCPUDuringReadbacks = nullptr;
|
||||
m_ui.spinGPUDuringReadbacks = nullptr;
|
||||
m_ui.overrideTextureBarriers = nullptr;
|
||||
@@ -857,6 +861,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
||||
tr("Skips synchronizing with the GS thread and host GPU for GS downloads. "
|
||||
"Can result in a large speed boost on slower systems, at the cost of many broken graphical effects. "
|
||||
"If games are broken and you have this option enabled, please disable it first."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.ntscFrameRate, tr("NTSC Frame Rate"), tr("59.94 Hz"),
|
||||
tr("Determines what frame rate NTSC games run at."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.palFrameRate, tr("PAL Frame Rate"), tr("50.00 Hz"),
|
||||
tr("Determines what frame rate PAL games run at."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<height>588</height>
|
||||
<width>722</width>
|
||||
<height>626</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -55,12 +55,12 @@
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabs">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="gameDisplayTab">
|
||||
<widget class="QWidget" name="gameDisplayTab">
|
||||
<attribute name="title">
|
||||
<string>Display</string>
|
||||
</attribute>
|
||||
@@ -391,7 +391,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="hardwareRenderingTab">
|
||||
<widget class="QWidget" name="hardwareRenderingTab">
|
||||
<attribute name="title">
|
||||
<string>Rendering</string>
|
||||
</attribute>
|
||||
@@ -652,7 +652,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="hardwareFixesTab">
|
||||
<widget class="QWidget" name="hardwareFixesTab">
|
||||
<attribute name="title">
|
||||
<string>Hardware Fixes</string>
|
||||
</attribute>
|
||||
@@ -950,7 +950,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="upscalingFixesTab">
|
||||
<widget class="QWidget" name="upscalingFixesTab">
|
||||
<attribute name="title">
|
||||
<string>Upscaling Fixes</string>
|
||||
</attribute>
|
||||
@@ -1470,7 +1470,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="osdTab">
|
||||
<widget class="QWidget" name="osdTab">
|
||||
<attribute name="title">
|
||||
<string>OSD</string>
|
||||
</attribute>
|
||||
@@ -1837,7 +1837,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="recordingTab">
|
||||
<widget class="QWidget" name="recordingTab">
|
||||
<attribute name="title">
|
||||
<string>Media Capture</string>
|
||||
</attribute>
|
||||
@@ -2158,7 +2158,7 @@
|
||||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@@ -2170,248 +2170,394 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="advancedTab">
|
||||
<widget class="QWidget" name="advancedTab">
|
||||
<attribute name="title">
|
||||
<string extracomment="Advanced here refers to the advanced graphics options.">Advanced</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="advancedTabLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="advancedOptions">
|
||||
<property name="title">
|
||||
<string>Advanced Options</string>
|
||||
<widget class="QScrollArea" name="advancedScrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="advancedOptionsFormLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="hwDownloadModeLabel">
|
||||
<property name="text">
|
||||
<string>Hardware Download Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="gsDownloadMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Accurate (Recommended)</string>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="advancedScrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>722</width>
|
||||
<height>499</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>499</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="advancedOptions">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disable Readbacks (Synchronize GS Thread)</string>
|
||||
<property name="title">
|
||||
<string>Advanced Options</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unsynchronized (Non-Deterministic)</string>
|
||||
<layout class="QFormLayout" name="advancedOptionsFormLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="hwDownloadModeLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hardware Download Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="gsDownloadMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Accurate (Recommended)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disable Readbacks (Synchronize GS Thread)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unsynchronized (Non-Deterministic)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled (Ignore Transfers)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="gsDumpCompressionLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>GS Dump Compression:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="gsDumpCompression">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Uncompressed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>LZMA (xz)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Zstandard (zst)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="advancedLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="extendedUpscales">
|
||||
<property name="text">
|
||||
<string>Extended Upscaling Multipliers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="disableMailboxPresentation">
|
||||
<property name="text">
|
||||
<string extracomment="Mailbox Presentation: a type of graphics-rendering technique that has not been exposed to the public that often, so chances are you will need to keep the word mailbox in English. It does not have anything to do with postal mailboxes or email inboxes/outboxes.">Disable Mailbox Presentation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="useBlitSwapChain">
|
||||
<property name="text">
|
||||
<string extracomment="Blit = a data operation. You might want to write it as-is, but fully uppercased. More information: https://en.wikipedia.org/wiki/Bit_blit \nSwap chain: see Microsoft's Terminology Portal.">Use Blit Swap Chain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="spinCPUDuringReadbacks">
|
||||
<property name="text">
|
||||
<string>Spin CPU During Readbacks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="spinGPUDuringReadbacks">
|
||||
<property name="text">
|
||||
<string>Spin GPU During Readbacks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="exclussiveFSLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow Exclusive Fullscreen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="exclusiveFullscreenControl">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disallowed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Allowed</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="texturePreloading">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Partial</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full (Hash Cache)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Texture Preloading:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="frameRateOptions">
|
||||
<property name="title">
|
||||
<string>Frame Rate Options</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled (Ignore Transfers)</string>
|
||||
<layout class="QGridLayout" name="frameRateOptionsFormLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="ntscLabel">
|
||||
<property name="text">
|
||||
<string>NTSC Frame Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="ntscFrameRate">
|
||||
<property name="suffix">
|
||||
<string extracomment="Hz=Hertz, as in the measuring unit. Shown after the corresponding number. Those languages who'd need to remove the space or do something in between should do so."> Hz</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>300.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="palLabel">
|
||||
<property name="text">
|
||||
<string>PAL Frame Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="palFrameRate">
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>300.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="debuggingOptions">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="gsDumpCompressionLabel">
|
||||
<property name="text">
|
||||
<string>GS Dump Compression:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="gsDumpCompression">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Uncompressed</string>
|
||||
<property name="title">
|
||||
<string>Debugging Options</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>LZMA (xz)</string>
|
||||
<layout class="QFormLayout" name="debuggingOptionsFormLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="barriersLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Override Texture Barriers:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="overrideTextureBarriers">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Enabled</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="debuggingOptionsLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="disableFramebufferFetch">
|
||||
<property name="text">
|
||||
<string>Disable Framebuffer Fetch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="disableShaderCache">
|
||||
<property name="text">
|
||||
<string>Disable Shader Cache</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="disableVertexShaderExpand">
|
||||
<property name="text">
|
||||
<string>Disable Vertex Shader Expand</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Zstandard (zst)</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="advancedLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="extendedUpscales">
|
||||
<property name="text">
|
||||
<string>Extended Upscaling Multipliers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="disableMailboxPresentation">
|
||||
<property name="text">
|
||||
<string extracomment="Mailbox Presentation: a type of graphics-rendering technique that has not been exposed to the public that often, so chances are you will need to keep the word mailbox in English. It does not have anything to do with postal mailboxes or email inboxes/outboxes.">Disable Mailbox Presentation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="useBlitSwapChain">
|
||||
<property name="text">
|
||||
<string extracomment="Blit = a data operation. You might want to write it as-is, but fully uppercased. More information: https://en.wikipedia.org/wiki/Bit_blit \nSwap chain: see Microsoft's Terminology Portal.">Use Blit Swap Chain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="spinCPUDuringReadbacks">
|
||||
<property name="text">
|
||||
<string>Spin CPU During Readbacks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="spinGPUDuringReadbacks">
|
||||
<property name="text">
|
||||
<string>Spin GPU During Readbacks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="exclussiveFSLabel">
|
||||
<property name="text">
|
||||
<string>Allow Exclusive Fullscreen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="exclusiveFullscreenControl">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disallowed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Allowed</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="texturePreloading">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Partial</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full (Hash Cache)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Texture Preloading:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="debuggingOptions">
|
||||
<property name="title">
|
||||
<string>Debugging Options</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="debuggingOptionsFormLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="barriersLabel">
|
||||
<property name="text">
|
||||
<string>Override Texture Barriers:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="overrideTextureBarriers">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Enabled</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="debuggingOptionsLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="disableFramebufferFetch">
|
||||
<property name="text">
|
||||
<string>Disable Framebuffer Fetch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="disableShaderCache">
|
||||
<property name="text">
|
||||
<string>Disable Shader Cache</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="disableVertexShaderExpand">
|
||||
<property name="text">
|
||||
<string>Disable Vertex Shader Expand</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
@@ -781,7 +781,8 @@ struct Pcsx2Config
|
||||
EnableVideoCaptureParameters : 1,
|
||||
VideoCaptureAutoResolution : 1,
|
||||
EnableAudioCapture : 1,
|
||||
EnableAudioCaptureParameters : 1;
|
||||
EnableAudioCaptureParameters : 1,
|
||||
OrganizeScreenshotsByGame : 1;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -205,8 +205,10 @@ const tMipsOpcode MipsOpcodes[] = {
|
||||
{ "dsrav", "d,s", MIPS_SPECIAL(0x17), MA_MIPS3, MO_64BIT|MO_RDT },
|
||||
{ "clo", "d,s", MIPS_SPECIAL(0x17), MA_PSP, 0 },
|
||||
{ "mult", "s,t", MIPS_SPECIAL(0x18), MA_MIPS1, 0 },
|
||||
{ "mult", "d,s,t", MIPS_SPECIAL(0x18), MA_PS2, 0 },
|
||||
{ "mult", "r\x0,s,t", MIPS_SPECIAL(0x18), MA_MIPS1, 0 },
|
||||
{ "multu", "s,t", MIPS_SPECIAL(0x19), MA_MIPS1, 0 },
|
||||
{ "multu", "d,s,t", MIPS_SPECIAL(0x19), MA_PS2, 0 },
|
||||
{ "multu", "r\x0,s,t", MIPS_SPECIAL(0x19), MA_MIPS1, 0 },
|
||||
{ "div", "s,t", MIPS_SPECIAL(0x1A), MA_MIPS1, 0 },
|
||||
{ "div", "r\x0,s,t", MIPS_SPECIAL(0x1A), MA_MIPS1, 0 },
|
||||
|
||||
@@ -27,11 +27,6 @@ static __fi bool IsAutoFlushEnabled()
|
||||
return GSIsHardwareRenderer() ? (GSConfig.UserHacks_AutoFlush != GSHWAutoFlushLevel::Disabled) : GSConfig.AutoFlushSW;
|
||||
}
|
||||
|
||||
static __fi bool IsFirstProvokingVertex()
|
||||
{
|
||||
return (GSIsHardwareRenderer() && !g_gs_device->Features().provoking_vertex_last);
|
||||
}
|
||||
|
||||
constexpr int GSState::GetSaveStateSize(int version)
|
||||
{
|
||||
int size = 0;
|
||||
@@ -99,7 +94,7 @@ constexpr int GSState::GetSaveStateSize(int version)
|
||||
}
|
||||
|
||||
GSState::GSState()
|
||||
: m_vt(this, IsFirstProvokingVertex())
|
||||
: m_vt(this)
|
||||
{
|
||||
// m_nativeres seems to be a hack. Unfortunately it impacts draw call number which make debug painful in the replayer.
|
||||
// Let's keep it disabled to ease debug.
|
||||
@@ -130,6 +125,8 @@ GSState::~GSState()
|
||||
{
|
||||
if (m_vertex.buff)
|
||||
_aligned_free(m_vertex.buff);
|
||||
if (m_vertex.buff_copy)
|
||||
_aligned_free(m_vertex.buff_copy);
|
||||
if (m_index.buff)
|
||||
_aligned_free(m_index.buff);
|
||||
if (m_draw_vertex.buff)
|
||||
@@ -206,29 +203,29 @@ void GSState::Reset(bool hardware_reset)
|
||||
memcpy(&m_prev_env, &m_env, sizeof(m_prev_env));
|
||||
}
|
||||
|
||||
template<bool auto_flush, bool index_swap>
|
||||
template<bool auto_flush>
|
||||
void GSState::SetPrimHandlers()
|
||||
{
|
||||
#define SetHandlerXYZ(P, auto_flush, index_swap) \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][0] = &GSState::GIFPackedRegHandlerXYZF2<P, 0, auto_flush, index_swap>; \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][1] = &GSState::GIFPackedRegHandlerXYZF2<P, 1, auto_flush, index_swap>; \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][2] = &GSState::GIFPackedRegHandlerXYZ2<P, 0, auto_flush, index_swap>; \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][3] = &GSState::GIFPackedRegHandlerXYZ2<P, 1, auto_flush, index_swap>; \
|
||||
m_fpGIFRegHandlerXYZ[P][0] = &GSState::GIFRegHandlerXYZF2<P, 0, auto_flush, index_swap>; \
|
||||
m_fpGIFRegHandlerXYZ[P][1] = &GSState::GIFRegHandlerXYZF2<P, 1, auto_flush, index_swap>; \
|
||||
m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2<P, 0, auto_flush, index_swap>; \
|
||||
m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2<P, 1, auto_flush, index_swap>; \
|
||||
m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2<P, auto_flush, index_swap>; \
|
||||
m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2<P, auto_flush, index_swap>;
|
||||
#define SetHandlerXYZ(P, auto_flush) \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][0] = &GSState::GIFPackedRegHandlerXYZF2<P, 0, auto_flush>; \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][1] = &GSState::GIFPackedRegHandlerXYZF2<P, 1, auto_flush>; \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][2] = &GSState::GIFPackedRegHandlerXYZ2<P, 0, auto_flush>; \
|
||||
m_fpGIFPackedRegHandlerXYZ[P][3] = &GSState::GIFPackedRegHandlerXYZ2<P, 1, auto_flush>; \
|
||||
m_fpGIFRegHandlerXYZ[P][0] = &GSState::GIFRegHandlerXYZF2<P, 0, auto_flush>; \
|
||||
m_fpGIFRegHandlerXYZ[P][1] = &GSState::GIFRegHandlerXYZF2<P, 1, auto_flush>; \
|
||||
m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2<P, 0, auto_flush>; \
|
||||
m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2<P, 1, auto_flush>; \
|
||||
m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2<P, auto_flush>; \
|
||||
m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2<P, auto_flush>;
|
||||
|
||||
SetHandlerXYZ(GS_POINTLIST, true, false);
|
||||
SetHandlerXYZ(GS_LINELIST, auto_flush, index_swap);
|
||||
SetHandlerXYZ(GS_LINESTRIP, auto_flush, index_swap);
|
||||
SetHandlerXYZ(GS_TRIANGLELIST, auto_flush, index_swap);
|
||||
SetHandlerXYZ(GS_TRIANGLESTRIP, auto_flush, index_swap);
|
||||
SetHandlerXYZ(GS_TRIANGLEFAN, auto_flush, index_swap);
|
||||
SetHandlerXYZ(GS_SPRITE, auto_flush, false);
|
||||
SetHandlerXYZ(GS_INVALID, auto_flush, false);
|
||||
SetHandlerXYZ(GS_POINTLIST, true);
|
||||
SetHandlerXYZ(GS_LINELIST, auto_flush);
|
||||
SetHandlerXYZ(GS_LINESTRIP, auto_flush);
|
||||
SetHandlerXYZ(GS_TRIANGLELIST, auto_flush);
|
||||
SetHandlerXYZ(GS_TRIANGLESTRIP, auto_flush);
|
||||
SetHandlerXYZ(GS_TRIANGLEFAN, auto_flush);
|
||||
SetHandlerXYZ(GS_SPRITE, auto_flush);
|
||||
SetHandlerXYZ(GS_INVALID, auto_flush);
|
||||
|
||||
#undef SetHandlerXYZ
|
||||
}
|
||||
@@ -249,11 +246,10 @@ void GSState::ResetHandlers()
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_A_D] = &GSState::GIFPackedRegHandlerA_D;
|
||||
m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP;
|
||||
|
||||
// swap first/last indices when the provoking vertex is the first (D3D/Vulkan)
|
||||
if (IsAutoFlushEnabled())
|
||||
IsFirstProvokingVertex() ? SetPrimHandlers<true, true>() : SetPrimHandlers<true, false>();
|
||||
SetPrimHandlers<true>();
|
||||
else
|
||||
IsFirstProvokingVertex() ? SetPrimHandlers<false, true>() : SetPrimHandlers<false, false>();
|
||||
SetPrimHandlers<false>();
|
||||
|
||||
std::fill(std::begin(m_fpGIFRegHandlers), std::end(m_fpGIFRegHandlers), &GSState::GIFRegHandlerNull);
|
||||
|
||||
@@ -606,7 +602,7 @@ void GSState::GIFPackedRegHandlerUV_Hack(const GIFPackedReg* RESTRICT r)
|
||||
m_isPackedUV_HackFlag = true;
|
||||
}
|
||||
|
||||
template <u32 prim, u32 adc, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, u32 adc, bool auto_flush>
|
||||
void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r)
|
||||
{
|
||||
const bool skip = adc || r->XYZF2.Skip();
|
||||
@@ -622,10 +618,10 @@ void GSState::GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r)
|
||||
|
||||
m_v.m[1] = xy.upl32(zf);
|
||||
|
||||
VertexKick<prim, auto_flush, index_swap>(skip);
|
||||
VertexKick<prim, auto_flush>(skip);
|
||||
}
|
||||
|
||||
template <u32 prim, u32 adc, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, u32 adc, bool auto_flush>
|
||||
void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r)
|
||||
{
|
||||
const bool skip = adc || r->XYZ2.Skip();
|
||||
@@ -639,7 +635,7 @@ void GSState::GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r)
|
||||
|
||||
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV));
|
||||
|
||||
VertexKick<prim, auto_flush, index_swap>(skip);
|
||||
VertexKick<prim, auto_flush>(skip);
|
||||
}
|
||||
|
||||
void GSState::GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r)
|
||||
@@ -656,7 +652,7 @@ void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r)
|
||||
{
|
||||
}
|
||||
|
||||
template <u32 prim, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, bool auto_flush>
|
||||
void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size)
|
||||
{
|
||||
pxAssert(size > 0 && size % 3 == 0);
|
||||
@@ -682,7 +678,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u3
|
||||
|
||||
m_v.m[1] = xy.upl32(zf); // TODO: only store the last one
|
||||
|
||||
VertexKick<prim, auto_flush, index_swap>(r[2].XYZF2.Skip());
|
||||
VertexKick<prim, auto_flush>(r[2].XYZF2.Skip());
|
||||
|
||||
r += 3;
|
||||
}
|
||||
@@ -690,7 +686,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u3
|
||||
m_q = r[-3].STQ.Q; // remember the last one, STQ outputs this to the temp Q each time
|
||||
}
|
||||
|
||||
template <u32 prim, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, bool auto_flush>
|
||||
void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size)
|
||||
{
|
||||
pxAssert(size > 0 && size % 3 == 0);
|
||||
@@ -715,7 +711,7 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32
|
||||
|
||||
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); // TODO: only store the last one
|
||||
|
||||
VertexKick<prim, auto_flush, index_swap>(r[2].XYZ2.Skip());
|
||||
VertexKick<prim, auto_flush>(r[2].XYZ2.Skip());
|
||||
|
||||
r += 3;
|
||||
}
|
||||
@@ -749,7 +745,7 @@ __forceinline void GSState::ApplyPRIM(u32 prim)
|
||||
|
||||
UpdateVertexKick();
|
||||
|
||||
pxAssert(m_index.tail == 0 || !g_gs_device->Features().provoking_vertex_last || m_index.buff[m_index.tail - 1] + 1 == m_vertex.next);
|
||||
pxAssert(m_index.tail == 0 || m_index.buff[m_index.tail - 1] + 1 == m_vertex.next);
|
||||
|
||||
if (m_index.tail == 0)
|
||||
m_vertex.next = 0;
|
||||
@@ -800,7 +796,7 @@ void GSState::GIFRegHandlerUV_Hack(const GIFReg* RESTRICT r)
|
||||
m_isPackedUV_HackFlag = false;
|
||||
}
|
||||
|
||||
template <u32 prim, u32 adc, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, u32 adc, bool auto_flush>
|
||||
void GSState::GIFRegHandlerXYZF2(const GIFReg* RESTRICT r)
|
||||
{
|
||||
if (!adc || GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET)))
|
||||
@@ -812,10 +808,10 @@ void GSState::GIFRegHandlerXYZF2(const GIFReg* RESTRICT r)
|
||||
|
||||
m_v.m[1] = xyz.upl64(uvf);
|
||||
|
||||
VertexKick<prim, auto_flush, index_swap>(adc);
|
||||
VertexKick<prim, auto_flush>(adc);
|
||||
}
|
||||
|
||||
template <u32 prim, u32 adc, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, u32 adc, bool auto_flush>
|
||||
void GSState::GIFRegHandlerXYZ2(const GIFReg* RESTRICT r)
|
||||
{
|
||||
if (!adc || GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GSUtil::GetPrimClass(m_env.PRIM.PRIM) || (m_dirty_gs_regs & (1 << DIRTY_REG_XYOFFSET)))
|
||||
@@ -823,7 +819,7 @@ void GSState::GIFRegHandlerXYZ2(const GIFReg* RESTRICT r)
|
||||
|
||||
m_v.m[1] = GSVector4i::load(&r->XYZ, &m_v.UV);
|
||||
|
||||
VertexKick<prim, auto_flush, index_swap>(adc);
|
||||
VertexKick<prim, auto_flush>(adc);
|
||||
}
|
||||
|
||||
template <int i>
|
||||
@@ -2908,56 +2904,53 @@ void GSState::UpdateVertexKick()
|
||||
void GSState::GrowVertexBuffer()
|
||||
{
|
||||
const u32 maxcount = std::max<u32>(m_vertex.maxcount * 3 / 2, 10000);
|
||||
const u32 old_vertex_size = sizeof(GSVertex) * m_vertex.tail;
|
||||
const u32 new_vertex_size = sizeof(GSVertex) * maxcount;
|
||||
const u32 old_index_size = sizeof(u16) * m_index.tail;
|
||||
const u32 new_index_size = sizeof(u16) * maxcount * 6; // Worst case index list is a list of points with vs expansion, 6 indices per point
|
||||
|
||||
GSVertex* vertex = static_cast<GSVertex*>(_aligned_malloc(sizeof(GSVertex) * maxcount, 32));
|
||||
GSVertex* draw_vertex = static_cast<GSVertex*>(_aligned_malloc(sizeof(GSVertex) * maxcount, 32));
|
||||
// Worst case index list is a list of points with vs expansion, 6 indices per point
|
||||
u16* index = static_cast<u16*>(_aligned_malloc(sizeof(u16) * maxcount * 6, 32));
|
||||
u16* draw_index = static_cast<u16*>(_aligned_malloc(sizeof(u16) * maxcount * 6, 32));
|
||||
|
||||
if (!vertex || !index)
|
||||
// Structure describing buffers to reallocate
|
||||
struct AllocDesc
|
||||
{
|
||||
const u32 vert_byte_count = sizeof(GSVertex) * maxcount;
|
||||
const u32 idx_byte_count = sizeof(u16) * maxcount * 3;
|
||||
void** pbuff;
|
||||
u32 old_size;
|
||||
u32 new_size;
|
||||
};
|
||||
std::vector<AllocDesc> alloc_desc = {
|
||||
{reinterpret_cast<void**>(&m_vertex.buff), old_vertex_size, new_vertex_size},
|
||||
// discard contents of buff_copy by setting old_size = 0
|
||||
{reinterpret_cast<void**>(&m_vertex.buff_copy), 0, new_vertex_size},
|
||||
{reinterpret_cast<void**>(&m_draw_vertex.buff), old_vertex_size, new_vertex_size},
|
||||
{reinterpret_cast<void**>(&m_index.buff), old_index_size, new_index_size},
|
||||
{reinterpret_cast<void**>(&m_draw_index.buff), old_index_size, new_index_size}
|
||||
};
|
||||
|
||||
Console.Error("GS: failed to allocate %zu bytes for vertices and %zu for indices.",
|
||||
vert_byte_count, idx_byte_count);
|
||||
pxFailRel("Memory allocation failed");
|
||||
// For logging
|
||||
u32 total_size = 0;
|
||||
for (const auto& desc : alloc_desc)
|
||||
total_size += desc.new_size;
|
||||
|
||||
// Reallocate each of the needed buffers
|
||||
for (const auto [pbuff, old_size, new_size] : alloc_desc)
|
||||
{
|
||||
void* new_buff = _aligned_malloc(new_size, 32);
|
||||
if (!new_buff)
|
||||
{
|
||||
Console.Error("GS: failed to allocate %zu bytes for vertices and indices.", total_size);
|
||||
pxFailRel("Memory allocation failed");
|
||||
}
|
||||
if (*pbuff)
|
||||
{
|
||||
if (old_size)
|
||||
{
|
||||
std::memcpy(new_buff, *pbuff, old_size);
|
||||
}
|
||||
_aligned_free(*pbuff);
|
||||
}
|
||||
*pbuff = new_buff;
|
||||
}
|
||||
|
||||
if (m_vertex.buff)
|
||||
{
|
||||
std::memcpy(vertex, m_vertex.buff, sizeof(GSVertex) * m_vertex.tail);
|
||||
|
||||
_aligned_free(m_vertex.buff);
|
||||
}
|
||||
|
||||
if (m_index.buff)
|
||||
{
|
||||
std::memcpy(index, m_index.buff, sizeof(u16) * m_index.tail);
|
||||
|
||||
_aligned_free(m_index.buff);
|
||||
}
|
||||
|
||||
if (m_draw_vertex.buff)
|
||||
{
|
||||
std::memcpy(draw_vertex, m_draw_vertex.buff, sizeof(GSVertex) * m_vertex.tail);
|
||||
|
||||
_aligned_free(m_draw_vertex.buff);
|
||||
}
|
||||
|
||||
if (m_draw_index.buff)
|
||||
{
|
||||
std::memcpy(draw_index, m_draw_index.buff, sizeof(u16) * m_index.tail);
|
||||
|
||||
_aligned_free(m_draw_index.buff);
|
||||
}
|
||||
|
||||
m_draw_vertex.buff = draw_vertex;
|
||||
m_draw_index.buff = draw_index;
|
||||
m_vertex.buff = vertex;
|
||||
m_vertex.maxcount = maxcount - 3; // -3 to have some space at the end of the buffer before DrawingKick can grow it
|
||||
m_index.buff = index;
|
||||
}
|
||||
|
||||
bool GSState::TrianglesAreQuads(bool shuffle_check)
|
||||
@@ -3424,7 +3417,7 @@ __forceinline void GSState::CheckCLUTValidity(u32 prim)
|
||||
}
|
||||
}
|
||||
|
||||
template<u32 prim, bool index_swap>
|
||||
template<u32 prim>
|
||||
__forceinline void GSState::HandleAutoFlush()
|
||||
{
|
||||
// Kind of a cheat, making the assumption that 2 consecutive fan/strip triangles won't overlap each other (*should* be safe)
|
||||
@@ -3520,9 +3513,8 @@ __forceinline void GSState::HandleAutoFlush()
|
||||
if (tex_rect.y == tex_rect.w)
|
||||
tex_rect += GSVector4i::cxpr(0, 0, 0, 1);
|
||||
|
||||
const bool swap_index = index_swap && GSUtil::GetPrimClass(m_prev_env.PRIM.PRIM) != GS_SPRITE_CLASS;
|
||||
// Get the last texture position from the last draw.
|
||||
const GSVertex* v = &m_vertex.buff[m_index.buff[m_index.tail - (swap_index ? n : 1)]];
|
||||
const GSVertex* v = &m_vertex.buff[m_index.buff[m_index.tail - 1]];
|
||||
|
||||
if (PRIM->FST)
|
||||
{
|
||||
@@ -3700,7 +3692,7 @@ __forceinline void GSState::HandleAutoFlush()
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 prim, bool auto_flush, bool index_swap>
|
||||
template <u32 prim, bool auto_flush>
|
||||
__forceinline void GSState::VertexKick(u32 skip)
|
||||
{
|
||||
constexpr u32 n = NumIndicesForPrim(prim);
|
||||
@@ -3716,7 +3708,7 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
|
||||
if (auto_flush && skip == 0 && m_index.tail > 0 && ((m_vertex.tail + 1) - m_vertex.head) >= n)
|
||||
{
|
||||
HandleAutoFlush<prim, index_swap>();
|
||||
HandleAutoFlush<prim>();
|
||||
}
|
||||
|
||||
u32 head = m_vertex.head;
|
||||
@@ -3878,8 +3870,8 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
m_index.tail += 1;
|
||||
break;
|
||||
case GS_LINELIST:
|
||||
buff[0] = static_cast<u16>(head + (index_swap ? 1 : 0));
|
||||
buff[1] = static_cast<u16>(head + (index_swap ? 0 : 1));
|
||||
buff[0] = static_cast<u16>(head + 0);
|
||||
buff[1] = static_cast<u16>(head + 1);
|
||||
m_vertex.head = head + 2;
|
||||
m_vertex.next = head + 2;
|
||||
m_index.tail += 2;
|
||||
@@ -3892,16 +3884,16 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
head = next;
|
||||
m_vertex.tail = next + 2;
|
||||
}
|
||||
buff[0] = static_cast<u16>(head + (index_swap ? 1 : 0));
|
||||
buff[1] = static_cast<u16>(head + (index_swap ? 0 : 1));
|
||||
buff[0] = static_cast<u16>(head + 0);
|
||||
buff[1] = static_cast<u16>(head + 1);
|
||||
m_vertex.head = head + 1;
|
||||
m_vertex.next = head + 2;
|
||||
m_index.tail += 2;
|
||||
break;
|
||||
case GS_TRIANGLELIST:
|
||||
buff[0] = static_cast<u16>(head + (index_swap ? 2 : 0));
|
||||
buff[0] = static_cast<u16>(head + 0);
|
||||
buff[1] = static_cast<u16>(head + 1);
|
||||
buff[2] = static_cast<u16>(head + (index_swap ? 0 : 2));
|
||||
buff[2] = static_cast<u16>(head + 2);
|
||||
m_vertex.head = head + 3;
|
||||
m_vertex.next = head + 3;
|
||||
m_index.tail += 3;
|
||||
@@ -3915,18 +3907,18 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
head = next;
|
||||
m_vertex.tail = next + 3;
|
||||
}
|
||||
buff[0] = static_cast<u16>(head + (index_swap ? 2 : 0));
|
||||
buff[0] = static_cast<u16>(head + 0);
|
||||
buff[1] = static_cast<u16>(head + 1);
|
||||
buff[2] = static_cast<u16>(head + (index_swap ? 0 : 2));
|
||||
buff[2] = static_cast<u16>(head + 2);
|
||||
m_vertex.head = head + 1;
|
||||
m_vertex.next = head + 3;
|
||||
m_index.tail += 3;
|
||||
break;
|
||||
case GS_TRIANGLEFAN:
|
||||
// TODO: remove gaps, next == head && head < tail - 3 || next > head && next < tail - 2 (very rare)
|
||||
buff[0] = static_cast<u16>(index_swap ? (tail - 1) : (head + 0));
|
||||
buff[0] = static_cast<u16>(head + 0);
|
||||
buff[1] = static_cast<u16>(tail - 2);
|
||||
buff[2] = static_cast<u16>(index_swap ? (head + 0) : (tail - 1));
|
||||
buff[2] = static_cast<u16>(tail - 1);
|
||||
m_vertex.next = tail;
|
||||
m_index.tail += 3;
|
||||
break;
|
||||
|
||||
@@ -38,8 +38,8 @@ private:
|
||||
void GIFPackedRegHandlerSTQ(const GIFPackedReg* RESTRICT r);
|
||||
void GIFPackedRegHandlerUV(const GIFPackedReg* RESTRICT r);
|
||||
void GIFPackedRegHandlerUV_Hack(const GIFPackedReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush, bool index_swap> void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush, bool index_swap> void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush> void GIFPackedRegHandlerXYZF2(const GIFPackedReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush> void GIFPackedRegHandlerXYZ2(const GIFPackedReg* RESTRICT r);
|
||||
void GIFPackedRegHandlerFOG(const GIFPackedReg* RESTRICT r);
|
||||
void GIFPackedRegHandlerA_D(const GIFPackedReg* RESTRICT r);
|
||||
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r);
|
||||
@@ -55,8 +55,8 @@ private:
|
||||
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8] = {};
|
||||
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8] = {};
|
||||
|
||||
template<u32 prim, bool auto_flush, bool index_swap> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size);
|
||||
template<u32 prim, bool auto_flush, bool index_swap> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size);
|
||||
template<u32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size);
|
||||
template<u32 prim, bool auto_flush> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size);
|
||||
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, u32 size);
|
||||
|
||||
template<int i> void ApplyTEX0(GIFRegTEX0& TEX0);
|
||||
@@ -68,8 +68,8 @@ private:
|
||||
void GIFRegHandlerST(const GIFReg* RESTRICT r);
|
||||
void GIFRegHandlerUV(const GIFReg* RESTRICT r);
|
||||
void GIFRegHandlerUV_Hack(const GIFReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush, bool index_swap> void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush, bool index_swap> void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush> void GIFRegHandlerXYZF2(const GIFReg* RESTRICT r);
|
||||
template<u32 prim, u32 adc, bool auto_flush> void GIFRegHandlerXYZ2(const GIFReg* RESTRICT r);
|
||||
template<int i> void GIFRegHandlerTEX0(const GIFReg* RESTRICT r);
|
||||
template<int i> void GIFRegHandlerCLAMP(const GIFReg* RESTRICT r);
|
||||
void GIFRegHandlerFOG(const GIFReg* RESTRICT r);
|
||||
@@ -102,8 +102,7 @@ private:
|
||||
void GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r);
|
||||
void GIFRegHandlerHWREG(const GIFReg* RESTRICT r);
|
||||
|
||||
template<bool auto_flush, bool index_swap>
|
||||
void SetPrimHandlers();
|
||||
template<bool auto_flush> void SetPrimHandlers();
|
||||
|
||||
struct GSTransferBuffer
|
||||
{
|
||||
@@ -137,6 +136,7 @@ protected:
|
||||
struct
|
||||
{
|
||||
GSVertex* buff;
|
||||
GSVertex* buff_copy; // same size buffer to copy/modify the original buffer
|
||||
u32 head, tail, next, maxcount; // head: first vertex, tail: last vertex + 1, next: last indexed + 1
|
||||
u32 xy_tail;
|
||||
GSVector4i xy[4];
|
||||
@@ -171,12 +171,10 @@ protected:
|
||||
|
||||
void GrowVertexBuffer();
|
||||
bool IsAutoFlushDraw(u32 prim);
|
||||
template<u32 prim, bool index_swap>
|
||||
void HandleAutoFlush();
|
||||
template<u32 prim> void HandleAutoFlush();
|
||||
void CheckCLUTValidity(u32 prim);
|
||||
|
||||
template <u32 prim, bool auto_flush, bool index_swap>
|
||||
void VertexKick(u32 skip);
|
||||
template <u32 prim, bool auto_flush> void VertexKick(u32 skip);
|
||||
|
||||
// following functions need m_vt to be initialized
|
||||
|
||||
|
||||
@@ -876,7 +876,30 @@ static std::string GSGetBaseFilename()
|
||||
std::string GSGetBaseSnapshotFilename()
|
||||
{
|
||||
// prepend snapshots directory
|
||||
return Path::Combine(EmuFolders::Snapshots, GSGetBaseFilename());
|
||||
std::string base_path = EmuFolders::Snapshots;
|
||||
|
||||
// If organize by game is enabled, create a game-specific folder
|
||||
if (GSConfig.OrganizeScreenshotsByGame)
|
||||
{
|
||||
std::string game_name = VMManager::GetTitle(true);
|
||||
if (!game_name.empty())
|
||||
{
|
||||
Path::SanitizeFileName(&game_name);
|
||||
if (game_name.length() > 219)
|
||||
{
|
||||
game_name.resize(219);
|
||||
}
|
||||
const std::string game_dir = Path::Combine(base_path, game_name);
|
||||
if (!FileSystem::DirectoryExists(game_dir.c_str()))
|
||||
{
|
||||
FileSystem::CreateDirectoryPath(game_dir.c_str(), false);
|
||||
}
|
||||
|
||||
base_path = game_dir;
|
||||
}
|
||||
}
|
||||
|
||||
return Path::Combine(base_path, GSGetBaseFilename());
|
||||
}
|
||||
|
||||
std::string GSGetBaseVideoFilename()
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
#include "common/Console.h"
|
||||
|
||||
GSVertexTrace::GSVertexTrace(const GSState* state, bool provoking_vertex_first)
|
||||
GSVertexTrace::GSVertexTrace(const GSState* state)
|
||||
: m_state(state)
|
||||
{
|
||||
MULTI_ISA_SELECT(GSVertexTracePopulateFunctions)(*this, provoking_vertex_first);
|
||||
MULTI_ISA_SELECT(GSVertexTracePopulateFunctions)(*this);
|
||||
}
|
||||
|
||||
void GSVertexTrace::Update(const void* vertex, const u16* index, int v_count, int i_count, GS_PRIM_CLASS primclass)
|
||||
|
||||
@@ -15,7 +15,7 @@ class GSState;
|
||||
class GSVertexTrace;
|
||||
|
||||
MULTI_ISA_DEF(class GSVertexTraceFMM;)
|
||||
MULTI_ISA_DEF(void GSVertexTracePopulateFunctions(GSVertexTrace& vt, bool provoking_vertex_first);)
|
||||
MULTI_ISA_DEF(void GSVertexTracePopulateFunctions(GSVertexTrace& vt);)
|
||||
|
||||
class alignas(32) GSVertexTrace final : public GSAlignedClass<32>
|
||||
{
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
GSVector2 m_lod = {}; // x = min, y = max
|
||||
|
||||
public:
|
||||
GSVertexTrace(const GSState* state, bool provoking_vertex_first);
|
||||
GSVertexTrace(const GSState* state);
|
||||
|
||||
void Update(const void* vertex, const u16* index, int v_count, int i_count, GS_PRIM_CLASS primclass);
|
||||
|
||||
|
||||
@@ -9,41 +9,36 @@ class CURRENT_ISA::GSVertexTraceFMM
|
||||
{
|
||||
static constexpr GSVector4 s_minmax = GSVector4::cxpr(FLT_MAX, -FLT_MAX, 0.f, 0.f);
|
||||
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool flat_swapped>
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
||||
static void FindMinMax(GSVertexTrace& vt, const void* vertex, const u16* index, int count);
|
||||
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
||||
static constexpr GSVertexTrace::FindMinMaxPtr GetFMM(bool provoking_vertex_first);
|
||||
static constexpr GSVertexTrace::FindMinMaxPtr GetFMM();
|
||||
|
||||
public:
|
||||
static void Populate(GSVertexTrace& vt, bool provoking_vertex_first);
|
||||
static void Populate(GSVertexTrace& vt);
|
||||
};
|
||||
|
||||
MULTI_ISA_UNSHARED_IMPL;
|
||||
|
||||
void CURRENT_ISA::GSVertexTracePopulateFunctions(GSVertexTrace& vt, bool provoking_vertex_first)
|
||||
void CURRENT_ISA::GSVertexTracePopulateFunctions(GSVertexTrace& vt)
|
||||
{
|
||||
GSVertexTraceFMM::Populate(vt, provoking_vertex_first);
|
||||
GSVertexTraceFMM::Populate(vt);
|
||||
}
|
||||
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
||||
constexpr GSVertexTrace::FindMinMaxPtr GSVertexTraceFMM::GetFMM(bool provoking_vertex_first)
|
||||
constexpr GSVertexTrace::FindMinMaxPtr GSVertexTraceFMM::GetFMM()
|
||||
{
|
||||
constexpr bool real_iip = primclass == GS_SPRITE_CLASS ? false : iip;
|
||||
constexpr bool real_fst = tme ? fst : false;
|
||||
constexpr bool provoking_vertex_first_class = primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS;
|
||||
const bool swap = provoking_vertex_first_class && !iip && provoking_vertex_first;
|
||||
|
||||
if (swap)
|
||||
return FindMinMax<primclass, real_iip, tme, real_fst, color, true>;
|
||||
else
|
||||
return FindMinMax<primclass, real_iip, tme, real_fst, color, false>;
|
||||
return FindMinMax<primclass, real_iip, tme, real_fst, color>;
|
||||
}
|
||||
|
||||
void GSVertexTraceFMM::Populate(GSVertexTrace& vt, bool provoking_vertex_first)
|
||||
void GSVertexTraceFMM::Populate(GSVertexTrace& vt)
|
||||
{
|
||||
#define InitUpdate3(P, IIP, TME, FST, COLOR) \
|
||||
vt.m_fmm[COLOR][FST][TME][IIP][P] = GetFMM<P, IIP, TME, FST, COLOR>(provoking_vertex_first);
|
||||
vt.m_fmm[COLOR][FST][TME][IIP][P] = GetFMM<P, IIP, TME, FST, COLOR>();
|
||||
|
||||
#define InitUpdate2(P, IIP, TME) \
|
||||
InitUpdate3(P, IIP, TME, 0, 0) \
|
||||
@@ -63,7 +58,7 @@ void GSVertexTraceFMM::Populate(GSVertexTrace& vt, bool provoking_vertex_first)
|
||||
InitUpdate(GS_SPRITE_CLASS);
|
||||
}
|
||||
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool flat_swapped>
|
||||
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color>
|
||||
void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u16* index, int count)
|
||||
{
|
||||
const GSDrawingContext* context = vt.m_state->m_context;
|
||||
@@ -110,7 +105,7 @@ void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u
|
||||
{
|
||||
// For even n, we process v1 and v2 of the same prim
|
||||
// (For odd n, we process one vertex from each of two prims)
|
||||
GSVector4i c = flat_swapped ? c0 : c1;
|
||||
GSVector4i c = c1; // second color is provoking in flat-shaded primitives
|
||||
cmin = cmin.min_u8(c);
|
||||
cmax = cmax.max_u8(c);
|
||||
}
|
||||
@@ -196,26 +191,16 @@ void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u
|
||||
int i = 0;
|
||||
for (; i < (count - 3); i += 6)
|
||||
{
|
||||
processVertices(v[index[i + 0]], v[index[i + 3]], flat_swapped);
|
||||
processVertices(v[index[i + 0]], v[index[i + 3]], false);
|
||||
processVertices(v[index[i + 1]], v[index[i + 4]], false);
|
||||
processVertices(v[index[i + 2]], v[index[i + 5]], !flat_swapped);
|
||||
processVertices(v[index[i + 2]], v[index[i + 5]], true);
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
if (flat_swapped)
|
||||
{
|
||||
processVertices(v[index[i + 1]], v[index[i + 2]], false);
|
||||
// Compiler optimizations go!
|
||||
// (And if they don't, it's only one vertex out of many)
|
||||
processVertices(v[index[i + 0]], v[index[i + 0]], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
processVertices(v[index[i + 0]], v[index[i + 1]], false);
|
||||
// Compiler optimizations go!
|
||||
// (And if they don't, it's only one vertex out of many)
|
||||
processVertices(v[index[i + 2]], v[index[i + 2]], true);
|
||||
}
|
||||
processVertices(v[index[i + 0]], v[index[i + 1]], false);
|
||||
// Compiler optimizations go!
|
||||
// (And if they don't, it's only one vertex out of many)
|
||||
processVertices(v[index[i + 2]], v[index[i + 2]], true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -4791,21 +4791,10 @@ bool GSRendererHW::VerifyIndices()
|
||||
return false;
|
||||
// Expect each line to be a pair next to each other
|
||||
// VS expand relies on this!
|
||||
if (g_gs_device->Features().provoking_vertex_last)
|
||||
for (u32 i = 0; i < m_index.tail; i += 2)
|
||||
{
|
||||
for (u32 i = 0; i < m_index.tail; i += 2)
|
||||
{
|
||||
if (m_index.buff[i] + 1 != m_index.buff[i + 1])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < m_index.tail; i += 2)
|
||||
{
|
||||
if (m_index.buff[i] != m_index.buff[i + 1] + 1)
|
||||
return false;
|
||||
}
|
||||
if (m_index.buff[i] + 1 != m_index.buff[i + 1])
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case GS_TRIANGLE_CLASS:
|
||||
@@ -4818,6 +4807,52 @@ bool GSRendererHW::VerifyIndices()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fix the colors in vertices in case the API only supports "provoking first vertex"
|
||||
// (i.e., when using flat shading the color comes from the first vertex, unlike PS2
|
||||
// which is "provoking last vertex").
|
||||
void GSRendererHW::HandleProvokingVertexFirst()
|
||||
{
|
||||
// Early exit conditions:
|
||||
if (g_gs_device->Features().provoking_vertex_last || // device supports provoking last vertex
|
||||
m_conf.vs.iip || // we are doing Gouraud shading
|
||||
m_vt.m_primclass == GS_POINT_CLASS || // drawing points (one vertex per primitive; color is unambiguous)
|
||||
m_vt.m_primclass == GS_SPRITE_CLASS) // drawing sprites (handled by the sprites -> triangles expand shader)
|
||||
return;
|
||||
|
||||
const int n = GSUtil::GetClassVertexCount(m_vt.m_primclass);
|
||||
|
||||
// If all first/last vertices have the same color there is nothing to do.
|
||||
bool first_eq_last = true;
|
||||
for (u32 i = 0; i < m_index.tail; i += n)
|
||||
{
|
||||
if (m_vertex.buff[m_index.buff[i]].RGBAQ.U32[0] != m_vertex.buff[m_index.buff[i + n - 1]].RGBAQ.U32[0])
|
||||
{
|
||||
first_eq_last = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_eq_last)
|
||||
return;
|
||||
|
||||
// De-index the vertices using the copy buffer
|
||||
while (m_vertex.maxcount < m_index.tail)
|
||||
GrowVertexBuffer();
|
||||
for (int i = static_cast<int>(m_index.tail) - 1; i >= 0; i--)
|
||||
{
|
||||
m_vertex.buff_copy[i] = m_vertex.buff[m_index.buff[i]];
|
||||
m_index.buff[i] = static_cast<u16>(i);
|
||||
}
|
||||
std::swap(m_vertex.buff, m_vertex.buff_copy);
|
||||
m_vertex.head = m_vertex.next = m_vertex.tail = m_index.tail;
|
||||
|
||||
// Put correct color in the first vertex
|
||||
for (u32 i = 0; i < m_index.tail; i += n)
|
||||
{
|
||||
m_vertex.buff[i].RGBAQ.U32[0] = m_vertex.buff[i + n - 1].RGBAQ.U32[0];
|
||||
m_vertex.buff[i + n - 1].RGBAQ.U32[0] = 0xff; // Make last vertex red for debugging if used improperly
|
||||
}
|
||||
}
|
||||
|
||||
void GSRendererHW::SetupIA(float target_scale, float sx, float sy, bool req_vert_backup)
|
||||
{
|
||||
GL_PUSH("HW: IA");
|
||||
@@ -7899,6 +7934,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
m_conf.drawarea = m_channel_shuffle ? scissor : scissor.rintersect(ComputeBoundingBox(rtsize, rtscale));
|
||||
m_conf.scissor = (DATE && !DATE_BARRIER) ? m_conf.drawarea : scissor;
|
||||
|
||||
HandleProvokingVertexFirst();
|
||||
|
||||
SetupIA(rtscale, sx, sy, m_channel_shuffle_width != 0);
|
||||
|
||||
if (ate_second_pass)
|
||||
|
||||
@@ -92,6 +92,7 @@ private:
|
||||
void DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Target* ds, GSTextureCache::Source* tex, const TextureMinMaxResult& tmm);
|
||||
|
||||
void ResetStates();
|
||||
void HandleProvokingVertexFirst();
|
||||
void SetupIA(float target_scale, float sx, float sy, bool req_vert_backup);
|
||||
void EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GSTextureCache::Source* tex);
|
||||
bool EmulateChannelShuffle(GSTextureCache::Target* src, bool test_only, GSTextureCache::Target* rt = nullptr);
|
||||
|
||||
@@ -1146,6 +1146,7 @@ bool GSDeviceMTL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
case ShaderConvert::COPY:
|
||||
case ShaderConvert::DOWNSAMPLE_COPY:
|
||||
case ShaderConvert::RGBA_TO_8I: // Yes really
|
||||
case ShaderConvert::RGB5A1_TO_8I:
|
||||
case ShaderConvert::RTA_CORRECTION:
|
||||
case ShaderConvert::RTA_DECORRECTION:
|
||||
case ShaderConvert::TRANSPARENCY_FILTER:
|
||||
|
||||
@@ -233,9 +233,7 @@ vertex MainVSOut vs_main_expand(
|
||||
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 Metal 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;
|
||||
uint vid_other = is_bottom ? vid_base - 1 : vid_base + 1;
|
||||
MainVSOut point = vs_main_run(load_vertex(vertices[vid_base]), cb);
|
||||
MainVSOut other = vs_main_run(load_vertex(vertices[vid_other]), cb);
|
||||
|
||||
|
||||
@@ -605,7 +605,7 @@ bool GSDeviceOGL::CreateTextureFX()
|
||||
bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
||||
{
|
||||
//bool vendor_id_amd = false;
|
||||
bool vendor_id_nvidia = false;
|
||||
//bool vendor_id_nvidia = false;
|
||||
//bool vendor_id_intel = false;
|
||||
|
||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||
@@ -618,7 +618,7 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
||||
else if (std::strstr(vendor, "NVIDIA Corporation"))
|
||||
{
|
||||
Console.WriteLn(Color_StrongGreen, "GL: NVIDIA GPU detected.");
|
||||
vendor_id_nvidia = true;
|
||||
//vendor_id_nvidia = true;
|
||||
}
|
||||
else if (std::strstr(vendor, "Intel"))
|
||||
{
|
||||
|
||||
@@ -367,12 +367,9 @@ namespace FullscreenUI
|
||||
static void DrawIntSpinBoxSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section, const char* key,
|
||||
int default_value, int min_value, int max_value, int step_value, const char* format = "%d", bool enabled = true,
|
||||
float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
||||
#if 0
|
||||
// Unused as of now
|
||||
static void DrawFloatRangeSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section, const char* key,
|
||||
float default_value, float min_value, float max_value, const char* format = "%f", float multiplier = 1.0f, bool enabled = true,
|
||||
float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
||||
#endif
|
||||
static void DrawFloatSpinBoxSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section,
|
||||
const char* key, float default_value, float min_value, float max_value, float step_value, float multiplier,
|
||||
const char* format = "%f", bool enabled = true, float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
@@ -2217,8 +2214,6 @@ void FullscreenUI::DrawIntSpinBoxSetting(SettingsInterface* bsi, const char* tit
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Unused as of now
|
||||
void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section,
|
||||
const char* key, float default_value, float min_value, float max_value, const char* format, float multiplier, bool enabled,
|
||||
float height, std::pair<ImFont*, float> font, std::pair<ImFont*, float> summary_font)
|
||||
@@ -2275,7 +2270,6 @@ void FullscreenUI::DrawFloatRangeSetting(SettingsInterface* bsi, const char* tit
|
||||
ImGui::PopStyleVar(4);
|
||||
ImGui::PopFont();
|
||||
}
|
||||
#endif
|
||||
|
||||
void FullscreenUI::DrawFloatSpinBoxSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section,
|
||||
const char* key, float default_value, float min_value, float max_value, float step_value, float multiplier, const char* format,
|
||||
@@ -4479,6 +4473,10 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
"Uploads full textures to the GPU on use, rather than only the utilized regions. Can improve performance in some games."),
|
||||
"EmuCore/GS", "texture_preloading", static_cast<int>(TexturePreloadingLevel::Off), s_preloading_options,
|
||||
std::size(s_preloading_options), true);
|
||||
DrawFloatRangeSetting(bsi, FSUI_CSTR("NTSC Frame Rate"), FSUI_CSTR("Determines what frame rate NTSC games run at."),
|
||||
"EmuCore/GS", "FrameRateNTSC", 59.94f, 10.0f, 300.0f, "%.2f Hz");
|
||||
DrawFloatRangeSetting(bsi, FSUI_CSTR("PAL Frame Rate"), FSUI_CSTR("Determines what frame rate PAL games run at."),
|
||||
"EmuCore/GS", "FrameRatePAL", 50.0f, 10.0f, 300.0f, "%.2f Hz");
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
@@ -920,6 +920,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
||||
SettingsWrapIntEnumEx(ScreenshotSize, "ScreenshotSize");
|
||||
SettingsWrapIntEnumEx(ScreenshotFormat, "ScreenshotFormat");
|
||||
SettingsWrapEntry(ScreenshotQuality);
|
||||
SettingsWrapBitBool(OrganizeScreenshotsByGame);
|
||||
SettingsWrapEntry(StretchY);
|
||||
SettingsWrapEntryEx(Crop[0], "CropLeft");
|
||||
SettingsWrapEntryEx(Crop[1], "CropTop");
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 68;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 69;
|
||||
|
||||
Reference in New Issue
Block a user