glgsg: detect and fix overlapping SSBO bindings

Fixes #1176
This commit is contained in:
rdb 2021-08-05 09:36:51 +02:00
parent 4a33e8866e
commit 20e081482f
3 changed files with 19 additions and 0 deletions

View File

@ -2134,6 +2134,8 @@ reset() {
get_extension_func("glGetProgramResourceName"); get_extension_func("glGetProgramResourceName");
_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) _glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)
get_extension_func("glGetProgramResourceiv"); get_extension_func("glGetProgramResourceiv");
_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)
get_extension_func("glShaderStorageBlockBinding");
} else } else
#endif #endif
{ {

View File

@ -1068,6 +1068,7 @@ public:
PFNGLGETPROGRAMINTERFACEIVPROC _glGetProgramInterfaceiv; PFNGLGETPROGRAMINTERFACEIVPROC _glGetProgramInterfaceiv;
PFNGLGETPROGRAMRESOURCENAMEPROC _glGetProgramResourceName; PFNGLGETPROGRAMRESOURCENAMEPROC _glGetProgramResourceName;
PFNGLGETPROGRAMRESOURCEIVPROC _glGetProgramResourceiv; PFNGLGETPROGRAMRESOURCEIVPROC _glGetProgramResourceiv;
PFNGLSHADERSTORAGEBLOCKBINDINGPROC _glShaderStorageBlockBinding;
#endif // !OPENGLES #endif // !OPENGLES
GLenum _edge_clamp; GLenum _edge_clamp;

View File

@ -341,6 +341,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
block_maxlength = max(64, block_maxlength); block_maxlength = max(64, block_maxlength);
char *block_name_cstr = (char *)alloca(block_maxlength); char *block_name_cstr = (char *)alloca(block_maxlength);
BitArray bindings;
for (int i = 0; i < block_count; ++i) { for (int i = 0; i < block_count; ++i) {
block_name_cstr[0] = 0; block_name_cstr[0] = 0;
_glgsg->_glGetProgramResourceName(_glsl_program, GL_SHADER_STORAGE_BLOCK, i, block_maxlength, nullptr, block_name_cstr); _glgsg->_glGetProgramResourceName(_glsl_program, GL_SHADER_STORAGE_BLOCK, i, block_maxlength, nullptr, block_name_cstr);
@ -349,6 +351,20 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
GLint values[2]; GLint values[2];
_glgsg->_glGetProgramResourceiv(_glsl_program, GL_SHADER_STORAGE_BLOCK, i, 2, props, 2, nullptr, values); _glgsg->_glGetProgramResourceiv(_glsl_program, GL_SHADER_STORAGE_BLOCK, i, 2, props, 2, nullptr, values);
if (bindings.get_bit(values[0])) {
// Binding index already in use, assign a different one.
values[0] = bindings.get_lowest_off_bit();
_glgsg->_glShaderStorageBlockBinding(_glsl_program, i, values[0]);
}
bindings.set_bit(values[0]);
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Active shader storage block " << block_name_cstr
<< " with size " << values[1] << " is bound to binding "
<< values[0] << "\n";
}
StorageBlock block; StorageBlock block;
block._name = InternalName::make(block_name_cstr); block._name = InternalName::make(block_name_cstr);
block._binding_index = values[0]; block._binding_index = values[0];