Tessellation partial implementation (not ready for use yet), including:

- the built-in constants
 - built-in variable declarations, some dependent on gl_MaxPatchVertices
 - layout qualifier for vertices (shared with geometry shader max_vertices)
 - layout qualifiers for vertex spacing, vertex order, point mode, and primitive type
 - link semantics for layout qualifiers

Still TBD:
 - patch qualifier and arrayed input handling
 - sizing of gl_out[]
 - additional semantic checking
 - supporting the extension on version 150

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24468 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-12-11 18:57:40 +00:00
parent 2fcc9ff1d2
commit 623833fabc
28 changed files with 831 additions and 342 deletions

View file

@ -221,6 +221,19 @@ enum TLayoutGeometry {
ElgIsolines,
};
enum TVertexSpacing {
EvsNone,
EvsEqual,
EvsFractionalEven,
EvsFractionalOdd
};
enum TVertexOrder {
EvoNone,
EvoCw,
EvoCcw
};
class TQualifier {
public:
void clear()
@ -232,7 +245,7 @@ public:
smooth = false;
flat = false;
nopersp = false;
patch = false;
patch = false; // TODO 4.0 tessellation: implement semantics of patch (all of 4.3 stuff...), including arrayed inputs
sample = false;
shared = false;
coherent = false;
@ -405,6 +418,23 @@ public:
default: return "none";
}
}
static const char* getVertexSpacingString(TVertexSpacing spacing)
{
switch (spacing) {
case EvsEqual: return "equal_spacing";
case EvsFractionalEven: return "fractional_even_spacing";
case EvsFractionalOdd: return "fractional_odd_spacing";
default: return "none";
}
}
static const char* getVertexOrderString(TVertexOrder order)
{
switch (order) {
case EvoCw: return "cw";
case EvoCcw: return "ccw";
default: return "none";
}
}
static int mapGeometryToSize(TLayoutGeometry geometry)
{
switch (geometry) {
@ -421,11 +451,14 @@ public:
// Qualifiers that don't need to be keep per object. They have shader scope, not object scope.
// So, they will not be part of TType, TQualifier, etc.
struct TShaderQualifiers {
TLayoutGeometry geometry; // geometry shader in/out primitives
TLayoutGeometry geometry; // geometry/tessellation shader in/out primitives
bool pixelCenterInteger; // fragment shader
bool originUpperLeft; // fragment shader
int invocations; // 0 means no declaration
int maxVertices;
int vertices; // both for tessellation "vertices" and geometry "max_vertices"
TVertexSpacing spacing;
TVertexOrder order;
bool pointMode;
void init()
{
@ -433,7 +466,10 @@ struct TShaderQualifiers {
originUpperLeft = false;
pixelCenterInteger = false;
invocations = 0; // 0 means no declaration
maxVertices = 0;
vertices = 0;
spacing = EvsNone;
order = EvoNone;
pointMode = false;
}
};

View file

@ -9,5 +9,5 @@
// source have to figure out how to create revision.h just to get a build
// going. However, if it is not updated, it can be a version behind.
#define GLSLANG_REVISION "24406"
#define GLSLANG_DATE "2013/12/08 17:37:46"
#define GLSLANG_REVISION "24420"
#define GLSLANG_DATE "2013/12/09 17:25:14"

View file

@ -1256,30 +1256,10 @@ void TBuiltIns::initialize(int version, EProfile profile)
//============================================================================
if (version >= 400) {
// TODO: 4.0 tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
stageBuiltins[EShLangTessControl].append(
"const int gl_MaxPatchVertices = 32;"
);
// Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below,
// as it depends on the resource sizing of gl_MaxPatchVertices.
stageBuiltins[EShLangTessControl].append(
"in gl_PerVertex {"
"vec4 gl_Position;"
"float gl_PointSize;"
"float gl_ClipDistance[];"
);
if (profile == ECompatibilityProfile)
stageBuiltins[EShLangTessControl].append(
"vec4 gl_ClipVertex;"
"vec4 gl_FrontColor;"
"vec4 gl_BackColor;"
"vec4 gl_FrontSecondaryColor;"
"vec4 gl_BackSecondaryColor;"
"vec4 gl_TexCoord[];"
"float gl_FogFragCoord;"
);
stageBuiltins[EShLangTessControl].append(
"} gl_in[gl_MaxPatchVertices];"
"in int gl_PatchVerticesIn;"
"in int gl_PrimitiveID;"
"in int gl_InvocationID;"
@ -1305,6 +1285,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
"patch out float gl_TessLevelOuter[4];"
"patch out float gl_TessLevelInner[2];"
"\n");
// TODO 4.0 tessellation: do we also need to support the gl_VerticesOut mentioned in the extension specification?
}
//============================================================================
@ -1314,30 +1296,10 @@ void TBuiltIns::initialize(int version, EProfile profile)
//============================================================================
if (version >= 400) {
// TODO: 4.0 tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
stageBuiltins[EShLangTessEvaluation].append(
"const int gl_MaxPatchVertices = 32;"
);
// Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below,
// as it depends on the resource sizing of gl_MaxPatchVertices.
stageBuiltins[EShLangTessEvaluation].append(
"in gl_PerVertex {"
"vec4 gl_Position;"
"float gl_PointSize;"
"float gl_ClipDistance[];"
);
if (version >= 400 && profile == ECompatibilityProfile)
stageBuiltins[EShLangTessEvaluation].append(
"vec4 gl_ClipVertex;"
"vec4 gl_FrontColor;"
"vec4 gl_BackColor;"
"vec4 gl_FrontSecondaryColor;"
"vec4 gl_BackSecondaryColor;"
"vec4 gl_TexCoord[];"
"float gl_FogFragCoord;"
);
stageBuiltins[EShLangTessEvaluation].append(
"} gl_in[gl_MaxPatchVertices];"
"in int gl_PatchVerticesIn;"
"in int gl_PrimitiveID;"
"in vec3 gl_TessCoord;"
@ -1858,266 +1820,302 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int vers
//
// Add context-dependent built-in functions and variables that are present
// for the given version and profile. Share common ones across stages, otherwise
// make stage-specific entries.
// for the given version and profile. All the results are put into just the
// commonBuiltins, because it is called for just a specific stage. So,
// add stage-specific entries to the commonBuiltins, and only if that stage
// was requested.
//
void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, EShLanguage language)
{
//
// Initialize the context-dependent (resource-dependent) built-in strings for parsing.
//
{
//============================================================================
//
// Standard Uniforms
//
//============================================================================
TString& s = commonBuiltins;
const int maxSize = 80;
char builtInConstant[maxSize];
//============================================================================
//
// Standard Uniforms
//
//============================================================================
//
// Build string of implementation dependent constants.
//
TString& s = commonBuiltins;
const int maxSize = 80;
char builtInConstant[maxSize];
if (profile == EEsProfile) {
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
//
// Build string of implementation dependent constants.
//
if (profile == EEsProfile) {
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexUniformVectors = %d;", resources.maxVertexUniformVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers);
s.append(builtInConstant);
if (version == 100) {
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexUniformVectors = %d;", resources.maxVertexUniformVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers);
s.append(builtInConstant);
if (version == 100) {
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors);
s.append(builtInConstant);
} else {
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexOutputVectors = %d;", resources.maxVertexOutputVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentInputVectors = %d;", resources.maxFragmentInputVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxProgramTexelOffset = %d;", resources.maxProgramTexelOffset);
s.append(builtInConstant);
}
} else {
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexOutputVectors = %d;", resources.maxVertexOutputVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentInputVectors = %d;", resources.maxFragmentInputVectors);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits);
snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits);
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxProgramTexelOffset = %d;", resources.maxProgramTexelOffset);
s.append(builtInConstant);
}
} else {
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxLights = %d;", resources.maxLights);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxClipPlanes = %d;", resources.maxClipPlanes);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTextureUnits = %d;", resources.maxTextureUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTextureCoords = %d;", resources.maxTextureCoords);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformComponents = %d;", resources.maxFragmentUniformComponents);
s.append(builtInConstant);
if (IncludeLegacy(version, profile)) {
//
// OpenGL'uniform' state. Page numbers are in reference to version
// 1.4 of the OpenGL specification.
//
//
// Matrix state. p. 31, 32, 37, 39, 40.
//
s.append("uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];"
//
// Derived matrix state that provides inverse and transposed versions
// of the matrices above.
//
"uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];"
"uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];"
"uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];"
//
// Clip planes p. 42.
//
"uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];"
//
// Light State p 50, 53, 55.
//
"uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];"
//
// Derived state from products of light.
//
"uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];"
"uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];"
//
// Texture Environment and Generation, p. 152, p. 40-42.
//
"uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];"
"uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];"
"uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];"
"uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];"
"uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];");
}
if (version >= 130) {
snprintf(builtInConstant, maxSize, "const int gl_MaxClipDistances = %d;", resources.maxClipDistances);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingComponents = %d;", resources.maxVaryingComponents);
s.append(builtInConstant);
}
// geometry
if (version >= 150) {
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryInputComponents = %d;", resources.maxGeometryInputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputComponents = %d;", resources.maxGeometryOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputVertices = %d;", resources.maxGeometryOutputVertices);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTotalOutputComponents = %d;", resources.maxGeometryTotalOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryUniformComponents = %d;", resources.maxGeometryUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryVaryingComponents = %d;", resources.maxGeometryVaryingComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers);
}
if (version >= 150) {
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexOutputComponents = %d;", resources.maxVertexOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentInputComponents = %d;", resources.maxFragmentInputComponents);
s.append(builtInConstant);
}
// tessellation
if (version >= 400) {
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlInputComponents = %d;", resources.maxTessControlInputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlOutputComponents = %d;", resources.maxTessControlOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTextureImageUnits = %d;", resources.maxTessControlTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlUniformComponents = %d;", resources.maxTessControlUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationTextureImageUnits = %d;", resources.maxTessEvaluationTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.maxTessGenLevel);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxPatchVertices = %d;", resources.maxPatchVertices);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxLights = %d;", resources.maxLights);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxClipPlanes = %d;", resources.maxClipPlanes);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTextureUnits = %d;", resources.maxTextureUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxTextureCoords = %d;", resources.maxTextureCoords);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformComponents = %d;", resources.maxFragmentUniformComponents);
s.append(builtInConstant);
if (IncludeLegacy(version, profile)) {
//
// OpenGL'uniform' state. Page numbers are in reference to version
// 1.4 of the OpenGL specification.
//
//
// Matrix state. p. 31, 32, 37, 39, 40.
//
s.append("uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];"
//
// Derived matrix state that provides inverse and transposed versions
// of the matrices above.
//
"uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];"
"uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];"
"uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];"
//
// Clip planes p. 42.
//
"uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];"
//
// Light State p 50, 53, 55.
//
"uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];"
//
// Derived state from products of light.
//
"uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];"
"uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];"
//
// Texture Environment and Generation, p. 152, p. 40-42.
//
"uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];"
"uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];"
"uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];"
"uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];"
"uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];"
"uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];");
}
if (version >= 130) {
snprintf(builtInConstant, maxSize, "const int gl_MaxClipDistances = %d;", resources.maxClipDistances);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingComponents = %d;", resources.maxVaryingComponents);
s.append(builtInConstant);
}
// geometry
if (version >= 150) {
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryInputComponents = %d;", resources.maxGeometryInputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputComponents = %d;", resources.maxGeometryOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputVertices = %d;", resources.maxGeometryOutputVertices);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTotalOutputComponents = %d;", resources.maxGeometryTotalOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryUniformComponents = %d;", resources.maxGeometryUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryVaryingComponents = %d;", resources.maxGeometryVaryingComponents);
s.append(builtInConstant);
}
if (version >= 150) {
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexOutputComponents = %d;", resources.maxVertexOutputComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentInputComponents = %d;", resources.maxFragmentInputComponents);
s.append(builtInConstant);
}
// tessellation
if (version >= 400) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlInputComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlOutputComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlUniformComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxPatchVertices = %d;", resources.);
}
if (version >= 410) {
snprintf(builtInConstant, maxSize, "const int gl_MaxViewports = %d;", resources.maxViewports);
s.append(builtInConstant);
}
// atomic counters
if (version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources.);
}
// images
if (version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTextureImageUnits = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationTextureImageUnits = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.);
}
// compute
if (version >= 430) {
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = {%d,%d,%d};", resources.maxComputeWorkGroupCountX,
resources.maxComputeWorkGroupCountY,
resources.maxComputeWorkGroupCountZ);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = {%d,%d,%d};", resources.maxComputeWorkGroupSizeX,
resources.maxComputeWorkGroupSizeY,
resources.maxComputeWorkGroupSizeZ);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers);
s.append(builtInConstant);
if (language == EShLangTessControl || language == EShLangTessEvaluation) {
s.append(
"in gl_PerVertex {"
"vec4 gl_Position;"
"float gl_PointSize;"
"float gl_ClipDistance[];"
);
if (profile == ECompatibilityProfile)
s.append(
"vec4 gl_ClipVertex;"
"vec4 gl_FrontColor;"
"vec4 gl_BackColor;"
"vec4 gl_FrontSecondaryColor;"
"vec4 gl_BackSecondaryColor;"
"vec4 gl_TexCoord[];"
"float gl_FogFragCoord;"
);
s.append(
"} gl_in[gl_MaxPatchVertices];"
"\n");
}
}
s.append("\n");
if (version >= 410) {
snprintf(builtInConstant, maxSize, "const int gl_MaxViewports = %d;", resources.maxViewports);
s.append(builtInConstant);
}
// atomic counters
if (version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources.);
}
// images
if (version >= 420) {
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.);
//snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.);
}
// compute
if (version >= 430) {
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = {%d,%d,%d};", resources.maxComputeWorkGroupCountX,
resources.maxComputeWorkGroupCountY,
resources.maxComputeWorkGroupCountZ);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = {%d,%d,%d};", resources.maxComputeWorkGroupSizeX,
resources.maxComputeWorkGroupSizeY,
resources.maxComputeWorkGroupSizeZ);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters);
s.append(builtInConstant);
snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers);
s.append(builtInConstant);
}
}
s.append("\n");
}
//

