From 9768698eda36d36b8ca2d7a5ffc91d88d97a2863 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 28 Jul 2018 12:43:35 +0200 Subject: [PATCH] - do not use SSBOs for dynamic lights on Intel graphics hardware for performance reasons. This was already disabled for GL 4.4 and lower but also needs to be done for Intel's GL 4.5 drivers. Unlike before this is now exclusive to the light buffer, the shadowmap feature is not affected anymore, although that should be impossible to use anyway on all affected hardware due to lack of computing power. --- src/gl/dynlights/gl_lightbuffer.cpp | 6 ++++- src/gl/shaders/gl_shader.cpp | 2 +- src/gl_load/gl_interface.cpp | 38 +++++++++++++---------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index 041735d57..465189937 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -39,7 +39,10 @@ FLightBuffer::FLightBuffer() mBufferSize = INITIAL_BUFFER_SIZE; mByteSize = mBufferSize * sizeof(float); - if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + // Hack alert: On Intel's GL driver SSBO's perform quite worse than UBOs. + // We only want to disable using SSBOs for lights but not disable the feature entirely. + // Note that using an uniform buffer here will limit the number of lights per surface so it isn't done for NVidia and AMD. + if (gl.flags & RFL_SHADER_STORAGE_BUFFER && !strstr(gl.vendorstring, "Intel")) { mBufferType = GL_SHADER_STORAGE_BUFFER; mBlockAlign = 0; @@ -50,6 +53,7 @@ FLightBuffer::FLightBuffer() mBufferType = GL_UNIFORM_BUFFER; mBlockSize = gl.maxuniformblock / 16; if (mBlockSize > 2048) mBlockSize = 2048; // we don't really need a larger buffer + mBlockAlign = mBlockSize / 2; } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 5d4ffe4d2..5f3fae934 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -365,7 +365,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * clipheightdirection_index = glGetUniformLocation(hShader, "uClipHeightDirection"); clipline_index = glGetUniformLocation(hShader, "uClipLine"); - if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (lightbuffertype == GL_UNIFORM_BUFFER) { int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO"); if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT); diff --git a/src/gl_load/gl_interface.cpp b/src/gl_load/gl_interface.cpp index 801350f21..4859a54e0 100644 --- a/src/gl_load/gl_interface.cpp +++ b/src/gl_load/gl_interface.cpp @@ -178,7 +178,7 @@ void gl_LoadExtensions() gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows. (TBD: Relegate to vintage build? Maybe after the next survey.) } #endif - gl.glslversion = 3.31f; // Force GLSL down to 3.3. + gl.glslversion = 3.31f; // Force GLSL down to 3.3. } else if (gl_version < 4.5f) { @@ -189,16 +189,7 @@ void gl_LoadExtensions() // Recent drivers, GL 4.4 don't have this problem, these can easily be recognized by also supporting the GL_ARB_buffer_storage extension. if (CheckExtension("GL_ARB_shader_storage_buffer_object")) { - // Intel's GLSL compiler is a bit broken with extensions, so unlock the feature only if not on Intel or having GL 4.3. - if (strstr(gl.vendorstring, "Intel") == NULL || gl_version >= 4.3f) - { - // Mesa implements shader storage only for fragment shaders. - // Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects. - int v; - glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); - if (v > 0) - gl.flags |= RFL_SHADER_STORAGE_BUFFER; - } + gl.flags |= RFL_SHADER_STORAGE_BUFFER; } gl.flags |= RFL_BUFFER_STORAGE; gl.lightmethod = LM_DIRECT; @@ -213,6 +204,14 @@ void gl_LoadExtensions() gl.buffermethod = BM_PERSISTENT; } + // Mesa implements shader storage only for fragment shaders. + // Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects. + int v; + glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); + if (v == 0) + gl.flags &= ~RFL_SHADER_STORAGE_BUFFER; + + if (gl_version >= 4.3f || CheckExtension("GL_ARB_invalidate_subdata")) gl.flags |= RFL_INVALIDATE_BUFFER; if (gl_version >= 4.3f || CheckExtension("GL_KHR_debug")) gl.flags |= RFL_DEBUG; @@ -228,8 +227,6 @@ void gl_LoadExtensions() if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED; } - int v; - if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); @@ -279,14 +276,6 @@ void gl_PrintStartupLog() glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); - if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) - { - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); - Printf ("Max. uniform block size: %d\n", v); - glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); - Printf ("Uniform block alignment: %d\n", v); - } - if (gl.flags & RFL_SHADER_STORAGE_BUFFER) { glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &v); @@ -294,6 +283,13 @@ void gl_PrintStartupLog() glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); Printf("Max. vertex shader storage blocks: %d\n", v); } + else + { + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); + Printf("Max. uniform block size: %d\n", v); + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); + Printf("Uniform block alignment: %d\n", v); + } } std::pair gl_getInfo()