From fea8e615f9fa68471687f3e61945879507b2d44f Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Thu, 2 Jul 2026 13:44:11 +0800 Subject: [PATCH] [Fix] (MG_Impl/GLImpl): fix indexed shader storage buffer queries [skip ci] --- MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp | 2 +- MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp | 30 ++++++++++++++++++-- MobileGL/MG_Util/Types.h | 13 +++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp index c1dc9849..c728bcc6 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp @@ -1285,7 +1285,7 @@ namespace MobileGL::MG_Impl::GLImpl { point.Bind(bufferObject); if (bufferObject) { - point.SetRange(Range1D(0, bufferObject->GetSize())); + point.SetRange(Range1D(0, bufferObject->GetSize()), false); MGLOG_D("%s: set range (0, %d)", __func__, bufferObject->GetSize()); } else { point.ClearRange(); diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 1b36058b..c0ce3733 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -143,6 +143,16 @@ namespace MobileGL::MG_Impl::GLImpl { return queryKind == IndexedBufferQueryKind::Start || queryKind == IndexedBufferQueryKind::Size; } + SizeT GetIndexedBufferQueryPointCount(BufferTarget bufferTarget) { + const SizeT frontendCount = MG_State::pGLContext->GetBufferBindingPointCount(bufferTarget); + if (bufferTarget == BufferTarget::ShaderStorage && MG_Backend::pActiveBackendObject) { + const Int backendCount = + MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxShaderStorageBufferBindings; + return std::min(frontendCount, static_cast(std::max(backendCount, 0))); + } + return frontendCount; + } + bool TryDecodeDrawBufferQuery(GLenum pname, SizeT& drawBufferIndex) { if (pname == GL_DRAW_BUFFER) { drawBufferIndex = 0; @@ -223,7 +233,7 @@ namespace MobileGL::MG_Impl::GLImpl { return false; } - if (index >= MG_State::pGLContext->GetBufferBindingPointCount(bufferTarget)) { + if (index >= GetIndexedBufferQueryPointCount(bufferTarget)) { MG_State::pGLContext->RecordError( ErrorCode::InvalidValue, MakeUnique( @@ -589,9 +599,17 @@ namespace MobileGL::MG_Impl::GLImpl { *data = static_cast(bufferObject->GetExternalIndex()); return; case IndexedBufferQueryKind::Start: + if (!bindingPoint.HasExplicitRange()) { + *data = 0; + return; + } *data = static_cast(bindingPoint.GetRange().start); return; case IndexedBufferQueryKind::Size: { + if (!bindingPoint.HasExplicitRange()) { + *data = 0; + return; + } const Range1D range = bindingPoint.GetRange(); const auto start = std::min(range.start, bufferObject->GetSize()); const auto end = std::min(range.end, bufferObject->GetSize()); @@ -639,9 +657,17 @@ namespace MobileGL::MG_Impl::GLImpl { *data = static_cast(bufferObject->GetExternalIndex()); return; case IndexedBufferQueryKind::Start: + if (!bindingPoint.HasExplicitRange()) { + *data = 0; + return; + } *data = static_cast(range.start); return; case IndexedBufferQueryKind::Size: { + if (!bindingPoint.HasExplicitRange()) { + *data = 0; + return; + } const auto start = std::min(range.start, bufferObject->GetSize()); const auto end = std::min(range.end, bufferObject->GetSize()); *data = static_cast(end - start); @@ -1669,7 +1695,7 @@ namespace MobileGL::MG_Impl::GLImpl { *params = dynamicParameters.MaxSampleMaskWords; break; case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: - *params = dynamicParameters.MaxShaderStorageBufferBindings; + *params = static_cast(GetIndexedBufferQueryPointCount(BufferTarget::ShaderStorage)); break; case GL_MAX_TEXTURE_BUFFER_SIZE: *params = dynamicParameters.MaxTextureBufferSize; diff --git a/MobileGL/MG_Util/Types.h b/MobileGL/MG_Util/Types.h index 54b5529d..040dfe14 100644 --- a/MobileGL/MG_Util/Types.h +++ b/MobileGL/MG_Util/Types.h @@ -179,12 +179,21 @@ namespace MobileGL { Range1D GetRange() const { return m_range; } - void SetRange(const Range1D& range) { m_range = range; } + Bool HasExplicitRange() const { return m_hasExplicitRange; } - void ClearRange() { m_range = Range1D(); } + void SetRange(const Range1D& range, Bool hasExplicitRange = true) { + m_range = range; + m_hasExplicitRange = hasExplicitRange; + } + + void ClearRange() { + m_range = Range1D(); + m_hasExplicitRange = false; + } private: Range1D m_range; + Bool m_hasExplicitRange = false; }; struct ComponentSizes {