mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 20:58:31 +09:00
The binding-point half of ARB_vertex_attrib_binding was implemented, but nothing
outside it could see the result. glGetIntegerv answered GL_MAX_VERTEX_ATTRIB_BINDINGS,
GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET and GL_MAX_VERTEX_ATTRIB_STRIDE with a hardcoded
0 and a comment saying the entry points were stubs, which they no longer are. An
application that sizes its loops off those limits therefore saw none, and every
"bindingindex must be less than MAX_VERTEX_ATTRIB_BINDINGS" check silently accepted
everything because the limit it validated against was not the one it reported.
The indexed getters answer GL_VERTEX_BINDING_{BUFFER,DIVISOR,OFFSET,STRIDE} from the
bound vertex array now, and the non-indexed getter reports them as indexed-only rather
than returning a fabricated 0.
glVertexAttribPointer is defined in terms of the binding model: it also points the
attribute at its own binding point and gives that point the buffer, the pointer as the
offset and the effective (never zero) stride. MobileGL resolved the pointer form
straight into the flat attribute view and left the binding point untouched, so
GL_VERTEX_BINDING_OFFSET read back 0 for every attribute set up the classic way. The
flat view keeps the raw stride, because GL_VERTEX_ATTRIB_ARRAY_STRIDE reports that
argument verbatim, so the binding point is recorded alongside it rather than resolved
from it. glVertexAttribDivisor likewise now moves the binding point's divisor.
The by-name entry points reject vertex array 0. MobileGL keeps a real object at index 0
for the compatibility paths, so the name validation used to let the default vertex array
through a direct-state-access call that has no such thing.
glVertexAttribFormat and friends validated with the pointer-only subset, which reports
GL_BGRA as an out-of-range size instead of applying the BGRA rules, and never saw
relativeoffset at all. They share the full format validation now, which also grew the
GL_UNSIGNED_INT_10F_11F_11F_REV rules - that type has no DataType of its own, so it has
to be recognised before the conversion turns it into Unknown and reports the wrong error.
glVertexAttribLFormat and glVertexArrayAttribLFormat were stubs. They validate their
arguments now and then report that 64-bit vertex attributes are unsupported, which is
honest; silently accepting a format that can never be used is not.
Takes direct_state_access.vertex_arrays_* from 12 to 17 of 19 on both backends.
49 lines
2.8 KiB
C++
49 lines
2.8 KiB
C++
// MobileGL - MobileGL/MG_Impl/GLImpl/VertexArray/Validators.h
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
#pragma once
|
|
#include <Includes.h>
|
|
#include <MG_State/GLState/VertexArrayState/VertexArrayObject.h>
|
|
|
|
namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl {
|
|
// The GL-visible GL_MAX_VERTEX_ATTRIBS: min(active backend limit, VertexArrayObject storage
|
|
// capacity). Falls back to the capacity when no backend is active (unit tests).
|
|
Uint GetMaxVertexAttribs();
|
|
|
|
// GL_MAX_VERTEX_ATTRIB_BINDINGS. The default attribute -> binding mapping is the identity, so a
|
|
// binding point that cannot also be an attribute index would resolve into an attribute the
|
|
// backend has to reject on every draw; real drivers report the two limits equal as well.
|
|
Uint GetMaxVertexAttribBindings();
|
|
|
|
// GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET. The relative offset is folded into the resolved
|
|
// attribute offset in the frontend and never reaches a backend limit, so this is the value the
|
|
// spec requires an implementation to support at minimum (GL 4.6 core table 23.63).
|
|
Uint GetMaxVertexAttribRelativeOffset();
|
|
|
|
// GL_MAX_VERTEX_ATTRIB_STRIDE. Like the relative offset above, the stride never reaches a
|
|
// backend limit of its own, so this is the spec minimum (GL 4.6 core table 23.63).
|
|
Uint GetMaxVertexAttribStride();
|
|
|
|
Bool ValidateVertexArrayName(Uint index);
|
|
Bool ValidateVertexArrayObject(Uint index);
|
|
Bool ValidateVertexAttributeIndex(Uint index);
|
|
Bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride);
|
|
// Full glVertexAttribPointer / glVertexAttribIPointer format validation, including the packed
|
|
// 2_10_10_10 types and GL_BGRA size. sizeRaw is the untranslated GL size (possibly GL_BGRA);
|
|
// integerPath selects the glVertexAttribIPointer rules.
|
|
Bool ValidateVertexAttribFormat(Uint index, GLint sizeRaw, GLenum glType, DataType type, Bool normalized,
|
|
Int stride, Bool integerPath);
|
|
// glVertexAttribLFormat / glVertexArrayAttribLFormat: the only accepted type is GL_DOUBLE and
|
|
// the size range is 1-4 (GL_BGRA is a float-path size). Separate from the function above
|
|
// because the long path shares none of its type or size rules.
|
|
Bool ValidateVertexAttribLFormat(Uint index, GLint size, GLenum type);
|
|
// Shared by every *Format entry point: INVALID_VALUE once relativeoffset leaves the range the
|
|
// implementation advertises.
|
|
Bool ValidateVertexAttribRelativeOffset(Uint relativeOffset);
|
|
} // namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl
|