diff --git a/bin/resources/shaders/dx11/convert.fx b/bin/resources/shaders/dx11/convert.fx index f85867964cd48..005d47665e3ee 100644 --- a/bin/resources/shaders/dx11/convert.fx +++ b/bin/resources/shaders/dx11/convert.fx @@ -169,6 +169,11 @@ float depth32_to_depth24(float d) return uint_to_depth24(depth_to_uint(d)); } +float4 primid_to_rgba8(float p) +{ + return uint_to_rgba8(asuint(p)); +} + #if defined(__ps_copy__) OUTPUT_TYPE ps_copy(PS_INPUT input) : OUTPUT_SV { @@ -323,6 +328,13 @@ OUTPUT_TYPE ps_convert_depth32_depth24(PS_INPUT input) : OUTPUT_SV } #endif +#if defined(__ps_convert_primid_rgba8__) +OUTPUT_TYPE ps_convert_primid_rgba8(PS_INPUT input) : OUTPUT_SV +{ + return primid_to_rgba8(sample_c(input.t)); +} +#endif + #define SAMPLE_RGBA_DEPTH_BILN(CONVERT_FN) \ uint width, height; \ Texture.GetDimensions(width, height); \ @@ -650,9 +662,9 @@ float ps_primid_image_init_0(PS_INPUT input) : SV_Target { float c; if ((127.5f / 255.0f) < sample_c(input.t).a) // < 0x80 pass (== 0x80 should not pass) - c = float(-1); + c = float(PRIMID_MIN); else - c = float(0x7FFFFFFF); + c = float(PRIMID_MAX); return c; } #endif @@ -662,9 +674,9 @@ float ps_primid_image_init_1(PS_INPUT input) : SV_Target { float c; if (sample_c(input.t).a < (127.5f / 255.0f)) // >= 0x80 pass - c = float(-1); + c = float(PRIMID_MIN); else - c = float(0x7FFFFFFF); + c = float(PRIMID_MAX); return c; } #endif @@ -674,9 +686,9 @@ float ps_primid_image_init_2(PS_INPUT input) : SV_Target { float c; if ((254.5f / 255.0f) < sample_c(input.t).a) // < 0x80 pass (== 0x80 should not pass) - c = float(-1); + c = float(PRIMID_MIN); else - c = float(0x7FFFFFFF); + c = float(PRIMID_MAX); return c; } #endif @@ -686,9 +698,9 @@ float ps_primid_image_init_3(PS_INPUT input) : SV_Target { float c; if (sample_c(input.t).a < (254.5f / 255.0f)) // >= 0x80 pass - c = float(-1); + c = float(PRIMID_MIN); else - c = float(0x7FFFFFFF); + c = float(PRIMID_MAX); return c; } #endif diff --git a/bin/resources/shaders/opengl/convert.glsl b/bin/resources/shaders/opengl/convert.glsl index d93d76cb8acd8..0904b0025cfea 100644 --- a/bin/resources/shaders/opengl/convert.glsl +++ b/bin/resources/shaders/opengl/convert.glsl @@ -139,6 +139,11 @@ float depth32_to_depth24(float d) return uint_to_depth24(depth_to_uint(d)); } +vec4 primid_to_rgba8(float p) +{ + return uint_to_rgba8(floatBitsToUint(p)); +} + #ifdef ps_copy void ps_copy() { @@ -212,6 +217,13 @@ void ps_convert_depth32_depth24() } #endif +#ifdef ps_convert_primid_rgba8 +void ps_convert_primid_rgba8() +{ + OUTPUT = primid_to_rgba8(sample_c()); +} +#endif + #define SAMPLE_RGBA_DEPTH_BILN(CONVERT_FN) \ ivec2 dims = textureSize(TextureSampler, 0); \ vec2 top_left_f = PSin_t * vec2(dims) - 0.5f; \ @@ -615,23 +627,23 @@ void ps_yuv() void main() { - o_col0 = vec4(0x7FFFFFFF); + o_col0 = vec4(PRIMID_MAX); #ifdef ps_primid_image_init_0 if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass) - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif #ifdef ps_primid_image_init_1 if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif #ifdef ps_primid_image_init_2 if((254.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass) - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif #ifdef ps_primid_image_init_3 if(sample_c().a < (254.5f / 255.0f)) // >= 0x80 pass - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif } #endif diff --git a/bin/resources/shaders/vulkan/convert.glsl b/bin/resources/shaders/vulkan/convert.glsl index 23f6b3c89b78c..9d10e1333957c 100644 --- a/bin/resources/shaders/vulkan/convert.glsl +++ b/bin/resources/shaders/vulkan/convert.glsl @@ -130,6 +130,11 @@ float depth32_to_depth24(float d) return uint_to_depth24(depth_to_uint(d)); } +vec4 primid_to_rgba8(float p) +{ + return uint_to_rgba8(floatBitsToUint(p)); +} + #ifdef ps_copy void ps_copy() { @@ -281,6 +286,13 @@ void ps_convert_depth32_depth24() } #endif +#ifdef ps_convert_primid_rgba8 +void ps_convert_primid_rgba8() +{ + OUTPUT = primid_to_rgba8(sample_c(v_tex)); +} +#endif + #define SAMPLE_RGBA_DEPTH_BILN(CONVERT_FN) \ ivec2 dims = textureSize(samp0, 0); \ vec2 top_left_f = v_tex * vec2(dims) - 0.5f; \ @@ -628,23 +640,23 @@ void ps_yuv() void main() { - o_col0 = vec4(0x7FFFFFFF); + o_col0 = vec4(PRIMID_MAX); #ifdef ps_primid_image_init_0 if((127.5f / 255.0f) < sample_c(v_tex).a) // < 0x80 pass (== 0x80 should not pass) - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif #ifdef ps_primid_image_init_1 if(sample_c(v_tex).a < (127.5f / 255.0f)) // >= 0x80 pass - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif #ifdef ps_primid_image_init_2 if((254.5f / 255.0f) < sample_c(v_tex).a) // < 0x80 pass (== 0x80 should not pass) - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif #ifdef ps_primid_image_init_3 if(sample_c(v_tex).a < (254.5f / 255.0f)) // >= 0x80 pass - o_col0 = vec4(-1); + o_col0 = vec4(PRIMID_MIN); #endif } #endif diff --git a/pcsx2/GS/Renderers/Common/GSDevice.cpp b/pcsx2/GS/Renderers/Common/GSDevice.cpp index a4f70a90a3a24..196c6c046942d 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.cpp +++ b/pcsx2/GS/Renderers/Common/GSDevice.cpp @@ -49,6 +49,7 @@ const char* ShaderEntryPoint(ShaderConvert value) case ShaderConvert::RGB5A1_TO_DEPTH16: return "ps_convert_rgb5a1_depth16"; case ShaderConvert::DEPTH32_TO_DEPTH24: return "ps_convert_depth32_depth24"; case ShaderConvert::DEPTH_COPY: return "ps_depth_copy"; + case ShaderConvert::PRIMID_TO_RGBA8: return "ps_convert_primid_rgba8"; case ShaderConvert::DOWNSAMPLE_COPY: return "ps_downsample_copy"; case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i"; case ShaderConvert::RGB5A1_TO_8I: return "ps_convert_rgb5a1_8i"; @@ -109,6 +110,7 @@ const char* ShaderConvertName(ShaderConvert shader) ENTRY(RGBA8_TO_DEPTH16); ENTRY(RGB5A1_TO_DEPTH16); ENTRY(DEPTH32_TO_DEPTH24); + ENTRY(PRIMID_TO_RGBA8); ENTRY(DOWNSAMPLE_COPY); ENTRY(RGBA_TO_8I); ENTRY(RGB5A1_TO_8I); diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index 9ef0233ef6236..e0d8ac1d07bc7 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -59,6 +59,7 @@ enum class ShaderConvert RGBA8_TO_DEPTH16, RGB5A1_TO_DEPTH16, DEPTH32_TO_DEPTH24, + PRIMID_TO_RGBA8, DOWNSAMPLE_COPY, RGBA_TO_8I, RGB5A1_TO_8I, @@ -122,6 +123,7 @@ static inline constexpr bool HasColorOutput(ShaderConvert shader) case ShaderConvert::DEPTH32_TO_RGBA8: case ShaderConvert::DEPTH32_TO_RGB8: case ShaderConvert::DEPTH16_TO_RGB5A1: + case ShaderConvert::PRIMID_TO_RGBA8: case ShaderConvert::DOWNSAMPLE_COPY: case ShaderConvert::RGBA_TO_8I: case ShaderConvert::RGB5A1_TO_8I: @@ -162,6 +164,7 @@ static inline constexpr bool HasFloat32Input(ShaderConvert shader) case ShaderConvert::DEPTH32_TO_RGB8: case ShaderConvert::DEPTH16_TO_RGB5A1: case ShaderConvert::DEPTH32_TO_DEPTH24: + case ShaderConvert::PRIMID_TO_RGBA8: return true; default: return false; @@ -526,6 +529,10 @@ static inline ShaderConvertSelector GetConvertShader(GSTexture::Format src, GSTe pxAssert(false); } break; + case GSTexture::Format::PrimID: + pxAssert(dst == GSTexture::Format::Color); + shader = ShaderConvert::PRIMID_TO_RGBA8; + break; default: pxAssert(false); break; @@ -1277,6 +1284,8 @@ struct alignas(16) GSHWDrawConfig SetDATM datm; bool line_expand; + const std::string* dump_primid_path; // for debugging only + struct AlphaPass { alignas(8) PSSelector ps; diff --git a/pcsx2/GS/Renderers/Common/GSShaderEnums.h b/pcsx2/GS/Renderers/Common/GSShaderEnums.h index 394bab8ee4353..f00df58ee4356 100644 --- a/pcsx2/GS/Renderers/Common/GSShaderEnums.h +++ b/pcsx2/GS/Renderers/Common/GSShaderEnums.h @@ -63,4 +63,15 @@ enum class PS_ROV_DEPTH : uint32_t READ_ONLY = 2, }; +#if defined(__METAL_VERSION__) + #define CONSTANT constant +#else + #define CONSTANT +#endif + +static constexpr CONSTANT int PRIMID_MAX = (1 << 24) - 1; +static constexpr CONSTANT int PRIMID_MIN = -1; + +#undef CONSTANT + } // namespace GSShader diff --git a/pcsx2/GS/Renderers/Common/GSTexture.cpp b/pcsx2/GS/Renderers/Common/GSTexture.cpp index e380573a564bb..9b8e3b51c4a4f 100644 --- a/pcsx2/GS/Renderers/Common/GSTexture.cpp +++ b/pcsx2/GS/Renderers/Common/GSTexture.cpp @@ -44,7 +44,7 @@ bool GSTexture::Save(const std::string& fn) { // Depth textures need special treatment - we have a stencil component. // Just re-use the existing conversion shader instead. - if (m_format == Format::DepthStencil || m_format == Format::DepthColor) + if (m_format == Format::DepthStencil || m_format == Format::DepthColor || m_format == Format::PrimID) { GSTexture* temp = g_gs_device->CreateRenderTarget(GetWidth(), GetHeight(), Format::Color, false); if (!temp) diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index 922746a68a9b6..faa107b419ab6 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -249,6 +249,8 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle) ShaderMacro sm_ps; sm_ps.AddMacro("PIXEL_SHADER", 1); + sm_ps.AddMacro("PRIMID_MAX", GSShader::PRIMID_MAX); + sm_ps.AddMacro("PRIMID_MIN", GSShader::PRIMID_MIN); sm_ps.AddMacro("HAS_BILN", static_cast(shader.Biln())); sm_ps.AddMacro("HAS_STENCIL_OUTPUT", static_cast(shader.StencilOutput())); sm_ps.AddMacro("HAS_INTEGER_OUTPUT", static_cast(shader.IntegerOutputBpp() != 0)); @@ -582,6 +584,8 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle) const std::string entry_point_macro = WrapEntryPointMacro(entry_point); ShaderMacro sm_ps; sm_ps.AddMacro("PIXEL_SHADER", 1); + sm_ps.AddMacro("PRIMID_MAX", GSShader::PRIMID_MAX); + sm_ps.AddMacro("PRIMID_MIN", GSShader::PRIMID_MIN); sm_ps.AddMacro(entry_point_macro.c_str(), 1); m_date.primid_init_ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, sm_ps.GetPtr(), entry_point.c_str()); if (!m_date.primid_init_ps[i]) @@ -3299,6 +3303,9 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) g_gs_device->SetColorClipTexture(nullptr); } } + + if (primid_texture && config.dump_primid_path) + primid_texture->Save(*config.dump_primid_path); } void GSDevice11::FeedbackCopyAndBind(const GSHWDrawConfig& config, diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp index 8541f266a5c7a..ab03cc1708fa8 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp @@ -2877,6 +2877,8 @@ bool GSDevice12::CompileConvertPipelines() ShaderMacro sm; sm.AddMacro("PIXEL_SHADER", 1); + sm.AddMacro("PRIMID_MAX", GSShader::PRIMID_MAX); + sm.AddMacro("PRIMID_MIN", GSShader::PRIMID_MIN); sm.AddMacro("HAS_BILN", static_cast(shader.Biln())); sm.AddMacro("HAS_STENCIL_OUTPUT", static_cast(shader.StencilOutput())); sm.AddMacro("HAS_INTEGER_OUTPUT", static_cast(shader.IntegerOutputBpp() != 0)); @@ -2930,6 +2932,8 @@ bool GSDevice12::CompileConvertPipelines() ShaderMacro sm; sm.AddMacro("PIXEL_SHADER", "1"); + sm.AddMacro("PRIMID_MAX", GSShader::PRIMID_MAX); + sm.AddMacro("PRIMID_MIN", GSShader::PRIMID_MIN); sm.AddMacro(entry_point_macro.c_str(), "1"); ComPtr ps(m_shader_cache.GetPixelShader(*source, sm.GetPtr(), entry_point.c_str())); @@ -4696,12 +4700,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) config.alpha_second_pass.require_full_barrier); } - if (date_image) - Recycle(date_image); - - if (draw_rt_clone) - Recycle(draw_rt_clone); - // now blit the colclip texture back to the original target if (colclip_rt) { @@ -4733,6 +4731,15 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) g_gs_device->SetColorClipTexture(nullptr); } } + + if (date_image && config.dump_primid_path) + date_image->Save(*config.dump_primid_path); + + if (date_image) + Recycle(date_image); + + if (draw_rt_clone) + Recycle(draw_rt_clone); } void GSDevice12::SendHWDraw(const PipelineSelector& pipe, const GSHWDrawConfig& config, GSTexture12* draw_rt, diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index fed6a013c3a77..9528f596882f9 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -6048,6 +6048,16 @@ void GSRendererHW::EmulateDATESelectMethod(DATEOptions& date_options, GSTextureC pxAssert(!(date_options.barrier && date_options.stencil_one)); pxAssert(!(date_options.primid && date_options.stencil_one)); pxAssert(!(date_options.primid && date_options.barrier)); + + if (date_options.primid && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()) && GSConfig.SaveRT) + { + m_dump_primid_path = GetDrawDumpPath("%05lld_f%05lld_primid.bmp", s_n, g_perfmon.GetFrame()); + m_conf.dump_primid_path = &m_dump_primid_path; + } + else + { + m_conf.dump_primid_path = nullptr; + } } void GSRendererHW::EmulateDATEGetConfig(DATEOptions& date_options, bool scale_rt_alpha, GSDevice::RecycledTexture& temp_ds) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index 4ee9d556ee671..a2aa78e2b7350 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -346,6 +346,8 @@ class GSRendererHW : public GSRenderer std::unique_ptr m_sw_texture[7 + 1]; std::unique_ptr> m_sw_rasterizer; + std::string m_dump_primid_path; + public: GSRendererHW(); virtual ~GSRendererHW() override; diff --git a/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm b/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm index 53f4d9dd51b41..17e005726f435 100644 --- a/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm +++ b/pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm @@ -2560,6 +2560,9 @@ static bool usesStencil(GSHWDrawConfig::DestinationAlphaMode dstalpha) } } + if (primid_tex && config.dump_primid_path) + primid_tex->Save(*config.dump_primid_path); + if (primid_tex) Recycle(primid_tex); }} diff --git a/pcsx2/GS/Renderers/Metal/convert.metal b/pcsx2/GS/Renderers/Metal/convert.metal index f37a9e7ede88b..d7bba46a4a4ce 100644 --- a/pcsx2/GS/Renderers/Metal/convert.metal +++ b/pcsx2/GS/Renderers/Metal/convert.metal @@ -112,22 +112,22 @@ fragment void ps_datm0(float4 p [[position]], DirectReadTextureIn tex) fragment float4 ps_primid_init_datm1(float4 p [[position]], DirectReadTextureIn tex) { - return tex.read(p).a < (127.5f / 255.f) ? -1 : FLT_MAX; + return tex.read(p).a < (127.5f / 255.f) ? GSShader::PRIMID_MIN : GSShader::PRIMID_MAX; } fragment float4 ps_primid_init_datm0(float4 p [[position]], DirectReadTextureIn tex) { - return tex.read(p).a > (127.5f / 255.f) ? -1 : FLT_MAX; + return tex.read(p).a > (127.5f / 255.f) ? GSShader::PRIMID_MIN : GSShader::PRIMID_MAX; } fragment float4 ps_primid_rta_init_datm1(float4 p [[position]], DirectReadTextureIn tex) { - return tex.read(p).a < (254.5f / 255.f) ? -1 : FLT_MAX; + return tex.read(p).a < (254.5f / 255.f) ? GSShader::PRIMID_MIN : GSShader::PRIMID_MAX; } fragment float4 ps_primid_rta_init_datm0(float4 p [[position]], DirectReadTextureIn tex) { - return tex.read(p).a > (254.5f / 255.f) ? -1 : FLT_MAX; + return tex.read(p).a > (254.5f / 255.f) ? GSShader::PRIMID_MIN : GSShader::PRIMID_MAX; } fragment float4 ps_rta_correction(ConvertShaderData data [[stage_in]], ConvertPSRes res) @@ -175,11 +175,6 @@ fragment float4 ps_convert_depth16_rgb5a1(ConvertShaderData data [[stage_in]], C return convert_depth16_rgba8(res.sample(data.t)) / 255.f; } -fragment float ps_convert_float32_depth_to_color(ConvertShaderData data [[stage_in]], ConvertPSDepthRes res) -{ - return res.sample(data.t); -} - fragment float4 ps_downsample_copy(ConvertShaderData data [[stage_in]], texture2d texture [[texture(GSMTLTextureIndexNonHW)]], constant GSMTLDownsamplePSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]]) @@ -273,6 +268,16 @@ struct ConvertToDepthRes } }; +static float4 primid_to_rgba8(float p) +{ + return float4(as_type(p)) / 255.f; +} + +fragment float4 ps_convert_primid_rgba8(ConvertShaderData data [[stage_in]], ConvertPSDepthOrColorRes res) +{ + return primid_to_rgba8(res.sample(data.t)); +} + fragment DepthOrColorOut ps_depth_copy(ConvertShaderData data [[stage_in]], ConvertPSDepthOrColorRes res) { return res.sample(data.t); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index e3b8f7b1c77fc..becbd4e500aa1 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -432,6 +432,8 @@ bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle) const char* name = shader.EntryPoint(); std::string macro; + macro += fmt::format("#define PRIMID_MAX {}\n", GSShader::PRIMID_MAX); + macro += fmt::format("#define PRIMID_MIN {}\n", GSShader::PRIMID_MIN); macro += fmt::format("#define HAS_BILN {}\n", static_cast(shader.Biln())); macro += fmt::format("#define HAS_STENCIL_OUTPUT {}\n", static_cast(shader.StencilOutput())); macro += fmt::format("#define HAS_INTEGER_OUTPUT {}\n", static_cast(shader.IntegerOutputBpp() != 0)); @@ -609,9 +611,13 @@ bool GSDeviceOGL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle) for (size_t i = 0; i < std::size(m_date.primid_ps); i++) { + std::string macro; + macro += fmt::format("#define PRIMID_MAX {}\n", GSShader::PRIMID_MAX); + macro += fmt::format("#define PRIMID_MIN {}\n", GSShader::PRIMID_MIN); + const std::string ps(GetShaderSource( fmt::format("ps_primid_image_init_{}", i), - GL_FRAGMENT_SHADER, *convert_glsl)); + GL_FRAGMENT_SHADER, *convert_glsl, macro)); m_shader_cache.GetProgram(&m_date.primid_ps[i], m_convert.vs, ps); m_date.primid_ps[i].SetFormattedName("PrimID Destination Alpha Init %d", i); } @@ -3196,6 +3202,9 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) g_gs_device->SetColorClipTexture(nullptr); } } + + if (primid_texture && config.dump_primid_path) + primid_texture->Save(*config.dump_primid_path); } void GSDeviceOGL::FeedbackCopyAndBind(const GSHWDrawConfig& config, diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index d9c66670f2dc6..54a96d3a2c53a 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -4196,6 +4196,8 @@ bool GSDeviceVK::CompileConvertPipelines() gpb.SetColorWriteMask(0, shader.Mask()); std::string macro; + macro += fmt::format("#define PRIMID_MAX {}\n", GSShader::PRIMID_MAX); + macro += fmt::format("#define PRIMID_MIN {}\n", GSShader::PRIMID_MIN); macro += fmt::format("#define HAS_BILN {}\n", static_cast(shader.Biln())); macro += fmt::format("#define HAS_STENCIL_OUTPUT {}\n", static_cast(shader.StencilOutput())); macro += fmt::format("#define HAS_INTEGER_OUTPUT {}\n", static_cast(shader.IntegerOutputBpp() != 0)); @@ -4263,9 +4265,14 @@ bool GSDeviceVK::CompileConvertPipelines() for (u32 datm = 0; datm < 4; datm++) { + std::string macro; + macro += fmt::format("#define PRIMID_MAX {}\n", GSShader::PRIMID_MAX); + macro += fmt::format("#define PRIMID_MIN {}\n", GSShader::PRIMID_MIN); + + const std::string source_with_header = macro + *source; + const std::string entry_point(StringUtil::StdStringFromFormat("ps_primid_image_init_%d", datm)); - VkShaderModule ps = - GetUtilityFragmentShader(*source, entry_point.c_str()); + VkShaderModule ps = GetUtilityFragmentShader(source_with_header, entry_point.c_str()); if (ps == VK_NULL_HANDLE) return false; @@ -6401,12 +6408,6 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) } } - if (draw_rt_clone) - Recycle(draw_rt_clone); - - if (date_image) - Recycle(date_image); - // now blit the colclip texture back to the original target if (colclip_rt) { @@ -6458,6 +6459,15 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) } config.colclip_mode = GSHWDrawConfig::ColClipMode::NoModify; + + if (date_image && config.dump_primid_path) + date_image->Save(*config.dump_primid_path); + + if (date_image) + Recycle(date_image); + + if (draw_rt_clone) + Recycle(draw_rt_clone); } void GSDeviceVK::UpdateHWPipelineSelector(GSHWDrawConfig& config, PipelineSelector& pipe) diff --git a/pcsx2/ShaderCacheVersion.h b/pcsx2/ShaderCacheVersion.h index c08b953adb375..b21c038f2eed1 100644 --- a/pcsx2/ShaderCacheVersion.h +++ b/pcsx2/ShaderCacheVersion.h @@ -3,4 +3,4 @@ /// Version number for GS and other shaders. Increment whenever any of the contents of the /// shaders change, to invalidate the cache. -static constexpr u32 SHADER_CACHE_VERSION = 109; // Last changed in PR 14795 +static constexpr u32 SHADER_CACHE_VERSION = 111; // Last changed in PR 14824 (2)