View file

@ -2061,7 +2061,7 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType
//
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
{
if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel())
if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
return 0;
// Potentially redeclaring a built-in variable...
@ -2589,7 +2589,52 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
return;
}
} else {
// TODO: 4.0 tessellation evaluation
// tessellation evaluation
// TODO: tessellation: semantic check these are on the in qualifier only
// input primitive
if (id == TQualifier::getGeometryString(ElgTriangles)) {
publicType.shaderQualifiers.geometry = ElgTriangles;
return;
}
if (id == TQualifier::getGeometryString(ElgQuads)) {
publicType.shaderQualifiers.geometry = ElgQuads;
return;
}
if (id == TQualifier::getGeometryString(ElgIsolines)) {
publicType.shaderQualifiers.geometry = ElgIsolines;
return;
}
// vertex spacing
if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
publicType.shaderQualifiers.spacing = EvsEqual;
return;
}
if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
publicType.shaderQualifiers.spacing = EvsFractionalEven;
return;
}
if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
publicType.shaderQualifiers.spacing = EvsFractionalOdd;
return;
}
// triangle order
if (id == TQualifier::getVertexOrderString(EvoCw)) {
publicType.shaderQualifiers.order = EvoCw;
return;
}
if (id == TQualifier::getVertexOrderString(EvoCcw)) {
publicType.shaderQualifiers.order = EvoCcw;
return;
}
// point mode
if (id == "point_mode") {
publicType.shaderQualifiers.pointMode = true;
return;
}
}
}
if (language == EShLangFragment) {
@ -2636,14 +2681,30 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
publicType.qualifier.layoutBinding = value;
return;
}
if (language == EShLangGeometry) {
switch (language) {
case EShLangVertex:
break;
case EShLangTessControl:
if (id == "vertices") {
// TODO: tessellation: implement gl_out[] array sizing based on this
// TODO: tessellation: semantic check this is on the out qualifier only
publicType.shaderQualifiers.vertices = value;
return;
}
break;
case EShLangTessEvaluation:
break;
case EShLangGeometry:
if (id == "invocations") {
profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, 0, "invocations");
publicType.shaderQualifiers.invocations = value;
return;
}
if (id == "max_vertices") {
publicType.shaderQualifiers.maxVertices = value;
publicType.shaderQualifiers.vertices = value;
if (value > resources.maxGeometryOutputVertices)
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
return;
@ -2652,7 +2713,18 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
publicType.qualifier.layoutStream = value;
return;
}
break;
case EShLangFragment:
break;
case EShLangCompute:
break;
default:
break;
}
error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
}
@ -2666,8 +2738,8 @@ void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TShaderQualifier
dst.geometry = src.geometry;
if (src.invocations != 0)
dst.invocations = src.invocations;
if (src.maxVertices != 0)
dst.maxVertices = src.maxVertices;
if (src.vertices != 0)
dst.vertices = src.vertices;
if (src.pixelCenterInteger)
dst.pixelCenterInteger = src.pixelCenterInteger;
if (src.originUpperLeft)
@ -2819,7 +2891,7 @@ void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers
error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
if (shaderQualifiers.invocations > 0)
error(loc, message, "invocations", "");
if (shaderQualifiers.maxVertices > 0)
if (shaderQualifiers.vertices > 0)
error(loc, message, "max_vertices", "");
}
@ -3604,9 +3676,13 @@ void TParseContext::invariantCheck(TSourceLoc loc, const TType& type, const TStr
//
void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType)
{
if (publicType.shaderQualifiers.maxVertices) {
if (! intermediate.setMaxVertices(publicType.shaderQualifiers.maxVertices))
error(loc, "cannot change previously set layout value", "max_vertices", "");
if (publicType.shaderQualifiers.vertices) {
if (! intermediate.setVertices(publicType.shaderQualifiers.vertices)) {
if (language == EShLangGeometry)
error(loc, "cannot change previously set layout value", "max_vertices", "");
else
error(loc, "cannot change previously set layout value", "vertices", "");
}
}
if (publicType.shaderQualifiers.invocations) {
if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
@ -3620,6 +3696,8 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
case ElgLinesAdjacency:
case ElgTriangles:
case ElgTrianglesAdjacency:
case ElgQuads:
case ElgIsolines:
if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry))
checkInputArrayConsistency(loc);
else
@ -3642,6 +3720,16 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
} else
error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
}
if (publicType.shaderQualifiers.spacing != EvsNone) {
if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
}
if (publicType.shaderQualifiers.order != EvoNone) {
if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
}
if (publicType.shaderQualifiers.pointMode)
intermediate.setPointMode();
const TQualifier& qualifier = publicType.qualifier;

