Compare commits

..
48 Commits
Author SHA1 Message Date
Stuart Kenny 79f4af8ab5 Qt: Delete SDLRawInput on non win32 builds 2023-04-25 15:05:30 +01:00
Stuart Kenny a5f83329cb FullscreenUI: Only show SDL Raw on win32 builds. 2023-04-25 15:05:30 +01:00
rayanHappy 267479f31d Misc: Cmake and GCC compiler flags cleanups 2023-04-25 15:04:39 +01:00
rayanHappy 164462e510 Misc: Remove ICC compiler support 2023-04-25 15:04:39 +01:00
TellowKrinkle 6331df306f qt:resources: Use black and white icon for forum menu entry 2023-04-25 15:04:26 +01:00
TellowKrinkle 027ceebcbd qt:resources: Use black and white icons for discord menu icon 2023-04-25 15:04:26 +01:00
TellowKrinkle edb2c0080c qt:resources: Use separate black/white github icon 2023-04-25 15:04:26 +01:00
TellowKrinkle caafc87b29 qt:resources: Sort qrc filenames
Many filesystems (e.g. btrfs, apfs) return results in some internal non-alphabetical ordering, which isn't great for minimizing changes to files
2023-04-25 15:04:26 +01:00
TellowKrinkle 5d37cac4a0 qt:resources: Skip dotfiles when generating qrc 2023-04-25 15:04:26 +01:00
Stenzek 8f68e096d4 GS/HW: Avoid render pass restarts to turn off RT
Significantly reduces render passes in Sly 2.
2023-04-24 22:17:25 +01:00
Stenzek 430cad48e3 GS/Metal: Get rid of redundant pointer 2023-04-24 22:17:04 +01:00
Stenzek 757a9532e6 GS: Add Render Pass stats 2023-04-24 22:17:04 +01:00
KamFretoZ f26f8cafa9 Qt: Even more fixes to the Cobalt Theme 2023-04-24 19:24:19 +02:00
KamFretoZ 128a79e355 Qt: Help menu icon fix for macOS user 2023-04-24 19:24:19 +02:00
PCSX2 Bot cc2d99db3a PAD: Update to latest controller database. 2023-04-24 19:21:18 +02:00
KamFretoZ 30a31d931a Qt: Add extra icons to the help menu 2023-04-23 03:56:36 +01:00
KamFretoZ 1c30d449bf Tools: Fix filename lookup error on the python glyph updater script 2023-04-23 03:56:36 +01:00
refractionpcsx2 dc4ce58248 VU-JIT: Avoid writeReg stealing loadReg GPR 2023-04-23 03:54:53 +01:00
Mrlinkwii dc93e861c7 GameDB: various fixes 2023-04-22 23:58:58 +01:00
refractionpcsx2 960daf27e2 GameDB: Add FullVU0SyncHack to the linter 2023-04-22 23:38:05 +01:00
Goatman13 844f21344d GameDB: Add patch for Michigan: Report from Hell 2023-04-22 16:55:27 +01:00
refractionpcsx2 535ad110e3 VU-JIT: Backup non cached VI before writing to it when load != write 2023-04-22 15:15:25 +01:00
JordanTheToaster 0e0d7a5441 GameDB: Various fixes
Fixes for vertical lines in Ring of Red and invisible text in Dynasty Warriors 2.
2023-04-22 03:03:27 +01:00
SeruranBlue ed63221c7e GameDB: Fixes for Air Ranger: Rescue Helicopter (#8711) 2023-04-22 03:02:46 +01:00
seta-san f9c2d7767d CDVD: Fix Error Message in InputIsoFile.cpp 2023-04-21 10:53:48 +01:00
Berylskid cb91478590 UI: Correct Recommended Value for Show Indicators 2023-04-20 10:18:25 +01:00
Mrlinkwii 5dec7fe27d GameDB : fixes for Hanjuku Hero 4 2023-04-19 23:30:31 +01:00
Berylskid 575d487c65 GameDB: Fix Armored Core water and game names (#8702) 2023-04-19 19:14:37 +01:00
Stenzek 2b9289f402 GS/HW: Fix missing init of non-CLUT replacement textures 2023-04-19 13:38:20 +01:00
Mrlinkwii 9273683d3c GameDB: fixes for Dark cloud 2023-04-17 21:06:48 +01:00
PCSX2 Bot 88f8465e7e PAD: Update to latest controller database. 2023-04-17 20:02:50 +02:00
refractionpcsx2 f26031cada Vif: Fix up Instant DMA behaviour 2023-04-16 21:15:26 +01:00
JordanTheToaster 3352d71515 GameDB: Various fixes
Fixes for a potential slowdown in Super Robot Taisen and replace disabling Instant VU with InstantDMA in MGS 3 Subsistence.
2023-04-16 21:10:31 +02:00
Connor McLaughlin 999f9532ee GS: Warning fix 2023-04-16 06:43:22 +01:00
Stenzek d1f62ca9bf GS: Remove GSVertexList
It doesn't appear to be used anywhere.
2023-04-16 06:35:05 +01:00
Stenzek ef9f0cf635 GS: Replace magic alignment number with constant
And ensure it gets used in None preloading.
2023-04-16 06:35:05 +01:00
Stenzek d745564451 GS/HW: Adjust Black/Burnout sky CRC hack
Apparently some stages use a sky height of 128 instead of 256?
2023-04-15 22:01:38 +01:00
Stenzek d37ac992fc GS/HW: Use bitfield extract for VS expand (GL/VK) 2023-04-15 20:10:25 +01:00
Stenzek e7fc3de90c GS/HW: Ensure region texture mipmaps don't go out of bounds 2023-04-15 20:10:15 +01:00
Stenzek bde81380c3 GS/SW: Stop C rasterizer crashing with AA1 2023-04-15 20:10:03 +01:00
Stenzek 839b482cb5 GS: Use 16-bit indices instead of 32-bit
Save some bandwidth.
2023-04-15 20:10:03 +01:00
Stenzek 72f70d4789 GS/Vulkan: Clear textures/RTs at end of frame
Prevents us from updating potentially changed-state descriptors.
2023-04-15 20:09:48 +01:00
Stenzek d646bbf5c1 GS/Vulkan: Prioritize VK_EXT_rasterization_order_attachment_access
.. over the ARM version. But continue to support both.
2023-04-15 20:09:48 +01:00
Stenzek e68aaf6540 GS/Vulkan: Saturate ImGui scissor to zero 2023-04-15 20:09:48 +01:00
Stenzek 20ab5ed0fa GS/Vulkan: Don't assume opaque composite alpha is supported 2023-04-15 20:09:48 +01:00
Stenzek 8590e390a2 GS/Vulkan: Don't enable geometryShader 2023-04-15 20:09:48 +01:00
Stenzek ab1d558420 GS/Vulkan: Make provoking vertex consistent across pipelines 2023-04-15 20:09:48 +01:00
Stenzek 53c9021455 GS/HW: Don't attempt to colour copy into depth target 2023-04-15 20:09:26 +01:00
72 changed files with 718 additions and 550 deletions
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -537,6 +537,7 @@
030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
030000009b2800006300000000000000,Raphnet N64 Adapter,a:b0,b:b1,start:b3,lefttrigger:b2,dpup:b10,dpleft:b12,dpdown:b11,dpright:b13,leftx:a0,lefty:a1,-rightx:b8,+rightx:b9,-righty:b6,+righty:b7,leftshoulder:b4,rightshoulder:b5,platform:Windows,
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
@@ -663,6 +664,7 @@
03000000c61100001000000000000000,Tencent Xianyou Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
03000000790000002601000000000000,TGZ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows,
03000000591c00002400000000000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000591c00002600000000000000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,start:b7,x:b3,y:b0,platform:Windows,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -983,6 +985,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000001c18000003100000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000591c00002400000021000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000591c00002600000021000000,THEGamepad,a:b2,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Mac OS X,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
030000004f0400000ed0000000020000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
@@ -1332,7 +1335,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
050000007e0500001920000001800000,NSO N64 Controller,a:b0,b:b1,guide:b11,misc1:b12,start:b6,leftshoulder:b3,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,-rightx:b9,+rightx:b10,-righty:b7,+righty:b8,lefttrigger:b2,righttrigger:b5,platform:Linux,
050000007e0500001920000001800000,NSO N64 Controller,+rightx:b10,+righty:b8,-rightx:b9,-righty:b7,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b3,lefttrigger:b2,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b4,righttrigger:b5,start:b6,platform:Linux,
050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
+4 -3
View File
@@ -128,11 +128,12 @@ ProcessedVertex load_vertex(uint index)
#endif
vec2 i_st = rvtx.ST;
vec4 i_c = vec4(uvec4(rvtx.RGBA & 0xFFu, (rvtx.RGBA >> 8) & 0xFFu, (rvtx.RGBA >> 16) & 0xFFu, rvtx.RGBA >> 24));
vec4 i_c = vec4(uvec4(bitfieldExtract(rvtx.RGBA, 0, 8), bitfieldExtract(rvtx.RGBA, 8, 8),
bitfieldExtract(rvtx.RGBA, 16, 8), bitfieldExtract(rvtx.RGBA, 24, 8)));
float i_q = rvtx.Q;
uvec2 i_p = uvec2(rvtx.XY & 0xFFFFu, rvtx.XY >> 16);
uvec2 i_p = uvec2(bitfieldExtract(rvtx.XY, 0, 16), bitfieldExtract(rvtx.XY, 16, 16));
uint i_z = rvtx.Z;
uvec2 i_uv = uvec2(rvtx.UV & 0xFFFFu, rvtx.UV >> 16);
uvec2 i_uv = uvec2(bitfieldExtract(rvtx.UV, 0, 16), bitfieldExtract(rvtx.UV, 16, 16));
vec4 i_f = unpackUnorm4x8(rvtx.FOG);
ProcessedVertex vtx;
+4 -3
View File
@@ -113,11 +113,12 @@ ProcessedVertex load_vertex(uint index)
RawVertex rvtx = vertex_buffer[gl_BaseVertexARB + index];
vec2 a_st = rvtx.ST;
uvec4 a_c = uvec4(rvtx.RGBA & 0xFFu, (rvtx.RGBA >> 8) & 0xFFu, (rvtx.RGBA >> 16) & 0xFFu, rvtx.RGBA >> 24);
uvec4 a_c = uvec4(bitfieldExtract(rvtx.RGBA, 0, 8), bitfieldExtract(rvtx.RGBA, 8, 8),
bitfieldExtract(rvtx.RGBA, 16, 8), bitfieldExtract(rvtx.RGBA, 24, 8));
float a_q = rvtx.Q;
uvec2 a_p = uvec2(rvtx.XY & 0xFFFFu, rvtx.XY >> 16);
uvec2 a_p = uvec2(bitfieldExtract(rvtx.XY, 0, 16), bitfieldExtract(rvtx.XY, 16, 16));
uint a_z = rvtx.Z;
uvec2 a_uv = uvec2(rvtx.UV & 0xFFFFu, rvtx.UV >> 16);
uvec2 a_uv = uvec2(bitfieldExtract(rvtx.UV, 0, 16), bitfieldExtract(rvtx.UV, 16, 16));
vec4 a_f = unpackUnorm4x8(rvtx.FOG);
ProcessedVertex vtx;
+3 -28
View File
@@ -52,9 +52,6 @@ if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
set(USE_CLANG TRUE)
message(STATUS "Building with Clang/LLVM.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(USE_ICC TRUE)
message(STATUS "Building with Intel's ICC.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(USE_GCC TRUE)
message(STATUS "Building with GNU GCC")
@@ -106,21 +103,13 @@ include(TargetArch)
target_architecture(PCSX2_TARGET_ARCHITECTURES)
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
message(STATUS "Compiling a ${PCSX2_TARGET_ARCHITECTURES} build on a ${CMAKE_HOST_SYSTEM_PROCESSOR} host.")
else()
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
endif()
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
# x86_64 requires -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(NOT DEFINED ARCH_FLAG AND NOT MSVC)
if (DISABLE_ADVANCE_SIMD)
if (USE_ICC)
set(ARCH_FLAG "-msse2 -msse4.1")
else()
set(ARCH_FLAG "-msse -msse2 -msse4.1 -mfxsr")
endif()
set(ARCH_FLAG "-msse -msse2 -msse4.1 -mfxsr")
else()
#set(ARCH_FLAG "-march=native -fabi-version=6")
set(ARCH_FLAG "-march=native")
@@ -132,9 +121,6 @@ if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "x86_64")
set(_ARCH_64 1)
set(_M_X86 1)
else()
# All but i386 requires -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
message(FATAL_ERROR "Unsupported architecture: ${PCSX2_TARGET_ARCHITECTURES}")
endif()
string(REPLACE " " ";" ARCH_FLAG_LIST "${ARCH_FLAG}")
@@ -220,24 +206,13 @@ endif()
if (MSVC)
set(DEFAULT_WARNINGS)
else()
set(DEFAULT_WARNINGS -Wall -Wextra -Wno-attributes -Wno-unused-function -Wno-unused-parameter -Wno-missing-field-initializers -Wno-format -Wno-format-security)
if (NOT USE_ICC)
list(APPEND DEFAULT_WARNINGS -Wno-unused-value)
endif()
set(DEFAULT_WARNINGS -Wall -Wextra -Wno-attributes -Wno-unused-function -Wno-unused-parameter -Wno-missing-field-initializers -Wno-format -Wno-format-security -Wno-unused-value)
endif()
if (USE_GCC)
list(APPEND DEFAULT_WARNINGS -Wno-stringop-truncation -Wno-stringop-overflow -Wno-maybe-uninitialized )
endif()
# -Wstrict-aliasing=n: to fix one day aliasing issue. n=1/2/3
if (USE_ICC)
set(AGGRESSIVE_WARNING -Wstrict-aliasing)
elseif(NOT MSVC)
set(AGGRESSIVE_WARNING -Wstrict-aliasing -Wstrict-overflow=1)
endif()
if (USE_PGO_GENERATE OR USE_PGO_OPTIMIZE)
add_compile_options("-fprofile-dir=${CMAKE_SOURCE_DIR}/profile")
endif()
@@ -264,7 +239,7 @@ if(USE_CLANG AND TIMETRACE)
add_compile_options(-ftime-trace)
endif()
set(PCSX2_WARNINGS ${DEFAULT_WARNINGS} ${AGGRESSIVE_WARNING})
set(PCSX2_WARNINGS ${DEFAULT_WARNINGS})
if(DISABLE_BUILD_DATE)
message(STATUS "Disabling the inclusion of the binary compile date.")
+16 -14
View File
@@ -468,10 +468,11 @@ namespace Vulkan
SupportsExtension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, false);
m_optional_extensions.vk_ext_line_rasterization =
SupportsExtension(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false);
m_optional_extensions.vk_ext_rasterization_order_attachment_access =
SupportsExtension(VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false) ||
SupportsExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false);
m_optional_extensions.vk_khr_driver_properties =
SupportsExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false);
m_optional_extensions.vk_arm_rasterization_order_attachment_access =
SupportsExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false);
m_optional_extensions.vk_khr_fragment_shader_barycentric =
SupportsExtension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME, false);
m_optional_extensions.vk_khr_shader_draw_parameters =
@@ -490,7 +491,6 @@ namespace Vulkan
// Enable the features we use.
m_device_features.dualSrcBlend = available_features.dualSrcBlend;
m_device_features.geometryShader = available_features.geometryShader;
m_device_features.largePoints = available_features.largePoints;
m_device_features.wideLines = available_features.wideLines;
m_device_features.fragmentStoresAndAtomics = available_features.fragmentStoresAndAtomics;
@@ -664,8 +664,8 @@ namespace Vulkan
// provoking vertex
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterization_order_access_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
@@ -679,7 +679,7 @@ namespace Vulkan
line_rasterization_feature.bresenhamLines = VK_TRUE;
Util::AddPointerToChain(&device_info, &line_rasterization_feature);
}
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
if (m_optional_extensions.vk_ext_rasterization_order_attachment_access)
{
rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE;
Util::AddPointerToChain(&device_info, &rasterization_order_access_feature);
@@ -745,15 +745,15 @@ namespace Vulkan
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterization_order_access_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
// add in optional feature structs
if (m_optional_extensions.vk_ext_provoking_vertex)
Util::AddPointerToChain(&features2, &provoking_vertex_features);
if (m_optional_extensions.vk_ext_line_rasterization)
Util::AddPointerToChain(&features2, &line_rasterization_feature);
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
if (m_optional_extensions.vk_ext_rasterization_order_attachment_access)
Util::AddPointerToChain(&features2, &rasterization_order_access_feature);
// query
@@ -761,7 +761,7 @@ namespace Vulkan
// confirm we actually support it
m_optional_extensions.vk_ext_provoking_vertex &= (provoking_vertex_features.provokingVertexLast == VK_TRUE);
m_optional_extensions.vk_arm_rasterization_order_attachment_access &= (rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess == VK_TRUE);
m_optional_extensions.vk_ext_rasterization_order_attachment_access &= (rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess == VK_TRUE);
m_optional_extensions.vk_ext_line_rasterization &= (line_rasterization_feature.bresenhamLines == VK_TRUE);
VkPhysicalDeviceProperties2 properties2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
@@ -817,8 +817,8 @@ namespace Vulkan
m_optional_extensions.vk_ext_line_rasterization ? "supported" : "NOT supported");
Console.WriteLn("VK_EXT_calibrated_timestamps is %s",
m_optional_extensions.vk_ext_calibrated_timestamps ? "supported" : "NOT supported");
Console.WriteLn("VK_ARM_rasterization_order_attachment_access is %s",
m_optional_extensions.vk_arm_rasterization_order_attachment_access ? "supported" : "NOT supported");
Console.WriteLn("VK_EXT_rasterization_order_attachment_access is %s",
m_optional_extensions.vk_ext_rasterization_order_attachment_access ? "supported" : "NOT supported");
}
bool Context::CreateAllocator()
@@ -1666,7 +1666,7 @@ namespace Vulkan
input_reference.layout = VK_IMAGE_LAYOUT_GENERAL;
input_reference_ptr = &input_reference;
if (!g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
if (!g_vulkan_context->GetOptionalExtensions().vk_ext_rasterization_order_attachment_access)
{
// don't need the framebuffer-local dependency when we have rasterization order attachment access
subpass_dependency.srcSubpass = 0;
@@ -1699,7 +1699,9 @@ namespace Vulkan
}
const VkSubpassDescriptionFlags subpass_flags =
(key.color_feedback_loop && g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access) ? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM : 0;
(key.color_feedback_loop && g_vulkan_context->GetOptionalExtensions().vk_ext_rasterization_order_attachment_access) ?
VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT :
0;
const VkSubpassDescription subpass = {subpass_flags, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
input_reference_ptr ? input_reference_ptr : nullptr, color_reference_ptr ? 1u : 0u,
color_reference_ptr ? color_reference_ptr : nullptr, nullptr, depth_reference_ptr, 0, nullptr};
+1 -1
View File
@@ -53,8 +53,8 @@ namespace Vulkan
bool vk_ext_memory_budget : 1;
bool vk_ext_calibrated_timestamps : 1;
bool vk_ext_line_rasterization : 1;
bool vk_ext_rasterization_order_attachment_access : 1;
bool vk_khr_driver_properties : 1;
bool vk_arm_rasterization_order_attachment_access : 1;
bool vk_khr_fragment_shader_barycentric : 1;
bool vk_khr_shader_draw_parameters : 1;
};
+9 -3
View File
@@ -545,9 +545,7 @@ namespace Vulkan
// Determine the dimensions of the swap chain. Values of -1 indicate the size we specify here
// determines window size?
VkExtent2D size = surface_capabilities.currentExtent;
#ifndef ANDROID
if (size.width == UINT32_MAX)
#endif
{
size.width = m_window_info.surface_width;
size.height = m_window_info.surface_height;
@@ -562,6 +560,14 @@ namespace Vulkan
if (!(surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR))
transform = surface_capabilities.currentTransform;
VkCompositeAlphaFlagBitsKHR alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
if (!(surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR))
{
// If we only support pre-multiplied/post-multiplied... :/
if (surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
alpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
}
// Select swap chain flags, we only need a colour attachment
VkImageUsageFlags image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
if (!(surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
@@ -577,7 +583,7 @@ namespace Vulkan
// Now we can actually create the swap chain
VkSwapchainCreateInfoKHR swap_chain_info = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, nullptr, 0, m_surface,
image_count, m_surface_format.format, m_surface_format.colorSpace, size, 1u, image_usage,
VK_SHARING_MODE_EXCLUSIVE, 0, nullptr, transform, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, m_present_mode,
VK_SHARING_MODE_EXCLUSIVE, 0, nullptr, transform, alpha, m_present_mode,
VK_TRUE, old_swap_chain};
std::array<uint32_t, 2> indices = {{
g_vulkan_context->GetGraphicsQueueFamilyIndex(),
+1 -1
View File
@@ -786,7 +786,7 @@ void MainWindow::setStyleFromSettings()
// Alternative dark theme.
qApp->setStyle(QStyleFactory::create("Fusion"));
const QColor gray(192, 192, 192);
const QColor gray(150, 150, 150);
const QColor royalBlue(29, 41, 81);
const QColor darkishBlue(17, 30, 108);
const QColor highlight(36, 93, 218);
+16
View File
@@ -438,16 +438,28 @@
<property name="text">
<string>&amp;GitHub Repository...</string>
</property>
<property name="icon">
<iconset theme="github">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionSupportForums">
<property name="text">
<string>Support &amp;Forums...</string>
</property>
<property name="icon">
<iconset theme="at">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionDiscordServer">
<property name="text">
<string>&amp;Discord Server...</string>
</property>
<property name="icon">
<iconset theme="discord">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionCheckForUpdates">
<property name="icon">
@@ -471,6 +483,10 @@
<property name="text">
<string>&amp;About PCSX2...</string>
</property>
<property name="icon">
<iconset resource="resources/resources.qrc">
<normaloff>:/icons/AppIcon.png</normaloff>:/icons/AppIcon.png</iconset>
</property>
</action>
<action name="actionChangeDisc">
<property name="icon">
@@ -37,13 +37,19 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
#ifdef SDL_BUILD
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableSDLSource, "InputSources", "SDL", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableSDLEnhancedMode, "InputSources", "SDLControllerEnhancedMode", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableSDLRawInput, "InputSources", "SDLRawInput", false);
connect(m_ui.enableSDLSource, &QCheckBox::stateChanged, this, &ControllerGlobalSettingsWidget::updateSDLOptionsEnabled);
connect(m_ui.ledSettings, &QToolButton::clicked, this, &ControllerGlobalSettingsWidget::ledSettingsClicked);
#else
m_ui.enableSDLSource->setEnabled(false);
m_ui.ledSettings->setEnabled(false);
m_ui.enableSDLRawInput->setEnabled(false);
#endif
#if defined(SDL_BUILD) && defined(_WIN32)
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableSDLRawInput, "InputSources", "SDLRawInput", false);
#else
m_ui.gridLayout_2->removeWidget(m_ui.enableSDLRawInput);
m_ui.enableSDLRawInput->deleteLater();
m_ui.enableSDLRawInput = nullptr;
#endif
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableMouseMapping, "UI", "EnableMouseMapping", false);
@@ -62,7 +68,6 @@ ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent,
m_ui.mainLayout->removeWidget(m_ui.dinputGroup);
m_ui.dinputGroup->deleteLater();
m_ui.dinputGroup = nullptr;
m_ui.enableSDLRawInput->hide();
#endif
if (dialog->isEditingProfile())
@@ -116,7 +121,9 @@ void ControllerGlobalSettingsWidget::updateSDLOptionsEnabled()
const bool enabled = m_ui.enableSDLSource->isChecked();
m_ui.enableSDLEnhancedMode->setEnabled(enabled);
m_ui.ledSettings->setEnabled(enabled);
#ifdef _WIN32
m_ui.enableSDLRawInput->setEnabled(enabled);
#endif
}
void ControllerGlobalSettingsWidget::ledSettingsClicked()
+1 -1
View File
@@ -662,7 +662,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.osdShowGSStats, tr("Show Statistics"), tr("Unchecked"),
tr("Shows counters for internal graphical utilization, useful for debugging."));
dialog->registerWidgetHelp(m_ui.osdShowIndicators, tr("Show Indicators"), tr("Unchecked"),
dialog->registerWidgetHelp(m_ui.osdShowIndicators, tr("Show Indicators"), tr("Checked"),
tr("Shows OSD icon indicators for emulation states such as Pausing, Turbo, Fast-Forward, and Slow-Motion."));
dialog->registerWidgetHelp(m_ui.osdShowSettings, tr("Show Settings"), tr("Unchecked"),
+1 -1
View File
@@ -5,7 +5,7 @@ IFS="
printf "<RCC>\n"
printf "\t<qresource>\n"
for i in $(find . -not -iname '*.sh' -not -iname '*.qrc' -type f | cut -d'/' -f2-99); do
for i in $(find . -not -iname '.*' -not -iname '*.sh' -not -iname '*.qrc' -type f | cut -d'/' -f2-99 | sort -f); do
printf "\t\t<file>%s</file>\n" "$i"
done
printf "\t</qresource>\n"
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -2,6 +2,10 @@
Name=Black Icon Theme
Comment=Black Icon Theme
[32]
Size=32
Type=Fixed
[svg]
Size=64
Type=Scalable
@@ -0,0 +1,3 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-at" viewBox="0 0 16 16"> <path d="M13.106 7.222c0-2.967-2.249-5.032-5.482-5.032-3.35 0-5.646 2.318-5.646 5.702 0 3.493 2.235 5.708 5.762 5.708.862 0 1.689-.123 2.304-.335v-.862c-.43.199-1.354.328-2.29.328-2.926 0-4.813-1.88-4.813-4.798 0-2.844 1.921-4.881 4.594-4.881 2.735 0 4.608 1.688 4.608 4.156 0 1.682-.554 2.769-1.416 2.769-.492 0-.772-.28-.772-.76V5.206H8.923v.834h-.11c-.266-.595-.881-.964-1.6-.964-1.4 0-2.378 1.162-2.378 2.823 0 1.737.957 2.906 2.379 2.906.8 0 1.415-.39 1.709-1.087h.11c.081.67.703 1.148 1.503 1.148 1.572 0 2.57-1.415 2.57-3.643zm-7.177.704c0-1.197.54-1.907 1.456-1.907.93 0 1.524.738 1.524 1.907S8.308 9.84 7.371 9.84c-.895 0-1.442-.725-1.442-1.914z"/> </svg>

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -2,6 +2,10 @@
Name=White Icon Theme
Comment=White Icon Theme
[32]
Size=32
Type=Fixed
[svg]
Size=64
Type=Scalable
@@ -0,0 +1,3 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg style="color: white" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-at" viewBox="0 0 16 16"> <path d="M13.106 7.222c0-2.967-2.249-5.032-5.482-5.032-3.35 0-5.646 2.318-5.646 5.702 0 3.493 2.235 5.708 5.762 5.708.862 0 1.689-.123 2.304-.335v-.862c-.43.199-1.354.328-2.29.328-2.926 0-4.813-1.88-4.813-4.798 0-2.844 1.921-4.881 4.594-4.881 2.735 0 4.608 1.688 4.608 4.156 0 1.682-.554 2.769-1.416 2.769-.492 0-.772-.28-.772-.76V5.206H8.923v.834h-.11c-.266-.595-.881-.964-1.6-.964-1.4 0-2.378 1.162-2.378 2.823 0 1.737.957 2.906 2.379 2.906.8 0 1.415-.39 1.709-1.087h.11c.081.67.703 1.148 1.503 1.148 1.572 0 2.57-1.415 2.57-3.643zm-7.177.704c0-1.197.54-1.907 1.456-1.907.93 0 1.524.738 1.524 1.907S8.308 9.84 7.371 9.84c-.895 0-1.442-.725-1.442-1.914z" fill="white"></path> </svg>

After

Width:  |  Height:  |  Size: 978 B

+7 -2
View File
@@ -1,10 +1,13 @@
<RCC>
<qresource>
<file>icons/address-book-new-22.png</file>
<file>icons/AppIcon.png</file>
<file>icons/applications-system-24.png</file>
<file>icons/black/32/discord.png</file>
<file>icons/black/32/github.png</file>
<file>icons/black/index.theme</file>
<file>icons/black/svg/arrow-left-right-line.svg</file>
<file>icons/black/svg/artboard-2-line.svg</file>
<file>icons/black/svg/at.svg</file>
<file>icons/black/svg/book-open-line.svg</file>
<file>icons/black/svg/brush-line.svg</file>
<file>icons/black/svg/checkbox-multiple-blank-line.svg</file>
@@ -56,16 +59,18 @@
<file>icons/black/svg/usb-fill.svg</file>
<file>icons/black/svg/volume-up-line.svg</file>
<file>icons/black/svg/window-2-line.svg</file>
<file>icons/discord.png</file>
<file>icons/logo.png</file>
<file>icons/media-optical-24.png</file>
<file>icons/media-optical-gear-24.png</file>
<file>icons/media-optical.png</file>
<file>icons/QT.png</file>
<file>icons/update.png</file>
<file>icons/white/32/discord.png</file>
<file>icons/white/32/github.png</file>
<file>icons/white/index.theme</file>
<file>icons/white/svg/arrow-left-right-line.svg</file>
<file>icons/white/svg/artboard-2-line.svg</file>
<file>icons/white/svg/at.svg</file>
<file>icons/white/svg/book-open-line.svg</file>
<file>icons/white/svg/brush-line.svg</file>
<file>icons/white/svg/checkbox-multiple-blank-line.svg</file>
+1 -1
View File
@@ -253,7 +253,7 @@ bool InputIsoFile::Open(std::string srcfile, bool testOnly)
if (!detected)
{
Console.Error(fmt::format("Unable to identify the ISO image type for '{}'", srcfile));
Console.Error(fmt::format("Unable to identify the ISO image type for '{}'", m_filename));
Close();
return false;
}
-1
View File
@@ -566,7 +566,6 @@ set(pcsx2GSHeaders
GS/Renderers/Common/GSRenderer.h
GS/Renderers/Common/GSTexture.h
GS/Renderers/Common/GSVertex.h
GS/Renderers/Common/GSVertexList.h
GS/Renderers/Common/GSVertexTrace.h
GS/Renderers/Null/GSRendererNull.h
GS/Renderers/HW/GSHwHack.h
+4
View File
@@ -38,6 +38,7 @@ SERIAL-12345: # !required! Serial number for the game, this is how games are loo
- GIFFIFOHack
- GoemonTlbHack
- IbitHack
- FullVU0SyncHack
- VUSyncHack
- VUOverflowHack
- SoftwareRendererFMVHack
@@ -220,6 +221,9 @@ These values are case-sensitive so take care. If you incorrectly specify a Game
* `IbitHack`
* VU I bit Hack avoid constant recompilation in some games (Scarface The World Is Yours, Crash Tag Team Racing).
* `FullVU0SyncHack`
* Increase the synchronisation points between COP2 and VU0.
* `VUSyncHack`
* Make the VU's run behind/in sync with the EE to fix some timing issues.
+1
View File
@@ -101,6 +101,7 @@
"VIFFIFOHack",
"VuAddSubHack",
"VUOverflowHack",
"FullVU0SyncHack",
"VUSyncHack",
"XGKickHack"
]
+2
View File
@@ -3748,6 +3748,8 @@ void FullscreenUI::DrawControllerSettingsPage()
DrawToggleSetting(bsi, ICON_FA_WIFI " SDL DualShock 4 / DualSense Enhanced Mode",
"Provides vibration and LED control support over Bluetooth.", "InputSources", "SDLControllerEnhancedMode", false,
bsi->GetBoolValue("InputSources", "SDL", true), false);
#endif
#if defined(SDL_BUILD) && defined(_WIN32)
DrawToggleSetting(bsi, ICON_FA_COG " SDL Raw Input", "Allow SDL to use raw access to input devices.", "InputSources", "SDLRawInput",
false, bsi->GetBoolValue("InputSources", "SDL", true), false);
#endif
+2 -1
View File
@@ -748,12 +748,13 @@ void GSgetStats(std::string& info)
}
else
{
fmt::format_to(std::back_inserter(info), "{} HW | {} P | {} D | {} DC | {} B | {} RB | {} TC | {} TU",
fmt::format_to(std::back_inserter(info), "{} HW | {} P | {} D | {} DC | {} B | {} RP | {} RB | {} TC | {} TU",
api_name,
(int)pm.Get(GSPerfMon::Prim),
(int)pm.Get(GSPerfMon::Draw),
(int)std::ceil(pm.Get(GSPerfMon::DrawCalls)),
(int)std::ceil(pm.Get(GSPerfMon::Barriers)),
(int)std::ceil(pm.Get(GSPerfMon::RenderPasses)),
(int)std::ceil(pm.Get(GSPerfMon::Readbacks)),
(int)std::ceil(pm.Get(GSPerfMon::TextureCopies)),
(int)std::ceil(pm.Get(GSPerfMon::TextureUploads)));
+2 -1
View File
@@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "GS/GSClut.h"
#include "GS/GSExtra.h"
#include "GS/GSLocalMemory.h"
#include "GS/GSGL.h"
#include "GS/Renderers/Common/GSDevice.h"
@@ -27,7 +28,7 @@ GSClut::GSClut(GSLocalMemory* mem)
static constexpr u32 CLUT_ALLOC_SIZE = 4096 * 2;
// 1k + 1k for mirrored area simulating wrapping memory
m_clut = static_cast<u16*>(_aligned_malloc(CLUT_ALLOC_SIZE, 32));
m_clut = static_cast<u16*>(_aligned_malloc(CLUT_ALLOC_SIZE, VECTOR_ALIGNMENT));
if (!m_clut)
throw std::bad_alloc();
+13 -1
View File
@@ -15,8 +15,9 @@
#pragma once
#include "GSVector.h"
#include "GS/GSVector.h"
#include "pcsx2/Config.h"
#include "common/Align.h"
/// Like `memcmp(&a, &b, sizeof(T)) == 0` but faster
template <typename T>
@@ -117,6 +118,17 @@ static constexpr u32 MAX_SKIPPED_DUPLICATE_FRAMES = 3;
extern void* GSAllocateWrappedMemory(size_t size, size_t repeat);
extern void GSFreeWrappedMemory(void* ptr, size_t size, size_t repeat);
/// We want all allocations and pitches to be aligned to 32-bit, regardless of whether we're
/// SSE4 or AVX2, because of multi-ISA.
static constexpr u32 VECTOR_ALIGNMENT = 32;
/// Aligns allocation/pitch size to preferred host size.
template<typename T>
__fi static T VectorAlign(T value)
{
return Common::AlignUpPow2(value, VECTOR_ALIGNMENT);
}
// clang-format off
#ifdef __POSIX__
+3 -3
View File
@@ -286,7 +286,7 @@ GSPixelOffset* GSLocalMemory::GetPixelOffset(const GIFRegFRAME& FRAME, const GIF
return it->second;
}
GSPixelOffset* off = (GSPixelOffset*)_aligned_malloc(sizeof(GSPixelOffset), 32);
GSPixelOffset* off = (GSPixelOffset*)_aligned_malloc(sizeof(GSPixelOffset), VECTOR_ALIGNMENT);
off->hash = hash;
off->fbp = fbp;
@@ -339,7 +339,7 @@ GSPixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& FRAME, const G
return it->second;
}
GSPixelOffset4* off = (GSPixelOffset4*)_aligned_malloc(sizeof(GSPixelOffset4), 32);
GSPixelOffset4* off = (GSPixelOffset4*)_aligned_malloc(sizeof(GSPixelOffset4), VECTOR_ALIGNMENT);
off->hash = hash;
off->fbp = fbp;
@@ -544,7 +544,7 @@ void GSLocalMemory::SaveBMP(const std::string& fn, u32 bp, u32 bw, u32 psm, int
{
int pitch = w * 4;
int size = pitch * h;
void* bits = _aligned_malloc(size, 32);
void* bits = _aligned_malloc(size, VECTOR_ALIGNMENT);
GIFRegTEX0 TEX0;
+5 -4
View File
@@ -19,8 +19,9 @@
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "GSDump.h"
#include "GSLzma.h"
#include "GS/GSDump.h"
#include "GS/GSLzma.h"
#include "GS/GSExtra.h"
using namespace GSDumpTypes;
@@ -273,8 +274,8 @@ void GSDumpLzma::Initialize()
}
m_buff_size = 1024*1024;
m_area = (uint8_t*)_aligned_malloc(m_buff_size, 32);
m_inbuf = (uint8_t*)_aligned_malloc(BUFSIZ, 32);
m_area = (uint8_t*)_aligned_malloc(m_buff_size, VECTOR_ALIGNMENT);
m_inbuf = (uint8_t*)_aligned_malloc(BUFSIZ, VECTOR_ALIGNMENT);
m_avail = 0;
m_start = 0;
+1 -1
View File
@@ -27,9 +27,9 @@ public:
Swizzle,
Unswizzle,
Fillrate,
Quad,
SyncPoint,
Barriers,
RenderPasses,
CounterLast,
// Reused counters for HW.
+33 -30
View File
@@ -2638,31 +2638,31 @@ void GSState::GrowVertexBuffer()
{
const u32 maxcount = std::max<u32>(m_vertex.maxcount * 3 / 2, 10000);
GSVertex* vertex = (GSVertex*)_aligned_malloc(sizeof(GSVertex) * maxcount, 32);
GSVertex* 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
u32* index = (u32*)_aligned_malloc(sizeof(u32) * maxcount * 6, 32);
u16* index = static_cast<u16*>(_aligned_malloc(sizeof(u16) * maxcount * 6, 32));
if (vertex == NULL || index == NULL)
if (!vertex || !index)
{
const u32 vert_byte_count = sizeof(GSVertex) * maxcount;
const u32 idx_byte_count = sizeof(u32) * maxcount * 3;
const u32 idx_byte_count = sizeof(u16) * maxcount * 3;
Console.Error("GS: failed to allocate %zu bytes for verticles and %zu for indices.",
Console.Error("GS: failed to allocate %zu bytes for vertices and %zu for indices.",
vert_byte_count, idx_byte_count);
throw GSError();
}
if (m_vertex.buff != NULL)
if (m_vertex.buff)
{
memcpy(vertex, m_vertex.buff, sizeof(GSVertex) * m_vertex.tail);
std::memcpy(vertex, m_vertex.buff, sizeof(GSVertex) * m_vertex.tail);
_aligned_free(m_vertex.buff);
}
if (m_index.buff != NULL)
if (m_index.buff)
{
memcpy(index, m_index.buff, sizeof(u32) * m_index.tail);
std::memcpy(index, m_index.buff, sizeof(u16) * m_index.tail);
_aligned_free(m_index.buff);
}
@@ -3063,21 +3063,24 @@ static constexpr u32 MaxVerticesForPrim(u32 prim)
{
switch (prim)
{
// Four indices per 1 vertex.
case GS_POINTLIST:
case GS_INVALID:
// Needed due to expansion in hardware renderers.
// Indices are shifted left by 2 to form quads.
case GS_LINELIST:
case GS_LINESTRIP:
return (std::numeric_limits<u16>::max() / 4) - 4;
// Four indices per two vertices.
case GS_SPRITE:
return (std::numeric_limits<u16>::max() / 2) - 2;
case GS_LINELIST:
case GS_LINESTRIP:
case GS_TRIANGLELIST:
case GS_TRIANGLESTRIP:
case GS_TRIANGLEFAN:
default:
return 0;
return (std::numeric_limits<u16>::max() - 3);
}
}
@@ -3229,19 +3232,19 @@ __forceinline void GSState::VertexKick(u32 skip)
m_backed_up_ctx = m_env.PRIM.CTXT;
}
u32* RESTRICT buff = &m_index.buff[m_index.tail];
u16* RESTRICT buff = &m_index.buff[m_index.tail];
switch (prim)
{
case GS_POINTLIST:
buff[0] = head + 0;
buff[0] = static_cast<u16>(head + 0);
m_vertex.head = head + 1;
m_vertex.next = head + 1;
m_index.tail += 1;
break;
case GS_LINELIST:
buff[0] = head + (index_swap ? 1 : 0);
buff[1] = head + (index_swap ? 0 : 1);
buff[0] = static_cast<u16>(head + (index_swap ? 1 : 0));
buff[1] = static_cast<u16>(head + (index_swap ? 0 : 1));
m_vertex.head = head + 2;
m_vertex.next = head + 2;
m_index.tail += 2;
@@ -3254,16 +3257,16 @@ __forceinline void GSState::VertexKick(u32 skip)
head = next;
m_vertex.tail = next + 2;
}
buff[0] = head + (index_swap ? 1 : 0);
buff[1] = head + (index_swap ? 0 : 1);
buff[0] = static_cast<u16>(head + (index_swap ? 1 : 0));
buff[1] = static_cast<u16>(head + (index_swap ? 0 : 1));
m_vertex.head = head + 1;
m_vertex.next = head + 2;
m_index.tail += 2;
break;
case GS_TRIANGLELIST:
buff[0] = head + (index_swap ? 2 : 0);
buff[1] = head + 1;
buff[2] = head + (index_swap ? 0 : 2);
buff[0] = static_cast<u16>(head + (index_swap ? 2 : 0));
buff[1] = static_cast<u16>(head + 1);
buff[2] = static_cast<u16>(head + (index_swap ? 0 : 2));
m_vertex.head = head + 3;
m_vertex.next = head + 3;
m_index.tail += 3;
@@ -3277,24 +3280,24 @@ __forceinline void GSState::VertexKick(u32 skip)
head = next;
m_vertex.tail = next + 3;
}
buff[0] = head + (index_swap ? 2 : 0);
buff[1] = head + 1;
buff[2] = head + (index_swap ? 0 : 2);
buff[0] = static_cast<u16>(head + (index_swap ? 2 : 0));
buff[1] = static_cast<u16>(head + 1);
buff[2] = static_cast<u16>(head + (index_swap ? 0 : 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] = index_swap ? (tail - 1) : (head + 0);
buff[1] = tail - 2;
buff[2] = index_swap ? (head + 0) : (tail - 1);
buff[0] = static_cast<u16>(index_swap ? (tail - 1) : (head + 0));
buff[1] = static_cast<u16>(tail - 2);
buff[2] = static_cast<u16>(index_swap ? (head + 0) : (tail - 1));
m_vertex.next = tail;
m_index.tail += 3;
break;
case GS_SPRITE:
buff[0] = head + 0;
buff[1] = head + 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;
+1 -1
View File
@@ -158,7 +158,7 @@ protected:
struct
{
u32* buff;
u16* buff;
u32 tail;
} m_index = {};
+24
View File
@@ -28,6 +28,16 @@ class alignas(16) GSVector4i
{
}
constexpr GSVector4i(cxpr_init_tag, short s0, short s1, short s2, short s3, short s4, short s5, short s6, short s7)
: I16{s0, s1, s2, s3, s4, s5, s6, s7}
{
}
constexpr GSVector4i(cxpr_init_tag, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9, char b10, char b11, char b12, char b13, char b14, char b15)
: I8{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}
{
}
public:
union
{
@@ -62,6 +72,16 @@ public:
return GSVector4i(cxpr_init, x, x, x, x);
}
constexpr static GSVector4i cxpr16(short s0, short s1, short s2, short s3, short s4, short s5, short s6, short s7)
{
return GSVector4i(cxpr_init, s0, s1, s2, s3, s4, s5, s6, s7);
}
constexpr static GSVector4i cxpr8(char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9, char b10, char b11, char b12, char b13, char b14, char b15)
{
return GSVector4i(cxpr_init, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15);
}
__forceinline GSVector4i(int x, int y, int z, int w)
{
m = _mm_set_epi32(w, z, y, x);
@@ -2001,6 +2021,10 @@ public:
return v;
}
__forceinline static GSVector4i broadcast16(u16 value)
{
return GSVector4i(_mm_set1_epi16(value));
}
__forceinline static GSVector4i zero() { return GSVector4i(_mm_setzero_si128()); }
+3 -2
View File
@@ -18,6 +18,7 @@
#include "GS/GSGL.h"
#include "GS/GS.h"
#include "Host.h"
#include "common/Align.h"
#include "common/StringUtil.h"
#include "imgui.h"
@@ -165,9 +166,9 @@ std::string GSDevice::GetFullscreenModeString(u32 width, u32 height, float refre
void GSDevice::GenerateExpansionIndexBuffer(void* buffer)
{
static constexpr u32 MAX_INDEX = std::numeric_limits<u16>::max();
static constexpr u32 MAX_INDEX = EXPAND_BUFFER_SIZE / 6 / sizeof(u16);
u32* idx_buffer = static_cast<u32*>(buffer);
u16* idx_buffer = static_cast<u16*>(buffer);
for (u32 i = 0; i < MAX_INDEX; i++)
{
const u32 base = i * 4;
+2 -2
View File
@@ -627,7 +627,7 @@ struct alignas(16) GSHWDrawConfig
GSTexture* tex; ///< Source texture
GSTexture* pal; ///< Palette texture
const GSVertex* verts;///< Vertices to draw
const u32* indices; ///< Indices to draw
const u16* indices; ///< Indices to draw
u32 nverts; ///< Number of vertices
u32 nindices; ///< Number of indices
u32 indices_per_prim; ///< Number of indices that make up one primitive
@@ -749,7 +749,7 @@ protected:
static constexpr float MAD_SENSITIVITY = 0.08f;
static constexpr u32 MAX_POOLED_TEXTURES = 300;
static constexpr u32 NUM_CAS_CONSTANTS = 12; // 8 plus src offset x/y, 16 byte alignment
static constexpr u32 EXPAND_BUFFER_SIZE = sizeof(u32) * std::numeric_limits<u16>::max() * 6;
static constexpr u32 EXPAND_BUFFER_SIZE = sizeof(u16) * 65532 * 6;
WindowInfo m_window_info;
VsyncMode m_vsync_mode = VsyncMode::Off;
@@ -1,17 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "GSVertexList.h"
-82
View File
@@ -1,82 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
template <class Vertex>
class GSVertexList
{
void* m_base;
Vertex* m_v[3];
int m_count;
public:
GSVertexList()
: m_count(0)
{
m_base = _aligned_malloc(sizeof(Vertex) * std::size(m_v), 32);
for (size_t i = 0; i < std::size(m_v); i++)
{
m_v[i] = &((Vertex*)m_base)[i];
}
}
virtual ~GSVertexList()
{
_aligned_free(m_base);
}
void RemoveAll()
{
m_count = 0;
}
__forceinline Vertex& AddTail()
{
ASSERT(m_count < 3);
return *m_v[m_count++];
}
__forceinline void RemoveAt(int pos, int keep)
{
if (keep == 1)
{
Vertex* tmp = m_v[pos + 0];
m_v[pos + 0] = m_v[pos + 1];
m_v[pos + 1] = tmp;
}
else if (keep == 2)
{
Vertex* tmp = m_v[pos + 0];
m_v[pos + 0] = m_v[pos + 1];
m_v[pos + 1] = m_v[pos + 2];
m_v[pos + 2] = tmp;
}
m_count = pos + keep;
}
__forceinline void GetAt(int i, Vertex& v)
{
v = *m_v[i];
}
int GetCount()
{
return m_count;
}
};
+2 -2
View File
@@ -24,7 +24,7 @@ GSVertexTrace::GSVertexTrace(const GSState* state, bool provoking_vertex_first)
MULTI_ISA_SELECT(GSVertexTracePopulateFunctions)(*this, provoking_vertex_first);
}
void GSVertexTrace::Update(const void* vertex, const u32* index, int v_count, int i_count, GS_PRIM_CLASS primclass)
void GSVertexTrace::Update(const void* vertex, const u16* index, int v_count, int i_count, GS_PRIM_CLASS primclass)
{
if (i_count == 0)
return;
@@ -43,7 +43,7 @@ void GSVertexTrace::Update(const void* vertex, const u32* index, int v_count, in
// that feel big enough.
if (!fst && !m_accurate_stq && m_min.t.z > 1e30)
{
fprintf(stderr, "Vertex Trace: float overflow detected ! min %e max %e\n", m_min.t.z, m_max.t.z);
Console.Warning("Vertex Trace: float overflow detected ! min %e max %e", m_min.t.z, m_max.t.z);
m_accurate_stq = true;
}
+2 -2
View File
@@ -49,7 +49,7 @@ public:
protected:
const GSState* m_state;
typedef void (*FindMinMaxPtr)(GSVertexTrace& vt, const void* vertex, const u32* index, int count);
typedef void (*FindMinMaxPtr)(GSVertexTrace& vt, const void* vertex, const u16* index, int count);
FindMinMaxPtr m_fmm[2][2][2][2][4];
@@ -77,7 +77,7 @@ public:
public:
GSVertexTrace(const GSState* state, bool provoking_vertex_first);
void Update(const void* vertex, const u32* index, int v_count, int i_count, GS_PRIM_CLASS primclass);
void Update(const void* vertex, const u16* index, int v_count, int i_count, GS_PRIM_CLASS primclass);
bool IsLinear() const { return m_filter.opt_linear; }
bool IsRealLinear() const { return m_filter.linear; }
@@ -22,7 +22,7 @@ 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>
static void FindMinMax(GSVertexTrace& vt, const void* vertex, const u32* index, int count);
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);
@@ -76,7 +76,7 @@ void GSVertexTraceFMM::Populate(GSVertexTrace& vt, bool provoking_vertex_first)
}
template <GS_PRIM_CLASS primclass, u32 iip, u32 tme, u32 fst, u32 color, bool flat_swapped>
void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u32* index, int count)
void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u16* index, int count)
{
const GSDrawingContext* context = vt.m_state->m_context;
+15 -21
View File
@@ -883,7 +883,9 @@ GSDevice::PresentResult GSDevice11::BeginPresent(bool frame_skip)
{
m_state.dsv->Release();
m_state.dsv = nullptr;
}
}
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
const GSVector2i size = GetWindowSize();
SetViewport(size);
@@ -1440,7 +1442,7 @@ void GSDevice11::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rect
const u32 vertex_reserve_size = num_rects * 4;
const u32 index_reserve_size = num_rects * 6;
GSVertexPT1* verts = static_cast<GSVertexPT1*>(IAMapVertexBuffer(sizeof(GSVertexPT1), vertex_reserve_size));
u32* idx = IAMapIndexBuffer(index_reserve_size);
u16* idx = IAMapIndexBuffer(index_reserve_size);
u32 icount = 0;
u32 vcount = 0;
for (u32 i = 0; i < num_rects; i++)
@@ -1712,7 +1714,6 @@ void GSDevice11::RenderImGui()
const UINT vb_stride = sizeof(ImDrawVert);
const UINT vb_offset = 0;
m_ctx->IASetVertexBuffers(0, 1, m_vb.addressof(), &vb_stride, &vb_offset);
m_ctx->IASetIndexBuffer(m_ib.get(), DXGI_FORMAT_R16_UINT, 0);
IASetInputLayout(m_imgui.il.get());
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
VSSetShader(m_imgui.vs.get(), m_imgui.vs_cb.get());
@@ -1756,16 +1757,8 @@ void GSDevice11::RenderImGui()
m_ctx->Unmap(m_vb.get(), 0);
}
// Bit awkward, because this is using 16-bit indices, not 32-bit.
static_assert(sizeof(ImDrawIdx) == sizeof(u16));
const u32 index_count = static_cast<u32>(cmd_list->IdxBuffer.Size + 1) / 2;
u32* index_map = IAMapIndexBuffer(index_count);
if (!index_map)
continue;
const u32 index_start = m_index.start * 2;
std::memcpy(index_map, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
IAUnmapIndexBuffer(index_count);
IASetIndexBuffer(cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
@@ -1787,14 +1780,13 @@ void GSDevice11::RenderImGui()
m_state.ps_sr_views[0] = static_cast<ID3D11ShaderResourceView*>(pcmd->GetTexID());
PSUpdateShaderState();
m_ctx->DrawIndexed(pcmd->ElemCount, index_start + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset);
m_ctx->DrawIndexed(pcmd->ElemCount, m_index.start + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset);
}
g_perfmon.Put(GSPerfMon::DrawCalls, cmd_list->CmdBuffer.Size);
}
m_ctx->IASetVertexBuffers(0, 1, m_vb.addressof(), &m_state.vb_stride, &vb_offset);
m_ctx->IASetIndexBuffer(m_state.index_buffer, DXGI_FORMAT_R32_UINT, 0);
}
void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm)
@@ -1912,9 +1904,9 @@ bool GSDevice11::IASetExpandVertexBuffer(const void* vertex, u32 stride, u32 cou
return true;
}
u32* GSDevice11::IAMapIndexBuffer(u32 count)
u16* GSDevice11::IAMapIndexBuffer(u32 count)
{
if (count > (INDEX_BUFFER_SIZE / sizeof(u32)))
if (count > (INDEX_BUFFER_SIZE / sizeof(u16)))
return nullptr;
D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE;
@@ -1922,7 +1914,7 @@ u32* GSDevice11::IAMapIndexBuffer(u32 count)
m_index.start = m_ib_pos;
m_ib_pos += count;
if (m_ib_pos > (INDEX_BUFFER_SIZE / sizeof(u32)))
if (m_ib_pos > (INDEX_BUFFER_SIZE / sizeof(u16)))
{
m_index.start = 0;
m_ib_pos = count;
@@ -1933,7 +1925,7 @@ u32* GSDevice11::IAMapIndexBuffer(u32 count)
if (FAILED(m_ctx->Map(m_ib.get(), 0, type, 0, &m)))
return nullptr;
return static_cast<u32*>(m.pData) + m_index.start;
return static_cast<u16*>(m.pData) + m_index.start;
}
void GSDevice11::IAUnmapIndexBuffer(u32 count)
@@ -1944,11 +1936,11 @@ void GSDevice11::IAUnmapIndexBuffer(u32 count)
bool GSDevice11::IASetIndexBuffer(const void* index, u32 count)
{
u32* map = IAMapIndexBuffer(count);
u16* map = IAMapIndexBuffer(count);
if (!map)
return false;
std::memcpy(map, index, count * sizeof(u32));
std::memcpy(map, index, count * sizeof(u16));
IAUnmapIndexBuffer(count);
IASetIndexBuffer(m_ib.get());
return true;
@@ -1958,7 +1950,7 @@ void GSDevice11::IASetIndexBuffer(ID3D11Buffer* buffer)
{
if (m_state.index_buffer != buffer)
{
m_ctx->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, 0);
m_ctx->IASetIndexBuffer(buffer, DXGI_FORMAT_R16_UINT, 0);
m_state.index_buffer = buffer;
}
}
@@ -2073,6 +2065,8 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
if (ds) dsv = *(GSTexture11*)ds;
const bool changed = (m_state.rt_view != rtv || m_state.dsv != dsv);
g_perfmon.Put(GSPerfMon::RenderPasses, static_cast<double>(changed));
if (m_state.rt_view != rtv)
{
if (m_state.rt_view)
+1 -1
View File
@@ -343,7 +343,7 @@ public:
bool IASetVertexBuffer(const void* vertex, u32 stride, u32 count);
bool IASetExpandVertexBuffer(const void* vertex, u32 stride, u32 count);
u32* IAMapIndexBuffer(u32 count);
u16* IAMapIndexBuffer(u32 count);
void IAUnmapIndexBuffer(u32 count);
bool IASetIndexBuffer(const void* index, u32 count);
void IASetIndexBuffer(ID3D11Buffer* buffer);
+37 -32
View File
@@ -538,6 +538,7 @@ GSDevice::PresentResult GSDevice12::BeginPresent(bool frame_skip)
swap_chain_buf.TransitionToState(cmdlist, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(swap_chain_buf.GetWriteDescriptor(), clear_color.data(), 0, nullptr);
cmdlist->OMSetRenderTargets(1, &swap_chain_buf.GetWriteDescriptor().cpu_handle, FALSE, nullptr);
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
const D3D12_VIEWPORT vp{0.0f, 0.0f, static_cast<float>(m_window_info.surface_width),
static_cast<float>(m_window_info.surface_height), 0.0f, 1.0f};
@@ -949,13 +950,13 @@ void GSDevice12::DoMultiStretchRects(
{
// Set up vertices first.
const u32 vertex_reserve_size = num_rects * 4 * sizeof(GSVertexPT1);
const u32 index_reserve_size = num_rects * 6 * sizeof(u32);
const u32 index_reserve_size = num_rects * 6 * sizeof(u16);
if (!m_vertex_stream_buffer.ReserveMemory(vertex_reserve_size, sizeof(GSVertexPT1)) ||
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u32)))
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u16)))
{
ExecuteCommandListAndRestartRenderPass(false, "Uploading bytes to vertex buffer");
if (!m_vertex_stream_buffer.ReserveMemory(vertex_reserve_size, sizeof(GSVertexPT1)) ||
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u32)))
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u16)))
{
pxFailRel("Failed to reserve space for vertices");
}
@@ -965,7 +966,7 @@ void GSDevice12::DoMultiStretchRects(
// Don't use primitive restart here, it ends up slower on some drivers.
const GSVector2 ds(static_cast<float>(dTex->GetWidth()), static_cast<float>(dTex->GetHeight()));
GSVertexPT1* verts = reinterpret_cast<GSVertexPT1*>(m_vertex_stream_buffer.GetCurrentHostPointer());
u32* idx = reinterpret_cast<u32*>(m_index_stream_buffer.GetCurrentHostPointer());
u16* idx = reinterpret_cast<u16*>(m_index_stream_buffer.GetCurrentHostPointer());
u32 icount = 0;
u32 vcount = 0;
for (u32 i = 0; i < num_rects; i++)
@@ -996,12 +997,12 @@ void GSDevice12::DoMultiStretchRects(
m_vertex.start = m_vertex_stream_buffer.GetCurrentOffset() / sizeof(GSVertexPT1);
m_vertex.count = vcount;
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u32);
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u16);
m_index.count = icount;
m_vertex_stream_buffer.CommitMemory(vcount * sizeof(GSVertexPT1));
m_index_stream_buffer.CommitMemory(icount * sizeof(u32));
m_index_stream_buffer.CommitMemory(icount * sizeof(u16));
SetVertexBuffer(m_vertex_stream_buffer.GetGPUPointer(), m_vertex_stream_buffer.GetSize(), sizeof(GSVertexPT1));
SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), m_index_stream_buffer.GetSize(), DXGI_FORMAT_R32_UINT);
SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), m_index_stream_buffer.GetSize(), DXGI_FORMAT_R16_UINT);
// Even though we're batching, a cmdbuffer submit could've messed this up.
const GSVector4i rc(dTex->GetRect());
@@ -1422,22 +1423,10 @@ void GSDevice12::RenderImGui()
m_vertex_stream_buffer.CommitMemory(size);
}
u32 index_offset;
{
const u32 size = sizeof(ImDrawIdx) * static_cast<u32>(cmd_list->IdxBuffer.Size);
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(ImDrawIdx)))
{
Console.Warning("Skipping ImGui draw because of no vertex buffer space");
return;
}
index_offset = m_index_stream_buffer.GetCurrentOffset() / sizeof(ImDrawIdx);
std::memcpy(m_index_stream_buffer.GetCurrentHostPointer(), cmd_list->IdxBuffer.Data, size);
m_index_stream_buffer.CommitMemory(size);
}
SetVertexBuffer(m_vertex_stream_buffer.GetGPUPointer(), m_vertex_stream_buffer.GetSize(), sizeof(ImDrawVert));
SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), m_index_stream_buffer.GetSize(), DXGI_FORMAT_R16_UINT);
static_assert(sizeof(ImDrawIdx) == sizeof(u16));
IASetIndexBuffer(cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
@@ -1468,7 +1457,7 @@ void GSDevice12::RenderImGui()
if (ApplyUtilityState())
{
g_d3d12_context->GetCommandList()->DrawIndexedInstanced(
pcmd->ElemCount, 1, index_offset + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset, 0);
pcmd->ElemCount, 1, m_index.start + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset, 0);
}
}
@@ -1536,17 +1525,17 @@ void GSDevice12::IASetVertexBuffer(const void* vertex, size_t stride, size_t cou
void GSDevice12::IASetIndexBuffer(const void* index, size_t count)
{
const u32 size = sizeof(u32) * static_cast<u32>(count);
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u32)))
const u32 size = sizeof(u16) * static_cast<u32>(count);
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u16)))
{
ExecuteCommandListAndRestartRenderPass(false, "Uploading bytes to index buffer");
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u32)))
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u16)))
pxFailRel("Failed to reserve space for vertices");
}
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u32);
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u16);
m_index.count = count;
SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), m_index_stream_buffer.GetSize(), DXGI_FORMAT_R32_UINT);
SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), m_index_stream_buffer.GetSize(), DXGI_FORMAT_R16_UINT);
std::memcpy(m_index_stream_buffer.GetCurrentHostPointer(), index, size);
m_index_stream_buffer.CommitMemory(size);
@@ -2758,11 +2747,15 @@ void GSDevice12::EndRenderPass()
if (!m_in_render_pass)
return;
g_d3d12_context->GetCommandList()->EndRenderPass();
m_in_render_pass = false;
// to render again, we need to reset OM
m_dirty_flags |= DIRTY_FLAG_RENDER_TARGET;
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
g_d3d12_context->GetCommandList()->EndRenderPass();
}
void GSDevice12::SetViewport(const D3D12_VIEWPORT& viewport)
@@ -3212,8 +3205,20 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
}
// avoid restarting the render pass just to switch from rt+depth to rt and vice versa
if (m_in_render_pass && !hdr_rt && !draw_ds && m_current_depth_target && m_current_render_target == draw_rt &&
config.tex != m_current_depth_target && m_current_depth_target->GetSize() == draw_rt->GetSize())
if (m_in_render_pass && (m_current_render_target == draw_rt || m_current_depth_target == draw_ds))
{
// avoid restarting the render pass just to switch from rt+depth to rt and vice versa
// keep the depth even if doing HDR draws, because the next draw will probably re-enable depth
if (!draw_rt && m_current_render_target && config.tex != m_current_render_target &&
m_current_render_target->GetSize() == draw_ds->GetSize())
{
draw_rt = m_current_render_target;
m_pipeline_selector.rt = true;
m_pipeline_selector.cms.wrgba = 0;
}
}
else if (!draw_ds && m_current_depth_target && config.tex != m_current_depth_target &&
m_current_depth_target->GetSize() == draw_rt->GetSize())
{
draw_ds = m_current_depth_target;
m_pipeline_selector.ds = true;
@@ -3353,7 +3358,7 @@ void GSDevice12::UploadHWDrawVerticesAndIndices(const GSHWDrawConfig& config)
{
m_index.start = 0;
m_index.count = config.nindices;
SetIndexBuffer(m_expand_index_buffer->GetGPUVirtualAddress(), EXPAND_BUFFER_SIZE, DXGI_FORMAT_R32_UINT);
SetIndexBuffer(m_expand_index_buffer->GetGPUVirtualAddress(), EXPAND_BUFFER_SIZE, DXGI_FORMAT_R16_UINT);
}
else
{
+1 -1
View File
@@ -297,7 +297,7 @@ bool GSHwHack::GSC_BlackAndBurnoutSky(GSRendererHW& r, int& skip)
if (RPRIM->PRIM == GS_SPRITE && !RPRIM->IIP && RPRIM->TME && !RPRIM->FGE && RPRIM->ABE && !RPRIM->AA1 && !RPRIM->FST && !RPRIM->FIX &&
ALPHA.A == ALPHA.B && ALPHA.D == 0 && FRAME.PSM == PSMCT32 && TEX0.CPSM == PSMCT32 && TEX0.TCC && !TEX0.TFX && !TEX0.CSM)
{
if (TEX0.TBW == 16 && TEX0.TW == 10 && TEX0.PSM == PSMT8 && TEX0.TH == 8 && FRAME.FBW == 16)
if (TEX0.TBW == 16 && TEX0.TW == 10 && TEX0.PSM == PSMT8 && TEX0.TH >= 7 && FRAME.FBW == 16)
{
// Readback clouds being rendered during level loading.
// Later the alpha channel from the 32 bit frame buffer is used as an 8 bit indexed texture to draw
+28 -28
View File
@@ -258,14 +258,10 @@ void GSRendererHW::Lines2Sprites()
int i = static_cast<int>(count) * 2 - 4;
GSVertex* s = &m_vertex.buff[count - 2];
GSVertex* q = &m_vertex.buff[count * 2 - 4];
u32* RESTRICT index = &m_index.buff[count * 3 - 6];
u16* RESTRICT index = &m_index.buff[count * 3 - 6];
alignas(16) static constexpr std::array<int, 8> tri_normal_indices = {{0, 1, 2, 1, 2, 3}};
alignas(16) static constexpr std::array<int, 8> tri_swapped_indices = {{0, 1, 2, 1, 2, 3}};
const bool index_swap = !g_gs_device->Features().provoking_vertex_last;
const int* tri_indices = index_swap ? tri_swapped_indices.data() : tri_normal_indices.data();
const GSVector4i indices_low(GSVector4i::load<true>(tri_indices));
const GSVector4i indices_high(GSVector4i::loadl(tri_indices + 4));
// Sprites are flat shaded, so the provoking vertex doesn't matter here.
constexpr GSVector4i indices = GSVector4i::cxpr16(0, 1, 2, 1, 2, 3, 0, 0);
for (; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
{
@@ -310,9 +306,10 @@ void GSRendererHW::Lines2Sprites()
q[1] = v0;
q[2] = v1;
const GSVector4i i_splat(i);
GSVector4i::store<false>(index, i_splat + indices_low);
GSVector4i::storel(index + 4, i_splat + indices_high);
const GSVector4i this_indices = GSVector4i::broadcast16(i).add16(indices);
const int high = this_indices.extract32<2>();
GSVector4i::storel(index, this_indices);
std::memcpy(&index[4], &high, sizeof(high));
}
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
@@ -322,26 +319,30 @@ void GSRendererHW::Lines2Sprites()
void GSRendererHW::ExpandLineIndices()
{
const u32 process_count = (m_index.tail + 3) / 4 * 4;
const u32 process_count = (m_index.tail + 7) / 8 * 8;
const u32 expansion_factor = 3;
m_index.tail *= expansion_factor;
GSVector4i* end = reinterpret_cast<GSVector4i*>(m_index.buff);
GSVector4i* read = reinterpret_cast<GSVector4i*>(m_index.buff + process_count);
GSVector4i* write = reinterpret_cast<GSVector4i*>(m_index.buff + process_count * expansion_factor);
constexpr GSVector4i low0 = GSVector4i::cxpr(0, 1, 2, 1);
constexpr GSVector4i low1 = GSVector4i::cxpr(2, 3, 0, 1);
constexpr GSVector4i low2 = GSVector4i::cxpr(2, 1, 2, 3);
constexpr GSVector4i mask0 = GSVector4i::cxpr8(0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5);
constexpr GSVector4i mask1 = GSVector4i::cxpr8(6, 7, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 8, 9);
constexpr GSVector4i mask2 = GSVector4i::cxpr8(10, 11, 10, 11, 12, 13, 12, 13, 14, 15, 12, 13, 14, 15, 14, 15);
constexpr GSVector4i low0 = GSVector4i::cxpr16(0, 1, 2, 1, 2, 3, 0, 1);
constexpr GSVector4i low1 = GSVector4i::cxpr16(2, 1, 2, 3, 0, 1, 2, 1);
constexpr GSVector4i low2 = GSVector4i::cxpr16(2, 3, 0, 1, 2, 1, 2, 3);
while (read > end)
{
read -= 1;
write -= expansion_factor;
const GSVector4i in = read->sll32(2);
write[0] = in.xxyx() | low0;
write[1] = in.yyzz() | low1;
write[2] = in.wzww() | low2;
const GSVector4i in = read->sll16(2);
write[0] = in.shuffle8(mask0) | low0;
write[1] = in.shuffle8(mask1) | low1;
write[2] = in.shuffle8(mask2) | low2;
}
}
@@ -1434,7 +1435,7 @@ void GSRendererHW::Draw()
#endif
}
GL_PUSH("HW Draw %d", s_n);
GL_PUSH("HW Draw %d (Context %u)", s_n, PRIM->CTXT);
// 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
@@ -3606,11 +3607,11 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
const u8 wms = EffectiveClamp(m_cached_ctx.CLAMP.WMS, !tex->m_target && (source_region.HasX() || redundant_wms));
const u8 wmt = EffectiveClamp(m_cached_ctx.CLAMP.WMT, !tex->m_target && (source_region.HasY() || redundant_wmt));
const bool complex_wms_wmt = !!((wms | wmt) & 2) || target_region;
GL_CACHE("WMS: %s [%s%s] WMT: %s [%s%s] Complex: %d TargetRegion: %d MINU: %d MAXU: %d MINV: %d MAXV: %d",
clamp_modes[m_cached_ctx.CLAMP.WMS], redundant_wms ? "redundant," : "", clamp_modes[wms],
clamp_modes[m_cached_ctx.CLAMP.WMT], redundant_wmt ? "redundant," : "", clamp_modes[wmt],
complex_wms_wmt, target_region,
m_cached_ctx.CLAMP.MINU, m_cached_ctx.CLAMP.MAXU, m_cached_ctx.CLAMP.MINV, m_cached_ctx.CLAMP.MAXV);
GL_CACHE("FST: %s WMS: %s [%s%s] WMT: %s [%s%s] Complex: %d TargetRegion: %d MINU: %d MAXU: %d MINV: %d MAXV: %d",
PRIM->FST ? "UV" : "STQ", clamp_modes[m_cached_ctx.CLAMP.WMS], redundant_wms ? "redundant," : "",
clamp_modes[wms], clamp_modes[m_cached_ctx.CLAMP.WMT], redundant_wmt ? "redundant," : "", clamp_modes[wmt],
complex_wms_wmt, target_region, m_cached_ctx.CLAMP.MINU, m_cached_ctx.CLAMP.MAXU, m_cached_ctx.CLAMP.MINV,
m_cached_ctx.CLAMP.MAXV);
const bool need_mipmap = IsMipMapDraw();
const bool shader_emulated_sampler = tex->m_palette || (tex->m_target && !m_conf.ps.shuffle && cpsm.fmt != 0) ||
@@ -4934,16 +4935,15 @@ void GSRendererHW::OI_DoubleHalfClear(GSTextureCache::Target*& rt, GSTextureCach
clear_depth ? "depth" : "target", base << 5, half << 5, w_pages, h_pages, m_cached_ctx.FRAME.FBW, color);
// If some of the channels are masked, we need to keep them.
if (m_cached_ctx.FRAME.FBMSK != 0)
if (!clear_depth && m_cached_ctx.FRAME.FBMSK != 0)
{
GSTexture* tex = nullptr;
GSTextureCache::Target* target = clear_depth ? ds : rt;
const GSVector2 size = GSVector2(static_cast<float>(target->GetUnscaledWidth()) * target->m_scale, static_cast<float>(target->GetUnscaledHeight()) * target->m_scale);
pxAssert(!target->m_texture->IsDepthStencil());
try
{
tex = target->m_texture->IsDepthStencil() ?
g_gs_device->CreateDepthStencil(size.x, size.y, target->m_texture->GetFormat(), true) :
g_gs_device->CreateRenderTarget(size.x, size.y, target->m_texture->GetFormat(), true);
tex = g_gs_device->CreateRenderTarget(size.x, size.y, target->m_texture->GetFormat(), false);
}
catch (const std::bad_alloc&)
{
+14 -9
View File
@@ -40,7 +40,8 @@ GSTextureCache::GSTextureCache()
// In theory 4MB is enough but 9MB is safer for overflow (8MB
// isn't enough in custom resolution)
// Test: onimusha 3 PAL 60Hz
s_unswizzle_buffer = (u8*)_aligned_malloc(9 * 1024 * 1024, 32);
s_unswizzle_buffer = (u8*)_aligned_malloc(9 * 1024 * 1024, VECTOR_ALIGNMENT);
pxAssertRel(s_unswizzle_buffer, "Failed to allocate unswizzle buffer");
m_surface_offset_cache.reserve(S_SURFACE_OFFSET_CACHE_MAX_SIZE);
}
@@ -2576,7 +2577,7 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
#undef V
static constexpr u32 indices[6] = { 0, 1, 2, 2, 1, 3 };
static constexpr u16 indices[6] = { 0, 1, 2, 2, 1, 3 };
// If we ever do this sort of thing somewhere else, extract this to a helper function.
GSHWDrawConfig config;
@@ -3605,6 +3606,7 @@ GSTextureCache::HashCacheEntry* GSTextureCache::LookupHashCache(const GIFRegTEX0
if (it != m_hash_cache.end())
{
// super easy, cache hit. remove paltex if it's a replacement texture.
GL_CACHE("HC Hit: %" PRIx64 " %" PRIx64 " R-%" PRIx64, key.TEX0Hash, key.CLUTHash, key.region.bits);
HashCacheEntry* entry = &it->second;
paltex &= (entry->texture->GetFormat() == GSTexture::Format::UNorm8);
entry->refcount++;
@@ -3612,6 +3614,8 @@ GSTextureCache::HashCacheEntry* GSTextureCache::LookupHashCache(const GIFRegTEX0
}
// cache miss.
GL_CACHE("HC Miss: %" PRIx64 " %" PRIx64 " R-%" PRIx64, key.TEX0Hash, key.CLUTHash, key.region.bits);
// check for a replacement texture with the full clut key
if (replace)
{
@@ -4154,7 +4158,7 @@ void GSTextureCache::Source::UpdateLayer(const GIFRegTEX0& TEX0, const GSVector4
void GSTextureCache::Source::Write(const GSVector4i& r, int layer, const GSOffset& off)
{
if (!m_write.rect)
m_write.rect = static_cast<GSVector4i*>(_aligned_malloc(3 * sizeof(GSVector4i), 32));
m_write.rect = static_cast<GSVector4i*>(_aligned_malloc(3 * sizeof(GSVector4i), 16));
m_write.rect[m_write.count++] = r;
@@ -4214,6 +4218,8 @@ void GSTextureCache::Source::Flush(u32 count, int layer, const GSOffset& off)
rtx = psm.rtxP;
}
pitch = VectorAlign(pitch);
for (u32 i = 0; i < count; i++)
{
const GSVector4i r(m_write.rect[i]);
@@ -4385,7 +4391,7 @@ void GSTextureCache::Target::Update(bool reset_age)
}
else
{
const int pitch = Common::AlignUpPow2(r.width() * sizeof(u32), 32);
const int pitch = VectorAlign(r.width() * sizeof(u32));
g_gs_renderer->m_mem.ReadTexture(off, r, s_unswizzle_buffer, pitch, TEXA);
t->Update(t_r, s_unswizzle_buffer, pitch);
@@ -5127,13 +5133,13 @@ GSTextureCache::SourceRegion GSTextureCache::SourceRegion::AdjustForMipmap(u32 l
if (HasX())
{
const u32 new_minx = GetMinX() >> level;
const u32 new_maxx = std::max<u32>(GetMaxX() >> level, new_minx + 1);
const u32 new_maxx = new_minx + std::max(GetWidth() >> level, 1u);
ret.SetX(new_minx, new_maxx);
}
if (HasY())
{
const u32 new_miny = GetMinY() >> level;
const u32 new_maxy = std::max<u32>(GetMaxY() >> level, new_miny + 1);
const u32 new_maxy = new_miny + std::max(GetHeight() >> level, 1u);
ret.SetY(new_miny, new_maxy);
}
return ret;
@@ -5241,7 +5247,7 @@ static void HashTextureLevel(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, GST
{
// Expand texture indices. Align to 32 bytes for AVX2.
const bool palette = (psm.pal > 0);
const u32 pitch = Common::AlignUpPow2(static_cast<u32>(block_rect.z) << (palette ? 0 : 2), 32);
const u32 pitch = VectorAlign(static_cast<u32>(block_rect.z) << (palette ? 0 : 2));
const u32 row_size = static_cast<u32>(tw) << (palette ? 0 : 2);
const GSLocalMemory::readTexture rtx = palette ? psm.rtxP : psm.rtx;
@@ -5317,8 +5323,7 @@ void GSTextureCache::PreloadTexture(const GIFRegTEX0& TEX0, const GIFRegTEXA& TE
}
else
{
// Align pitch to 32 bytes for AVX2 if we're going through the temp buffer path.
pitch = Common::AlignUpPow2(pitch, 32);
pitch = VectorAlign(pitch);
u8* buff = s_unswizzle_buffer;
rtx(mem, off, block_rect, buff, pitch, TEXA);
@@ -209,6 +209,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
&ret.bits, &extension_dot) == 4 &&
extension_dot == '.')
{
ret.CLUTHash = 0;
return ret;
}
@@ -225,6 +226,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
3 &&
extension_dot == '.')
{
ret.CLUTHash = 0;
return ret;
}
+16 -17
View File
@@ -371,6 +371,7 @@ void GSDeviceMTL::EndRenderPass()
if (m_current_render.encoder)
{
EndDebugGroup(m_current_render.encoder);
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
if (m_spin_timer)
[m_current_render.encoder updateFence:m_spin_fence afterStages:MTLRenderStageFragment];
[m_current_render.encoder endEncoding];
@@ -1240,53 +1241,51 @@ static bool s_capture_next = false;
GSDevice::PresentResult GSDeviceMTL::BeginPresent(bool frame_skip)
{ @autoreleasepool {
GSDeviceMTL* dev = static_cast<GSDeviceMTL*>(g_gs_device.get());
if (dev && m_capture_start_frame && dev->FrameNo() == m_capture_start_frame)
if (m_capture_start_frame && FrameNo() == m_capture_start_frame)
s_capture_next = true;
if (frame_skip || m_window_info.type == WindowInfo::Type::Surfaceless || !g_gs_device)
{
ImGui::EndFrame();
return PresentResult::FrameSkipped;
}
id<MTLCommandBuffer> buf = dev->GetRenderCmdBuf();
id<MTLCommandBuffer> buf = GetRenderCmdBuf();
m_current_drawable = MRCRetain([m_layer nextDrawable]);
dev->EndRenderPass();
EndRenderPass();
if (!m_current_drawable)
{
[buf pushDebugGroup:@"Present Skipped"];
[buf popDebugGroup];
dev->FlushEncoders();
FlushEncoders();
ImGui::EndFrame();
return PresentResult::FrameSkipped;
}
[m_pass_desc colorAttachments][0].texture = [m_current_drawable texture];
id<MTLRenderCommandEncoder> enc = [buf renderCommandEncoderWithDescriptor:m_pass_desc];
[enc setLabel:@"Present"];
dev->m_current_render.encoder = MRCRetain(enc);
m_current_render.encoder = MRCRetain(enc);
return PresentResult::OK;
}}
void GSDeviceMTL::EndPresent()
{ @autoreleasepool {
GSDeviceMTL* dev = static_cast<GSDeviceMTL*>(g_gs_device.get());
pxAssertDev(dev && dev->m_current_render.encoder && dev->m_current_render_cmdbuf, "BeginPresent cmdbuf was destroyed");
pxAssertDev(m_current_render.encoder && m_current_render_cmdbuf, "BeginPresent cmdbuf was destroyed");
ImGui::Render();
dev->RenderImGui(ImGui::GetDrawData());
dev->EndRenderPass();
RenderImGui(ImGui::GetDrawData());
EndRenderPass();
if (m_current_drawable)
{
const bool use_present_drawable = m_use_present_drawable == UsePresentDrawable::Always ||
(m_use_present_drawable == UsePresentDrawable::IfVsync && m_vsync_mode != VsyncMode::Off);
if (use_present_drawable)
[dev->m_current_render_cmdbuf presentDrawable:m_current_drawable];
[m_current_render_cmdbuf presentDrawable:m_current_drawable];
else
[dev->m_current_render_cmdbuf addScheduledHandler:[drawable = std::move(m_current_drawable)](id<MTLCommandBuffer>){
[m_current_render_cmdbuf addScheduledHandler:[drawable = std::move(m_current_drawable)](id<MTLCommandBuffer>){
[drawable present];
}];
}
dev->FlushEncoders();
dev->FrameCompleted();
FlushEncoders();
FrameCompleted();
m_current_drawable = nullptr;
if (m_capture_start_frame)
{
@@ -2178,7 +2177,7 @@ void GSDeviceMTL::SendHWDraw(GSHWDrawConfig& config, id<MTLRenderCommandEncoder>
textureBarrier(enc);
[enc drawIndexedPrimitives:topology
indexCount:count
indexType:MTLIndexTypeUInt32
indexType:MTLIndexTypeUInt16
indexBuffer:buffer
indexBufferOffset:off + p * sizeof(*config.indices)];
p += count;
@@ -2200,7 +2199,7 @@ void GSDeviceMTL::SendHWDraw(GSHWDrawConfig& config, id<MTLRenderCommandEncoder>
textureBarrier(enc);
[enc drawIndexedPrimitives:topology
indexCount:config.indices_per_prim
indexType:MTLIndexTypeUInt32
indexType:MTLIndexTypeUInt16
indexBuffer:buffer
indexBufferOffset:off + p * sizeof(*config.indices)];
}
@@ -2217,7 +2216,7 @@ void GSDeviceMTL::SendHWDraw(GSHWDrawConfig& config, id<MTLRenderCommandEncoder>
[enc drawIndexedPrimitives:topology
indexCount:config.nindices
indexType:MTLIndexTypeUInt32
indexType:MTLIndexTypeUInt16
indexBuffer:buffer
indexBufferOffset:off];
+26 -28
View File
@@ -163,7 +163,7 @@ bool GSDeviceOGL::Create(const WindowInfo& wi, VsyncMode vsync)
GLint max_vertex_ssbos = 0;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_vertex_ssbos);
DevCon.WriteLn("GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: %d", max_vertex_ssbos);
m_features.vs_expand = (max_vertex_ssbos > 0);
m_features.vs_expand = (max_vertex_ssbos > 0 && GLAD_GL_ARB_gpu_shader5);
}
if (!m_features.vs_expand)
Console.Warning("Vertex expansion is not supported. This will reduce performance.");
@@ -876,8 +876,8 @@ void GSDeviceOGL::DrawPrimitive()
void GSDeviceOGL::DrawIndexedPrimitive()
{
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
glDrawElementsBaseVertex(m_draw_topology, static_cast<u32>(m_index.count), GL_UNSIGNED_INT,
reinterpret_cast<void*>(static_cast<u32>(m_index.start) * sizeof(u32)), static_cast<GLint>(m_vertex.start));
glDrawElementsBaseVertex(m_draw_topology, static_cast<u32>(m_index.count), GL_UNSIGNED_SHORT,
reinterpret_cast<void*>(static_cast<u32>(m_index.start) * sizeof(u16)), static_cast<GLint>(m_vertex.start));
}
void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
@@ -885,8 +885,8 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count)
//ASSERT(offset + count <= (int)m_index.count);
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
glDrawElementsBaseVertex(m_draw_topology, count, GL_UNSIGNED_INT,
reinterpret_cast<void*>((static_cast<u32>(m_index.start) + static_cast<u32>(offset)) * sizeof(u32)),
glDrawElementsBaseVertex(m_draw_topology, count, GL_UNSIGNED_SHORT,
reinterpret_cast<void*>((static_cast<u32>(m_index.start) + static_cast<u32>(offset)) * sizeof(u16)),
static_cast<GLint>(m_vertex.start));
}
@@ -1134,7 +1134,9 @@ std::string GSDeviceOGL::GenGlslHeader(const std::string_view& entry, GLenum typ
else
{
header = "#version 330 core\n";
header += "#extension GL_ARB_shading_language_420pack: require\n";
header += "#extension GL_ARB_shading_language_420pack : require\n";
if (GLAD_GL_ARB_gpu_shader5)
header += "#extension GL_ARB_gpu_shader5 : require\n";
if (m_features.vs_expand)
header += "#extension GL_ARB_shader_storage_buffer_object: require\n";
}
@@ -1548,15 +1550,15 @@ void GSDeviceOGL::DrawMultiStretchRects(
void GSDeviceOGL::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, const GSVector2& ds)
{
const u32 vertex_reserve_size = num_rects * 4 * sizeof(GSVertexPT1);
const u32 index_reserve_size = num_rects * 6 * sizeof(u32);
const u32 index_reserve_size = num_rects * 6 * sizeof(u16);
auto vertex_map = m_vertex_stream_buffer->Map(sizeof(GSVertexPT1), vertex_reserve_size);
auto index_map = m_index_stream_buffer->Map(sizeof(u32), index_reserve_size);
auto index_map = m_index_stream_buffer->Map(sizeof(u16), index_reserve_size);
m_vertex.start = vertex_map.index_aligned;
m_index.start = index_map.index_aligned;
// Don't use primitive restart here, it ends up slower on some drivers.
GSVertexPT1* verts = reinterpret_cast<GSVertexPT1*>(vertex_map.pointer);
u32* idx = reinterpret_cast<u32*>(index_map.pointer);
u16* idx = reinterpret_cast<u16*>(index_map.pointer);
u32 icount = 0;
u32 vcount = 0;
for (u32 i = 0; i < num_rects; i++)
@@ -1587,7 +1589,7 @@ void GSDeviceOGL::DoMultiStretchRects(const MultiStretchRect* rects, u32 num_rec
m_vertex.count = vcount;
m_index.count = icount;
m_vertex_stream_buffer->Unmap(vcount * sizeof(GSVertexPT1));
m_index_stream_buffer->Unmap(icount * sizeof(u32));
m_index_stream_buffer->Unmap(icount * sizeof(u16));
PSSetShaderResource(0, rects[0].src);
PSSetSamplerState(rects[0].linear ? m_convert.ln : m_convert.pt);
@@ -1807,8 +1809,8 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t count)
void GSDeviceOGL::IASetIndexBuffer(const void* index, size_t count)
{
const u32 size = static_cast<u32>(count) * sizeof(u32);
auto res = m_index_stream_buffer->Map(sizeof(u32), size);
const u32 size = static_cast<u32>(count) * sizeof(u16);
auto res = m_index_stream_buffer->Map(sizeof(u16), size);
m_index.start = res.index_aligned;
m_index.count = count;
std::memcpy(res.pointer, index, size);
@@ -1999,18 +2001,7 @@ void GSDeviceOGL::RenderImGui()
m_vertex_stream_buffer->Unmap(size);
}
// Bit awkward, because this is using 16-bit indices, not 32-bit.
u32 index_start;
{
static_assert(sizeof(ImDrawIdx) == sizeof(u16));
const u32 size = static_cast<u32>(cmd_list->IdxBuffer.Size) * sizeof(ImDrawIdx);
auto res = m_index_stream_buffer->Map(sizeof(u16), size);
index_start = res.index_aligned;
std::memcpy(res.pointer, cmd_list->IdxBuffer.Data, size);
m_index_stream_buffer->Unmap(size);
m_index_stream_buffer->Bind();
}
IASetIndexBuffer(cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
@@ -2038,7 +2029,7 @@ void GSDeviceOGL::RenderImGui()
}
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT,
(void*)(intptr_t)((pcmd->IdxOffset + index_start) * sizeof(ImDrawIdx)), pcmd->VtxOffset + vertex_start);
(void*)(intptr_t)((pcmd->IdxOffset + m_index.start) * sizeof(ImDrawIdx)), pcmd->VtxOffset + vertex_start);
}
g_perfmon.Put(GSPerfMon::DrawCalls, cmd_list->CmdBuffer.Size);
@@ -2165,6 +2156,8 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
GSTextureOGL* RT = static_cast<GSTextureOGL*>(rt);
GSTextureOGL* DS = static_cast<GSTextureOGL*>(ds);
g_perfmon.Put(GSPerfMon::RenderPasses, static_cast<double>(GLState::rt != RT || GLState::ds != DS));
OMSetFBO(m_fbo);
if (rt)
{
@@ -2431,13 +2424,17 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor],
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
config.blend.constant_enable, config.blend.constant);
OMSetColorMaskState(config.colormask);
// avoid changing framebuffer just to switch from rt+depth to rt and vice versa
GSTexture* draw_rt = hdr_rt ? hdr_rt : config.rt;
GSTexture* draw_ds = config.ds;
if (!draw_ds && GLState::ds && GLState::rt == draw_rt && config.tex != GLState::ds &&
GLState::ds->GetSize() == draw_rt->GetSize())
OMColorMaskSelector draw_colormask = config.colormask;
if (!draw_rt && GLState::rt && GLState::ds == draw_ds && GLState::rt->GetSize() == draw_ds->GetSize())
{
draw_rt = GLState::rt;
draw_colormask.wrgba = 0;
}
else if (!draw_ds && GLState::ds && GLState::rt == draw_rt && GLState::ds->GetSize() == draw_rt->GetSize())
{
// should already be always-pass.
draw_ds = GLState::ds;
@@ -2446,6 +2443,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
}
OMSetRenderTargets(draw_rt, draw_ds, &config.scissor);
OMSetColorMaskState(draw_colormask);
SetupOM(config.depth);
SendHWDraw(config, psel.ps.IsFeedbackLoop());
+2 -1
View File
@@ -18,6 +18,7 @@
#include "GS/Renderers/OpenGL/GSDeviceOGL.h"
#include "GS/Renderers/OpenGL/GSTextureOGL.h"
#include "GS/Renderers/OpenGL/GLState.h"
#include "GS/GSExtra.h"
#include "GS/GSPerfMon.h"
#include "GS/GSPng.h"
#include "GS/GSGL.h"
@@ -476,7 +477,7 @@ std::unique_ptr<GSDownloadTextureOGL> GSDownloadTextureOGL::Create(u32 width, u3
}
// Fallback to glReadPixels() + CPU buffer.
u8* cpu_buffer = static_cast<u8*>(_aligned_malloc(buffer_size, 32));
u8* cpu_buffer = static_cast<u8*>(_aligned_malloc(buffer_size, VECTOR_ALIGNMENT));
if (!cpu_buffer)
return {};
+10 -13
View File
@@ -161,7 +161,7 @@ typedef GSVector4 VectorF;
#define LOCAL_STEP local.d4
#endif
void GSDrawScanline::CSetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local)
void GSDrawScanline::CSetupPrim(const GSVertexSW* vertex, const u16* index, const GSVertexSW& dscan, GSScanlineLocalData& local)
{
const GSScanlineGlobalData& global = GlobalFromLocal(local);
GSScanlineSelector sel = global.sel;
@@ -451,10 +451,14 @@ __ri static void WritePixel(const T& src, int addr, int i, u32 psm, const GSScan
}
void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local)
{
CDrawScanline(pixels, left, top, scan, local, GlobalFromLocal(local).sel);
}
__ri void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local, GSScanlineSelector sel)
{
const GSScanlineGlobalData& global = GlobalFromLocal(local);
GSScanlineSelector sel = global.sel;
constexpr int vlen = sizeof(VectorF) / sizeof(float);
#if _M_SSE < 0x501
@@ -1729,17 +1733,10 @@ void GSDrawScanline::CDrawScanline(int pixels, int left, int top, const GSVertex
void GSDrawScanline::CDrawEdge(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local)
{
// This sucks. But so does not jitting!
const GSScanlineGlobalData* old_gd = local.gd;
GSScanlineGlobalData gd;
std::memcpy(&gd, &local.gd, sizeof(gd));
gd.sel.zwrite = 0;
gd.sel.edge = 1;
local.gd = &gd;
CDrawScanline(pixels, left, top, scan, local);
local.gd = old_gd;
GSScanlineSelector sel = local.gd->sel;
sel.zwrite = 0;
sel.edge = 1;
CDrawScanline(pixels, left, top, scan, local, sel);
}
template <class T, bool masked>
+3 -2
View File
@@ -38,7 +38,7 @@ public:
~GSDrawScanline() override;
/// Function pointer types which we call back into.
using SetupPrimPtr = void(*)(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local);
using SetupPrimPtr = void(*)(const GSVertexSW* vertex, const u16* index, const GSVertexSW& dscan, GSScanlineLocalData& local);
using DrawScanlinePtr = void(*)(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local);
/// Flushes the code cache, forcing everything to be recompiled.
@@ -60,9 +60,10 @@ private:
GSCodeGeneratorFunctionMap<GSSetupPrimCodeGenerator, u64, SetupPrimPtr> m_sp_map;
GSCodeGeneratorFunctionMap<GSDrawScanlineCodeGenerator, u64, DrawScanlinePtr> m_ds_map;
static void CSetupPrim(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, GSScanlineLocalData& local);
static void CSetupPrim(const GSVertexSW* vertex, const u16* index, const GSVertexSW& dscan, GSScanlineLocalData& local);
static void CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local);
static void CDrawEdge(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local);
__ri static void CDrawScanline(int pixels, int left, int top, const GSVertexSW& scan, GSScanlineLocalData& local, GSScanlineSelector sel);
};
MULTI_ISA_UNSHARED_END
@@ -91,7 +91,8 @@ GSDrawScanlineCodeGenerator::GSDrawScanlineCodeGenerator(u64 key, void* code, si
if (shouldUseCDrawScanline(key))
{
jmp(reinterpret_cast<const void*>(&GSDrawScanline::CDrawScanline));
jmp(reinterpret_cast<const void*>(static_cast<void (*)(int, int, int, const GSVertexSW&, GSScanlineLocalData&)>(
&GSDrawScanline::CDrawScanline)));
return;
}
+11 -11
View File
@@ -55,7 +55,7 @@ GSRasterizer::GSRasterizer(GSDrawScanline* ds, int id, int threads)
m_thread_height = compute_best_thread_height(threads);
m_edge.buff = static_cast<GSVertexSW*>(_aligned_malloc(sizeof(GSVertexSW) * 2048, 32));
m_edge.buff = static_cast<GSVertexSW*>(_aligned_malloc(sizeof(GSVertexSW) * 2048, VECTOR_ALIGNMENT));
m_edge.count = 0;
if (!m_edge.buff)
throw std::bad_alloc();
@@ -154,10 +154,10 @@ void GSRasterizer::Draw(GSRasterizerData& data)
const GSVertexSW* vertex = data.vertex;
const GSVertexSW* vertex_end = data.vertex + data.vertex_count;
const u32* index = data.index;
const u32* index_end = data.index + data.index_count;
const u16* index = data.index;
const u16* index_end = data.index + data.index_count;
u32 tmp_index[] = {0, 1, 2};
static constexpr u16 tmp_index[] = {0, 1, 2};
bool scissor_test = !data.bbox.eq(data.bbox.rintersect(data.scissor));
@@ -261,7 +261,7 @@ void GSRasterizer::Draw(GSRasterizerData& data)
}
template <bool scissor_test>
void GSRasterizer::DrawPoint(const GSVertexSW* vertex, int vertex_count, const u32* index, int index_count)
void GSRasterizer::DrawPoint(const GSVertexSW* vertex, int vertex_count, const u16* index, int index_count)
{
m_primcount++;
@@ -286,7 +286,7 @@ void GSRasterizer::DrawPoint(const GSVertexSW* vertex, int vertex_count, const u
}
else
{
u32 tmp_index[1] = {0};
static constexpr u16 tmp_index[1] = {0};
for (int i = 0; i < vertex_count; i++, vertex++)
{
@@ -307,7 +307,7 @@ void GSRasterizer::DrawPoint(const GSVertexSW* vertex, int vertex_count, const u
}
}
void GSRasterizer::DrawLine(const GSVertexSW* vertex, const u32* index)
void GSRasterizer::DrawLine(const GSVertexSW* vertex, const u16* index)
{
m_primcount++;
@@ -425,7 +425,7 @@ static const u8 s_ysort[8][4] =
#if _M_SSE >= 0x501
void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u32* index)
void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index)
{
m_primcount++;
@@ -606,7 +606,7 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW2& RESTRIC
#else
void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u32* index)
void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index)
{
m_primcount++;
@@ -784,7 +784,7 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& RESTRICT
#endif
void GSRasterizer::DrawSprite(const GSVertexSW* vertex, const u32* index)
void GSRasterizer::DrawSprite(const GSVertexSW* vertex, const u16* index)
{
m_primcount++;
@@ -1082,7 +1082,7 @@ void GSRasterizer::AddScanline(GSVertexSW* e, int pixels, int left, int top, con
AddScanlineInfo(e, pixels, left, top);
}
void GSRasterizer::Flush(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, bool edge /* = false */)
void GSRasterizer::Flush(const GSVertexSW* vertex, const u16* index, const GSVertexSW& dscan, bool edge /* = false */)
{
// TODO: on win64 this could be the place where xmm6-15 are preserved (not by each DrawScanline)
+6 -6
View File
@@ -38,7 +38,7 @@ public:
u8* buff;
GSVertexSW* vertex;
int vertex_count;
u32* index;
u16* index;
int index_count;
u64 frame;
u64 start;
@@ -101,10 +101,10 @@ protected:
__forceinline bool HasEdge() const { return (m_draw_edge != nullptr); }
template <bool scissor_test>
void DrawPoint(const GSVertexSW* vertex, int vertex_count, const u32* index, int index_count);
void DrawLine(const GSVertexSW* vertex, const u32* index);
void DrawTriangle(const GSVertexSW* vertex, const u32* index);
void DrawSprite(const GSVertexSW* vertex, const u32* index);
void DrawPoint(const GSVertexSW* vertex, int vertex_count, const u16* index, int index_count);
void DrawLine(const GSVertexSW* vertex, const u16* index);
void DrawTriangle(const GSVertexSW* vertex, const u16* index);
void DrawSprite(const GSVertexSW* vertex, const u16* index);
#if _M_SSE >= 0x501
__forceinline void DrawTriangleSection(int top, int bottom, GSVertexSW2& RESTRICT edge, const GSVertexSW2& RESTRICT dedge, const GSVertexSW2& RESTRICT dscan, const GSVector4& RESTRICT p0);
@@ -115,7 +115,7 @@ protected:
void DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GSVertexSW& dv, int orientation, int side);
__forceinline void AddScanline(GSVertexSW* e, int pixels, int left, int top, const GSVertexSW& scan);
__forceinline void Flush(const GSVertexSW* vertex, const u32* index, const GSVertexSW& dscan, bool edge = false);
__forceinline void Flush(const GSVertexSW* vertex, const u16* index, const GSVertexSW& dscan, bool edge = false);
__forceinline void DrawScanline(int pixels, int left, int top, const GSVertexSW& scan);
__forceinline void DrawEdge(int pixels, int left, int top, const GSVertexSW& scan);
+5 -5
View File
@@ -39,7 +39,7 @@ GSRendererSW::GSRendererSW(int threads)
m_tc = std::make_unique<GSTextureCacheSW>();
m_rl = GSRasterizerList::Create(threads);
m_output = (u8*)_aligned_malloc(1024 * 1024 * sizeof(u32), 32);
m_output = (u8*)_aligned_malloc(1024 * 1024 * sizeof(u32), VECTOR_ALIGNMENT);
std::fill(std::begin(m_fzb_pages), std::end(m_fzb_pages), 0);
std::fill(std::begin(m_tex_pages), std::end(m_tex_pages), 0);
@@ -343,7 +343,7 @@ void GSRendererSW::Draw()
sd->buff = (u8*)m_vertex_heap.alloc(sizeof(GSVertexSW) * ((m_vertex.next + 1) & ~1) + sizeof(u32) * m_index.tail, 64);
sd->vertex = (GSVertexSW*)sd->buff;
sd->vertex_count = m_vertex.next;
sd->index = (u32*)(sd->buff + sizeof(GSVertexSW) * ((m_vertex.next + 1) & ~1));
sd->index = (u16*)(sd->buff + sizeof(GSVertexSW) * ((m_vertex.next + 1) & ~1));
sd->index_count = m_index.tail;
sd->scanmsk_value = m_draw_env->SCANMSK.MSK;
@@ -354,7 +354,7 @@ void GSRendererSW::Draw()
GSVertexSW::s_cvb[m_vt.m_primclass][PRIM->TME][PRIM->FST][q_div](m_context, sd->vertex, m_vertex.buff, m_vertex.next);
memcpy(sd->index, m_index.buff, sizeof(u32) * m_index.tail);
std::memcpy(sd->index, m_index.buff, sizeof(u16) * m_index.tail);
GSVector4i scissor = GSVector4i(context->scissor.in);
GSVector4i bbox = GSVector4i(m_vt.m_min.p.floor().xyxy(m_vt.m_max.p.ceil()));
@@ -1046,7 +1046,7 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
{
gd.sel.tlu = 1;
gd.clut = (u32*)m_vertex_heap.alloc(sizeof(u32) * 256, 32); // FIXME: might address uninitialized data of the texture (0xCD) that is not in 0-15 range for 4-bpp formats
gd.clut = (u32*)m_vertex_heap.alloc(sizeof(u32) * 256, VECTOR_ALIGNMENT); // FIXME: might address uninitialized data of the texture (0xCD) that is not in 0-15 range for 4-bpp formats
memcpy(gd.clut, (const u32*)m_mem.m_clut, sizeof(u32) * GSLocalMemory::m_psm[context->TEX0.PSM].pal);
}
@@ -1333,7 +1333,7 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
ExpandDIMX(m_dimx, env.DIMX);
}
gd.dimx = (GSVector4i*)m_vertex_heap.alloc(sizeof(m_dimx), 32);
gd.dimx = (GSVector4i*)m_vertex_heap.alloc(sizeof(m_dimx), VECTOR_ALIGNMENT);
std::memcpy(gd.dimx, m_dimx, sizeof(m_dimx));
}
@@ -210,7 +210,7 @@ void GSSetupPrimCodeGenerator2::Depth_XMM()
{
// GSVector4 p = vertex[index[1]].p;
mov(eax, ptr[_index + sizeof(u32) * 1]);
movzx(eax, word[_index + sizeof(u16) * 1]);
shl(eax, 6); // * sizeof(GSVertexSW)
add(rax, _64_vertex);
@@ -299,7 +299,7 @@ void GSSetupPrimCodeGenerator2::Depth_YMM()
{
// GSVector4 p = vertex[index[1]].p;
mov(eax, ptr[_index + sizeof(u32) * 1]);
movzx(eax, word[_index + sizeof(u16) * 1]);
shl(eax, 6); // * sizeof(GSVertexSW)
add(rax, _64_vertex);
@@ -504,7 +504,7 @@ void GSSetupPrimCodeGenerator2::Color()
if (!(m_sel.prim == GS_SPRITE_CLASS && (m_en.z || m_en.f))) // if this is a sprite, the last vertex was already loaded in Depth()
{
mov(eax, ptr[_index + sizeof(u32) * last]);
movzx(eax, word[_index + sizeof(u16) * last]);
shl(eax, 6); // * sizeof(GSVertexSW)
add(rax, _64_vertex);
}
+5 -7
View File
@@ -14,7 +14,8 @@
*/
#include "PrecompiledHeader.h"
#include "GSTextureCacheSW.h"
#include "GS/Renderers/SW/GSTextureCacheSW.h"
#include "GS/GSExtra.h"
GSTextureCacheSW::GSTextureCacheSW() = default;
@@ -233,14 +234,11 @@ bool GSTextureCacheSW::Texture::Update(const GSVector4i& rect)
if (m_buff == NULL)
{
u32 pitch = (1 << m_tw) << shift;
const u32 pitch = (1 << m_tw) << shift;
m_buff = _aligned_malloc(pitch * th * 4, 32);
if (m_buff == NULL)
{
m_buff = _aligned_malloc(pitch * th * 4, VECTOR_ALIGNMENT);
if (!m_buff)
return false;
}
}
GSLocalMemory& mem = g_gs_renderer->m_mem;
+3 -2
View File
@@ -14,7 +14,8 @@
*/
#include "PrecompiledHeader.h"
#include "GSTextureSW.h"
#include "GS/Renderers/SW/GSTextureSW.h"
#include "GS/GSExtra.h"
#include "GS/GSPng.h"
GSTextureSW::GSTextureSW(Type type, int width, int height)
@@ -24,7 +25,7 @@ GSTextureSW::GSTextureSW(Type type, int width, int height)
m_type = type;
m_format = Format::Invalid;
m_pitch = ((width << 2) + 31) & ~31;
m_data = _aligned_malloc(m_pitch * height, 32);
m_data = _aligned_malloc(m_pitch * height, VECTOR_ALIGNMENT);
}
GSTextureSW::~GSTextureSW()
+70 -71
View File
@@ -475,6 +475,7 @@ void GSDeviceVK::EndPresent()
VkCommandBuffer cmdbuffer = g_vulkan_context->GetCurrentCommandBuffer();
vkCmdEndRenderPass(g_vulkan_context->GetCurrentCommandBuffer());
m_swap_chain->GetCurrentTexture().TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
g_vulkan_context->SubmitCommandBuffer(m_swap_chain.get(), !m_swap_chain->IsPresentModeSynchronizing());
g_vulkan_context->MoveToNextCommandBuffer();
@@ -578,7 +579,7 @@ bool GSDeviceVK::CheckFeatures()
const bool isAMD = (vendorID == 0x1002 || vendorID == 0x1022);
// const bool isNVIDIA = (vendorID == 0x10DE);
m_features.framebuffer_fetch = g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access && !GSConfig.DisableFramebufferFetch;
m_features.framebuffer_fetch = g_vulkan_context->GetOptionalExtensions().vk_ext_rasterization_order_attachment_access && !GSConfig.DisableFramebufferFetch;
m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0;
m_features.broken_point_sampler = isAMD;
// Usually, geometry shader indicates primid support
@@ -955,13 +956,13 @@ void GSDeviceVK::DoMultiStretchRects(
{
// Set up vertices first.
const u32 vertex_reserve_size = num_rects * 4 * sizeof(GSVertexPT1);
const u32 index_reserve_size = num_rects * 6 * sizeof(u32);
const u32 index_reserve_size = num_rects * 6 * sizeof(u16);
if (!m_vertex_stream_buffer.ReserveMemory(vertex_reserve_size, sizeof(GSVertexPT1)) ||
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u32)))
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u16)))
{
ExecuteCommandBufferAndRestartRenderPass(false, "Uploading bytes to vertex buffer");
if (!m_vertex_stream_buffer.ReserveMemory(vertex_reserve_size, sizeof(GSVertexPT1)) ||
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u32)))
!m_index_stream_buffer.ReserveMemory(index_reserve_size, sizeof(u16)))
{
pxFailRel("Failed to reserve space for vertices");
}
@@ -971,7 +972,7 @@ void GSDeviceVK::DoMultiStretchRects(
// Don't use primitive restart here, it ends up slower on some drivers.
const GSVector2 ds(static_cast<float>(dTex->GetWidth()), static_cast<float>(dTex->GetHeight()));
GSVertexPT1* verts = reinterpret_cast<GSVertexPT1*>(m_vertex_stream_buffer.GetCurrentHostPointer());
u32* idx = reinterpret_cast<u32*>(m_index_stream_buffer.GetCurrentHostPointer());
u16* idx = reinterpret_cast<u16*>(m_index_stream_buffer.GetCurrentHostPointer());
u32 icount = 0;
u32 vcount = 0;
for (u32 i = 0; i < num_rects; i++)
@@ -1001,11 +1002,11 @@ void GSDeviceVK::DoMultiStretchRects(
m_vertex.start = m_vertex_stream_buffer.GetCurrentOffset() / sizeof(GSVertexPT1);
m_vertex.count = vcount;
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u32);
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u16);
m_index.count = icount;
m_vertex_stream_buffer.CommitMemory(vcount * sizeof(GSVertexPT1));
m_index_stream_buffer.CommitMemory(icount * sizeof(u32));
SetIndexBuffer(m_index_stream_buffer.GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
m_index_stream_buffer.CommitMemory(icount * sizeof(u16));
SetIndexBuffer(m_index_stream_buffer.GetBuffer(), 0, VK_INDEX_TYPE_UINT16);
// Even though we're batching, a cmdbuffer submit could've messed this up.
const GSVector4i rc(dTex->GetRect());
@@ -1368,21 +1369,21 @@ void GSDeviceVK::IASetVertexBuffer(const void* vertex, size_t stride, size_t cou
void GSDeviceVK::IASetIndexBuffer(const void* index, size_t count)
{
const u32 size = sizeof(u32) * static_cast<u32>(count);
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u32)))
const u32 size = sizeof(u16) * static_cast<u32>(count);
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u16)))
{
ExecuteCommandBufferAndRestartRenderPass(false, "Uploading bytes to index buffer");
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u32)))
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(u16)))
pxFailRel("Failed to reserve space for vertices");
}
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u32);
m_index.start = m_index_stream_buffer.GetCurrentOffset() / sizeof(u16);
m_index.count = count;
std::memcpy(m_index_stream_buffer.GetCurrentHostPointer(), index, size);
m_index_stream_buffer.CommitMemory(size);
SetIndexBuffer(m_index_stream_buffer.GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
SetIndexBuffer(m_index_stream_buffer.GetBuffer(), 0, VK_INDEX_TYPE_UINT16);
}
void GSDeviceVK::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i& scissor, FeedbackLoopFlag feedback_loop)
@@ -1529,6 +1530,15 @@ static void AddUtilityVertexAttributes(Vulkan::GraphicsPipelineBuilder& gpb)
gpb.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
}
static void SetPipelineProvokingVertex(const GSDevice::FeatureSupport& features, Vulkan::GraphicsPipelineBuilder& gpb)
{
// We enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass.
// Normally we wouldn't enable it on the present/swap chain, but apparently the rule is it applies to the last
// pipeline bound before the render pass begun, and in this case, we can't bind null.
if (features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
}
VkShaderModule GSDeviceVK::GetUtilityVertexShader(const std::string& source, const char* replace_main = nullptr)
{
std::stringstream ss;
@@ -1769,6 +1779,7 @@ bool GSDeviceVK::CompileConvertPipelines()
ScopedGuard vs_guard([&vs]() { Vulkan::Util::SafeDestroyShaderModule(vs); });
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
AddUtilityVertexAttributes(gpb);
gpb.SetPipelineLayout(m_utility_pipeline_layout);
gpb.SetDynamicViewportAndScissorState();
@@ -1777,10 +1788,6 @@ bool GSDeviceVK::CompileConvertPipelines()
gpb.SetNoBlendingState();
gpb.SetVertexShader(vs);
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
if (m_features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
for (ShaderConvert i = ShaderConvert::COPY; static_cast<int>(i) < static_cast<int>(ShaderConvert::Count);
i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
{
@@ -1964,6 +1971,7 @@ bool GSDeviceVK::CompilePresentPipelines()
ScopedGuard vs_guard([&vs]() { Vulkan::Util::SafeDestroyShaderModule(vs); });
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
AddUtilityVertexAttributes(gpb);
gpb.SetPipelineLayout(m_utility_pipeline_layout);
gpb.SetDynamicViewportAndScissorState();
@@ -1975,10 +1983,6 @@ bool GSDeviceVK::CompilePresentPipelines()
gpb.SetNoStencilState();
gpb.SetRenderPass(m_swap_chain_render_pass, 0);
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
if (m_features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
for (PresentShader i = PresentShader::COPY; static_cast<int>(i) < static_cast<int>(PresentShader::Count);
i = static_cast<PresentShader>(static_cast<int>(i) + 1))
{
@@ -2023,6 +2027,7 @@ bool GSDeviceVK::CompileInterlacePipelines()
ScopedGuard vs_guard([&vs]() { Vulkan::Util::SafeDestroyShaderModule(vs); });
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
AddUtilityVertexAttributes(gpb);
gpb.SetPipelineLayout(m_utility_pipeline_layout);
gpb.SetDynamicViewportAndScissorState();
@@ -2033,10 +2038,6 @@ bool GSDeviceVK::CompileInterlacePipelines()
gpb.SetRenderPass(rp, 0);
gpb.SetVertexShader(vs);
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
if (m_features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
for (int i = 0; i < static_cast<int>(m_interlace.size()); i++)
{
VkShaderModule ps = GetUtilityFragmentShader(*shader, StringUtil::StdStringFromFormat("ps_main%d", i).c_str());
@@ -2077,6 +2078,7 @@ bool GSDeviceVK::CompileMergePipelines()
ScopedGuard vs_guard([&vs]() { Vulkan::Util::SafeDestroyShaderModule(vs); });
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
AddUtilityVertexAttributes(gpb);
gpb.SetPipelineLayout(m_utility_pipeline_layout);
gpb.SetDynamicViewportAndScissorState();
@@ -2086,10 +2088,6 @@ bool GSDeviceVK::CompileMergePipelines()
gpb.SetRenderPass(rp, 0);
gpb.SetVertexShader(vs);
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
if (m_features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
for (int i = 0; i < static_cast<int>(m_merge.size()); i++)
{
VkShaderModule ps = GetUtilityFragmentShader(*shader, StringUtil::StdStringFromFormat("ps_main%d", i).c_str());
@@ -2119,6 +2117,7 @@ bool GSDeviceVK::CompilePostProcessingPipelines()
return false;
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
AddUtilityVertexAttributes(gpb);
gpb.SetPipelineLayout(m_utility_pipeline_layout);
gpb.SetDynamicViewportAndScissorState();
@@ -2128,10 +2127,6 @@ bool GSDeviceVK::CompilePostProcessingPipelines()
gpb.SetNoBlendingState();
gpb.SetRenderPass(rp, 0);
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
if (m_features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
{
std::optional<std::string> vshader = Host::ReadResourceFileToString("shaders/vulkan/convert.glsl");
if (!vshader)
@@ -2267,6 +2262,7 @@ bool GSDeviceVK::CompileImGuiPipeline()
ScopedGuard ps_guard([&ps]() { Vulkan::Util::SafeDestroyShaderModule(ps); });
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
gpb.SetPipelineLayout(m_utility_pipeline_layout);
gpb.SetRenderPass(m_swap_chain_render_pass, 0);
gpb.AddVertexBuffer(0, sizeof(ImDrawVert), VK_VERTEX_INPUT_RATE_VERTEX);
@@ -2319,9 +2315,6 @@ void GSDeviceVK::RenderImGui()
m_dirty_flags |= DIRTY_FLAG_UTILITY_TEXTURE;
}
// imgui uses 16-bit indices
SetIndexBuffer(m_index_stream_buffer.GetBuffer(), 0, VK_INDEX_TYPE_UINT16);
// this is for presenting, we don't want to screw with the viewport/scissor set by display
m_dirty_flags &= ~(DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR);
@@ -2343,19 +2336,8 @@ void GSDeviceVK::RenderImGui()
m_vertex_stream_buffer.CommitMemory(size);
}
u32 index_offset;
{
const u32 size = sizeof(ImDrawIdx) * static_cast<u32>(cmd_list->IdxBuffer.Size);
if (!m_index_stream_buffer.ReserveMemory(size, sizeof(ImDrawIdx)))
{
Console.Warning("Skipping ImGui draw because of no vertex buffer space");
return;
}
index_offset = m_index_stream_buffer.GetCurrentOffset() / sizeof(ImDrawIdx);
std::memcpy(m_index_stream_buffer.GetCurrentHostPointer(), cmd_list->IdxBuffer.Data, size);
m_index_stream_buffer.CommitMemory(size);
}
static_assert(sizeof(ImDrawIdx) == sizeof(u16));
IASetIndexBuffer(cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
@@ -2366,7 +2348,7 @@ void GSDeviceVK::RenderImGui()
if ((clip.zwzw() <= clip.xyxy()).mask() != 0)
continue;
SetScissor(GSVector4i(clip));
SetScissor(GSVector4i(clip).max_i32(GSVector4i::zero()));
// Since we don't have the GSTexture...
Vulkan::Texture* tex = static_cast<Vulkan::Texture*>(pcmd->GetTexID());
@@ -2379,7 +2361,7 @@ void GSDeviceVK::RenderImGui()
if (ApplyUtilityState())
{
vkCmdDrawIndexed(g_vulkan_context->GetCurrentCommandBuffer(), pcmd->ElemCount, 1,
index_offset + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset, 0);
m_index.start + pcmd->IdxOffset, vertex_offset + pcmd->VtxOffset, 0);
}
}
@@ -2655,6 +2637,7 @@ VkPipeline GSDeviceVK::CreateTFXPipeline(const PipelineSelector& p)
return VK_NULL_HANDLE;
Vulkan::GraphicsPipelineBuilder gpb;
SetPipelineProvokingVertex(m_features, gpb);
// Common state
gpb.SetPipelineLayout(m_tfx_pipeline_layout);
@@ -2739,14 +2722,11 @@ VkPipeline GSDeviceVK::CreateTFXPipeline(const PipelineSelector& p)
VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, p.cms.wrgba);
}
if (m_features.provoking_vertex_last)
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
// Tests have shown that it's faster to just enable rast order on the entire pass, rather than alternating
// between turning it on and off for different draws, and adding the required barrier between non-rast-order
// and rast-order draws.
if (m_features.framebuffer_fetch && p.IsRTFeedbackLoop())
gpb.AddBlendFlags(VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM);
gpb.AddBlendFlags(VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT);
VkPipeline pipeline = gpb.Create(g_vulkan_context->GetDevice(), g_vulkan_shader_cache->GetPipelineCache(true));
if (pipeline)
@@ -2786,7 +2766,7 @@ void GSDeviceVK::InitializeState()
m_vertex_buffer_offset = 0;
m_index_buffer = m_index_stream_buffer.GetBuffer();
m_index_buffer_offset = 0;
m_index_type = VK_INDEX_TYPE_UINT32;
m_index_type = VK_INDEX_TYPE_UINT16;
m_current_framebuffer = VK_NULL_HANDLE;
m_current_render_pass = VK_NULL_HANDLE;
@@ -2864,7 +2844,12 @@ void GSDeviceVK::ExecuteCommandBufferAndRestartRenderPass(bool wait_for_completi
Console.Warning("Vulkan: Executing command buffer due to '%s'", reason);
const VkRenderPass render_pass = m_current_render_pass;
const GSVector4i render_pass_area(m_current_render_pass_area);
const GSVector4i render_pass_area = m_current_render_pass_area;
const GSVector4i scissor = m_scissor;
GSTexture* const current_rt = m_current_render_target;
GSTexture* const current_ds = m_current_depth_target;
const FeedbackLoopFlag current_feedback_loop = m_current_framebuffer_feedback_loop;
EndRenderPass();
g_vulkan_context->ExecuteCommandBuffer(GetWaitType(wait_for_completion, GSConfig.HWSpinCPUForReadbacks));
InvalidateCachedState();
@@ -2872,8 +2857,7 @@ void GSDeviceVK::ExecuteCommandBufferAndRestartRenderPass(bool wait_for_completi
if (render_pass != VK_NULL_HANDLE)
{
// rebind framebuffer
ApplyBaseState(m_dirty_flags, g_vulkan_context->GetCurrentCommandBuffer());
m_dirty_flags &= ~DIRTY_BASE_STATE;
OMSetRenderTargets(current_rt, current_ds, scissor, current_feedback_loop);
// restart render pass
BeginRenderPass(render_pass, render_pass_area);
@@ -2906,6 +2890,15 @@ void GSDeviceVK::InvalidateCachedState()
m_dirty_flags |= DIRTY_FLAG_VERTEX_BUFFER;
if (m_index_buffer != VK_NULL_HANDLE)
m_dirty_flags |= DIRTY_FLAG_INDEX_BUFFER;
for (u32 i = 0; i < NUM_TFX_TEXTURES; i++)
m_tfx_textures[i] = &m_null_texture;
m_utility_texture = &m_null_texture;
m_current_framebuffer = VK_NULL_HANDLE;
m_current_render_target = nullptr;
m_current_depth_target = nullptr;
m_current_framebuffer_feedback_loop = FeedbackLoopFlag_None;
m_current_pipeline_layout = PipelineLayout::Undefined;
m_tfx_descriptor_sets[1] = VK_NULL_HANDLE;
m_tfx_descriptor_sets[2] = VK_NULL_HANDLE;
@@ -3113,9 +3106,10 @@ void GSDeviceVK::EndRenderPass()
if (m_current_render_pass == VK_NULL_HANDLE)
return;
vkCmdEndRenderPass(g_vulkan_context->GetCurrentCommandBuffer());
m_current_render_pass = VK_NULL_HANDLE;
g_perfmon.Put(GSPerfMon::RenderPasses, 1);
vkCmdEndRenderPass(g_vulkan_context->GetCurrentCommandBuffer());
}
void GSDeviceVK::SetViewport(const VkViewport& viewport)
@@ -3648,13 +3642,19 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
(!hdr_rt && DATE_rp != DATE_RENDER_PASS_STENCIL_ONE && CheckRenderPassArea(render_area));
// render pass restart optimizations
if (render_area_okay)
if (render_area_okay && (m_current_render_target == draw_rt || m_current_depth_target == draw_ds))
{
// avoid restarting the render pass just to switch from rt+depth to rt and vice versa
if (!draw_ds && m_current_depth_target && m_current_render_target == draw_rt &&
config.tex != m_current_depth_target && m_current_depth_target->GetSize() == draw_rt->GetSize() &&
((pipe.feedback_loop_flags & FeedbackLoopFlag_ReadAndWriteRT) ==
(m_current_framebuffer_feedback_loop & FeedbackLoopFlag_ReadAndWriteRT)))
// keep the depth even if doing HDR draws, because the next draw will probably re-enable depth
if (!draw_rt && m_current_render_target && config.tex != m_current_render_target &&
m_current_render_target->GetSize() == draw_ds->GetSize())
{
draw_rt = m_current_render_target;
m_pipeline_selector.rt = true;
m_pipeline_selector.cms.wrgba = 0;
}
else if (!draw_ds && m_current_depth_target && config.tex != m_current_depth_target &&
m_current_depth_target->GetSize() == draw_rt->GetSize())
{
draw_ds = m_current_depth_target;
m_pipeline_selector.ds = true;
@@ -3663,9 +3663,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
}
// Prefer keeping feedback loop enabled, that way we're not constantly restarting render passes
pipe.feedback_loop_flags |= (m_current_render_target == draw_rt && m_current_depth_target == draw_ds) ?
m_current_framebuffer_feedback_loop :
0;
pipe.feedback_loop_flags |= m_current_framebuffer_feedback_loop;
}
// We don't need the very first barrier if this is the first draw after switching to feedback loop,
@@ -3833,7 +3831,8 @@ void GSDeviceVK::UpdateHWPipelineSelector(GSHWDrawConfig& config, PipelineSelect
(config.ps.IsFeedbackLoop() || config.require_one_barrier || config.require_full_barrier)) ?
FeedbackLoopFlag_ReadAndWriteRT :
FeedbackLoopFlag_None;
pipe.feedback_loop_flags |= (config.tex == config.ds) ? FeedbackLoopFlag_ReadDS : FeedbackLoopFlag_None;
pipe.feedback_loop_flags |=
(config.tex && config.tex == config.ds) ? FeedbackLoopFlag_ReadDS : FeedbackLoopFlag_None;
// enable point size in the vertex shader if we're rendering points regardless of upscaling.
pipe.vs.point_size |= (config.topology == GSHWDrawConfig::Topology::Point);
@@ -3847,7 +3846,7 @@ void GSDeviceVK::UploadHWDrawVerticesAndIndices(const GSHWDrawConfig& config)
{
m_index.start = 0;
m_index.count = config.nindices;
SetIndexBuffer(m_expand_index_buffer, 0, VK_INDEX_TYPE_UINT32);
SetIndexBuffer(m_expand_index_buffer, 0, VK_INDEX_TYPE_UINT16);
}
else
{
+1
View File
@@ -316,6 +316,7 @@ __fi void vif1Interrupt()
CPU_INT(DMAC_VIF1, 128);
if (gifRegs.stat.APATH == 3)
vif1Regs.stat.VGW = 1; //We're waiting for path 3. Gunslinger II
CPU_SET_DMASTALL(DMAC_VIF1, true);
return;
}
vif1Regs.stat.VGW = 0; //Path 3 isn't busy so we don't need to wait for it.
+24
View File
@@ -83,7 +83,10 @@ static __fi void vuExecMicro(int idx, u32 addr, bool requires_wait)
vifFlush(idx);
if (GetVifX.waitforvu)
{
CPU_SET_DMASTALL(idx ? DMAC_VIF1 : DMAC_VIF0, true);
return;
}
if (vifRegs.itops > (idx ? 0x3ffu : 0xffu))
{
@@ -220,7 +223,10 @@ vifOp(vifCode_Flush)
}
if (vif1.waitforvu || vif1Regs.stat.VGW)
{
CPU_SET_DMASTALL(DMAC_VIF1, true);
return 0;
}
vif1.cmd = 0;
vif1.pass = 0;
@@ -250,7 +256,10 @@ vifOp(vifCode_FlushA)
}
if (vif1.waitforvu || vif1Regs.stat.VGW)
{
CPU_SET_DMASTALL(DMAC_VIF1, true);
return 0;
}
vif1.cmd = 0;
vif1.pass = 0;
@@ -268,7 +277,10 @@ vifOp(vifCode_FlushE)
vifFlush(idx);
if (vifX.waitforvu)
{
CPU_SET_DMASTALL(idx ? DMAC_VIF1 : DMAC_VIF0, true);
return 0;
}
vifX.cmd = 0;
vifX.pass = 0;
@@ -373,7 +385,10 @@ vifOp(vifCode_MPG)
vifFlush(idx);
if (vifX.waitforvu)
{
CPU_SET_DMASTALL(idx ? DMAC_VIF1 : DMAC_VIF0, true);
return 0;
}
else
{
vifX.pass = 1;
@@ -418,7 +433,10 @@ vifOp(vifCode_MSCAL)
vifFlush(idx);
if (vifX.waitforvu)
{
CPU_SET_DMASTALL(idx ? DMAC_VIF1 : DMAC_VIF0, true);
return 0;
}
vuExecMicro(idx, (u16)(vifXRegs.code), false);
vifX.cmd = 0;
@@ -454,7 +472,10 @@ vifOp(vifCode_MSCALF)
}
if (vifX.waitforvu || vif1Regs.stat.VGW)
{
CPU_SET_DMASTALL(idx ? DMAC_VIF1 : DMAC_VIF0, true);
return 0;
}
vuExecMicro(idx, (u16)(vifXRegs.code), true);
vifX.cmd = 0;
@@ -473,7 +494,10 @@ vifOp(vifCode_MSCNT)
vifFlush(idx);
if (vifX.waitforvu)
{
CPU_SET_DMASTALL(idx ? DMAC_VIF1 : DMAC_VIF0, true);
return 0;
}
vuExecMicro(idx, -1, false);
vifX.cmd = 0;
-2
View File
@@ -311,7 +311,6 @@
<ClCompile Include="GS\Renderers\SW\GSTextureSW.cpp" />
<ClCompile Include="GS\GSUtil.cpp" />
<ClCompile Include="GS\GSVector.cpp" />
<ClCompile Include="GS\Renderers\Common\GSVertexList.cpp" />
<ClCompile Include="GS\Renderers\SW\GSVertexSW.cpp" />
<ClCompile Include="GS\Renderers\Common\GSVertexTrace.cpp" />
<ClCompile Include="GS\Renderers\Common\GSVertexTraceFMM.cpp" />
@@ -646,7 +645,6 @@
<ClInclude Include="GS\GSVector8.h" />
<ClInclude Include="GS\Renderers\Common\GSVertex.h" />
<ClInclude Include="GS\Renderers\HW\GSVertexHW.h" />
<ClInclude Include="GS\Renderers\Common\GSVertexList.h" />
<ClInclude Include="GS\Renderers\SW\GSVertexSW.h" />
<ClInclude Include="GS\Renderers\Common\GSVertexTrace.h" />
<ClInclude Include="GS\GSXXH.h" />
-6
View File
@@ -1133,9 +1133,6 @@
<ClCompile Include="GS\Renderers\Common\GSVertexTraceFMM.cpp">
<Filter>System\Ps2\GS\Renderers\Common</Filter>
</ClCompile>
<ClCompile Include="GS\Renderers\Common\GSVertexList.cpp">
<Filter>System\Ps2\GS\Renderers\Common</Filter>
</ClCompile>
<ClCompile Include="GS\Renderers\Common\GSFunctionMap.cpp">
<Filter>System\Ps2\GS\Renderers\Common</Filter>
</ClCompile>
@@ -2020,9 +2017,6 @@
<ClInclude Include="GS\Renderers\Common\GSVertexTrace.h">
<Filter>System\Ps2\GS\Renderers\Common</Filter>
</ClInclude>
<ClInclude Include="GS\Renderers\Common\GSVertexList.h">
<Filter>System\Ps2\GS\Renderers\Common</Filter>
</ClInclude>
<ClInclude Include="GS\Renderers\Common\GSVertex.h">
<Filter>System\Ps2\GS\Renderers\Common</Filter>
</ClInclude>
+14 -1
View File
@@ -1015,6 +1015,9 @@ public:
microMapGPR& mapI = gprMap[i];
if (mapI.VIreg == viLoadReg)
{
// Do this first, there is a case where when loadReg != writeReg, the findFreeGPR can steal the loadReg
gprMap[i].count = this_counter;
if (viWriteReg >= 0) // Reg will be modified
{
if (viLoadReg != viWriteReg)
@@ -1025,7 +1028,17 @@ public:
// allocate a new register for writing to
int x = findFreeGPR(viWriteReg);
const xRegister32& gprX = xRegister32::GetInstance(x);
writeBackReg(gprX, true);
// writeReg not cached, needs backing up
if (backup && gprMap[x].VIreg != viWriteReg)
{
xMOVZX(gprX, ptr16[&getVI(viWriteReg)]);
writeVIBackup(gprX);
backup = false;
}
if (zext_if_dirty)
xMOVZX(gprX, xRegister16(i));
else
@@ -1048,7 +1061,7 @@ public:
xMOVZX(xRegister32(i), xRegister16(i));
gprMap[i].isZeroExtended = true;
}
gprMap[i].count = this_counter;
gprMap[i].isNeeded = true;
if (backup)
+1 -1
View File
@@ -24,7 +24,7 @@ import functools
src_dirs = [os.path.join(os.path.dirname(__file__), "..", "pcsx2"), os.path.join(os.path.dirname(__file__), "..", "pcsx2-qt")]
fa_file = os.path.join(os.path.dirname(__file__), "..", "3rdparty", "include", "IconsFontAwesome5.h")
dst_file = os.path.join(os.path.dirname(__file__), "..", "pcsx2", "Frontend", "ImguiManager.cpp")
dst_file = os.path.join(os.path.dirname(__file__), "..", "pcsx2", "Frontend", "ImGuiManager.cpp")
all_source_files = list(functools.reduce(lambda prev, src_dir: prev + glob.glob(os.path.join(src_dir, "**", "*.cpp"), recursive=True) + \
glob.glob(os.path.join(src_dir, "**", "*.h"), recursive=True) + \