GPU: Support clip and cull distances separately.

Older GL devices, and it seems Apple devices, may not support cull.
This commit is contained in:
Unknown W. Brackets 2021-09-19 23:27:30 -07:00
parent 7b00c4a572
commit 33598f2e75
6 changed files with 23 additions and 12 deletions

View File

@ -401,8 +401,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
WRITE(p, " vec4 gl_Position : POSITION;\n");
} else {
WRITE(p, " vec4 gl_Position : SV_Position;\n");
if (vertexRangeCulling && gstate_c.Supports(GPU_SUPPORTS_CLIP_CULL_DISTANCE)) {
if (vertexRangeCulling && gstate_c.Supports(GPU_SUPPORTS_CLIP_DISTANCE)) {
WRITE(p, " float gl_ClipDistance : SV_ClipDistance0;\n");
}
if (vertexRangeCulling && gstate_c.Supports(GPU_SUPPORTS_CULL_DISTANCE)) {
WRITE(p, " float2 gl_CullDistance : SV_CullDistance0;\n");
}
}
@ -1121,9 +1123,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
const char *clip0 = compat.shaderLanguage == HLSL_D3D11 ? "" : "[0]";
const char *cull0 = compat.shaderLanguage == HLSL_D3D11 ? ".x" : "[0]";
const char *cull1 = compat.shaderLanguage == HLSL_D3D11 ? ".y" : "[1]";
if (gstate_c.Supports(GPU_SUPPORTS_CLIP_CULL_DISTANCE)) {
if (gstate_c.Supports(GPU_SUPPORTS_CLIP_DISTANCE)) {
// TODO: Not rectangles...
WRITE(p, " %sgl_ClipDistance%s = projZ * outPos.w + outPos.w;\n", compat.vsOutPrefix, clip0);
}
if (gstate_c.Supports(GPU_SUPPORTS_CULL_DISTANCE)) {
// Cull any triangle fully outside in the same direction when depth clamp enabled.
WRITE(p, " if (u_cullRangeMin.w > 0.0) {\n");
WRITE(p, " %sgl_CullDistance%s = projPos.z - u_cullRangeMin.z;\n", compat.vsOutPrefix, cull0);

View File

@ -128,8 +128,10 @@ void GPU_D3D11::CheckGPUFeatures() {
features |= GPU_SUPPORTS_DUALSOURCE_BLEND;
if (draw_->GetDeviceCaps().depthClampSupported)
features |= GPU_SUPPORTS_DEPTH_CLAMP;
if (draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported)
features |= GPU_SUPPORTS_CLIP_CULL_DISTANCE;
if (draw_->GetDeviceCaps().clipDistanceSupported)
features |= GPU_SUPPORTS_CLIP_DISTANCE;
if (draw_->GetDeviceCaps().cullDistanceSupported)
features |= GPU_SUPPORTS_CULL_DISTANCE;
features |= GPU_SUPPORTS_COPY_IMAGE;
features |= GPU_SUPPORTS_TEXTURE_FLOAT;
features |= GPU_SUPPORTS_INSTANCE_RENDERING;

View File

@ -228,8 +228,10 @@ void GPU_GLES::CheckGPUFeatures() {
if (gl_extensions.GLES3)
features |= GPU_SUPPORTS_DEPTH_TEXTURE;
}
if (draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported)
features |= GPU_SUPPORTS_CLIP_CULL_DISTANCE;
if (draw_->GetDeviceCaps().clipDistanceSupported)
features |= GPU_SUPPORTS_CLIP_DISTANCE;
if (draw_->GetDeviceCaps().cullDistanceSupported)
features |= GPU_SUPPORTS_CULL_DISTANCE;
// If we already have a 16-bit depth buffer, we don't need to round.
bool prefer24 = draw_->GetDeviceCaps().preferredDepthBufferFormat == Draw::DataFormat::D24_S8;

View File

@ -183,7 +183,7 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs,
initialize.push_back({ &u_tess_weights_v, 0, 6 });
bool useDualSource = (gstate_c.featureFlags & GPU_SUPPORTS_DUALSOURCE_BLEND) != 0;
bool useClip0 = VSID.Bit(VS_BIT_VERTEX_RANGE_CULLING) && gstate_c.Supports(GPU_SUPPORTS_CLIP_CULL_DISTANCE);
bool useClip0 = VSID.Bit(VS_BIT_VERTEX_RANGE_CULLING) && gstate_c.Supports(GPU_SUPPORTS_CLIP_DISTANCE);
program = render->CreateProgram(shaders, semantics, queries, initialize, useDualSource, useClip0);
// The rest, use the "dirty" mechanism.

View File

@ -482,7 +482,7 @@ enum {
GPU_SUPPORTS_32BIT_INT_FSHADER = FLAG_BIT(15),
GPU_SUPPORTS_DEPTH_TEXTURE = FLAG_BIT(16),
GPU_SUPPORTS_ACCURATE_DEPTH = FLAG_BIT(17),
GPU_SUPPORTS_CLIP_CULL_DISTANCE = FLAG_BIT(18),
// Free bit: 18
GPU_SUPPORTS_COPY_IMAGE = FLAG_BIT(19),
GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH = FLAG_BIT(20),
GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT = FLAG_BIT(21),
@ -492,8 +492,8 @@ enum {
GPU_SUPPORTS_FRAMEBUFFER_BLIT = FLAG_BIT(26),
GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH = FLAG_BIT(27),
GPU_SUPPORTS_TEXTURE_NPOT = FLAG_BIT(28),
// Free bit: 29
// Free bit: 30
GPU_SUPPORTS_CLIP_DISTANCE = FLAG_BIT(29),
GPU_SUPPORTS_CULL_DISTANCE = FLAG_BIT(30),
GPU_PREFER_REVERSE_COLOR_ORDER = FLAG_BIT(31),
};

View File

@ -241,9 +241,12 @@ void GPU_Vulkan::CheckGPUFeatures() {
if (enabledFeatures.depthClamp) {
features |= GPU_SUPPORTS_DEPTH_CLAMP;
}
if (enabledFeatures.shaderClipDistance && enabledFeatures.shaderCullDistance) {
if (enabledFeatures.shaderClipDistance) {
features |= GPU_SUPPORTS_CLIP_DISTANCE;
}
if (enabledFeatures.shaderCullDistance) {
// Must support at least 8 if feature supported, so we're fine.
features |= GPU_SUPPORTS_CLIP_CULL_DISTANCE;
features |= GPU_SUPPORTS_CULL_DISTANCE;
}
if (enabledFeatures.dualSrcBlend) {
if (!g_Config.bVendorBugChecksEnabled || !draw_->GetBugs().Has(Draw::Bugs::DUAL_SOURCE_BLENDING_BROKEN)) {