View file

@ -523,7 +523,7 @@ bool CompileDeferred(
}
if (messages & EShMsgAST)
intermediate.outputTree(parseContext.infoSink);
intermediate.output(parseContext.infoSink, true);
delete [] lengths;
delete [] strings;
@ -1057,12 +1057,12 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
std::list<TShader*>::const_iterator it;
for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
if (messages & EShMsgAST)
intermediate[stage]->outputTree(*infoSink);
}
intermediate[stage]->errorCheck(*infoSink);
intermediate[stage]->finalCheck(*infoSink);
if (messages & EShMsgAST)
intermediate[stage]->output(*infoSink, stages[stage].size() > 1);
return intermediate[stage]->getNumErrors() == 0;
}

View file

@ -161,6 +161,7 @@ void TParseContext::initializeExtensionBehavior()
extensionBehavior[GL_ARB_texture_gather] = EBhDisable;
extensionBehavior[GL_ARB_gpu_shader5] = EBhDisablePartial;
extensionBehavior[GL_ARB_separate_shader_objects] = EBhDisable;
extensionBehavior[GL_ARB_tessellation_shader] = EBhDisable;
}
// Get code that is not part of a shared symbol table, is specific to this shader,
@ -183,6 +184,7 @@ const char* TParseContext::getPreamble()
"#define GL_ARB_texture_gather 1\n"
"#define GL_ARB_gpu_shader5 1\n"
"#define GL_ARB_separate_shader_objects 1\n";
"#define GL_ARB_tessellation_shader 1\n";
}
}

