SPV: Correctly enforce 'location' presence on in/out blocks.
authorJohn Kessenich <cepheus@frii.com>
Sat, 20 May 2017 18:14:13 +0000 (12:14 -0600)
committerJohn Kessenich <cepheus@frii.com>
Sat, 20 May 2017 18:15:41 +0000 (12:15 -0600)
Blocks have this on members, not the object.

Test/baseResults/spv.noLocation.vert.out
Test/spv.noLocation.vert
glslang/MachineIndependent/ParseHelper.cpp

index 43e2534..7bd7467 100644 (file)
@@ -2,7 +2,10 @@ spv.noLocation.vert
 Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
 ERROR: spv.noLocation.vert:4: 'location' : SPIR-V requires location for user input/output 
 ERROR: spv.noLocation.vert:8: 'location' : SPIR-V requires location for user input/output 
-ERROR: 2 compilation errors.  No code generated.
+ERROR: spv.noLocation.vert:19: 'location' : SPIR-V requires location for user input/output 
+ERROR: spv.noLocation.vert:25: 'location' : SPIR-V requires location for user input/output 
+ERROR: spv.noLocation.vert:29: 'location' : SPIR-V requires location for user input/output 
+ERROR: 5 compilation errors.  No code generated.
 
 
 SPIR-V is not generated for failed compile or link
index e3c02ee..dd495b7 100644 (file)
@@ -8,6 +8,25 @@ layout(location = 1) out vec4 out1;
 out vec4 out2;\r
 layout(location = 3) out vec4 out3;\r
 \r
+layout(location = 10) out inb1 { \r
+    vec4 a;\r
+    vec4 b;\r
+} inbi1;\r
+out inb2 { \r
+    layout(location = 12) vec4 a;\r
+    layout(location = 13) vec4 b;\r
+} inbi2;\r
+out inb3 {\r
+    vec4 a;\r
+    vec4 b;\r
+} inbi3;\r
+\r
+layout(location = 14) out struct S1 { vec4 a; } s1;\r
+out struct S2 { vec4 a; } s2;\r
+\r
+struct SS { int a; };\r
+out layout(location = 15) SS ss1;\r
+out SS ss2;\r
 \r
 void main()\r
 {\r
index b3dbeda..ebe5b50 100644 (file)
@@ -4332,14 +4332,19 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
         default:
             break;
         }
-    } else if (spvVersion.spv > 0) {
+    }
+
+    // user-variable location check, which are required for SPIR-V in/out:
+    //  - variables have it directly,
+    //  - blocks have it on each member (already enforced), so check first one
+    if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone &&
+        !qualifier.hasLocation() && !intermediate.getAutoMapLocations()) {
+
         switch (qualifier.storage) {
         case EvqVaryingIn:
         case EvqVaryingOut:
-            if (! parsingBuiltins && qualifier.builtIn == EbvNone) {
-                if (!intermediate.getAutoMapLocations())
-                    error(loc, "SPIR-V requires location for user input/output", "location", "");
-            }
+            if (type.getBasicType() != EbtBlock || !(*type.getStruct())[0].type->getQualifier().hasLocation())
+                error(loc, "SPIR-V requires location for user input/output", "location", "");
             break;
         default:
             break;