Browse Source

location aliasing (#3438)

* location aliasing
    when location aliasing, the aliases sharing the location must have the same underlying numerical type
    (floating-point or integer) and the same auxiliary storage and interpolation qualification.
    The following case, glslang need report error.

    layout(vertices = 1) out;

    layout (location = 1, component = 0)  in  double gohan[];
    layout (location = 1, component = 2)  in  float goten[];

    in  vec4 vs_tcs[];
    out vec4 tcs_tes[];

    void main()
    {
    }

* Need consider the following case: location aliasing with different interpolation qualifier.
jimihem 1 year ago
parent
commit
44fcbccd06

+ 1 - 1
Test/baseResults/440.frag.out

@@ -1,7 +1,7 @@
 440.frag
 ERROR: 0:11: 'location' : overlapping use of location 4
 ERROR: 0:13: 'component' : type overflows the available 4 components 
-ERROR: 0:22: 'location' : fragment outputs or tileImageEXTs sharing the same location 30 must be the same basic type
+ERROR: 0:22: 'location' : the aliases sharing the location 30 must be the same basic type and interpolation qualification
 ERROR: 0:24: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
 ERROR: 0:25: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
 ERROR: 0:26: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 

+ 6 - 1
Test/baseResults/440.vert.out

@@ -10,16 +10,21 @@ ERROR: 0:39: 'component' : type overflows the available 4 components
 ERROR: 0:40: 'component' : type overflows the available 4 components 
 ERROR: 0:42: 'component' : cannot apply to a matrix, structure, or block 
 ERROR: 0:43: 'component' : cannot apply to a matrix, structure, or block 
+ERROR: 0:43: 'location' : the aliases sharing the location 33 must be the same basic type and interpolation qualification
 ERROR: 0:44: 'component' : cannot apply to a matrix, structure, or block 
+ERROR: 0:44: 'location' : the aliases sharing the location 34 must be the same basic type and interpolation qualification
 ERROR: 0:46: 'component' : must specify 'location' to use 'component' 
 ERROR: 0:52: 'location' : overlapping use of location 40
 ERROR: 0:54: 'component' : type overflows the available 4 components 
 ERROR: 0:55: 'component' : type overflows the available 4 components 
 ERROR: 0:57: 'component' : cannot apply to a matrix, structure, or block 
 ERROR: 0:58: 'component' : cannot apply to a matrix, structure, or block 
+ERROR: 0:58: 'location' : the aliases sharing the location 43 must be the same basic type and interpolation qualification
 ERROR: 0:61: 'location/component/index' : cannot declare a default, use a full declaration 
+ERROR: 0:64: 'location' : the aliases sharing the location 50 must be the same basic type and interpolation qualification
 ERROR: 0:66: 'component' : doubles cannot start on an odd-numbered component 
 ERROR: 0:67: 'component' : type overflows the available 4 components 
+ERROR: 0:69: 'location' : the aliases sharing the location 53 must be the same basic type and interpolation qualification
 ERROR: 0:71: 'location' : overlapping use of location 55
 ERROR: 0:75: 'location' : overlapping use of location 57
 ERROR: 0:78: 'location' : overlapping use of location 59
@@ -56,7 +61,7 @@ ERROR: 0:193: 'assign' :  l-value required "gl_BaseVertexARB" (can't modify shad
 ERROR: 0:194: 'assign' :  l-value required "gl_BaseInstanceARB" (can't modify shader input)
 ERROR: 0:195: 'assign' :  l-value required "gl_DrawIDARB" (can't modify shader input)
 ERROR: 0:196: 'glBaseInstanceARB' : undeclared identifier 
-ERROR: 57 compilation errors.  No code generated.
+ERROR: 62 compilation errors.  No code generated.
 
 
 Shader version: 440

+ 33 - 0
Test/baseResults/location_aliasing.tesc.out

@@ -0,0 +1,33 @@
+location_aliasing.tesc
+ERROR: 0:7: 'location' : the aliases sharing the location 1 must be the same basic type and interpolation qualification
+ERROR: 1 compilation errors.  No code generated.
+
+
+Shader version: 430
+Requested GL_ARB_enhanced_layouts
+vertices = 1
+ERROR: node is still EOpNull!
+0:13  Function Definition: main( ( global void)
+0:13    Function Parameters: 
+0:?   Linker Objects
+0:?     'gohan' (layout( location=1 component=0) in 32-element array of double)
+0:?     'goten' (layout( location=1 component=2) in 32-element array of float)
+0:?     'vs_tcs' ( in 32-element array of 4-component vector of float)
+0:?     'tcs_tes' ( out 1-element array of 4-component vector of float)
+
+
+Linked tessellation control stage:
+
+
+Shader version: 430
+Requested GL_ARB_enhanced_layouts
+vertices = 1
+ERROR: node is still EOpNull!
+0:13  Function Definition: main( ( global void)
+0:13    Function Parameters: 
+0:?   Linker Objects
+0:?     'gohan' (layout( location=1 component=0) in 32-element array of double)
+0:?     'goten' (layout( location=1 component=2) in 32-element array of float)
+0:?     'vs_tcs' ( in 32-element array of 4-component vector of float)
+0:?     'tcs_tes' ( out 1-element array of 4-component vector of float)
+

+ 27 - 0
Test/baseResults/location_aliasing1.frag.out

@@ -0,0 +1,27 @@
+location_aliasing1.frag
+ERROR: 0:6: 'location' : the aliases sharing the location 1 must be the same basic type and interpolation qualification
+ERROR: 1 compilation errors.  No code generated.
+
+
+Shader version: 430
+Requested GL_ARB_enhanced_layouts
+ERROR: node is still EOpNull!
+0:8  Function Definition: main( ( global void)
+0:8    Function Parameters: 
+0:?   Linker Objects
+0:?     'in1' (layout( location=1 component=0) smooth in float)
+0:?     'in2' (layout( location=1 component=2) flat in float)
+
+
+Linked fragment stage:
+
+
+Shader version: 430
+Requested GL_ARB_enhanced_layouts
+ERROR: node is still EOpNull!
+0:8  Function Definition: main( ( global void)
+0:8    Function Parameters: 
+0:?   Linker Objects
+0:?     'in1' (layout( location=1 component=0) smooth in float)
+0:?     'in2' (layout( location=1 component=2) flat in float)
+

+ 1 - 1
Test/baseResults/spv.ext.ShaderTileImage.typemismatch.frag.out

@@ -1,5 +1,5 @@
 spv.ext.ShaderTileImage.typemismatch.frag
-ERROR: 0:7: 'location' : fragment outputs or tileImageEXTs sharing the same location 0 must be the same basic type
+ERROR: 0:7: 'location' : the aliases sharing the location 0 must be the same basic type and interpolation qualification
 ERROR: 1 compilation errors.  No code generated.
 
 

+ 15 - 0
Test/location_aliasing.tesc

@@ -0,0 +1,15 @@
+#version 430 core
+#extension GL_ARB_enhanced_layouts : require
+
+layout(vertices = 1) out;
+
+layout (location = 1, component = 0)  in  double gohan[];
+layout (location = 1, component = 2)  in  float goten[];
+
+
+in  vec4 vs_tcs[];
+out vec4 tcs_tes[];
+
+void main()
+{
+}

+ 10 - 0
Test/location_aliasing1.frag

@@ -0,0 +1,10 @@
+#version 430 core
+#extension GL_ARB_enhanced_layouts : require
+
+
+layout (location = 1, component = 0)  in smooth float in1;
+layout (location = 1, component = 2)  in flat float in2;
+
+void main()
+{
+}

+ 4 - 4
glslang/MachineIndependent/ParseHelper.cpp

@@ -6568,10 +6568,10 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
         int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
         if (repeated >= 0 && ! typeCollision)
             error(loc, "overlapping use of location", "location", "%d", repeated);
-        // "fragment-shader outputs/tileImageEXT ... if two variables are placed within the same
-        // location, they must have the same underlying type (floating-point or integer)"
-        if (typeCollision && language == EShLangFragment && (qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT))
-            error(loc, "fragment outputs or tileImageEXTs sharing the same location", "location", "%d must be the same basic type", repeated);
+        // When location aliasing, the aliases sharing the location must have the same underlying numerical type and bit width(
+        // floating - point or integer, 32 - bit versus 64 - bit,etc.)
+        if (typeCollision && (qualifier.isPipeInput() || qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT))
+            error(loc, "the aliases sharing the location", "location", "%d must be the same basic type and interpolation qualification", repeated);
     }
 
     if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {

+ 8 - 4
glslang/MachineIndependent/linkValidate.cpp

@@ -1689,7 +1689,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
         // First range:
         TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
         TRange componentRange(0, 3);
-        TIoRange range(locationRange, componentRange, type.getBasicType(), 0);
+        TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
 
         // check for collisions
         collision = checkLocationRange(set, range, type, typeCollision);
@@ -1699,7 +1699,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
             // Second range:
             TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
             TRange componentRange2(0, 1);
-            TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);
+            TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
 
             // check for collisions
             collision = checkLocationRange(set, range2, type, typeCollision);
@@ -1725,7 +1725,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
     TBasicType basicTy = type.getBasicType();
     if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT())
         basicTy = type.getSampler().type;
-    TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0);
+    TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
 
     // check for collisions, except for vertex inputs on desktop targeting OpenGL
     if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
@@ -1748,7 +1748,11 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
         if (range.overlap(usedIo[set][r])) {
             // there is a collision; pick one
             return std::max(range.location.start, usedIo[set][r].location.start);
-        } else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
+        } else if (range.location.overlap(usedIo[set][r].location) &&
+                   (type.getBasicType() != usedIo[set][r].basicType ||
+                    type.getQualifier().centroid != usedIo[set][r].centroid ||
+                    type.getQualifier().smooth != usedIo[set][r].smooth ||
+                    type.getQualifier().flat != usedIo[set][r].flat)) {
             // aliased-type mismatch
             typeCollision = true;
             return std::max(range.location.start, usedIo[set][r].location.start);

+ 7 - 2
glslang/MachineIndependent/localintermediate.h

@@ -123,8 +123,10 @@ struct TRange {
 // within the same location range, component range, and index value.  Locations don't alias unless
 // all other dimensions of their range overlap.
 struct TIoRange {
-    TIoRange(TRange location, TRange component, TBasicType basicType, int index)
-        : location(location), component(component), basicType(basicType), index(index) { }
+    TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat)
+        : location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat)
+    {
+    }
     bool overlap(const TIoRange& rhs) const
     {
         return location.overlap(rhs.location) && component.overlap(rhs.component) && index == rhs.index;
@@ -133,6 +135,9 @@ struct TIoRange {
     TRange component;
     TBasicType basicType;
     int index;
+    bool centroid;
+    bool smooth;
+    bool flat;
 };
 
 // An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying

+ 2 - 0
gtests/AST.FromFile.cpp

@@ -306,6 +306,8 @@ INSTANTIATE_TEST_SUITE_P(
         "coord_conventions.frag",
         "gl_FragCoord.frag",
         "glsl.interpOp.error.frag",
+        "location_aliasing.tesc",
+        "location_aliasing1.frag",
         "GL_EXT_draw_instanced.vert",
         "overflow_underflow_toinf_0.frag",
         "GL_EXT_texture_array.frag",