diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 4efecef4aa..de86dff177 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -547,7 +547,7 @@ void ProgramShaderCache::CreateHeader() , (g_ogl_config.bSupportSampleShading) ? "#extension GL_ARB_sample_shading : enable" : "" , g_ActiveConfig.backend_info.bSupportsBindingLayout ? "#define SAMPLER_BINDING(x) layout(binding = x)" : "#define SAMPLER_BINDING(x)" , g_ActiveConfig.backend_info.bSupportsBBox ? "#extension GL_ARB_shader_storage_buffer_object : enable" : "" - , (g_ogl_config.bSupportGSInvocation) ? "#extension GL_ARB_gpu_shader5 : enable" : "" + , g_ActiveConfig.backend_info.bSupportsGSInstancing ? "#extension GL_ARB_gpu_shader5 : enable" : "" , v>=GLSLES_300 ? "precision highp float;" : "" , v>=GLSLES_300 ? "precision highp int;" : "" diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index b6c288bf2c..802a1b1f96 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -476,6 +476,7 @@ Renderer::Renderer() ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart")); g_Config.backend_info.bSupportsEarlyZ = GLExtensions::Supports("GL_ARB_shader_image_load_store"); g_Config.backend_info.bSupportsBBox = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"); + g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5"); // Desktop OpenGL supports the binding layout if it supports 420pack // OpenGL ES 3.1 supports it implicitly without an extension @@ -491,7 +492,6 @@ Renderer::Renderer() g_ogl_config.bSupportSampleShading = GLExtensions::Supports("GL_ARB_sample_shading"); g_ogl_config.bSupportOGL31 = GLExtensions::Version() >= 310; g_ogl_config.bSupportViewportFloat = GLExtensions::Supports("GL_ARB_viewport_array"); - g_ogl_config.bSupportGSInvocation = GLExtensions::Supports("GL_ARB_gpu_shader5"); if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3) { diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 3888142c47..f35487a373 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -30,7 +30,6 @@ struct VideoConfig GLSL_VERSION eSupportedGLSLVersion; bool bSupportOGL31; bool bSupportViewportFloat; - bool bSupportGSInvocation; const char* gl_vendor; const char* gl_renderer; diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 20636cccb8..a6307fe722 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -45,8 +45,11 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy { // Insert layout parameters uid_data->stereo = g_ActiveConfig.bStereo; - out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); - out.Write("layout(triangle_strip, max_vertices = 3) out;\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); + else + out.Write("layout(triangles) in;\n"); + out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.backend_info.bSupportsGSInstancing ? 3 : 6); } out.Write("%s", s_lighting_struct); @@ -67,9 +70,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("flat out int eye;\n"); out.Write("void main()\n{\n"); + if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\tfor (eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.bStereo ? 2 : 1); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); - out.Write("\t\teye = gl_InvocationID;\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\t\teye = gl_InvocationID;\n"); if (g_ActiveConfig.bStereo) out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[eye * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); @@ -77,6 +83,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); + if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\t}\n"); out.Write("}\n"); if (is_writing_shadercode) diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 8f869dc100..5efdf17336 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -139,6 +139,7 @@ struct VideoConfig final bool bSupportsEarlyZ; // needed by PixelShaderGen, so must stay in VideoCommon bool bSupportsBindingLayout; // Needed by ShaderGen, so must stay in VideoCommon bool bSupportsBBox; + bool bSupportsGSInstancing; // Needed by GeometryShaderGen, so must stay in VideoCommon } backend_info; // Utility