[Feat] (MG_State/MG_Impl): ARB_vertex_attrib_binding + ARB_multi_bind state model

Add a separate binding-point model to VertexArrayObject with eager
resolution into the flat per-attribute view backends already consume.
Implements glBindVertexBuffer(s), glVertexAttrib(I)Format,
glVertexAttribBinding, glVertexBindingDivisor and the DSA variants
(glVertexArrayAttribBinding, glVertexArrayBindingDivisor,
glVertexArrayVertexBuffers), fixing glVertexArrayVertexBuffer which
previously conflated binding index with attribute index. Multi-bind
(glBindBuffersBase/Range) loops over the single-bind entry points.

Needed by Flywheel's indirect backend (GlVertexArrayDSA setup path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 13:32:40 +00:00
co-authored by Claude Fable 5
parent f355080b6f
commit 9fbb708e64
7 changed files with 303 additions and 37 deletions
@@ -1444,4 +1444,23 @@ namespace MobileGL::MG_Impl::GLImpl {
void BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
BindBufferRange_State(target, index, buffer, offset, size);
}
// ARB_multi_bind: defined by the spec as equivalent to a loop over the single-bind entry
// points (with buffer 0 resetting the binding point).
void BindBuffersBase(GLenum target, GLuint first, GLsizei count, const GLuint* buffers) {
for (GLsizei i = 0; i < count; ++i) {
BindBufferBase_State(target, first + i, buffers ? buffers[i] : 0);
}
}
void BindBuffersRange(GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets,
const GLsizeiptr* sizes) {
for (GLsizei i = 0; i < count; ++i) {
if (!buffers || buffers[i] == 0) {
BindBufferBase_State(target, first + i, 0);
} else {
BindBufferRange_State(target, first + i, buffers[i], offsets ? offsets[i] : 0, sizes ? sizes[i] : 0);
}
}
}
} // namespace MobileGL::MG_Impl::GLImpl