diff --git a/Test/baseResults/400.geom.out b/Test/baseResults/400.geom.out index 4884f6d28..0b9242df8 100644 --- a/Test/baseResults/400.geom.out +++ b/Test/baseResults/400.geom.out @@ -70,5 +70,6 @@ ERROR: node is still EOpNull! Linked geometry stage: +ERROR: Linking geometry stage: At least one geometry shader must specify an output layout primitive diff --git a/Test/baseResults/410.geom.out b/Test/baseResults/410.geom.out index 1ff66f38e..13bd5f96f 100644 --- a/Test/baseResults/410.geom.out +++ b/Test/baseResults/410.geom.out @@ -46,5 +46,8 @@ ERROR: node is still EOpNull! Linked geometry stage: +ERROR: Linking geometry stage: At least one geometry shader must specify an input layout primitive +ERROR: Linking geometry stage: At least one geometry shader must specify an output layout primitive +ERROR: Linking geometry stage: At least one geometry shader must specify a layout(max_vertices = value) diff --git a/Test/baseResults/420.geom.out b/Test/baseResults/420.geom.out index d8dcf1966..f05e2c837 100644 --- a/Test/baseResults/420.geom.out +++ b/Test/baseResults/420.geom.out @@ -120,5 +120,7 @@ ERROR: node is still EOpNull! Linked geometry stage: ERROR: Linking geometry stage: Missing entry point: Each stage requires one "void main()" entry point +ERROR: Linking geometry stage: At least one geometry shader must specify an output layout primitive +ERROR: Linking geometry stage: At least one geometry shader must specify a layout(max_vertices = value) diff --git a/Test/baseResults/mains1.frag.out b/Test/baseResults/mains1.frag.out index 723d725d1..87d8800de 100644 --- a/Test/baseResults/mains1.frag.out +++ b/Test/baseResults/mains1.frag.out @@ -21,7 +21,7 @@ ERROR: 1 compilation errors. No code generated. invocations = 0 max_vertices = 0 input primitive = none -output primitive = none +output primitive = points ERROR: node is still EOpNull! 0:3 Function Definition: foo( (void) 0:3 Function Parameters: @@ -33,7 +33,7 @@ Warning, version 150 is not yet complete; some version-specific features are pre invocations = 0 max_vertices = 0 input primitive = none -output primitive = none +output primitive = line_strip 0:? Sequence 0:3 Function Definition: bar( (void) 0:3 Function Parameters: @@ -42,7 +42,10 @@ output primitive = none Linked geometry stage: +ERROR: Linking geometry stage: Contradictory output layout primitives ERROR: Linking geometry stage: Missing entry point: Each stage requires one "void main()" entry point +ERROR: Linking geometry stage: At least one geometry shader must specify an input layout primitive +ERROR: Linking geometry stage: At least one geometry shader must specify a layout(max_vertices = value) Linked fragment stage: @@ -52,7 +55,7 @@ ERROR: Linking fragment stage: Multiple function bodies in multiple compilation invocations = 0 max_vertices = 0 input primitive = none -output primitive = none +output primitive = points ERROR: node is still EOpNull! 0:3 Function Definition: foo( (void) 0:3 Function Parameters: diff --git a/Test/noMain1.geom b/Test/noMain1.geom index 866984560..ab0834f9c 100644 --- a/Test/noMain1.geom +++ b/Test/noMain1.geom @@ -3,3 +3,5 @@ void foo() { } + +layout(points) out; \ No newline at end of file diff --git a/Test/noMain2.geom b/Test/noMain2.geom index 45c866b6f..9fb5fd7d2 100644 --- a/Test/noMain2.geom +++ b/Test/noMain2.geom @@ -3,3 +3,5 @@ void bar() { } + +layout(line_strip) out; diff --git a/Todo.txt b/Todo.txt index 462863a10..d59631412 100644 --- a/Todo.txt +++ b/Todo.txt @@ -25,20 +25,20 @@ Link Validation - number of texture image units - texel offsets (or compile-time?) - number of input/output compononents - - tessellation limits + - 4.x tessellation limits + - 1.50: geometry shaders: max_vertices must be checked against gl_MaxGeometryOutputVertices (maybe at compile time) + - Non ES: gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords - ... + exactly one main + ES 3.0: fragment outputs all have locations, if more than one - ES 3.0: location aliasing/overlap (except desktop vertex shader inputs) - Non ES: binding overlap? - - Non ES: gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords + Non ES: geometry shader input array sizes and input layout qualifier declaration + Non ES: read or write to both gl_ClipVertex and gl_ClipDistance + Non ES: write to only one of gl_FragColor, gl_FragData, or user-declared + 1.50: match between all explicit input array sizes and input primitive - - 1.50: at least one geometry shader says input primitive and at least one says output primitive... - - 1.50: at least one geometry shader says max_vertices... - - 1.50: geometry shaders: max_vertices must be checked against gl_MaxGeometryOutputVertices (maybe at compile time) + + 1.50: at least one geometry shader says input primitive and at least one says output primitive... + + 1.50: at least one geometry shader says max_vertices... + 1.50: origin_upper_left and pixel_center_integer have to match - Even the potential for recursion through subroutine uniforms is an error. - 4.4: An interface contains two different blocks, each with no instance name, where the blocks contain a member with the same name. diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index f170a1587..139580bdc 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -76,6 +76,19 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) error(infoSink, "gl_FragCoord redeclarations must match across shaders\n"); + if (inputPrimitive == ElgNone) + 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) + error(infoSink, "Contradictory layout max_vertices values"); + if (unit.treeRoot == 0) return; @@ -259,6 +272,24 @@ void TIntermediate::errorCheck(TInfoSink& infoSink) error(infoSink, "Cannot use gl_FragColor or gl_FragData when using user-defined outputs"); if (inIoAccessed("gl_FragColor") && inIoAccessed("gl_FragData")) error(infoSink, "Cannot use both gl_FragColor and gl_FragData"); + + switch (language) { + case EShLangVertex: + case EShLangTessControl: + case EShLangTessEvaluation: + 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) + error(infoSink, "At least one geometry shader must specify a layout(max_vertices = value)"); + break; + case EShLangFragment: + case EShLangCompute: + break; + } } // diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index c3213ef73..43177be31 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -184,7 +184,7 @@ protected: bool currentPath; bool errorGiven; }; - typedef TList TGraph; + typedef std::list TGraph; TGraph callGraph; std::set ioAccessed; // set of names of statically read/written I/O that might need extra checking