Skip to content

Commit

Permalink
Vulkan: Avoid OpKill workaround with no stencil.
Browse files Browse the repository at this point in the history
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 9a7ee41
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
7 changes: 6 additions & 1 deletion GPU/Common/ShaderId.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 9a7ee41

Please sign in to comment.