diff --git a/Test/420.vert b/Test/420.vert index ebe7d0ed..3a268524 100644 --- a/Test/420.vert +++ b/Test/420.vert @@ -71,3 +71,6 @@ layout(binding = 1) in inblock { int aoeua; }; // ERROR layout(binding = 100000) uniform anonblock2 { int aooeu; } ; layout(binding = 4) uniform sampler2D sampb1; layout(binding = 5) uniform sampler2D sampb2[10]; +layout(binding = 32) uniform sampler2D sampb3; // ERROR, binding too big +layout(binding = 31) uniform sampler2D sampb4; +layout(binding = 31) uniform sampler2D sampb5[2]; // ERROR, binding too big diff --git a/Test/baseResults/420.vert.out b/Test/baseResults/420.vert.out index 8f6816ad..51049074 100644 --- a/Test/baseResults/420.vert.out +++ b/Test/baseResults/420.vert.out @@ -25,7 +25,9 @@ ERROR: 0:66: 'binding' : cannot declare a default, include a type or full declar ERROR: 0:69: 'location' : cannot declare a default, use a full declaration ERROR: 0:70: 'binding' : requires uniform or buffer storage qualifier ERROR: 0:71: 'binding' : binding is too large -ERROR: 24 compilation errors. No code generated. +ERROR: 0:74: 'binding' : sampler binding not less than gl_MaxCombinedTextureImageUnits +ERROR: 0:76: 'binding' : sampler binding not less than gl_MaxCombinedTextureImageUnits (using array) +ERROR: 26 compilation errors. No code generated. ERROR: node is still EOpNull! @@ -124,6 +126,9 @@ ERROR: node is still EOpNull! 0:? '__anon__2' (layout(column_major shared ) uniform block{aooeu}) 0:? 'sampb1' (layout(binding=4 ) uniform sampler2D) 0:? 'sampb2' (layout(binding=5 ) uniform 10-element array of sampler2D) +0:? 'sampb3' (layout(binding=32 ) uniform sampler2D) +0:? 'sampb4' (layout(binding=31 ) uniform sampler2D) +0:? 'sampb5' (layout(binding=31 ) uniform 2-element array of sampler2D) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) diff --git a/Todo.txt b/Todo.txt index c9c54656..95d4d083 100644 --- a/Todo.txt +++ b/Todo.txt @@ -1,5 +1,7 @@ Current functionality level: ESSL 3.0 +- create version system + Link Validation + provide input config file for setting limits - also consider spitting out measures of complexity @@ -22,14 +24,17 @@ Link Validation Intra-stage linking, single shader + recursion for functions - limits checking: + + bindings - number of input/output compononents - - 4.x tessellation limits + - tessellation limits + - tessellation primitive array sizing consistency - 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: binding overlap + - location overlap + 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 @@ -102,6 +107,11 @@ Shader Functionality to Implement/Finish + 1.50: geometry shaders: max_vertices must be checked against gl_MaxGeometryOutputVertices (maybe at compile time) GLSL 4.0 - tessellation control stage and tessellation evaluation stage. Includes barrier() built-in for synchronization. + - patch in, patch out + - input/output arrays + - unsized array sizing to gl_MaxPatchVertices, including gl_in/gl_out + - built-in variables, functions, and constants verification + - layout qualifiers for primitive types - Polymorphic functions: Run-time selection of what function gets called, through the new keyword subroutine. - 64bit floating point numbers with the new type keyword double. Built-in functions extended for doubles, and new function matching rules are added to both allow implicit conversions when calling a function and preserve most existing function matching once doubles are included. + More implicit conversions diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 0c80c18f..cacaedb7 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2687,6 +2687,13 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol) if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock) error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", ""); // TODO: 4.2 functionality: atomic counter: include in test above + if (type.getBasicType() == EbtSampler) { + int lastBinding = qualifier.layoutBinding; + if (type.isArray()) + lastBinding += type.getArraySize(); + if (lastBinding >= resources.maxCombinedTextureImageUnits) + error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); + } } } @@ -3721,7 +3728,7 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, return switchNode; } -// TODO: simplification: constant folding: these should use a follow a fully folded model now, and probably move to Constant.cpp scheme. +// TODO: simplification: constant folding: these should use a fully folded model now, and probably move to Constant.cpp scheme. // // Make a constant scalar or vector node, representing a given constant vector and constant swizzle into it. diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 139580bd..b0669128 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -159,6 +159,10 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin // the initializer if (symbol->getConstArray().empty() && ! unitSymbol->getConstArray().empty()) symbol->setConstArray(unitSymbol->getConstArray()); + + // Similarly for binding + if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding()) + symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding; // Check for consistent types/qualification/initializers etc. mergeErrorCheck(infoSink, *symbol, *unitSymbol, false); @@ -230,7 +234,8 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy // Layouts... if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix || symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking || - symbol.getQualifier().layoutSlotLocation != unitSymbol.getQualifier().layoutSlotLocation) { + symbol.getQualifier().layoutSlotLocation != unitSymbol.getQualifier().layoutSlotLocation || + symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) { error(infoSink, "Layout qualification must match:"); writeTypeComparison = true; }