GPU: Clip against neg Z even w/o cull support.

This should fix rendering issues on Apple devices.
This commit is contained in:
Unknown W. Brackets 2022-10-06 00:34:02 -07:00
parent 87d00f79da
commit 3aa863ec41
2 changed files with 21 additions and 17 deletions

View file

@ -1287,19 +1287,22 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
if (vertexRangeCulling && !IsVRBuild()) {
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
WRITE(p, " float projZ = (projPos.z - u_depthRange.z) * u_depthRange.w;\n");
// Vertex range culling doesn't happen when Z clips, note sign of w is important.
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || projZ * outPos.w > -outPos.w) {\n");
const char *outMin = "projPos.x < u_cullRangeMin.x || projPos.y < u_cullRangeMin.y";
const char *outMax = "projPos.x > u_cullRangeMax.x || projPos.y > u_cullRangeMax.y";
WRITE(p, " if ((%s) || (%s)) {\n", outMin, outMax);
WRITE(p, " outPos.xyzw = u_cullRangeMax.wwww;\n");
WRITE(p, " }\n");
WRITE(p, " }\n");
WRITE(p, " if (u_cullRangeMin.w <= 0.0) {\n");
WRITE(p, " if (projPos.z < u_cullRangeMin.z || projPos.z > u_cullRangeMax.z) {\n");
WRITE(p, " outPos.xyzw = u_cullRangeMax.wwww;\n");
WRITE(p, " }\n");
WRITE(p, " }\n");
if (!bugs.Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) {
// Vertex range culling doesn't happen when Z clips, note sign of w is important.
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || projZ * outPos.w > -outPos.w) {\n");
const char *outMin = "projPos.x < u_cullRangeMin.x || projPos.y < u_cullRangeMin.y";
const char *outMax = "projPos.x > u_cullRangeMax.x || projPos.y > u_cullRangeMax.y";
WRITE(p, " if ((%s) || (%s)) {\n", outMin, outMax);
WRITE(p, " outPos.xyzw = u_cullRangeMax.wwww;\n");
WRITE(p, " }\n");
WRITE(p, " }\n");
WRITE(p, " if (u_cullRangeMin.w <= 0.0) {\n");
WRITE(p, " if (projPos.z < u_cullRangeMin.z || projPos.z > u_cullRangeMax.z) {\n");
WRITE(p, " outPos.xyzw = u_cullRangeMax.wwww;\n");
WRITE(p, " }\n");
WRITE(p, " }\n");
}
const char *cull0 = compat.shaderLanguage == HLSL_D3D11 ? ".x" : "[0]";
const char *cull1 = compat.shaderLanguage == HLSL_D3D11 ? ".y" : "[1]";

View file

@ -3305,10 +3305,11 @@ u32 GPUCommon::CheckGPUFeatures() const {
features |= GPU_SUPPORTS_DEPTH_TEXTURE;
}
if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) {
if (draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported) {
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
}
bool canClipOrCull = draw_->GetDeviceCaps().clipDistanceSupported || draw_->GetDeviceCaps().cullDistanceSupported;
bool canDiscardVertex = draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL);
if (canClipOrCull || canDiscardVertex) {
// We'll dynamically use the parts that are supported, to reduce artifacts as much as possible.
features |= GPU_SUPPORTS_VS_RANGE_CULLING;
}
if (draw_->GetDeviceCaps().framebufferFetchSupported) {