View file

@ -85,6 +85,7 @@ const char* const GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420
const char* const GL_ARB_texture_gather = "GL_ARB_texture_gather";
const char* const GL_ARB_gpu_shader5 = "GL_ARB_gpu_shader5";
const char* const GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects";
const char* const GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader"; // TODO: tessellation: make this extension work on version 150 and above shaders
} // end namespace glslang

View file

@ -577,22 +577,46 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it
// Individual functions can be initialized to 0 to skip processing of that
// type of node. It's children will still be processed.
//
void TIntermediate::outputTree(TInfoSink& infoSink)
void TIntermediate::output(TInfoSink& infoSink, bool tree)
{
if (language == EShLangGeometry) {
switch (language) {
case EShLangVertex:
break;
case EShLangTessControl:
infoSink.debug << "vertices = " << vertices << "\n";
break;
case EShLangTessEvaluation:
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
if (pointMode)
infoSink.debug << "using point mode\n";
break;
case EShLangGeometry:
infoSink.debug << "invocations = " << invocations << "\n";
infoSink.debug << "max_vertices = " << maxVertices << "\n";
infoSink.debug << "max_vertices = " << vertices << "\n";
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
}
if (language == EShLangFragment) {
break;
case EShLangFragment:
if (pixelCenterInteger)
infoSink.debug << "gl_FragCoord pixel center is integer\n";
if (originUpperLeft)
infoSink.debug << "gl_FragCoord origin is upper left\n";
break;
case EShLangCompute:
break;
default:
break;
}
if (treeRoot == 0)
if (treeRoot == 0 || ! tree)
return;
TOutputTraverser it(infoSink);

View file

@ -80,15 +80,30 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
inputPrimitive = unit.inputPrimitive;
else if (inputPrimitive != unit.inputPrimitive)
error(infoSink, "Contradictory input layout primitives");
if (outputPrimitive == ElgNone)
outputPrimitive = unit.outputPrimitive;
else if (outputPrimitive != unit.outputPrimitive)
error(infoSink, "Contradictory output layout primitives");
if (maxVertices == 0)
maxVertices = unit.maxVertices;
else if (maxVertices != unit.maxVertices)
if (vertices == 0)
vertices = unit.vertices;
else if (vertices != unit.vertices)
error(infoSink, "Contradictory layout max_vertices values");
if (vertexSpacing == ElgNone)
vertexSpacing = unit.vertexSpacing;
else if (vertexSpacing != unit.vertexSpacing)
error(infoSink, "Contradictory input vertex spacing");
if (vertexOrder == EvoNone)
vertexOrder = unit.vertexOrder;
else if (vertexOrder != unit.vertexOrder)
error(infoSink, "Contradictory triangle ordering");
if (unit.pointMode)
pointMode = true;
if (unit.treeRoot == 0)
return;
@ -259,7 +274,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// Do final link-time error checking of a complete (merged) intermediate representation.
// (Much error checking was done during merging).
//
void TIntermediate::errorCheck(TInfoSink& infoSink)
// Also, lock in defaults of things not set.
//
void TIntermediate::finalCheck(TInfoSink& infoSink)
{
if (numMains < 1)
error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point");
@ -281,14 +298,21 @@ void TIntermediate::errorCheck(TInfoSink& infoSink)
switch (language) {
case EShLangVertex:
case EShLangTessControl:
break;
case EShLangTessEvaluation:
if (inputPrimitive == ElgNone)
error(infoSink, "At least one tessellation shader must specify an input layout primitive");
if (vertexSpacing == EvsNone)
vertexSpacing = EvsEqual;
if (vertexOrder == EvoNone)
vertexOrder = EvoCcw;
break;
case EShLangGeometry:
if (inputPrimitive == ElgNone)
error(infoSink, "At least one geometry shader must specify an input layout primitive");
if (outputPrimitive == ElgNone)
error(infoSink, "At least one geometry shader must specify an output layout primitive");
if (maxVertices == 0)
if (vertices == 0)
error(infoSink, "At least one geometry shader must specify a layout(max_vertices = value)");
break;
case EShLangFragment:

View file

@ -61,9 +61,10 @@ class TIntermediate {
public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v),
numMains(0), numErrors(0), recursive(false),
invocations(0), maxVertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false) { }
invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false) { }
bool postProcess(TIntermNode*, EShLanguage);
void outputTree(TInfoSink&);
void output(TInfoSink&, bool tree);
void removeTree();
void setVersion(int v) { version = v; }
@ -121,11 +122,11 @@ public:
invocations = i;
return true;
}
bool setMaxVertices(int m)
bool setVertices(int m)
{
if (maxVertices > 0)
return maxVertices == m;
maxVertices = m;
if (vertices > 0)
return vertices == m;
vertices = m;
return true;
}
bool setInputPrimitive(TLayoutGeometry p)
@ -135,7 +136,22 @@ public:
inputPrimitive = p;
return true;
}
TLayoutGeometry getInputPrimitive() { return inputPrimitive; }
TLayoutGeometry getInputPrimitive() const { return inputPrimitive; }
bool setVertexSpacing(TVertexSpacing s)
{
if (vertexSpacing != EvsNone)
return vertexSpacing == s;
vertexSpacing = s;
return true;
}
bool setVertexOrder(TVertexOrder o)
{
if (vertexOrder != EvoNone)
return vertexOrder == o;
vertexOrder = o;
return true;
}
void setPointMode() { pointMode = true; }
bool setOutputPrimitive(TLayoutGeometry p)
{
if (outputPrimitive != ElgNone)
@ -150,7 +166,7 @@ public:
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
void merge(TInfoSink&, TIntermediate&);
void errorCheck(TInfoSink&);
void finalCheck(TInfoSink&);
void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
@ -177,11 +193,14 @@ protected:
int numErrors;
bool recursive;
int invocations;
int maxVertices;
int vertices;
TLayoutGeometry inputPrimitive;
TLayoutGeometry outputPrimitive;
bool pixelCenterInteger;
bool originUpperLeft;
TVertexSpacing vertexSpacing;
TVertexOrder vertexOrder;
bool pointMode;
// for detecting recursion: pair is <caller, callee>
struct TCall {