Files
MobileGL/MobileGL/MG_State/GLState/VertexArrayState
BZLZHH 34f09291da [Feat] (MG_State, MG_Backend, MG_Util): feed a 64-bit vertex attribute on DirectVulkan
glVertexAttribLFormat validated its arguments and then refused unconditionally
with "64-bit vertex attributes are not supported", so
direct_state_access.vertex_arrays_attribute_format failed every GL_DOUBLE
subcase on both backends - the format never landed, the draw fetched whatever
the attribute held before, and the captured values came back as reinterpreted
garbage.

The attribute is now real state. IsLong is its own bit rather than being
inferred from Float64, because glVertexAttribFormat(GL_DOUBLE) also reads
doubles - it just asks for them converted to float - so the type alone cannot
tell the two apart. It participates in the format comparison, so an L-format
call over a plain one still bumps the version, and glVertexAttribPointer clears
it inside the mutation block so the clear and the bump stay atomic.
GL_VERTEX_ATTRIB_ARRAY_LONG stops being hardcoded false, and the pname is now
accepted by the attribute queries at all.

Support is detected, never assumed. SupportsFloat64VertexAttributes comes from
VkPhysicalDeviceFeatures::shaderFloat64 on DirectVulkan and is false on
DirectGLES - not a driver question there and never will be, since ES has no
GL_DOUBLE vertex format and ESSL has no fp64 type to consume one with. A backend
without it declines in the entry point, with the GL error and a log line naming
the reason, rather than accepting state no draw could honour. Both cases get a
DriverPost row so the loss is named at startup instead of at draw setup.

On DirectVulkan the attribute deliberately does not use VK_FORMAT_R64*_SFLOAT:
those are optional and lavapipe advertises zero features for all four of them.
It is fetched as its 32-bit word pair (R32G32_UINT / R32G32B32A32_UINT) and
bitcast back to double in the shader by a new SPIR-V pass, which is bit-exact
and needs no format capability at all. The pass re-declares the input as uvec2 /
uvec4, demotes the original variable to a Private global and seeds it once at
the top of the entry point, so every existing load keeps its id and its double
type and no other instruction is rewritten. Both halves branch on nothing but
"is this attribute long", so they cannot disagree - and if the pass ever fails,
the assertion fires rather than letting a UINT format sit under a double input.
The pointer types are all created before any variable that names them and the
demoted variable is moved after them, since the types-and-variables section may
not forward-reference a type.

dvec3/dvec4 are declined rather than fetched wrong: six or eight uint32
components have no single VkFormat, and GL spreads such an input over two
attribute locations, which the location-per-index model here does not express.

Fixes vertex_arrays_attribute_format on Magma (369/371). On Espryt it stays
failing, now as a detected and explained decline rather than a blanket refusal.
2026-08-05 08:49:23 -04:00
..