ES check for vertex out or fragment in containing any of
• An array of arrays
• An array of structures
• A structure containing an array
• A structure containing a structure


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@28745 e7fa87d3-cd2b-0410-9028-fcbf551c1848
diff --git a/Test/310.frag b/Test/310.frag
index 25d8d4a..87f6efc 100644
--- a/Test/310.frag
+++ b/Test/310.frag
@@ -103,3 +103,15 @@
 out image2D imageOut;   // ERROR

 out mat2x3 mout;        // ERROR

 

+in bool inb;         // ERROR

+in sampler2D ino;    // ERROR

+in float ina[4];

+in float inaa[4][2]; // ERROR

+struct S { float f; };

+in S ins;

+in S[4] inasa;       // ERROR

+in S insa[4];        // ERROR

+struct SA { float f[4]; };

+in SA inSA;          // ERROR

+struct SS { float f; S s; };

+in SS inSS;          // ERROR

diff --git a/Test/310.vert b/Test/310.vert
index ed8ab34..326a4cc 100644
--- a/Test/310.vert
+++ b/Test/310.vert
@@ -67,4 +67,17 @@
     textureSamples(s2dms);   // ERROR

 

 

-}
\ No newline at end of file
+}

+

+out bool outb;         // ERROR

+out sampler2D outo;    // ERROR

+out float outa[4];

+out float outaa[4][2]; // ERROR

+struct S { float f; };

+out S outs;

+out S[4] outasa;       // ERROR

+out S outsa[4];        // ERROR

+struct SA { float f[4]; };

+out SA outSA;          // ERROR

+struct SS { float f; S s; };

+out SS outSS;          // ERROR

diff --git a/Test/450.vert b/Test/450.vert
index fb4c9c1..48da3ed 100644
--- a/Test/450.vert
+++ b/Test/450.vert
@@ -8,3 +8,16 @@
 {

     gl_CullDistance[2] = 4.5;

 }

+

+out bool outb;         // ERROR

+out sampler2D outo;    // ERROR

+out float outa[4];

+out float outaa[4][2];

+struct S { float f; };

+out S outs;

+out S[4] outasa;

+out S outsa[4];

+struct SA { float f[4]; };

+out SA outSA;

+struct SS { float f; S s; };

+out SS outSS;

diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out
index c582327..0d4e70e 100644
--- a/Test/baseResults/310.frag.out
+++ b/Test/baseResults/310.frag.out
@@ -29,7 +29,14 @@
 ERROR: 0:103: 'image2D' : sampler/image types can only be used in uniform variables or function parameters: imageOut

 ERROR: 0:103: '' : image variables not declared 'writeonly' must have a format layout qualifier 

 ERROR: 0:104: 'out' : cannot be a matrix 

-ERROR: 29 compilation errors.  No code generated.

+ERROR: 0:106: 'in' : cannot be bool 

+ERROR: 0:107: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: ino

+ERROR: 0:109: 'fragment-shader array-of-array input' : not supported with this profile: es

+ERROR: 0:112: 'fragment-shader array-of-struct input' : not supported with this profile: es

+ERROR: 0:113: 'fragment-shader array-of-struct input' : not supported with this profile: es

+ERROR: 0:115: 'fragment-shader struct input containing an array' : not supported with this profile: es

+ERROR: 0:117: 'fragment-shader struct input containing structure' : not supported with this profile: es

+ERROR: 36 compilation errors.  No code generated.

 

 

 Shader version: 310

@@ -259,6 +266,15 @@
 0:?     'bout' (out bool)

 0:?     'imageOut' (out highp image2D)

 0:?     'mout' (out mediump 2X3 matrix of float)

+0:?     'inb' (smooth in bool)

+0:?     'ino' (smooth in highp sampler2D)

+0:?     'ina' (smooth in 4-element array of mediump float)

+0:?     'inaa' (smooth in 4-element array of mediump float)

+0:?     'ins' (smooth in structure{mediump float f})

+0:?     'inasa' (smooth in 4-element array of structure{mediump float f})

+0:?     'insa' (smooth in 4-element array of structure{mediump float f})

+0:?     'inSA' (smooth in structure{4-element array of mediump float f})

+0:?     'inSS' (smooth in structure{mediump float f, structure{mediump float f} s})

 

 

 Linked fragment stage:

@@ -492,4 +508,13 @@
 0:?     'bout' (out bool)

 0:?     'imageOut' (out highp image2D)

 0:?     'mout' (out mediump 2X3 matrix of float)

+0:?     'inb' (smooth in bool)

+0:?     'ino' (smooth in highp sampler2D)

+0:?     'ina' (smooth in 4-element array of mediump float)

+0:?     'inaa' (smooth in 4-element array of mediump float)

+0:?     'ins' (smooth in structure{mediump float f})

