From 1cb3e6bd494655e1a4e63c0ed2be8ba3c1514d57 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 24 Mar 2024 22:29:21 +1000 Subject: [PATCH] ShaderGen: Support multiple render target output --- src/core/gpu_hw_shadergen.cpp | 27 ++++++++++++++------------- src/core/gpu_shadergen.cpp | 6 +++--- src/util/shadergen.cpp | 24 +++++++++++++----------- src/util/shadergen.h | 12 +++++++----- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index ccf1b222a..65d989a7c 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -809,20 +809,21 @@ float3 ApplyDebanding(float2 frag_coord) { DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "uint4 v_texpage"}, {"nointerpolation", "float4 v_uv_limits"}}, - true, use_dual_source ? 2 : 1, m_write_mask_as_depth, UsingMSAA(), + true, use_dual_source ? 2 : 1, use_dual_source, m_write_mask_as_depth, UsingMSAA(), UsingPerSampleShading(), false, m_disable_color_perspective, shader_blending); } else { DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "uint4 v_texpage"}}, true, use_dual_source ? 2 : 1, - m_write_mask_as_depth, UsingMSAA(), UsingPerSampleShading(), false, + use_dual_source, m_write_mask_as_depth, UsingMSAA(), UsingPerSampleShading(), false, m_disable_color_perspective, shader_blending); } } else { - DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, m_write_mask_as_depth, UsingMSAA(), - UsingPerSampleShading(), false, m_disable_color_perspective, shader_blending); + DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, use_dual_source, m_write_mask_as_depth, + UsingMSAA(), UsingPerSampleShading(), false, m_disable_color_perspective, + shader_blending); } ss << R"( @@ -1170,7 +1171,7 @@ std::string GPU_HW_ShaderGen::GenerateWireframeFragmentShader() WriteHeader(ss); WriteCommonFunctions(ss); - DeclareFragmentEntryPoint(ss, 0, 0, {}, false, 1); + DeclareFragmentEntryPoint(ss, 0, 0); ss << R"( { o_col0 = float4(1.0, 1.0, 1.0, 0.5); @@ -1277,7 +1278,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMWriteFragmentShader(bool use_buffer, b ss << "#define GET_VALUE(buffer_offset) (LOAD_TEXTURE_BUFFER(samp0, int(buffer_offset)).r)\n\n"; } - DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, m_write_mask_as_depth); + DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, m_write_mask_as_depth); ss << R"( { uint2 coords = uint2(v_pos.xy) / uint2(RESOLUTION_SCALE, RESOLUTION_SCALE); @@ -1326,7 +1327,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMCopyFragmentShader() DeclareTexture(ss, "samp0", 0, msaa); DefineMacro(ss, "MSAA_COPY", msaa); - DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, m_write_mask_as_depth, false, false, msaa); + DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, m_write_mask_as_depth, false, false, msaa); ss << R"( { uint2 dst_coords = uint2(v_pos.xy); @@ -1373,7 +1374,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMFillFragmentShader(bool wrapped, bool DeclareUniformBuffer( ss, {"uint2 u_dst_coords", "uint2 u_end_coords", "float4 u_fill_color", "uint u_interlaced_displayed_field"}, true); - DeclareFragmentEntryPoint(ss, 0, 1, {}, interlaced || wrapped, 1, m_write_mask_as_depth, false, false, false); + DeclareFragmentEntryPoint(ss, 0, 1, {}, interlaced || wrapped, 1, false, m_write_mask_as_depth, false, false, false); ss << R"( { #if INTERLACED || WRAPPED @@ -1409,7 +1410,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMUpdateDepthFragmentShader() WriteHeader(ss); WriteCommonFunctions(ss); DeclareTexture(ss, "samp0", 0, UsingMSAA()); - DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 0, true, false, false, UsingMSAA()); + DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 0, false, true, false, false, UsingMSAA()); ss << R"( { @@ -1484,7 +1485,7 @@ float4 get_bias(float4 c00, float4 c01, float4 c10, float4 c11) )"; - DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, false, false, false, false); + DeclareFragmentEntryPoint(ss, 0, 1); ss << R"( { float2 uv = v_tex0 - (u_rcp_resolution * 0.25); @@ -1516,7 +1517,7 @@ std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleBlurFragmentShader() DeclareTexture(ss, "samp0", 0, false); // mipmap_blur.glsl ported from parallel-rsx. - DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, false, false, false, false); + DeclareFragmentEntryPoint(ss, 0, 1); ss << R"( { float bias = 0.0; @@ -1549,7 +1550,7 @@ std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleCompositeFragmentShader( DeclareTexture(ss, "samp1", 1, false); // mipmap_resolve.glsl ported from parallel-rsx. - DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, false, false, false); + DeclareFragmentEntryPoint(ss, 0, 1, {}, true); ss << R"( { float bias = SAMPLE_TEXTURE(samp1, v_tex0).r; @@ -1572,7 +1573,7 @@ std::string GPU_HW_ShaderGen::GenerateBoxSampleDownsampleFragmentShader(u32 fact ss << "#define FACTOR " << factor << "\n"; - DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, false, false, false); + DeclareFragmentEntryPoint(ss, 0, 1, {}, true); ss << R"( { float3 color = float3(0.0, 0.0, 0.0); diff --git a/src/core/gpu_shadergen.cpp b/src/core/gpu_shadergen.cpp index ac35b6d0c..40400c63c 100644 --- a/src/core/gpu_shadergen.cpp +++ b/src/core/gpu_shadergen.cpp @@ -46,7 +46,7 @@ std::string GPUShaderGen::GenerateDisplayFragmentShader(bool clamp_uv) WriteHeader(ss); WriteDisplayUniformBuffer(ss); DeclareTexture(ss, "samp0", 0); - DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1); + DeclareFragmentEntryPoint(ss, 0, 1); if (clamp_uv) ss << "{\n o_col0 = float4(SAMPLE_TEXTURE(samp0, ClampUV(v_tex0)).rgb, 1.0f);\n }"; else @@ -64,7 +64,7 @@ std::string GPUShaderGen::GenerateDisplaySharpBilinearFragmentShader() // Based on // https://github.com/rsn8887/Sharp-Bilinear-Shaders/blob/master/Copy_To_RetroPie/shaders/sharp-bilinear-simple.glsl - DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, false, false, false, false); + DeclareFragmentEntryPoint(ss, 0, 1); ss << R"( { float2 scale = u_params.xy; @@ -234,7 +234,7 @@ float3 SampleVRAMAverage2x2(uint2 icoords) } )"; - DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1); + DeclareFragmentEntryPoint(ss, 0, 1, {}, true); ss << R"( { uint2 icoords = uint2(v_pos.xy) + u_sample_offset; diff --git a/src/util/shadergen.cpp b/src/util/shadergen.cpp index bfb173485..8ecc4c947 100644 --- a/src/util/shadergen.cpp +++ b/src/util/shadergen.cpp @@ -542,10 +542,10 @@ void ShaderGen::DeclareVertexEntryPoint( void ShaderGen::DeclareFragmentEntryPoint( std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs, - const std::initializer_list>& additional_inputs, - bool declare_fragcoord /* = false */, u32 num_color_outputs /* = 1 */, bool depth_output /* = false */, - bool msaa /* = false */, bool ssaa /* = false */, bool declare_sample_id /* = false */, - bool noperspective_color /* = false */, bool feedback_loop /* = false */) + const std::initializer_list>& additional_inputs /* = */, + bool declare_fragcoord /* = false */, u32 num_color_outputs /* = 1 */, bool dual_source_output /* = false */, + bool depth_output /* = false */, bool msaa /* = false */, bool ssaa /* = false */, + bool declare_sample_id /* = false */, bool noperspective_color /* = false */, bool feedback_loop /* = false */) { if (m_glsl) { @@ -650,7 +650,7 @@ void ShaderGen::DeclareFragmentEntryPoint( if (m_use_glsl_binding_layout) { - if (m_supports_dual_source_blend && num_color_outputs > 1) + if (dual_source_output && m_supports_dual_source_blend && num_color_outputs > 1) { for (u32 i = 0; i < num_color_outputs; i++) { @@ -660,8 +660,11 @@ void ShaderGen::DeclareFragmentEntryPoint( } else { - Assert(num_color_outputs <= 1); - ss << "layout(location = 0) " << target_0_qualifier << " float4 o_col0;\n"; + for (u32 i = 0; i < num_color_outputs; i++) + { + ss << "layout(location = " << i << ") " << ((i == 0) ? target_0_qualifier : "out") << " float4 o_col" << i + << ";\n"; + } } } else @@ -762,12 +765,11 @@ std::string ShaderGen::GenerateFillFragmentShader() std::stringstream ss; WriteHeader(ss); DeclareUniformBuffer(ss, {"float4 u_fill_color"}, true); - DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, true); + DeclareFragmentEntryPoint(ss, 0, 1); ss << R"( { o_col0 = u_fill_color; - o_depth = u_fill_color.a; } )"; @@ -780,7 +782,7 @@ std::string ShaderGen::GenerateCopyFragmentShader() WriteHeader(ss); DeclareUniformBuffer(ss, {"float4 u_src_rect"}, true); DeclareTexture(ss, "samp0", 0); - DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1); + DeclareFragmentEntryPoint(ss, 0, 1); ss << R"( { @@ -817,7 +819,7 @@ std::string ShaderGen::GenerateImGuiFragmentShader() std::stringstream ss; WriteHeader(ss); DeclareTexture(ss, "samp0", 0); - DeclareFragmentEntryPoint(ss, 1, 1, {}, false, 1); + DeclareFragmentEntryPoint(ss, 1, 1); ss << R"( { diff --git a/src/util/shadergen.h b/src/util/shadergen.h index bcea76fda..82e8ec1a5 100644 --- a/src/util/shadergen.h +++ b/src/util/shadergen.h @@ -56,11 +56,13 @@ protected: const std::initializer_list>& additional_outputs, bool declare_vertex_id = false, const char* output_block_suffix = "", bool msaa = false, bool ssaa = false, bool noperspective_color = false); - void DeclareFragmentEntryPoint(std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs, - const std::initializer_list>& additional_inputs, - bool declare_fragcoord = false, u32 num_color_outputs = 1, bool depth_output = false, - bool msaa = false, bool ssaa = false, bool declare_sample_id = false, - bool noperspective_color = false, bool feedback_loop = false); + void + DeclareFragmentEntryPoint(std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs, + const std::initializer_list>& additional_inputs = {}, + bool declare_fragcoord = false, u32 num_color_outputs = 1, bool dual_source_output = false, + bool depth_output = false, bool msaa = false, bool ssaa = false, + bool declare_sample_id = false, bool noperspective_color = false, + bool feedback_loop = false); RenderAPI m_render_api; GPUShaderLanguage m_shader_language;