From e86d7cbc999223ca113af7b4c0aac6850c1854fe Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 17 Aug 2016 20:12:44 +0200 Subject: [PATCH] OGL: Workaround gl_ClipDistance bug on Mesa i965. --- Source/Core/VideoBackends/OGL/Render.cpp | 4 +--- Source/Core/VideoCommon/DriverDetails.h | 7 ++++--- Source/Core/VideoCommon/GeometryShaderGen.cpp | 10 ++++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 78d5d106b7..d637c308ca 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -482,9 +482,7 @@ Renderer::Renderer() GLExtensions::Supports("GL_ARB_shading_language_420pack"); // Clip distance support is useless without a method to clamp the depth range - g_Config.backend_info.bSupportsDepthClamp = - GLExtensions::Supports("GL_ARB_depth_clamp") && - !DriverDetails::HasBug(DriverDetails::BUG_BROKENCLIPDISTANCE); + g_Config.backend_info.bSupportsDepthClamp = GLExtensions::Supports("GL_ARB_depth_clamp"); g_ogl_config.bSupportsGLSLCache = GLExtensions::Supports("GL_ARB_get_program_binary"); g_ogl_config.bSupportsGLPinnedMemory = GLExtensions::Supports("GL_AMD_pinned_memory"); diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index 414ef03390..b6dcf87963 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -205,12 +205,13 @@ enum Bug // everywhere else. BUG_SLOWGETBUFFERSUBDATA, - // Bug: Broken lines in geometry shaders when writing to gl_ClipDistance + // Bug: Broken lines in geometry shaders when writing to gl_ClipDistance in the vertex shader // Affected Devices: Mesa i965 // Started Version: -1 // Ended Version: -1 - // Mesa hasn't tested geometry shaders on i965 with user-defined clipping planes. - // Causes misrenderings on a large amount of things that draw lines. + // Writing to gl_ClipDistance in both the vertex shader and the geometry shader will break + // the geometry shader. Current workaround is to make sure the geometry shader always consumes + // the gl_ClipDistance inputs from the vertex shader. BUG_BROKENCLIPDISTANCE, }; diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 2630a422fa..83b30943bc 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -7,6 +7,7 @@ #include "Common/CommonTypes.h" #include "VideoCommon/BPMemory.h" +#include "VideoCommon/DriverDetails.h" #include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/VideoCommon.h" @@ -211,6 +212,15 @@ ShaderCode GenerateGeometryShaderCode(APIType ApiType, const geometry_shader_uid { out.Write("\tVS_OUTPUT f;\n"); AssignVSOutputMembers(out, "f", "vs[i]", uid_data->numTexGens, uid_data->pixel_lighting); + + if (g_ActiveConfig.backend_info.bSupportsDepthClamp && + DriverDetails::HasBug(DriverDetails::BUG_BROKENCLIPDISTANCE)) + { + // On certain GPUs we have to consume the clip distance from the vertex shader + // or else the other vertex shader outputs will get corrupted. + out.Write("\tf.clipDist0 = gl_in[i].gl_ClipDistance[0];\n"); + out.Write("\tf.clipDist1 = gl_in[i].gl_ClipDistance[1];\n"); + } } else {