diff --git a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp index 4cbe2c50ff..a48f1d17e9 100644 --- a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp +++ b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp @@ -291,6 +291,11 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag WRITE(p, " float4 v = In.v_color0 %s;\n", secondary); } + if (enableFog) { + WRITE(p, " float fogCoef = clamp(In.v_fogdepth, 0.0, 1.0);\n"); + WRITE(p, " v = lerp(float4(u_fogcolor, v.a), v, fogCoef);\n"); + } + if (enableAlphaTest) { if (alphaTestAgainstZero) { // When testing against 0 (extremely common), we can avoid some math. @@ -322,11 +327,6 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag } } - if (enableFog) { - WRITE(p, " float fogCoef = clamp(In.v_fogdepth, 0.0, 1.0);\n"); - WRITE(p, " v = lerp(float4(u_fogcolor, v.a), v, fogCoef);\n"); - } - if (enableColorTest) { if (colorTestAgainstZero) { // When testing against 0 (common), we can avoid some math. diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index 29579a11e4..a726a8558a 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -352,6 +352,11 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ WRITE(p, " vec4 v = v_color0 %s;\n", secondary); } + if (enableFog) { + WRITE(p, " float fogCoef = clamp(v_fogdepth, 0.0, 1.0);\n"); + WRITE(p, " v = mix(vec4(u_fogcolor, v.a), v, fogCoef);\n"); + } + // Texture access is at half texels [0.5/256, 255.5/256], but colors are normalized [0, 255]. // So we have to scale to account for the difference. std::string alphaTestXCoord = "0"; @@ -374,7 +379,7 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ } else { const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " }; if (alphaTestFuncs[alphaTestFunc][0] != '#') { - WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s u_alphacolorref.a) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement); + WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s int(u_alphacolorref.a)) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement); } else { // This means NEVER. See above. WRITE(p, " %s\n", discardStatement); @@ -382,12 +387,6 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ } } - if (enableFog) { - WRITE(p, " float fogCoef = clamp(v_fogdepth, 0.0, 1.0);\n"); - WRITE(p, " v = mix(vec4(u_fogcolor, v.a), v, fogCoef);\n"); - // WRITE(p, " v.x = v_depth;\n"); - } - if (enableColorTest) { if (colorTestAgainstZero) { // When testing against 0 (common), we can avoid some math. @@ -419,7 +418,7 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ } if (replaceBlend == REPLACE_BLEND_PRE_SRC || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA) { - const char *srcFactor = "ERROR"; + const char *srcFactor = nullptr; switch (replaceBlendFuncA) { case GE_SRCBLEND_DSTCOLOR: srcFactor = "ERROR"; break; case GE_SRCBLEND_INVDSTCOLOR: srcFactor = "ERROR"; break; @@ -429,9 +428,12 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ case GE_SRCBLEND_INVDSTALPHA: srcFactor = "ERROR"; break; case GE_SRCBLEND_DOUBLESRCALPHA: srcFactor = "vec3(v.a * 2.0)"; break; case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "vec3(1.0 - v.a * 2.0)"; break; - case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "ERROR"; break; + // PRE_SRC for REPLACE_BLEND_PRE_SRC_2X_ALPHA means "double the src." + // It's close to the same, but clamping can still be an issue. + case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "vec3(2.0)"; break; case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "ERROR"; break; case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break; + default: srcFactor = "u_blendFixA"; break; } if (!strcmp(srcFactor, "ERROR")) { @@ -460,6 +462,7 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "vec3(destColor.a * 2.0)"; break; case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "vec3(1.0 - destColor.a * 2.0)"; break; case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break; + default: srcFactor = "u_blendFixA"; break; } switch (replaceBlendFuncB) { case GE_DSTBLEND_SRCCOLOR: dstFactor = "v.rgb"; break; @@ -473,6 +476,7 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ case GE_DSTBLEND_DOUBLEDSTALPHA: dstFactor = "vec3(destColor.a * 2.0)"; break; case GE_DSTBLEND_DOUBLEINVDSTALPHA: dstFactor = "vec3(1.0 - destColor.a * 2.0)"; break; case GE_DSTBLEND_FIXB: dstFactor = "u_blendFixB"; break; + default: dstFactor = "u_blendFixB"; break; } switch (replaceBlendEq) { @@ -494,6 +498,9 @@ bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_ case GE_BLENDMODE_ABSDIFF: WRITE(p, " v.rgb = abs(v.rgb - destColor.rgb);\n"); break; + default: + *errorString = "Bad replace blend eq"; + return false; } } diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp index cb28331bb0..7fea59c9bb 100644 --- a/unittest/TestShaderGenerators.cpp +++ b/unittest/TestShaderGenerators.cpp @@ -174,19 +174,21 @@ bool TestShaderGenerators() { id.d[1] = top; bool generateSuccess[numLanguages]{}; + std::string genErrorString[numLanguages]; for (int j = 0; j < numLanguages; j++) { - std::string genErrorString; - generateSuccess[j] = GenerateFShader(id, buffer[j], languages[j], &genErrorString); - if (!genErrorString.empty()) { - printf("%s\n", genErrorString.c_str()); + generateSuccess[j] = GenerateFShader(id, buffer[j], languages[j], &genErrorString[j]); + if (!genErrorString[j].empty()) { + printf("%s\n", genErrorString[j].c_str()); } // We ignore the contents of the error string here, not even gonna try to compile if it errors. } // Temporary test: Compare GLSL-in-Vulkan-mode vs Vulkan if (generateSuccess[0] != generateSuccess[1]) { - printf("mismatching success!\n"); + printf("mismatching success! %s %s\n", genErrorString[0].c_str(), genErrorString[1].c_str()); + printf("%s\n", buffer[0]); + printf("%s\n", buffer[1]); return 1; } if (generateSuccess[0] && strcmp(buffer[0], buffer[1])) {