[Fix] (MG_Impl): let an indexed buffer bind reach the generic binding point too

BindBufferBase and BindBufferRange bind the buffer to the indexed point AND to the
generic binding point of the same target (GL 4.6 core 6.1.1); only the indexed half
was implemented. Applications lean on the second half constantly, because it is what
makes the set-up idiom work:

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, size, nullptr, GL_DYNAMIC_DRAW);

With the generic point left at 0 the glBufferData raised GL_INVALID_OPERATION and
the buffer kept its zero size, so the later glMapBufferRange over it failed the
offset+length bound and returned nullptr. The whole KHR-GL40.texture_gather group
verifies its result through exactly that sequence and dereferences the map's return
value without checking it, so 51 of its 75 cases took the process down with a
SIGSEGV inside the test.

Unbinding propagates the same way: buffer 0 clears both points.
This commit is contained in:
BZLZHH
2026-08-04 09:40:28 -04:00
parent 3dc6a1b6db
commit 41e45f7d48
@@ -1366,6 +1366,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (buffer == 0) {
point.Bind(nullptr);
point.SetRange(Range1D(0, 0));
GetBufferBindingSlot(bufferTarget).Bind(nullptr);
return;
}
@@ -1384,6 +1385,12 @@ namespace MobileGL::MG_Impl::GLImpl {
} else {
point.ClearRange();
}
// The indexed bind also binds to the generic binding point of the same target
// (GL 4.6 core 6.1.1). Callers rely on it: the texture_gather tests set up their
// SSBO with BindBufferBase and then size it through glBufferData on the generic
// target alone, which would otherwise raise GL_INVALID_OPERATION and leave the
// buffer with no storage.
GetBufferBindingSlot(bufferTarget).Bind(bufferObject);
}
void BindBufferRange_State(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
@@ -1407,6 +1414,7 @@ namespace MobileGL::MG_Impl::GLImpl {
if (buffer == 0) {
point.Bind(nullptr);
point.SetRange(Range1D(0, 0));
GetBufferBindingSlot(bufferTarget).Bind(nullptr);
return;
}
@@ -1424,6 +1432,8 @@ namespace MobileGL::MG_Impl::GLImpl {
} else {
point.ClearRange();
}
// Also the generic binding point, exactly as BindBufferBase (GL 4.6 core 6.1.1).
GetBufferBindingSlot(bufferTarget).Bind(bufferObject);
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */