From b4a76a9f093157c667282982ff78e27f9177103a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 29 Oct 2020 00:13:32 +0100 Subject: [PATCH] Change fragment shader output to work the same in GLSL and HLSL. --- GPU/Common/ShaderCommon.cpp | 2 ++ GPU/Directx9/FragmentShaderGeneratorHLSL.cpp | 25 +++++++++++++++----- GPU/GLES/FragmentShaderGeneratorGLES.cpp | 18 +++++++++----- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/GPU/Common/ShaderCommon.cpp b/GPU/Common/ShaderCommon.cpp index 797f96a361..820b87a23d 100644 --- a/GPU/Common/ShaderCommon.cpp +++ b/GPU/Common/ShaderCommon.cpp @@ -116,6 +116,7 @@ void GLSLShaderCompat::SetupForVulkan() { lastFragData = nullptr; texture = "texture"; texelFetch = "texelFetch"; + d3d11 = false; vulkan = true; forceMatrix4x4 = false; coefsFromBuffers = true; @@ -137,6 +138,7 @@ void GLSLShaderCompat::SetupForD3D11() { lastFragData = nullptr; texture = "texture"; texelFetch = "texelFetch"; + vulkan = false; d3d11 = true; forceMatrix4x4 = false; coefsFromBuffers = true; diff --git a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp index 7c015e40b3..477cf63b8c 100644 --- a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp +++ b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp @@ -33,9 +33,10 @@ const char *hlsl_preamble = "#define vec2 float2\n" "#define vec3 float3\n" "#define vec4 float4\n" -"#define uvec3 uint\n" +"#define uvec3 uint3\n" "#define ivec3 int3\n" -"#define splat3(x) float3(x, x, x)\n"; +"#define splat3(x) float3(x, x, x)\n" +"#define usplat3(x) uvec3(x, x, x)\n"; const char *hlsl_d3d11_preamble = "#define DISCARD discard\n" @@ -153,7 +154,7 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag } if (enableColorTest) { if (lang == HLSL_D3D11) { - WRITE(p, "uint3 roundAndScaleTo255iv(float3 x) { return uint3(floor(x * 255.0f + 0.5f)); }\n"); + WRITE(p, "uvec3 roundAndScaleTo255iv(float3 x) { return uvec3(floor(x * 255.0f + 0.5f)); }\n"); } else { WRITE(p, "vec3 roundAndScaleTo255v(float3 x) { return floor(x * 255.0f + 0.5f); }\n"); } @@ -364,9 +365,9 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag if (colorTestFuncs[colorTestFunc][0] != '#') { const char *test = colorTestFuncs[colorTestFunc]; if (lang == HLSL_D3D11) { - WRITE(p, " uint3 v_scaled = roundAndScaleTo255iv(v.rgb);\n"); - WRITE(p, " uint3 v_masked = v_scaled & u_alphacolormask.rgb;\n"); - WRITE(p, " uint3 colorTestRef = u_alphacolorref.rgb & u_alphacolormask.rgb;\n"); + WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n"); + WRITE(p, " ivec3 v_masked = v_scaled & u_alphacolormask.rgb;\n"); + WRITE(p, " ivec3 colorTestRef = u_alphacolorref.rgb & u_alphacolormask.rgb;\n"); // We have to test the components separately, or we get incorrect results. See #10629. WRITE(p, " if (v_masked.r %s colorTestRef.r && v_masked.g %s colorTestRef.g && v_masked.b %s colorTestRef.b) DISCARD;\n", test, test, test); } else { @@ -518,6 +519,10 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag } switch (stencilToAlpha) { + case REPLACE_ALPHA_DUALSOURCE: + // Handled at the end. + break; + case REPLACE_ALPHA_YES: WRITE(p, " v.a = %s;\n", replacedAlpha.c_str()); break; @@ -525,6 +530,10 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag case REPLACE_ALPHA_NO: // Do nothing, v is already fine. break; + + default: + *errorString = "Bad stencil-to-alpha type, corrupt ID?"; + return false; } LogicOpReplaceType replaceLogicOpType = (LogicOpReplaceType)id.Bits(FS_BIT_REPLACE_LOGIC_OP_TYPE, 2); @@ -537,6 +546,10 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag break; case LOGICOPTYPE_NORMAL: break; + + default: + *errorString = "Bad logic op type, corrupt ID?"; + return false; } if (gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { diff --git a/GPU/GLES/FragmentShaderGeneratorGLES.cpp b/GPU/GLES/FragmentShaderGeneratorGLES.cpp index 8bb5ab979d..e286ab866f 100644 --- a/GPU/GLES/FragmentShaderGeneratorGLES.cpp +++ b/GPU/GLES/FragmentShaderGeneratorGLES.cpp @@ -833,16 +833,15 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha switch (stencilToAlpha) { case REPLACE_ALPHA_DUALSOURCE: - WRITE(p, " %s = vec4(v.rgb, %s);\n", compat.fragColor0, replacedAlpha.c_str()); - WRITE(p, " %s = vec4(0.0, 0.0, 0.0, v.a);\n", compat.fragColor1); + // Handled at the end. break; case REPLACE_ALPHA_YES: - WRITE(p, " %s = vec4(v.rgb, %s);\n", compat.fragColor0, replacedAlpha.c_str()); + WRITE(p, " v.a = %s;\n", replacedAlpha.c_str()); break; case REPLACE_ALPHA_NO: - WRITE(p, " %s = v;\n", compat.fragColor0); + // Nothing to do. break; default: @@ -853,10 +852,10 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha LogicOpReplaceType replaceLogicOpType = (LogicOpReplaceType)id.Bits(FS_BIT_REPLACE_LOGIC_OP_TYPE, 2); switch (replaceLogicOpType) { case LOGICOPTYPE_ONE: - WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0);\n", compat.fragColor0); + WRITE(p, " v.rgb = splat3(1.0);\n"); break; case LOGICOPTYPE_INVERT: - WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0) - %s.rgb;\n", compat.fragColor0, compat.fragColor0); + WRITE(p, " v.rgb = splat3(1.0) - v.rgb;\n"); break; case LOGICOPTYPE_NORMAL: break; @@ -888,6 +887,13 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLSha WRITE(p, " gl_FragDepth = gl_FragCoord.z;\n"); } + if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE) { + WRITE(p, " %s = vec4(v.rgb, %s);\n", compat.fragColor0, replacedAlpha.c_str()); + WRITE(p, " %s = vec4(0.0, 0.0, 0.0, v.a);\n", compat.fragColor1); + } else { + WRITE(p, " %s = v;\n", compat.fragColor0); + } + if (compat.d3d11) { WRITE(p, " return outfragment;\n"); }