+0:?     'inasa' (smooth in 4-element array of structure{mediump float f})

+0:?     'insa' (smooth in 4-element array of structure{mediump float f})

+0:?     'inSA' (smooth in structure{4-element array of mediump float f})

+0:?     'inSS' (smooth in structure{mediump float f, structure{mediump float f} s})

 

diff --git a/Test/baseResults/310.vert.out b/Test/baseResults/310.vert.out
index 4deca14..90033f5 100644
--- a/Test/baseResults/310.vert.out
+++ b/Test/baseResults/310.vert.out
@@ -7,7 +7,14 @@
 ERROR: 0:58: 'usampler2DMSArray' : Reserved word. 

 ERROR: 0:58: 'sampler/image' : type requires declaration of default precision qualifier 

 ERROR: 0:67: 'textureSamples' : no matching overloaded function found 

-ERROR: 7 compilation errors.  No code generated.

+ERROR: 0:72: 'out' : cannot be bool 

+ERROR: 0:73: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: outo

+ERROR: 0:75: 'vertex-shader array-of-array output' : not supported with this profile: es

+ERROR: 0:78: 'vertex-shader array-of-struct output' : not supported with this profile: es

+ERROR: 0:79: 'vertex-shader array-of-struct output' : not supported with this profile: es

+ERROR: 0:81: 'vertex-shader struct output containing an array' : not supported with this profile: es

+ERROR: 0:83: 'vertex-shader struct output containing structure' : not supported with this profile: es

+ERROR: 14 compilation errors.  No code generated.

 

 

 Shader version: 310

@@ -169,6 +176,15 @@
 0:?     'is2dms' (uniform highp isampler2DMS)

 0:?     'us2dms' (uniform highp usampler2DMS)

 0:?     'us2dmsa' (uniform mediump usampler2DMSArray)

+0:?     'outb' (smooth out bool)

+0:?     'outo' (smooth out highp sampler2D)

+0:?     'outa' (smooth out 4-element array of highp float)

+0:?     'outaa' (smooth out 4-element array of highp float)

+0:?     'outs' (smooth out structure{highp float f})

+0:?     'outasa' (smooth out 4-element array of structure{highp float f})

+0:?     'outsa' (smooth out 4-element array of structure{highp float f})

+0:?     'outSA' (smooth out structure{4-element array of highp float f})

+0:?     'outSS' (smooth out structure{highp float f, structure{highp float f} s})

 0:?     'gl_VertexID' (gl_VertexId highp int)

 0:?     'gl_InstanceID' (gl_InstanceId highp int)

 

@@ -335,6 +351,15 @@
 0:?     'is2dms' (uniform highp isampler2DMS)

 0:?     'us2dms' (uniform highp usampler2DMS)

 0:?     'us2dmsa' (uniform mediump usampler2DMSArray)

+0:?     'outb' (smooth out bool)

+0:?     'outo' (smooth out highp sampler2D)

+0:?     'outa' (smooth out 4-element array of highp float)

+0:?     'outaa' (smooth out 4-element array of highp float)

+0:?     'outs' (smooth out structure{highp float f})

+0:?     'outasa' (smooth out 4-element array of structure{highp float f})

+0:?     'outsa' (smooth out 4-element array of structure{highp float f})

+0:?     'outSA' (smooth out structure{4-element array of highp float f})

+0:?     'outSS' (smooth out structure{highp float f, structure{highp float f} s})

 0:?     'gl_VertexID' (gl_VertexId highp int)

 0:?     'gl_InstanceID' (gl_InstanceId highp int)

 

diff --git a/Test/baseResults/450.vert.out b/Test/baseResults/450.vert.out
index 6b752d1..4fd5d90 100644
--- a/Test/baseResults/450.vert.out
+++ b/Test/baseResults/450.vert.out
@@ -1,8 +1,12 @@
 450.vert

 Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.

+ERROR: 0:12: 'out' : cannot be bool 

+ERROR: 0:13: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: outo

+ERROR: 2 compilation errors.  No code generated.

+

 

 Shader version: 450

-0:? Sequence

