Permalink
Browse files

Vulkan: Avoid OpKill workaround with no stencil.

It seems like depth gets messed up either way on discard, but behaves
sorta better without the write to depth.
  • Loading branch information...
unknownbrackets committed Dec 1, 2018
1 parent 5932cba commit 9a7ee411918846d00bc1a6f9c22c983c6af6b793
Showing with 9 additions and 3 deletions.
  1. +6 −1 GPU/Common/ShaderId.cpp
  2. +3 −2 GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp
@@ -201,8 +201,10 @@ std::string FragmentShaderDesc(const ShaderID &id) {
case STENCIL_VALUE_INCR_8: desc << "StenIncr8 "; break;
case STENCIL_VALUE_DECR_4: desc << "StenDecr4 "; break;
case STENCIL_VALUE_DECR_8: desc << "StenDecr4 "; break;
default: desc << "StenUnknown"; break;
default: desc << "StenUnknown "; break;
}
} else if (id.Bit(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE)) {
desc << "StenOff ";
}
if (id.Bit(FS_BIT_DO_TEXTURE)) {
switch (id.Bits(FS_BIT_TEXFUNC, 3)) {
@@ -292,6 +294,9 @@ void ComputeFragmentShaderID(ShaderID *id_out) {
if (stencilToAlpha != REPLACE_ALPHA_NO) {
// 4 bits
id.SetBits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4, ReplaceAlphaWithStencilType());
} else {
// Use those bits instead for whether stencil output is disabled.
id.SetBit(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, IsStencilTestOutputDisabled());
}
// 2 bits.
@@ -84,12 +84,13 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
const char *shading = doFlatShading ? "flat" : "";
bool earlyFragmentTests = ((!enableAlphaTest && !enableColorTest) || testForceToZero) && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT);
bool hasStencilOutput = stencilToAlpha != REPLACE_ALPHA_NO || id.Bit(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE) == 0;
bool isAdreno = vulkanVendorId == VULKAN_VENDOR_QUALCOMM;
if (earlyFragmentTests) {
WRITE(p, "layout (early_fragment_tests) in;\n");
} else if (isAdreno) {
} else if (isAdreno && hasStencilOutput && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) {
WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n");
}
@@ -585,7 +586,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
WRITE(p, " z = (1.0/65535.0) * floor(z * 65535.0);\n");
}
WRITE(p, " gl_FragDepth = z;\n");
} else if (!earlyFragmentTests && isAdreno) {
} else if (!earlyFragmentTests && isAdreno && hasStencilOutput) {
// Adreno (and possibly MESA/others) apply early frag tests even with discard in the shader.
// Writing depth prevents the bug, even with depth_unchanged specified.
WRITE(p, " gl_FragDepth = gl_FragCoord.z;\n");

0 comments on commit 9a7ee41

Please sign in to comment.