mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 04:38:30 +09:00
[Fix] (MG_State): let a double-typed varying be captured by transform feedback
ResolveXfbSymbolType accepted only float, int and uint, and its caller reports anything it rejects as "Transform feedback varying 'x' is not an output of the vertex stage" - which is a misleading thing to say about a varying that is right there in the shader, just declared `double`. Program linkage failed outright. Doubles are now resolved to the GL_DOUBLE* types, in vector and matrix form, and the per-element size is computed from an 8-byte component rather than a hardcoded 4 (GL 4.6 core 11.1.2.1), so the byte-based limit checks charge a double what GL says it costs. direct_state_access.vertex_arrays_attribute_format stops throwing on both backends and fails on the captured values instead: the capture layout still owes the 8-byte alignment doubles require, and neither backend feeds a 64-bit vertex attribute yet - DirectGLES cannot at all, ESSL having no double.
This commit is contained in:
@@ -195,27 +195,42 @@ namespace MobileGL::MG_State::GLState {
|
||||
static constexpr GLenum kIntTypes[5] = {0, GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4};
|
||||
static constexpr GLenum kUintTypes[5] = {0, GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
|
||||
GL_UNSIGNED_INT_VEC4};
|
||||
static constexpr GLenum kDoubleTypes[5] = {0, GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3,
|
||||
GL_DOUBLE_VEC4};
|
||||
if (type.isMatrix()) {
|
||||
if (basic != glslang::EbtFloat) return false;
|
||||
if (basic != glslang::EbtFloat && basic != glslang::EbtDouble) return false;
|
||||
static constexpr GLenum kMatTypes[5][5] = {
|
||||
{}, {},
|
||||
{0, 0, GL_FLOAT_MAT2, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4},
|
||||
{0, 0, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3, GL_FLOAT_MAT3x4},
|
||||
{0, 0, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_FLOAT_MAT4},
|
||||
};
|
||||
static constexpr GLenum kDoubleMatTypes[5][5] = {
|
||||
{}, {},
|
||||
{0, 0, GL_DOUBLE_MAT2, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4},
|
||||
{0, 0, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT3x4},
|
||||
{0, 0, GL_DOUBLE_MAT4x2, GL_DOUBLE_MAT4x3, GL_DOUBLE_MAT4},
|
||||
};
|
||||
if (columns < 2 || columns > 4 || components < 2 || components > 4) return false;
|
||||
outType = kMatTypes[columns][components];
|
||||
outType = basic == glslang::EbtDouble ? kDoubleMatTypes[columns][components]
|
||||
: kMatTypes[columns][components];
|
||||
} else if (components >= 1 && components <= 4) {
|
||||
switch (basic) {
|
||||
case glslang::EbtFloat: outType = kFloatTypes[components]; break;
|
||||
case glslang::EbtInt: outType = kIntTypes[components]; break;
|
||||
case glslang::EbtUint: outType = kUintTypes[components]; break;
|
||||
// A double-typed varying is capturable like any other; rejecting it here reported
|
||||
// the varying as "not an output of the vertex stage", which it plainly was.
|
||||
case glslang::EbtDouble: outType = kDoubleTypes[components]; break;
|
||||
default: return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
outBytesPerElement = static_cast<Uint32>(columns * components) * 4u;
|
||||
// GL 4.6 core 11.1.2.1: a double component occupies eight basic machine units, and
|
||||
// counts as two components against the transform feedback limits.
|
||||
const Uint32 bytesPerComponent = basic == glslang::EbtDouble ? 8u : 4u;
|
||||
outBytesPerElement = static_cast<Uint32>(columns * components) * bytesPerComponent;
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user