+ERROR: node is still EOpNull!

 0:7  Function Definition: main( (void)

 0:7    Function Parameters: 

 0:9    Sequence

@@ -18,6 +22,15 @@
 0:9          4.500000

 0:?   Linker Objects

 0:?     'anon@0' (out block{out implicitly-sized array of float gl_CullDistance})

+0:?     'outb' (smooth out bool)

+0:?     'outo' (smooth out sampler2D)

+0:?     'outa' (smooth out 4-element array of float)

+0:?     'outaa' (smooth out 4-element array of float)

+0:?     'outs' (smooth out structure{float f})

+0:?     'outasa' (smooth out 4-element array of structure{float f})

+0:?     'outsa' (smooth out 4-element array of structure{float f})

+0:?     'outSA' (smooth out structure{4-element array of float f})

+0:?     'outSS' (smooth out structure{float f, structure{float f} s})

 0:?     'gl_VertexID' (gl_VertexId int)

 0:?     'gl_InstanceID' (gl_InstanceId int)

 

@@ -26,7 +39,7 @@
 

 

 Shader version: 450

-0:? Sequence

+ERROR: node is still EOpNull!

 0:7  Function Definition: main( (void)

 0:7    Function Parameters: 

 0:9    Sequence

@@ -42,6 +55,15 @@
 0:9          4.500000

 0:?   Linker Objects

 0:?     'anon@0' (out block{out 3-element array of float gl_CullDistance})

+0:?     'outb' (smooth out bool)

+0:?     'outo' (smooth out sampler2D)

+0:?     'outa' (smooth out 4-element array of float)

+0:?     'outaa' (smooth out 4-element array of float)

+0:?     'outs' (smooth out structure{float f})

+0:?     'outasa' (smooth out 4-element array of structure{float f})

+0:?     'outsa' (smooth out 4-element array of structure{float f})

+0:?     'outSA' (smooth out structure{4-element array of float f})

+0:?     'outSS' (smooth out structure{float f, structure{float f} s})

 0:?     'gl_VertexID' (gl_VertexId int)

 0:?     'gl_InstanceID' (gl_InstanceId int)

 

diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 4ac3a02..80ae123 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -1053,6 +1053,7 @@
     virtual int getMatrixCols() const { return matrixCols; }
     virtual int getMatrixRows() const { return matrixRows; }
     virtual int getArraySize()  const { return arraySizes->sizes.front(); }
+    virtual bool isArrayOfArrays() const { return arraySizes && arraySizes->isArrayOfArrays(); }
     virtual int getImplicitArraySize () const { return arraySizes->implicitArraySize; }
 
     virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); }
@@ -1093,6 +1094,18 @@
         return false;
     }
 
+    // Check the structure for any structures, needed for some error checks
+    virtual bool containsStructure() const
+    {
+        if (! structure)
+            return false;
+        for (unsigned int i = 0; i < structure->size(); ++i) {
+            if ((*structure)[i].type->structure)
+                return true;
+        }
+        return false;
+    }
+
     // Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
     virtual bool containsImplicitlySizedArray() const
     {
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 6510c8f..944bf1f 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -2077,6 +2077,10 @@
             if (publicType.userDef) {
                 profileRequires(loc, EEsProfile, 300, 0, "fragment-shader struct input");
                 profileRequires(loc, ~EEsProfile, 150, 0, "fragment-shader struct input");
+                if (publicType.userDef->containsStructure())
+                    requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing structure");
+                if (publicType.userDef->containsArray())
+                    requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
             }
             break;
 
@@ -2095,7 +2099,12 @@
             if (publicType.userDef) {
                 profileRequires(loc, EEsProfile, 300, 0, "vertex-shader struct output");
                 profileRequires(loc, ~EEsProfile, 150, 0, "vertex-shader struct output");
+                if (publicType.userDef->containsStructure())
+                    requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing structure");
+                if (publicType.userDef->containsArray())
+                    requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing an array");
             }
+
             break;
 
         case EShLangTessControl:
@@ -2348,6 +2357,30 @@
 }
 
 //
+// See if this qualifier and type combination can be an array.
+// Assumes arrayQualifierError() was also called to catch the type-invariant tests.
+//
+// Returns true if there is an error.
+//
+bool TParseContext::arrayError(TSourceLoc loc, const TType& type)
+{
+    if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
+        if (type.isArrayOfArrays())
+            requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output");
+        else if (type.getArraySize() && type.isStruct())
+            requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output");
+    }
+    if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) {
+        if (type.isArrayOfArrays())
+            requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input");
+        else if (type.getArraySize() && type.isStruct())
+            requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input");
+    }
+
+    return false;
+}
+
+//
 // Require array to have size
 //
 void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size)
@@ -3932,7 +3965,7 @@
         if (profile == EEsProfile && ! initializer)
             arraySizeRequiredCheck(loc, type.getArraySize());
 
-        if (! arrayQualifierError(loc, type.getQualifier()))
+        if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
             declareArray(loc, identifier, type, symbol, newDeclaration);
 
         if (initializer) {
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index c678e42..b675b29 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -120,6 +120,7 @@
     bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
     void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
     bool arrayQualifierError(TSourceLoc, const TQualifier&);
+    bool arrayError(TSourceLoc, const TType&);
     void arraySizeRequiredCheck(TSourceLoc, int size);
     void structArrayCheck(TSourceLoc, TType* structure);
     void arrayDimError(TSourceLoc);