mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 13:48:30 +09:00
[Feat] (Program): report the geometry and tessellation link properties glGetProgramiv had no source for
This commit is contained in:
@@ -670,9 +670,14 @@ namespace MobileGL::MG_State::GLState {
|
||||
return;
|
||||
}
|
||||
|
||||
// GL_GEOMETRY_INPUT_TYPE. A draw's primitive type has to be compatible with it
|
||||
// (GL 4.6 core 11.3.1), so it is resolved for every link, not only a capturing one.
|
||||
// The geometry stage's link properties. GL_GEOMETRY_INPUT_TYPE is load-bearing beyond the
|
||||
// query surface - a draw's primitive type has to be compatible with it (GL 4.6 core
|
||||
// 11.3.1) - so this block runs for every link, not only a capturing one. The other three
|
||||
// are pure glGetProgramiv answers that previously had no source at all.
|
||||
artifacts.gsInputPrimitive = GL_NONE;
|
||||
artifacts.gsOutputPrimitive = GL_NONE;
|
||||
artifacts.gsMaxVertices = 0;
|
||||
artifacts.gsInvocations = 0;
|
||||
if (const glslang::TIntermediate* gs = artifacts.program->getIntermediate(EShLangGeometry)) {
|
||||
switch (gs->getInputPrimitive()) {
|
||||
case glslang::ElgPoints: artifacts.gsInputPrimitive = GL_POINTS; break;
|
||||
@@ -682,6 +687,45 @@ namespace MobileGL::MG_State::GLState {
|
||||
case glslang::ElgTrianglesAdjacency: artifacts.gsInputPrimitive = GL_TRIANGLES_ADJACENCY; break;
|
||||
default: break;
|
||||
}
|
||||
switch (gs->getOutputPrimitive()) {
|
||||
case glslang::ElgPoints: artifacts.gsOutputPrimitive = GL_POINTS; break;
|
||||
case glslang::ElgLineStrip: artifacts.gsOutputPrimitive = GL_LINE_STRIP; break;
|
||||
case glslang::ElgTriangleStrip: artifacts.gsOutputPrimitive = GL_TRIANGLE_STRIP; break;
|
||||
default: break;
|
||||
}
|
||||
// glslang leaves both at TQualifier::layoutNotSet (-1) when the shader declared no
|
||||
// such layout, and `invocations` defaults to one per GLSL 4.60 4.4.2.2 - so clamp
|
||||
// rather than forward, or GL_GEOMETRY_SHADER_INVOCATIONS reports the sentinel.
|
||||
artifacts.gsMaxVertices = std::max(gs->getVertices(), 0);
|
||||
artifacts.gsInvocations = std::max(gs->getInvocations(), 1);
|
||||
}
|
||||
|
||||
// The tessellation evaluation stage's link properties, GL 4.6 core table 23.35: the
|
||||
// primitive generator's mode, spacing, winding and point mode. (The control stage's
|
||||
// output patch size is captured below, together with the limit check that goes with it.)
|
||||
artifacts.tessGenMode = GL_NONE;
|
||||
artifacts.tessGenSpacing = GL_NONE;
|
||||
artifacts.tessGenVertexOrder = GL_NONE;
|
||||
artifacts.tessGenPointMode = false;
|
||||
if (const glslang::TIntermediate* tes = artifacts.program->getIntermediate(EShLangTessEvaluation)) {
|
||||
switch (tes->getInputPrimitive()) {
|
||||
case glslang::ElgTriangles: artifacts.tessGenMode = GL_TRIANGLES; break;
|
||||
case glslang::ElgQuads: artifacts.tessGenMode = GL_QUADS; break;
|
||||
case glslang::ElgIsolines: artifacts.tessGenMode = GL_ISOLINES; break;
|
||||
default: break;
|
||||
}
|
||||
// GLSL 4.60 4.4.2.3: equal_spacing and ccw are the defaults, which is what an unset
|
||||
// qualifier means here.
|
||||
switch (tes->getVertexSpacing()) {
|
||||
case glslang::EvsFractionalEven: artifacts.tessGenSpacing = GL_FRACTIONAL_EVEN; break;
|
||||
case glslang::EvsFractionalOdd: artifacts.tessGenSpacing = GL_FRACTIONAL_ODD; break;
|
||||
default: artifacts.tessGenSpacing = GL_EQUAL; break;
|
||||
}
|
||||
switch (tes->getVertexOrder()) {
|
||||
case glslang::EvoCw: artifacts.tessGenVertexOrder = GL_CW; break;
|
||||
default: artifacts.tessGenVertexOrder = GL_CCW; break;
|
||||
}
|
||||
artifacts.tessGenPointMode = tes->getPointMode();
|
||||
}
|
||||
|
||||
// GL_TESS_CONTROL_OUTPUT_VERTICES, i.e. the `layout(vertices = N) out` the control stage
|
||||
|
||||
@@ -1356,6 +1356,23 @@ namespace MobileGL::MG_State::GLState {
|
||||
// tessellation control stage, or 0 when the program has none. Checked against
|
||||
// GL_MAX_PATCH_VERTICES at link (GL 4.6 core 11.2.1.1).
|
||||
Int tcsOutputVertices = 0;
|
||||
// The rest of the geometry stage's link properties, and the tessellation evaluation
|
||||
// stage's. Every one of these is a glGetProgramiv answer that had no source at all:
|
||||
// the query surface listed the geometry pnames only to fall through to
|
||||
// GL_INVALID_ENUM, and the GL_TESS_GEN_* pnames were not mentioned anywhere. They
|
||||
// come from the linked intermediates for the same reason gsInputPrimitive and
|
||||
// tcsOutputVertices do - glslang has already merged the compilation units' layout
|
||||
// qualifiers and diagnosed contradictions, so the linked program is the thing that
|
||||
// knows.
|
||||
GLenum gsOutputPrimitive = GL_NONE;
|
||||
Int gsMaxVertices = 0;
|
||||
Int gsInvocations = 0;
|
||||
// The tessellation evaluation stage's layout: GL_QUADS / GL_TRIANGLES / GL_ISOLINES,
|
||||
// GL_EQUAL / GL_FRACTIONAL_EVEN / GL_FRACTIONAL_ODD, GL_CW / GL_CCW, and point mode.
|
||||
GLenum tessGenMode = GL_NONE;
|
||||
GLenum tessGenSpacing = GL_NONE;
|
||||
GLenum tessGenVertexOrder = GL_NONE;
|
||||
Bool tessGenPointMode = false;
|
||||
GLenum xfbBufferMode = GL_INTERLEAVED_ATTRIBS;
|
||||
Int xfbVaryingNameMaxLength = 0;
|
||||
Bool xfbNeedsScatteredCapture = false;
|
||||
@@ -1545,10 +1562,22 @@ namespace MobileGL::MG_State::GLState {
|
||||
// GL_LINES_ADJACENCY, GL_TRIANGLES or GL_TRIANGLES_ADJACENCY), or GL_NONE when the
|
||||
// program has no geometry stage. Draws must present a compatible primitive type.
|
||||
GLenum GetGeometryInputType() const { return Artifacts().gsInputPrimitive; }
|
||||
// GL_GEOMETRY_OUTPUT_TYPE (GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP),
|
||||
// GL_GEOMETRY_VERTICES_OUT and GL_GEOMETRY_SHADER_INVOCATIONS of the linked geometry
|
||||
// stage. Meaningless without one - glGetProgramiv raises INVALID_OPERATION there.
|
||||
GLenum GetGeometryOutputType() const { return Artifacts().gsOutputPrimitive; }
|
||||
Int GetGeometryVerticesOut() const { return Artifacts().gsMaxVertices; }
|
||||
Int GetGeometryShaderInvocations() const { return Artifacts().gsInvocations; }
|
||||
// GL_TESS_CONTROL_OUTPUT_VERTICES of the linked tessellation control stage, or 0 when
|
||||
// the program has no such stage. Never greater than GL_MAX_PATCH_VERTICES: a program
|
||||
// that declared more does not link at all (GL 4.6 core 11.2.1.1).
|
||||
Int GetTessControlOutputVertices() const { return Artifacts().tcsOutputVertices; }
|
||||
// GL_TESS_GEN_MODE / _SPACING / _VERTEX_ORDER / _POINT_MODE of the linked tessellation
|
||||
// evaluation stage.
|
||||
GLenum GetTessGenMode() const { return Artifacts().tessGenMode; }
|
||||
GLenum GetTessGenSpacing() const { return Artifacts().tessGenSpacing; }
|
||||
GLenum GetTessGenVertexOrder() const { return Artifacts().tessGenVertexOrder; }
|
||||
Bool GetTessGenPointMode() const { return Artifacts().tessGenPointMode; }
|
||||
|
||||
Uint GetExternalIndex() const { return m_externalIndex; }
|
||||
// Globally-unique, never-reused id for this program object's lifetime. Unlike the GL
|
||||
|
||||
Reference in New Issue
Block a user