mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Fix] (MG_Util): glBindBufferBase must not freeze the buffer's size
BindBufferBase_State stored Range1D(0, bufferObject->GetSize()) as the binding
point's range, so the range reflected whatever size the buffer happened to have
at bind time. Binding an empty buffer and giving it storage afterwards is
ordinary application code - glGenBuffers / glBindBufferBase / glBufferData is
exactly the order KHR-GL3{0,2,3}.clip_distance.coverage uses - and the binding
then stayed frozen at [0, 0).
Every backend consumer reads GetRange() as the range the binding actually
covers, so the stale window meant the capture buffer was bound with
glBindBufferRange(..., 0, 0) instead of glBindBufferBase, transform feedback
captured nothing, and the test read back its pre-draw zeros. The same stale
range also under-counted the CPU-side transform feedback capacity accounting.
GL resolves a whole-buffer binding against the object's size at every use;
only glBindBufferRange pins a fixed window, and the binding point already
tracked which of the two it was for the glGetIntegeri_v START/SIZE queries.
GetRange() now resolves the non-explicit case dynamically.
Fixes KHR-GL3{0,2,3}.clip_distance.coverage on Espryt; transform_feedback stays
21/21 on all four versions, and DirectVulkan (lavapipe) re-verified unaffected.
This commit is contained in:
@@ -181,7 +181,19 @@ namespace MobileGL {
|
||||
explicit BindingSlotRange1D(TargetEnum target, const Range1D& range = Range1D())
|
||||
: BindingSlot<ObjectType>(target), m_range(range) {}
|
||||
|
||||
Range1D GetRange() const { return m_range; }
|
||||
// The range the binding actually covers right now. A whole-buffer binding
|
||||
// (glBindBufferBase) does not freeze anything: GL resolves it against the
|
||||
// object's size at every use, so a glBufferData issued after the bind has to
|
||||
// be visible here - binding an empty buffer and giving it storage afterwards
|
||||
// is ordinary application code. Only glBindBufferRange pins a fixed window.
|
||||
Range1D GetRange() const {
|
||||
if (!m_hasExplicitRange) {
|
||||
if (const auto& object = this->GetBoundObject()) {
|
||||
return Range1D(0, object->GetSize());
|
||||
}
|
||||
}
|
||||
return m_range;
|
||||
}
|
||||
|
||||
Bool HasExplicitRange() const { return m_hasExplicitRange; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user