mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 13:48:30 +09:00
[Fix] (Espryt): resolve an attribute's pushed vertex buffer by its attribute index, not by the GL binding point the wire attribute carries
This commit is contained in:
@@ -3594,22 +3594,34 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// view: it is resolved per binding point and rides in MGPVertexBuffer::Divisor, which
|
// view: it is resolved per binding point and rides in MGPVertexBuffer::Divisor, which
|
||||||
// is where glVertexAttribDivisor reads it (D-G2).
|
// is where glVertexAttribDivisor reads it (D-G2).
|
||||||
|
|
||||||
// The entry of the applied set that feeds this attribute. The client emits one entry
|
// The entry of the applied set that feeds ATTRIBUTE `attributeIndex`.
|
||||||
// per enabled attribute with BindingIndex == the attribute index, so the positional
|
//
|
||||||
// slot is the answer in every real record; the scan behind it is what keeps a record
|
// THE KEY IS THE ATTRIBUTE INDEX, NOT MGPVertexAttribWire::BindingIndex, and the two
|
||||||
// that numbers its entries differently correct rather than silently misfed.
|
// live in different spaces. Espryt consumes RESOLVED attributes, so the client emits
|
||||||
const MG_Pipe::MGPVertexBuffer* VertexBufferForBindingIndex(const MG_Pipe::MGPipeApplierState& st,
|
// set_vertex_buffers as one entry per attribute slot with
|
||||||
Uint32 bindingIndex) {
|
// MGPVertexBuffer::BindingIndex == the attribute index (VertexInputEmit.h:190-193,
|
||||||
|
// :229 - "Espryt consumes RESOLVED attributes, so the set is one entry per attribute
|
||||||
|
// slot with BindingIndex == the attribute index"), each carrying that attribute's
|
||||||
|
// already-folded buffer, stride and divisor. MGPVertexAttribWire::BindingIndex is the
|
||||||
|
// OTHER thing: the GL binding POINT the attribute was attached to by
|
||||||
|
// glVertexAttribBinding, which is the key of the binding-point view this arm never
|
||||||
|
// reads (it needs no separate view, because the resolution already happened on the
|
||||||
|
// client). The two coincide whenever the attribute was configured through
|
||||||
|
// glVertexAttribPointer, which is why every scenario that uses the pointer API stayed
|
||||||
|
// green while glVertexAttribBinding(2, 3) / (0, 5) fetched the wrong entry or none -
|
||||||
|
// KHR-GL43.vertex_attrib_binding's whole subject.
|
||||||
|
const MG_Pipe::MGPVertexBuffer* VertexBufferForAttributeIndex(const MG_Pipe::MGPipeApplierState& st,
|
||||||
|
Uint32 attributeIndex) {
|
||||||
if (st.VertexBufferCount == 0) return nullptr;
|
if (st.VertexBufferCount == 0) return nullptr;
|
||||||
const Uint32 begin = st.VertexBufferStart;
|
const Uint32 begin = st.VertexBufferStart;
|
||||||
const Uint32 end = begin + st.VertexBufferCount;
|
const Uint32 end = begin + st.VertexBufferCount;
|
||||||
if (bindingIndex >= begin && bindingIndex < end &&
|
if (attributeIndex >= begin && attributeIndex < end &&
|
||||||
bindingIndex < MG_Pipe::kMGPipeMaxVertexAttribs &&
|
attributeIndex < MG_Pipe::kMGPipeMaxVertexAttribs &&
|
||||||
st.VertexBuffers[bindingIndex].BindingIndex == bindingIndex) {
|
st.VertexBuffers[attributeIndex].BindingIndex == attributeIndex) {
|
||||||
return &st.VertexBuffers[bindingIndex];
|
return &st.VertexBuffers[attributeIndex];
|
||||||
}
|
}
|
||||||
for (Uint32 i = begin; i < end && i < MG_Pipe::kMGPipeMaxVertexAttribs; ++i) {
|
for (Uint32 i = begin; i < end && i < MG_Pipe::kMGPipeMaxVertexAttribs; ++i) {
|
||||||
if (st.VertexBuffers[i].BindingIndex == bindingIndex) return &st.VertexBuffers[i];
|
if (st.VertexBuffers[i].BindingIndex == attributeIndex) return &st.VertexBuffers[i];
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -4021,7 +4033,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
++attribIndex) {
|
++attribIndex) {
|
||||||
const MGPVertexAttribWire& attrib = rec->Attributes[attribIndex];
|
const MGPVertexAttribWire& attrib = rec->Attributes[attribIndex];
|
||||||
const MG_Pipe::MGPVertexBuffer* binding =
|
const MG_Pipe::MGPVertexBuffer* binding =
|
||||||
VertexBufferForBindingIndex(st, attrib.BindingIndex);
|
VertexBufferForAttributeIndex(st, attribIndex);
|
||||||
const Uint32 divisor = binding != nullptr ? binding->Divisor : 0u;
|
const Uint32 divisor = binding != nullptr ? binding->Divisor : 0u;
|
||||||
|
|
||||||
// The enable/disable block. On this arm there is no per-attribute version to
|
// The enable/disable block. On this arm there is no per-attribute version to
|
||||||
|
|||||||
Reference in New Issue
Block a user