From 65c78a0b629f8d67034389437959f712889a9119 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 10 Aug 2015 17:08:55 -0600 Subject: [PATCH] Array of array: Implement the core functionality: types, constructors, operations. There will be subsequent commits to refine semantics, esp. version-specific semantics, as well as I/O functionality and restrictions. Note: I'm getting white-space differences in the preprocessor test results, which I'm not checking in. I think they need to be tagged as binary or something. --- SPIRV/GlslangToSpv.cpp | 14 +- Test/430AofA.frag | 108 ++++ Test/baseResults/120.vert.out | 1 - Test/baseResults/300.frag.out | 1 - Test/baseResults/310.frag.out | 1 - Test/baseResults/310.vert.out | 1 - Test/baseResults/310AofA.vert.out | 1 - Test/baseResults/430AofA.frag.out | 803 ++++++++++++++++++++++++++++ Test/baseResults/450.vert.out | 1 - Test/baseResults/specExamples.frag.out | 80 ++- Test/baseResults/specExamples.vert.out | 45 +- Test/specExamples.vert | 2 +- Test/testlist | 1 + glslang/Include/Types.h | 97 ++-- glslang/Include/arrays.h | 100 +++- glslang/Include/revision.h | 2 +- glslang/MachineIndependent/Initialize.cpp | 6 +- glslang/MachineIndependent/ParseHelper.cpp | 209 +++++--- glslang/MachineIndependent/ParseHelper.h | 9 +- glslang/MachineIndependent/SymbolTable.cpp | 2 +- glslang/MachineIndependent/glslang.y | 20 +- glslang/MachineIndependent/linkValidate.cpp | 17 +- glslang/MachineIndependent/reflection.cpp | 8 +- 23 files changed, 1344 insertions(+), 185 deletions(-) create mode 100644 Test/430AofA.frag create mode 100644 Test/baseResults/430AofA.frag.out diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 1d1dcaf..4b8c933 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -953,7 +953,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt { glslang::TIntermTyped* typedNode = node->getSequence()[0]->getAsTyped(); assert(typedNode); - spv::Id length = builder.makeIntConstant(typedNode->getType().getArraySize()); + spv::Id length = builder.makeIntConstant(typedNode->getType().getOuterArraySize()); builder.clearAccessChain(); builder.setAccessChainRValue(length); @@ -1428,7 +1428,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spv::MissingFunctionality("Unsized array"); arraySize = 8; } else - arraySize = type.getArraySize(); + arraySize = type.getOuterArraySize(); spvType = builder.makeArrayType(spvType, arraySize); } @@ -2637,15 +2637,11 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT spv::Id typeId = convertGlslangToSpvType(glslangType); if (glslangType.isArray()) { - glslang::TType elementType; - elementType.deepCopy(glslangType); - elementType.dereference(); - for (int i = 0; i < glslangType.getArraySize(); ++i) + glslang::TType elementType(glslangType, 0); + for (int i = 0; i < glslangType.getOuterArraySize(); ++i) spvConsts.push_back(createSpvConstant(elementType, consts, nextConst)); } else if (glslangType.isMatrix()) { - glslang::TType vectorType; - vectorType.shallowCopy(glslangType); - vectorType.dereference(); + glslang::TType vectorType(glslangType, 0); for (int col = 0; col < glslangType.getMatrixCols(); ++col) spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst)); } else if (glslangType.getStruct()) { diff --git a/Test/430AofA.frag b/Test/430AofA.frag new file mode 100644 index 0000000..54d0923 --- /dev/null +++ b/Test/430AofA.frag @@ -0,0 +1,108 @@ +#version 430 + +float[4][5][6] many[1][2][3]; + +float gu[][7]; +float gimp[][]; // ERROR, implicit inner +float g4[4][7]; +float g5[5][7]; + +float[4][7] foo(float a[5][7]) +{ + float r[7]; + r = a[2]; + float[](a[0], a[1], r, a[3]); // ERROR, too few dims + float[4][7][4](a[0], a[1], r, a[3]); // ERROR, too many dims + return float[4][7](a[0], a[1], r, a[3]); + return float[][](a[0], a[1], r, a[3]); + return float[][7](a[0], a[1], a[2], a[3]); +} + +void bar(float[5][7]) {} + +void main() +{ + { + float gu[3][4][2]; + + gu[2][4][1] = 4.0; // ERROR, overflow + } + vec4 ca4[3][2] = vec4[][](vec4[2](vec4(0.0), vec4(1.0)), + vec4[2](vec4(0.0), vec4(1.0)), + vec4[2](vec4(0.0), vec4(1.0))); + vec4 caim[][2] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0))); + vec4 caim2[][] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0))); + vec4 caim3[3][] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0))); + + vec4 a4[3][2] = {vec4[](vec4(0.0), vec4(1.0)), + vec4[2](vec4(0.0), vec4(1.0)), + vec4[2](vec4(0.0), vec4(1.0)) }; + vec4 aim[][2] = {vec4[2](vec4(4.0), vec4(2.0)), + vec4[](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)) }; + vec4 aim2[][] = {vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)), + vec4[](vec4(4.0), vec4(2.0)) }; + vec4 aim3[3][] = {vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)) }; + + vec4 bad2[3][] = {vec4[2](vec4(4.0), vec4(2.0)), // ERROR + vec4[3](vec4(4.0), vec4(2.0), vec4(5.0)), + vec4[2](vec4(4.0), vec4(2.0)) }; + + vec4 bad3[3][] = {vec4[3](vec4(4.0), vec4(2.0), vec4(5.0)), // ERROR + vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)) }; + + vec4 bad4[4][] = {vec4[2](vec4(4.0), vec4(2.0)), // ERROR + vec4[2](vec4(4.0), vec4(2.0)), + vec4[2](vec4(4.0), vec4(2.0)) }; + + + g4 = foo(g5); + g5 = g4; // ERROR, wrong types + gu = g4; // ERROR, not yet sized + + foo(gu); // ERROR, not yet sized + bar(g5); + + if (foo(g5) == g4) + ; + if (foo(g5) == g5) // ERROR, different types + ; + + float u[][7]; + u[2][2] = 3.0; + float u[5][7]; + u[5][2] = 5.0; // ERROR + foo(u); +} + +void foo3() +{ + float resize1[][5][7]; + resize1.length(); // ERROR + resize1[1][4][5] = 2.0; + resize1.length(); // ERROR + float resize1[3][5][7]; + resize1.length(); // 3 in AST + resize1[1].length(); // 5 in AST + resize1[1][1].length(); // 7 in AST + resize1[1][1][1].length(); // ERROR + + float resize2[][5][7]; + float resize2[3][4][7]; // ERROR, inner dim change + + float resize3[][5][7]; + float resize3[3][5][9]; // ERROR, inner dim changed + + float resize4[][5][7]; + int resize4[3][5][7]; // ERROR, element type +} diff --git a/Test/baseResults/120.vert.out b/Test/baseResults/120.vert.out index 8db27da..7b58c8b 100644 --- a/Test/baseResults/120.vert.out +++ b/Test/baseResults/120.vert.out @@ -17,7 +17,6 @@ ERROR: 0:34: '.' : cannot apply to an array: flizbit ERROR: 0:34: 'f' : can't use function syntax on variable ERROR: 0:34: 'a4' : redefinition ERROR: 0:35: 'arrays of arrays' : not supported with this profile: none -WARNING: 0:35: 'Not supported yet.' : arrays of arrays ERROR: 0:36: 'arrays of arrays' : not supported with this profile: none ERROR: 0:37: 'arrays of arrays' : not supported with this profile: none ERROR: 0:38: 'arrays of arrays' : not supported with this profile: none diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out index 1d1d533..fb050a5 100644 --- a/Test/baseResults/300.frag.out +++ b/Test/baseResults/300.frag.out @@ -21,7 +21,6 @@ ERROR: 0:85: 'double vector' : not supported with this profile: es ERROR: 0:86: 'dvec4' : Reserved word. ERROR: 0:86: 'double vector' : not supported with this profile: es ERROR: 0:101: 'arrays of arrays' : not supported for this version or the enabled extensions -WARNING: 0:101: 'Not supported yet.' : arrays of arrays ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions ERROR: 0:103: 'arrays of arrays' : not supported for this version or the enabled extensions diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out index 7676e70..c74b9f0 100644 --- a/Test/baseResults/310.frag.out +++ b/Test/baseResults/310.frag.out @@ -37,7 +37,6 @@ ERROR: 0:111: '' : image variables not declared 'writeonly' must have a format l ERROR: 0:112: 'out' : cannot be a matrix ERROR: 0:114: 'in' : cannot be bool ERROR: 0:115: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: ino -WARNING: 0:117: 'Not supported yet.' : arrays of arrays ERROR: 0:117: 'fragment-shader array-of-array input' : not supported with this profile: es ERROR: 0:120: 'fragment-shader array-of-struct input' : not supported with this profile: es ERROR: 0:121: 'fragment-shader array-of-struct input' : not supported with this profile: es diff --git a/Test/baseResults/310.vert.out b/Test/baseResults/310.vert.out index 82a1311..d6face4 100644 --- a/Test/baseResults/310.vert.out +++ b/Test/baseResults/310.vert.out @@ -9,7 +9,6 @@ ERROR: 0:58: 'sampler/image' : type requires declaration of default precision qu ERROR: 0:67: 'textureSamples' : no matching overloaded function found 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 -WARNING: 0:75: 'Not supported yet.' : arrays of arrays 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 diff --git a/Test/baseResults/310AofA.vert.out b/Test/baseResults/310AofA.vert.out index a8de634..63598fc 100644 --- a/Test/baseResults/310AofA.vert.out +++ b/Test/baseResults/310AofA.vert.out @@ -1,6 +1,5 @@ 310AofA.vert Warning, version 310 is not yet complete; most version-specific features are present, but some are missing. -WARNING: 0:8: 'Not supported yet.' : arrays of arrays Shader version: 310 0:? Sequence diff --git a/Test/baseResults/430AofA.frag.out b/Test/baseResults/430AofA.frag.out new file mode 100644 index 0000000..c6ab950 --- /dev/null +++ b/Test/baseResults/430AofA.frag.out @@ -0,0 +1,803 @@ +430AofA.frag +Warning, version 430 is not yet complete; most version-specific features are present, but some are missing. +ERROR: 0:6: '[]' : only outermost dimension of an array of arrays can be implicitly sized +ERROR: 0:14: 'constructor' : constructing non-array constituent from array argument +ERROR: 0:15: 'constructior' : array constructor argument not correct type to construct array element +ERROR: 0:28: '[' : array index out of range '4' +ERROR: 0:56: 'constructor' : cannot convert parameter 2 from 'const 3-element array of 4-component vector of float' to 'temp 2-element array of 4-component vector of float' +ERROR: 0:60: 'constructor' : cannot convert parameter 2 from 'const 2-element array of 4-component vector of float' to 'temp 3-element array of 4-component vector of float' +ERROR: 0:64: '=' : cannot convert from 'temp 3-element array of 2-element array of 4-component vector of float' to 'temp 4-element array of 2-element array of 4-component vector of float' +ERROR: 0:70: 'assign' : cannot convert from 'global 4-element array of 7-element array of float' to 'global 5-element array of 7-element array of float' +ERROR: 0:71: 'assign' : cannot convert from 'global 4-element array of 7-element array of float' to 'global implicitly-sized array of 7-element array of float' +ERROR: 0:73: 'foo' : no matching overloaded function found +ERROR: 0:78: '==' : wrong operand types: no operation '==' exists that takes a left-hand operand of type 'global 4-element array of 7-element array of float' and a right operand of type 'global 5-element array of 7-element array of float' (or there is no acceptable conversion) +ERROR: 0:84: '[' : array index out of range '5' +ERROR: 0:91: 'length' : array must be declared with a size before using this method +ERROR: 0:93: 'length' : array must be declared with a size before using this method +ERROR: 0:98: 'length' : does not operate on this type: temp float +ERROR: 0:98: '' : function call, method, or subroutine call expected +ERROR: 0:98: '' : no matching overloaded function found +ERROR: 0:101: 'resize2' : redeclaration of array with a different array dimensions or sizes +ERROR: 0:104: 'resize3' : redeclaration of array with a different array dimensions or sizes +ERROR: 0:107: 'resize4' : redeclaration of array with a different element type +ERROR: 20 compilation errors. No code generated. + + +Shader version: 430 +ERROR: node is still EOpNull! +0:10 Function Definition: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:10 Function Parameters: +0:10 'a' (in 5-element array of 7-element array of float) +0:? Sequence +0:13 move second child to first child (temp 7-element array of float) +0:13 'r' (temp 7-element array of float) +0:13 direct index (temp 7-element array of float) +0:13 'a' (in 5-element array of 7-element array of float) +0:13 Constant: +0:13 2 (const int) +0:14 Constant: +0:14 0.000000 +0:15 Constant: +0:15 0.000000 +0:16 Branch: Return with expression +0:16 Construct float (temp 4-element array of 7-element array of float) +0:16 direct index (temp 7-element array of float) +0:16 'a' (in 5-element array of 7-element array of float) +0:16 Constant: +0:16 0 (const int) +0:16 direct index (temp 7-element array of float) +0:16 'a' (in 5-element array of 7-element array of float) +0:16 Constant: +0:16 1 (const int) +0:16 'r' (temp 7-element array of float) +0:16 direct index (temp 7-element array of float) +0:16 'a' (in 5-element array of 7-element array of float) +0:16 Constant: +0:16 3 (const int) +0:17 Branch: Return with expression +0:17 Construct float (temp 4-element array of 7-element array of float) +0:17 direct index (temp 7-element array of float) +0:17 'a' (in 5-element array of 7-element array of float) +0:17 Constant: +0:17 0 (const int) +0:17 direct index (temp 7-element array of float) +0:17 'a' (in 5-element array of 7-element array of float) +0:17 Constant: +0:17 1 (const int) +0:17 'r' (temp 7-element array of float) +0:17 direct index (temp 7-element array of float) +0:17 'a' (in 5-element array of 7-element array of float) +0:17 Constant: +0:17 3 (const int) +0:18 Branch: Return with expression +0:18 Construct float (temp 4-element array of 7-element array of float) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 0 (const int) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 1 (const int) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 2 (const int) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 3 (const int) +0:21 Function Definition: bar(f1[5][7]; (global void) +0:21 Function Parameters: +0:21 '' (in 5-element array of 7-element array of float) +0:23 Function Definition: main( (global void) +0:23 Function Parameters: +0:? Sequence +0:? Sequence +0:28 move second child to first child (temp float) +0:28 direct index (temp float) +0:28 direct index (temp 2-element array of float) +0:28 direct index (temp 4-element array of 2-element array of float) +0:28 'gu' (temp 3-element array of 4-element array of 2-element array of float) +0:28 Constant: +0:28 2 (const int) +0:28 Constant: +0:28 4 (const int) +0:28 Constant: +0:28 1 (const int) +0:28 Constant: +0:28 4.000000 +0:30 Sequence +0:30 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:30 'ca4' (temp 3-element array of 2-element array of 4-component vector of float) +0:32 Constant: +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:33 Sequence +0:33 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:33 'caim' (temp 3-element array of 2-element array of 4-component vector of float) +0:35 Constant: +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:36 Sequence +0:36 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:36 'caim2' (temp 3-element array of 2-element array of 4-component vector of float) +0:38 Constant: +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:39 Sequence +0:39 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:39 'caim3' (temp 3-element array of 2-element array of 4-component vector of float) +0:41 Constant: +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:43 Sequence +0:43 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:43 'a4' (temp 3-element array of 2-element array of 4-component vector of float) +0:43 Constant: +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:46 Sequence +0:46 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:46 'aim' (temp 3-element array of 2-element array of 4-component vector of float) +0:46 Constant: +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:49 Sequence +0:49 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:49 'aim2' (temp 3-element array of 2-element array of 4-component vector of float) +0:49 Constant: +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:52 Sequence +0:52 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:52 'aim3' (temp 3-element array of 2-element array of 4-component vector of float) +0:52 Constant: +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:69 move second child to first child (temp 4-element array of 7-element array of float) +0:69 'g4' (global 4-element array of 7-element array of float) +0:69 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:69 'g5' (global 5-element array of 7-element array of float) +0:70 'g5' (global 5-element array of 7-element array of float) +0:71 'gu' (global implicitly-sized array of 7-element array of float) +0:73 Constant: +0:73 0.000000 +0:74 Function Call: bar(f1[5][7]; (global void) +0:74 'g5' (global 5-element array of 7-element array of float) +0:76 Test condition and select (temp void) +0:76 Condition +0:76 Compare Equal (temp bool) +0:76 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:76 'g5' (global 5-element array of 7-element array of float) +0:76 'g4' (global 4-element array of 7-element array of float) +0:76 true case is null +0:78 Test condition and select (temp void) +0:78 Condition +0:78 Constant: +0:78 false (const bool) +0:78 true case is null +0:82 move second child to first child (temp float) +0:82 direct index (temp float) +0:82 direct index (temp 7-element array of float) +0:82 'u' (temp 5-element array of 7-element array of float) +0:82 Constant: +0:82 2 (const int) +0:82 Constant: +0:82 2 (const int) +0:82 Constant: +0:82 3.000000 +0:84 move second child to first child (temp float) +0:84 direct index (temp float) +0:84 direct index (temp 7-element array of float) +0:84 'u' (temp 5-element array of 7-element array of float) +0:84 Constant: +0:84 5 (const int) +0:84 Constant: +0:84 2 (const int) +0:84 Constant: +0:84 5.000000 +0:85 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:85 'u' (temp 5-element array of 7-element array of float) +0:88 Function Definition: foo3( (global void) +0:88 Function Parameters: +0:? Sequence +0:91 Constant: +0:91 1 (const int) +0:92 move second child to first child (temp float) +0:92 direct index (temp float) +0:92 direct index (temp 7-element array of float) +0:92 direct index (temp 5-element array of 7-element array of float) +0:92 'resize1' (temp 3-element array of 5-element array of 7-element array of float) +0:92 Constant: +0:92 1 (const int) +0:92 Constant: +0:92 4 (const int) +0:92 Constant: +0:92 5 (const int) +0:92 Constant: +0:92 2.000000 +0:93 Constant: +0:93 1 (const int) +0:95 Constant: +0:95 3 (const int) +0:96 Constant: +0:96 5 (const int) +0:97 Constant: +0:97 7 (const int) +0:98 Constant: +0:98 0.000000 +0:? Linker Objects +0:? 'many' (global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of float) +0:? 'gu' (global implicitly-sized array of 7-element array of float) +0:? 'gimp' (global implicitly-sized array of implicitly-sized array of float) +0:? 'g4' (global 4-element array of 7-element array of float) +0:? 'g5' (global 5-element array of 7-element array of float) + + +Linked fragment stage: + + +Shader version: 430 +ERROR: node is still EOpNull! +0:10 Function Definition: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:10 Function Parameters: +0:10 'a' (in 5-element array of 7-element array of float) +0:? Sequence +0:13 move second child to first child (temp 7-element array of float) +0:13 'r' (temp 7-element array of float) +0:13 direct index (temp 7-element array of float) +0:13 'a' (in 5-element array of 7-element array of float) +0:13 Constant: +0:13 2 (const int) +0:14 Constant: +0:14 0.000000 +0:15 Constant: +0:15 0.000000 +0:16 Branch: Return with expression +0:16 Construct float (temp 4-element array of 7-element array of float) +0:16 direct index (temp 7-element array of float) +0:16 'a' (in 5-element array of 7-element array of float) +0:16 Constant: +0:16 0 (const int) +0:16 direct index (temp 7-element array of float) +0:16 'a' (in 5-element array of 7-element array of float) +0:16 Constant: +0:16 1 (const int) +0:16 'r' (temp 7-element array of float) +0:16 direct index (temp 7-element array of float) +0:16 'a' (in 5-element array of 7-element array of float) +0:16 Constant: +0:16 3 (const int) +0:17 Branch: Return with expression +0:17 Construct float (temp 4-element array of 7-element array of float) +0:17 direct index (temp 7-element array of float) +0:17 'a' (in 5-element array of 7-element array of float) +0:17 Constant: +0:17 0 (const int) +0:17 direct index (temp 7-element array of float) +0:17 'a' (in 5-element array of 7-element array of float) +0:17 Constant: +0:17 1 (const int) +0:17 'r' (temp 7-element array of float) +0:17 direct index (temp 7-element array of float) +0:17 'a' (in 5-element array of 7-element array of float) +0:17 Constant: +0:17 3 (const int) +0:18 Branch: Return with expression +0:18 Construct float (temp 4-element array of 7-element array of float) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 0 (const int) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 1 (const int) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 2 (const int) +0:18 direct index (temp 7-element array of float) +0:18 'a' (in 5-element array of 7-element array of float) +0:18 Constant: +0:18 3 (const int) +0:21 Function Definition: bar(f1[5][7]; (global void) +0:21 Function Parameters: +0:21 '' (in 5-element array of 7-element array of float) +0:23 Function Definition: main( (global void) +0:23 Function Parameters: +0:? Sequence +0:? Sequence +0:28 move second child to first child (temp float) +0:28 direct index (temp float) +0:28 direct index (temp 2-element array of float) +0:28 direct index (temp 4-element array of 2-element array of float) +0:28 'gu' (temp 3-element array of 4-element array of 2-element array of float) +0:28 Constant: +0:28 2 (const int) +0:28 Constant: +0:28 4 (const int) +0:28 Constant: +0:28 1 (const int) +0:28 Constant: +0:28 4.000000 +0:30 Sequence +0:30 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:30 'ca4' (temp 3-element array of 2-element array of 4-component vector of float) +0:32 Constant: +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:32 1.000000 +0:33 Sequence +0:33 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:33 'caim' (temp 3-element array of 2-element array of 4-component vector of float) +0:35 Constant: +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 4.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:35 2.000000 +0:36 Sequence +0:36 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:36 'caim2' (temp 3-element array of 2-element array of 4-component vector of float) +0:38 Constant: +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 4.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:38 2.000000 +0:39 Sequence +0:39 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:39 'caim3' (temp 3-element array of 2-element array of 4-component vector of float) +0:41 Constant: +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 4.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:41 2.000000 +0:43 Sequence +0:43 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:43 'a4' (temp 3-element array of 2-element array of 4-component vector of float) +0:43 Constant: +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 0.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:43 1.000000 +0:46 Sequence +0:46 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:46 'aim' (temp 3-element array of 2-element array of 4-component vector of float) +0:46 Constant: +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 4.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:46 2.000000 +0:49 Sequence +0:49 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:49 'aim2' (temp 3-element array of 2-element array of 4-component vector of float) +0:49 Constant: +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 4.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:49 2.000000 +0:52 Sequence +0:52 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:52 'aim3' (temp 3-element array of 2-element array of 4-component vector of float) +0:52 Constant: +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 4.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:52 2.000000 +0:69 move second child to first child (temp 4-element array of 7-element array of float) +0:69 'g4' (global 4-element array of 7-element array of float) +0:69 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:69 'g5' (global 5-element array of 7-element array of float) +0:70 'g5' (global 5-element array of 7-element array of float) +0:71 'gu' (global 1-element array of 7-element array of float) +0:73 Constant: +0:73 0.000000 +0:74 Function Call: bar(f1[5][7]; (global void) +0:74 'g5' (global 5-element array of 7-element array of float) +0:76 Test condition and select (temp void) +0:76 Condition +0:76 Compare Equal (temp bool) +0:76 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:76 'g5' (global 5-element array of 7-element array of float) +0:76 'g4' (global 4-element array of 7-element array of float) +0:76 true case is null +0:78 Test condition and select (temp void) +0:78 Condition +0:78 Constant: +0:78 false (const bool) +0:78 true case is null +0:82 move second child to first child (temp float) +0:82 direct index (temp float) +0:82 direct index (temp 7-element array of float) +0:82 'u' (temp 5-element array of 7-element array of float) +0:82 Constant: +0:82 2 (const int) +0:82 Constant: +0:82 2 (const int) +0:82 Constant: +0:82 3.000000 +0:84 move second child to first child (temp float) +0:84 direct index (temp float) +0:84 direct index (temp 7-element array of float) +0:84 'u' (temp 5-element array of 7-element array of float) +0:84 Constant: +0:84 5 (const int) +0:84 Constant: +0:84 2 (const int) +0:84 Constant: +0:84 5.000000 +0:85 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float) +0:85 'u' (temp 5-element array of 7-element array of float) +0:88 Function Definition: foo3( (global void) +0:88 Function Parameters: +0:? Sequence +0:91 Constant: +0:91 1 (const int) +0:92 move second child to first child (temp float) +0:92 direct index (temp float) +0:92 direct index (temp 7-element array of float) +0:92 direct index (temp 5-element array of 7-element array of float) +0:92 'resize1' (temp 3-element array of 5-element array of 7-element array of float) +0:92 Constant: +0:92 1 (const int) +0:92 Constant: +0:92 4 (const int) +0:92 Constant: +0:92 5 (const int) +0:92 Constant: +0:92 2.000000 +0:93 Constant: +0:93 1 (const int) +0:95 Constant: +0:95 3 (const int) +0:96 Constant: +0:96 5 (const int) +0:97 Constant: +0:97 7 (const int) +0:98 Constant: +0:98 0.000000 +0:? Linker Objects +0:? 'many' (global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of float) +0:? 'gu' (global 1-element array of 7-element array of float) +0:? 'gimp' (global 1-element array of implicitly-sized array of float) +0:? 'g4' (global 4-element array of 7-element array of float) +0:? 'g5' (global 5-element array of 7-element array of float) + diff --git a/Test/baseResults/450.vert.out b/Test/baseResults/450.vert.out index aecef87..44aff42 100644 --- a/Test/baseResults/450.vert.out +++ b/Test/baseResults/450.vert.out @@ -2,7 +2,6 @@ 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 -WARNING: 0:15: 'Not supported yet.' : arrays of arrays ERROR: 2 compilation errors. No code generated. diff --git a/Test/baseResults/specExamples.frag.out b/Test/baseResults/specExamples.frag.out index bf3ae55..f73c7e3 100644 --- a/Test/baseResults/specExamples.frag.out +++ b/Test/baseResults/specExamples.frag.out @@ -17,10 +17,6 @@ ERROR: 0:102: 'color' : redefinition ERROR: 0:112: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth ERROR: 0:118: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth ERROR: 0:121: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth -WARNING: 0:146: 'Not supported yet.' : arrays of arrays -ERROR: 0:150: 'constructor' : constructing from a non-dereferenced array -ERROR: 0:150: '=' : cannot convert from 'const float' to 'temp 3-element array of 2-element array of 4-component vector of float' -ERROR: 0:152: 'constructor' : cannot convert parameter 1 from 'const 2-element array of 4-component vector of float' to 'temp 4-component vector of float' ERROR: 0:172: 'x' : undeclared identifier ERROR: 0:172: '[]' : scalar integer expression required ERROR: 0:175: 'x' : undeclared identifier @@ -42,7 +38,7 @@ ERROR: 0:226: 'in' : not allowed in nested scope ERROR: 0:227: 'in' : not allowed in nested scope ERROR: 0:228: 'in' : not allowed in nested scope ERROR: 0:232: 'out' : not allowed in nested scope -ERROR: 41 compilation errors. No code generated. +ERROR: 38 compilation errors. No code generated. Shader version: 430 @@ -164,6 +160,41 @@ ERROR: node is still EOpNull! 0:149 0.100000 0:149 0.100000 0:149 0.100000 +0:150 Sequence +0:150 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:150 'a3' (temp 3-element array of 2-element array of 4-component vector of float) +0:150 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:150 'b' (temp 2-element array of 4-component vector of float) +0:150 'b' (temp 2-element array of 4-component vector of float) +0:150 'b' (temp 2-element array of 4-component vector of float) +0:152 Sequence +0:152 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:152 'a4' (temp 3-element array of 2-element array of 4-component vector of float) +0:152 Constant: +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 0:? Sequence 0:159 Sequence 0:159 Sequence @@ -191,7 +222,7 @@ ERROR: node is still EOpNull! 0:171 Constant: 0:171 3 (const int) 0:172 Constant: -0:172 4 (const int) +0:172 2 (const int) 0:175 Constant: 0:175 0.000000 0:178 Constant: @@ -418,6 +449,41 @@ ERROR: node is still EOpNull! 0:149 0.100000 0:149 0.100000 0:149 0.100000 +0:150 Sequence +0:150 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:150 'a3' (temp 3-element array of 2-element array of 4-component vector of float) +0:150 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:150 'b' (temp 2-element array of 4-component vector of float) +0:150 'b' (temp 2-element array of 4-component vector of float) +0:150 'b' (temp 2-element array of 4-component vector of float) +0:152 Sequence +0:152 move second child to first child (temp 3-element array of 2-element array of 4-component vector of float) +0:152 'a4' (temp 3-element array of 2-element array of 4-component vector of float) +0:152 Constant: +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 0.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 +0:152 1.000000 0:? Sequence 0:159 Sequence 0:159 Sequence @@ -445,7 +511,7 @@ ERROR: node is still EOpNull! 0:171 Constant: 0:171 3 (const int) 0:172 Constant: -0:172 4 (const int) +0:172 2 (const int) 0:175 Constant: 0:175 0.000000 0:178 Constant: diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out index 80e4929..8359f12 100644 --- a/Test/baseResults/specExamples.vert.out +++ b/Test/baseResults/specExamples.vert.out @@ -1,6 +1,5 @@ specExamples.vert Warning, version 430 is not yet complete; most version-specific features are present, but some are missing. -ERROR: 0:23: 'transforms' : redeclaration of array with size ERROR: 0:29: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers ERROR: 0:31: 'triangles' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:31: 'invocations' : there is no such layout identifier for this stage taking an assigned value @@ -35,11 +34,7 @@ ERROR: 0:134: '' : function does not return a value: funcA ERROR: 0:136: '' : function does not return a value: funcB ERROR: 0:153: '' : function does not return a value: func3 ERROR: 0:170: 'coherent' : argument cannot drop memory qualifier when passed to formal parameter -WARNING: 0:192: 'Not supported yet.' : arrays of arrays -ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array -ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array -ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array -ERROR: 37 compilation errors. No code generated. +ERROR: 33 compilation errors. No code generated. Shader version: 430 @@ -269,18 +264,25 @@ ERROR: node is still EOpNull! 0:191 1.000000 0:191 1.000000 0:191 1.000000 -0:192 Constant: -0:192 0.000000 -0:193 Constant: -0:193 0.000000 -0:194 Constant: -0:194 0.000000 +0:192 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:192 'b' (temp 2-element array of 4-component vector of float) +0:192 'b' (temp 2-element array of 4-component vector of float) +0:192 'b' (temp 2-element array of 4-component vector of float) +0:193 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:193 'b' (temp 2-element array of 4-component vector of float) +0:193 'b' (temp 2-element array of 4-component vector of float) +0:193 'b' (temp 2-element array of 4-component vector of float) +0:194 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:194 'b' (temp 2-element array of 4-component vector of float) +0:194 'b' (temp 2-element array of 4-component vector of float) +0:194 'b' (temp 2-element array of 4-component vector of float) 0:? Linker Objects 0:? 'Coords' (out block{out 4-component vector of float Position, out 2-component vector of float Texture}) 0:? 'anon@0' (out block{out 4-component vector of float Color}) 0:? 'transforms' (layout(column_major shared ) uniform 4-element array of block{layout(column_major shared ) uniform 4X4 matrix of float ModelViewMatrix, layout(column_major shared ) uniform 4X4 matrix of float ModelViewProjectionMatrix, layout(column_major shared ) uniform implicitly-sized array of 4-component vector of float a, layout(column_major shared ) uniform float Deformation}) 0:? 'normal' (layout(location=3 ) in 4-component vector of float) 0:? 'colors' (layout(location=6 ) in 3-element array of 4-component vector of float) +0:? 'transforms2' (layout(location=9 ) in 2-element array of 4X4 matrix of float) 0:? 's' (layout(location=3 ) temp structure{global 3-component vector of float a1, global 2X2 matrix of float b, global 2-element array of 4-component vector of float c}) 0:? 'var1' (smooth out 4-component vector of float) 0:? 'anon@1' (out block{out 4-component vector of float var2, out 2-component vector of float var3, out 3-component vector of float var4}) @@ -546,18 +548,25 @@ ERROR: node is still EOpNull! 0:191 1.000000 0:191 1.000000 0:191 1.000000 -0:192 Constant: -0:192 0.000000 -0:193 Constant: -0:193 0.000000 -0:194 Constant: -0:194 0.000000 +0:192 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:192 'b' (temp 2-element array of 4-component vector of float) +0:192 'b' (temp 2-element array of 4-component vector of float) +0:192 'b' (temp 2-element array of 4-component vector of float) +0:193 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:193 'b' (temp 2-element array of 4-component vector of float) +0:193 'b' (temp 2-element array of 4-component vector of float) +0:193 'b' (temp 2-element array of 4-component vector of float) +0:194 Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float) +0:194 'b' (temp 2-element array of 4-component vector of float) +0:194 'b' (temp 2-element array of 4-component vector of float) +0:194 'b' (temp 2-element array of 4-component vector of float) 0:? Linker Objects 0:? 'Coords' (out block{out 4-component vector of float Position, out 2-component vector of float Texture}) 0:? 'anon@0' (out block{out 4-component vector of float Color}) 0:? 'transforms' (layout(column_major shared ) uniform 4-element array of block{layout(column_major shared ) uniform 4X4 matrix of float ModelViewMatrix, layout(column_major shared ) uniform 4X4 matrix of float ModelViewProjectionMatrix, layout(column_major shared ) uniform 1-element array of 4-component vector of float a, layout(column_major shared ) uniform float Deformation}) 0:? 'normal' (layout(location=3 ) in 4-component vector of float) 0:? 'colors' (layout(location=6 ) in 3-element array of 4-component vector of float) +0:? 'transforms2' (layout(location=9 ) in 2-element array of 4X4 matrix of float) 0:? 's' (layout(location=3 ) temp structure{global 3-component vector of float a1, global 2X2 matrix of float b, global 2-element array of 4-component vector of float c}) 0:? 'var1' (smooth out 4-component vector of float) 0:? 'anon@1' (out block{out 4-component vector of float var2, out 2-component vector of float var3, out 3-component vector of float var4}) diff --git a/Test/specExamples.vert b/Test/specExamples.vert index a9c9178..9df1561 100644 --- a/Test/specExamples.vert +++ b/Test/specExamples.vert @@ -20,7 +20,7 @@ uniform Transform { // API uses layout(location = 3) in vec4 normal; layout(location = 6) in vec4 colors[3]; -layout(location = 9) in mat4 transforms[2]; +layout(location = 9) in mat4 transforms2[2]; layout(location = 3) struct S { vec3 a1; diff --git a/Test/testlist b/Test/testlist index 797dca2..3478040 100644 --- a/Test/testlist +++ b/Test/testlist @@ -76,6 +76,7 @@ numeral.frag 410.geom 430.vert 430.comp +430AofA.frag 440.vert 440.frag 450.vert diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index fd12bcc..8900b5b 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -896,15 +896,32 @@ public: // and using only shallow copy TType(const TType& type, int derefIndex, bool rowMajor = false) { - if (! type.isArray() && (type.basicType == EbtStruct || type.basicType == EbtBlock)) { + if (type.isArray()) { + shallowCopy(type); + if (type.getArraySizes()->getNumDims() == 1) { + arraySizes = nullptr; + } else { + // want our own copy of the array, so we can edit it + arraySizes = new TArraySizes; + arraySizes->copyDereferenced(*type.arraySizes); + } + } else if (type.basicType == EbtStruct || type.basicType == EbtBlock) { // do a structure dereference const TTypeList& memberList = *type.getStruct(); shallowCopy(*memberList[derefIndex].type); return; } else { - // do an array/vector/matrix dereference + // do a vector/matrix dereference shallowCopy(type); - dereference(rowMajor); + if (matrixCols > 0) { + if (rowMajor) + vectorSize = matrixCols; + else + vectorSize = matrixRows; + matrixCols = 0; + matrixRows = 0; + } else if (vectorSize > 1) + vectorSize = 1; } } // for making structures, ... @@ -990,28 +1007,13 @@ public: qualifier = parentType.qualifier; sampler = parentType.sampler; if (parentType.arraySizes) - setArraySizes(parentType.arraySizes); + newArraySizes(*parentType.arraySizes); if (parentType.userDef) { structure = parentType.userDef->getWritableStruct(); setTypeName(parentType.userDef->getTypeName()); } } - virtual void dereference(bool rowMajor = false) - { - if (arraySizes) - arraySizes = nullptr; - else if (matrixCols > 0) { - if (rowMajor) - vectorSize = matrixCols; - else - vectorSize = matrixRows; - matrixCols = 0; - matrixRows = 0; - } else if (vectorSize > 1) - vectorSize = 1; - } - virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; } virtual bool hiddenMember() const { return basicType == EbtVoid; } @@ -1038,17 +1040,20 @@ public: virtual int getVectorSize() const { return vectorSize; } virtual int getMatrixCols() const { return matrixCols; } virtual int getMatrixRows() const { return matrixRows; } - virtual int getArraySize() const { return arraySizes->getOuterSize(); } + virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); } + virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); } virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } + virtual const TArraySizes* getArraySizes() const { return arraySizes; } + virtual TArraySizes& getArraySizes() { assert(arraySizes != nullptr); return *arraySizes; } virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); } virtual bool isVector() const { return vectorSize > 1; } virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != nullptr; } - virtual bool isExplicitlySizedArray() const { return isArray() && getArraySize() != UnsizedArraySize; } - virtual bool isImplicitlySizedArray() const { return isArray() && getArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; } - virtual bool isRuntimeSizedArray() const { return isArray() && getArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; } + virtual bool isExplicitlySizedArray() const { return isArray() && getOuterArraySize() != UnsizedArraySize; } + virtual bool isImplicitlySizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; } + virtual bool isRuntimeSizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; } virtual bool isStruct() const { return structure != nullptr; } virtual bool isImage() const { return basicType == EbtSampler && getSampler().image; } @@ -1125,22 +1130,27 @@ public: assert(type.arraySizes != nullptr); *arraySizes = *type.arraySizes; } - void setArraySizes(TArraySizes* s) + void newArraySizes(const TArraySizes& s) { // For setting a fresh new set of array sizes, not yet worrying about sharing. arraySizes = new TArraySizes; - assert(s != nullptr); - *arraySizes = *s; + *arraySizes = s; + } + void addArrayOuterSizes(const TArraySizes& s) + { + if (arraySizes == nullptr) + newArraySizes(s); + else + arraySizes->addOuterSizes(s); } - void setArraySizes(const TType& type) { setArraySizes(type.arraySizes); } - void changeArraySize(int s) { arraySizes->changeOuterSize(s); } + void changeOuterArraySize(int s) { arraySizes->changeOuterSize(s); } void setImplicitArraySize (int s) { arraySizes->setImplicitSize(s); } // Recursively make the implicit array size the explicit array size, through the type tree. void adoptImplicitArraySizes() { if (isImplicitlySizedArray()) - changeArraySize(getImplicitArraySize()); + changeOuterArraySize(getImplicitArraySize()); if (isStruct()) { for (int i = 0; i < (int)structure->size(); ++i) (*structure)[i].type->adoptImplicitArraySizes(); @@ -1151,7 +1161,7 @@ public: { return TType::getBasicString(basicType); } - + static const char* getBasicString(TBasicType t) { switch (t) { @@ -1242,12 +1252,12 @@ public: p += snprintf(p, end - p, "writeonly "); p += snprintf(p, end - p, "%s ", getStorageQualifierString()); if (arraySizes) { - if (arraySizes->getOuterSize() == UnsizedArraySize) { - p += snprintf(p, end - p, "implicitly-sized array of "); - } else { - for(int i = 0; i < (int)arraySizes->getNumDims() ; ++i) { - p += snprintf(p, end - p, "%d-element array of ", (*arraySizes)[i]); - } + for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) { + int size = arraySizes->getDimSize(i); + if (size == 0) + p += snprintf(p, end - p, "implicitly-sized array of "); + else + p += snprintf(p, end - p, "%d-element array of ", arraySizes->getDimSize(i)); } } if (qualifier.precision != EpqNone) @@ -1310,10 +1320,8 @@ public: else components = vectorSize; - if (isArray()) { - // this function can only be used in paths that have a known array size - assert(isExplicitlySizedArray()); - components *= getArraySize(); + if (arraySizes != nullptr) { + components *= arraySizes->getCumulativeSize(); } return components; @@ -1371,7 +1379,14 @@ public: bool sameArrayness(const TType& right) const { return ((arraySizes == nullptr && right.arraySizes == nullptr) || - (arraySizes && right.arraySizes && *arraySizes == *right.arraySizes)); + (arraySizes != nullptr && right.arraySizes != nullptr && *arraySizes == *right.arraySizes)); + } + + // See if two type's arrayness match in everything except their outer dimension + bool sameInnerArrayness(const TType& right) const + { + assert(arraySizes != nullptr && right.arraySizes != nullptr); + return arraySizes->sameInnerArrayness(*right.arraySizes); } // See if two type's elements match in all ways except basic type diff --git a/glslang/Include/arrays.h b/glslang/Include/arrays.h index 67f91e9..cc2cdab 100644 --- a/glslang/Include/arrays.h +++ b/glslang/Include/arrays.h @@ -43,13 +43,13 @@ namespace glslang { -// This is used to mean there is no size yet, it is waiting to get a size from somewhere else. -// Historically, this is not fully encapsulated, trying to catch them all... +// This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else. const int UnsizedArraySize = 0; // // TSmallArrayVector is used as the container for the set of sizes in TArraySizes. // It has generic-container semantics, while TArraySizes has array-of-array semantics. +// That is, TSmallArrayVector should be more focused on mechanism and TArraySizes on policy. // struct TSmallArrayVector { // @@ -101,9 +101,43 @@ struct TSmallArrayVector { sizes->push_back(e); } + void push_front(const TSmallArrayVector& newDims) + { + alloc(); + sizes->insert(sizes->begin(), newDims.sizes->begin(), newDims.sizes->end()); + } + + void pop_front() + { + assert(sizes != nullptr && sizes->size() > 0); + if (sizes->size() == 1) + dealloc(); + else + sizes->erase(sizes->begin()); + } + + // 'this' should currently not be holding anything, and copyNonFront + // will make it hold a copy of all but the first element of rhs. + // (This would be useful for making a type that is dereferenced by + // one dimension.) + void copyNonFront(const TSmallArrayVector& rhs) + { + assert(sizes == nullptr); + if (rhs.size() > 1) { + alloc(); + sizes->insert(sizes->begin(), rhs.sizes->begin() + 1, rhs.sizes->end()); + } + } + unsigned int operator[](int i) const { - assert(sizes && (int)sizes->size() > i); + assert(sizes != nullptr && (int)sizes->size() > i); + return (*sizes)[i]; + } + + unsigned int& operator[](int i) + { + assert(sizes != nullptr && (int)sizes->size() > i); return (*sizes)[i]; } @@ -115,6 +149,7 @@ struct TSmallArrayVector { return false; return *sizes == *rhs.sizes; } + bool operator!=(const TSmallArrayVector& rhs) const { return ! operator==(rhs); } protected: TSmallArrayVector(const TSmallArrayVector&); @@ -127,6 +162,7 @@ protected: void dealloc() { delete sizes; + sizes = nullptr; } TVector* sizes; // will either hold such a pointer, or in the future, hold the two array sizes @@ -134,11 +170,17 @@ protected: // // Represent an array, or array of arrays, to arbitrary depth. This is not -// done through a hierarchy of types, but localized into this single cumulative object. +// done through a hierarchy of types in a type tree, rather all contiguous arrayness +// in the type hierarchy is localized into this single cumulative object. // // The arrayness in TTtype is a pointer, so that it can be non-allocated and zero // for the vast majority of types that are non-array types. // +// Order Policy: these are all identical: +// - left to right order within a contiguous set of ...[..][..][..]... in the source language +// - index order 0, 1, 2, ... within the 'sizes' member below +// - outer-most to inner-most +// struct TArraySizes { POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) @@ -155,13 +197,57 @@ struct TArraySizes { // translate from array-of-array semantics to container semantics int getNumDims() const { return sizes.size(); } + int getDimSize(int dim) const { return sizes[dim]; } + void setDimSize(int dim, int size) { sizes[dim] = size; } int getOuterSize() const { return sizes.front(); } - void setOuterSize(int s) { sizes.push_back((unsigned)s); } + int getCumulativeSize() const + { + int size = 1; + for (int d = 0; d < sizes.size(); ++d) { + // this only makes sense in paths that have a known array size + assert(sizes[d] != UnsizedArraySize); + size *= sizes[d]; + } + return size; + } + void addInnerSize() { sizes.push_back((unsigned)UnsizedArraySize); } + void addInnerSize(int s) { sizes.push_back((unsigned)s); } void changeOuterSize(int s) { sizes.changeFront((unsigned)s); } int getImplicitSize() const { return (int)implicitArraySize; } void setImplicitSize(int s) { implicitArraySize = s; } - int operator[](int i) const { return sizes[i]; } - bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; } + bool isInnerImplicit() const + { + for (int d = 1; d < sizes.size(); ++d) { + if (sizes[d] == (unsigned)UnsizedArraySize) + return true; + } + + return false; + } + void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); } + void dereference() { sizes.pop_front(); } + void copyDereferenced(const TArraySizes& rhs) + { + assert(sizes.size() == 0); + if (rhs.sizes.size() > 1) + sizes.copyNonFront(rhs.sizes); + } + + bool sameInnerArrayness(const TArraySizes& rhs) const + { + if (sizes.size() != rhs.sizes.size()) + return false; + + for (int d = 1; d < sizes.size(); ++d) { + if (sizes[d] != rhs.sizes[d]) + return false; + } + + return true; + } + + bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; } + bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; } protected: TSmallArrayVector sizes; diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index f129ded..e7d7f4d 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -3,4 +3,4 @@ // For the date, it uses the current date (when then script is run). #define GLSLANG_REVISION "2.3.706" -#define GLSLANG_DATE "09-Aug-2015" +#define GLSLANG_DATE "10-Aug-2015" diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index f3620c2..28b8ccd 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -3276,9 +3276,9 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb if (version == 100 || IncludeLegacy(version, profile) || (! ForwardCompatibility && profile != EEsProfile && version < 420)) { TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone; TType fragData(EbtFloat, EvqFragColor, pq, 4); - TArraySizes* arraySizes = new TArraySizes; - arraySizes->setOuterSize(resources.maxDrawBuffers); - fragData.setArraySizes(arraySizes); + TArraySizes& arraySizes = *new TArraySizes; + arraySizes.addInnerSize(resources.maxDrawBuffers); + fragData.newArraySizes(arraySizes); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 56f65a6..4f44376 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -558,9 +558,9 @@ void TParseContext::checkIndex(const TSourceLoc& loc, const TType& type, int& in error(loc, "", "[", "index out of range '%d'", index); index = 0; } else if (type.isArray()) { - if (type.isExplicitlySizedArray() && index >= type.getArraySize()) { + if (type.isExplicitlySizedArray() && index >= type.getOuterArraySize()) { error(loc, "", "[", "array index out of range '%d'", index); - index = type.getArraySize() - 1; + index = type.getOuterArraySize() - 1; } } else if (type.isVector()) { if (index >= type.getVectorSize()) { @@ -629,10 +629,10 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type) return; if (language == EShLangTessControl || language == EShLangTessEvaluation) { - if (type.getArraySize() != resources.maxPatchVertices) { + if (type.getOuterArraySize() != resources.maxPatchVertices) { if (type.isExplicitlySizedArray()) error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", ""); - type.changeArraySize(resources.maxPatchVertices); + type.changeOuterArraySize(resources.maxPatchVertices); } } } @@ -662,7 +662,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm if (symbolNode->getType().isImplicitlySizedArray()) { int newSize = getIoArrayImplicitSize(); if (newSize) - symbolNode->getWritableType().changeArraySize(newSize); + symbolNode->getWritableType().changeOuterArraySize(newSize); } } @@ -710,8 +710,8 @@ int TParseContext::getIoArrayImplicitSize() const void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name) { if (type.isImplicitlySizedArray()) - type.changeArraySize(requiredSize); - else if (type.getArraySize() != requiredSize) { + type.changeOuterArraySize(requiredSize); + else if (type.getOuterArraySize() != requiredSize) { if (language == EShLangGeometry) error(loc, "inconsistent input primitive for array size of", feature, name.c_str()); else if (language == EShLangTessControl) @@ -1203,7 +1203,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); } } else - length = type.getArraySize(); + length = type.getOuterArraySize(); } else if (type.isMatrix()) length = type.getMatrixCols(); else if (type.isVector()) @@ -1993,17 +1993,41 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T error(loc, "array constructor must have at least one argument", "constructor", ""); return true; } + if (type.isImplicitlySizedArray()) { // auto adapt the constructor type to the number of arguments - type.changeArraySize(function.getParamCount()); - } else if (type.getArraySize() != function.getParamCount()) { + type.changeOuterArraySize(function.getParamCount()); + } else if (type.getOuterArraySize() != function.getParamCount()) { error(loc, "array constructor needs one argument per array element", "constructor", ""); return true; } + + if (type.isArrayOfArrays()) { + // Types have to match, but we're still making the type. + // Finish making the type, and the comparison is done later + // when checking for conversion. + TArraySizes& arraySizes = type.getArraySizes(); + + // At least the dimensionalities have to match. + if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes().getNumDims() + 1) { + error(loc, "array constructor argument not correct type to construct array element", "constructior", ""); + return true; + } + + if (arraySizes.isInnerImplicit()) { + // "Arrays of arrays ..., and the size for any dimension is optional" + // That means we need to adopt (from the first argument) the other array sizes into the type. + for (int d = 1; d < arraySizes.getNumDims(); ++d) { + if (arraySizes.getDimSize(d) == UnsizedArraySize) { + arraySizes.setDimSize(d, function[0].type->getArraySizes().getDimSize(d - 1)); + } + } + } + } } - if (arrayArg && op != EOpConstructStruct) { - error(loc, "constructing from a non-dereferenced array", "constructor", ""); + if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) { + error(loc, "constructing non-array constituent from array argument", "constructor", ""); return true; } @@ -2490,13 +2514,13 @@ bool TParseContext::arrayError(const 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()) + else if (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()) + else if (type.isStruct()) requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input"); } @@ -2522,11 +2546,24 @@ void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& typ } } -void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, int size, bool initializer) +void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer) { - // desktop always allows unsized variable arrays, - // ES always allows them if there is an initializer present to get the size from - if (parsingBuiltins || profile != EEsProfile || initializer) + assert(arraySizes); + + // always allow special built-in ins/outs sized to topologies + if (parsingBuiltins) + return; + + // always allow an initializer to set any unknown array sizes + if (initializer) + return; + + // No environment lets any non-outer-dimension that's to be implicitly sized + if (arraySizes->isInnerImplicit()) + error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", ""); + + // desktop always allows outer-dimension-unsized variable arrays, + if (profile != EEsProfile) return; // for ES, if size isn't coming from an initializer, it has to be explicitly declared now, @@ -2553,7 +2590,7 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q break; } - arraySizeRequiredCheck(loc, size); + arraySizeRequiredCheck(loc, arraySizes->getOuterSize()); } void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc) @@ -2563,15 +2600,9 @@ void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc) requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); profileRequires(loc, EEsProfile, 310, nullptr, feature); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature); - - static int once = false; - if (! once) { - warn(loc, feature, "Not supported yet.", ""); - once = true; - } } -void TParseContext::arrayDimCheck(const TSourceLoc& loc, TArraySizes* sizes1, TArraySizes* sizes2) +void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TArraySizes* sizes1, const TArraySizes* sizes2) { if ((sizes1 && sizes2) || (sizes1 && sizes1->getNumDims() > 1) || @@ -2579,13 +2610,28 @@ void TParseContext::arrayDimCheck(const TSourceLoc& loc, TArraySizes* sizes1, TA arrayOfArrayVersionCheck(loc); } -void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, TArraySizes* sizes2) +void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, const TArraySizes* sizes2) { + // skip checking for multiple dimensions on the type; it was caught earlier if ((type && type->isArray() && sizes2) || (sizes2 && sizes2->getNumDims() > 1)) arrayOfArrayVersionCheck(loc); } +// Merge array dimensions listed in 'sizes' onto the type's array dimensions. +// +// From the spec: "vec4[2] a[3]; // size-3 array of size-2 array of vec4" +// +// That means, the 'sizes' go in front of the 'type' as outermost sizes. +// 'type' is the type part of the declaration (to the left) +// 'sizes' is the arrayness tagged on the identifier (to the right) +// +void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes) +{ + if (sizes) + type.addArrayOuterSizes(*sizes); +} + // // Do all the semantic checking for declaring or redeclaring an array, with and // without a size, and make the right changes to the symbol table. @@ -2642,19 +2688,25 @@ void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, con error(loc, "redeclaring non-array as array", identifier.c_str(), ""); return; } - if (existingType.isExplicitlySizedArray()) { - // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size - if (! (isIoResizeArray(type) && existingType.getArraySize() == type.getArraySize())) - error(loc, "redeclaration of array with size", identifier.c_str(), ""); + + if (! existingType.sameElementType(type)) { + error(loc, "redeclaration of array with a different element type", identifier.c_str(), ""); return; } - if (! existingType.sameElementType(type)) { - error(loc, "redeclaration of array with a different type", identifier.c_str(), ""); + if (! existingType.sameInnerArrayness(type)) { + error(loc, "redeclaration of array with a different array dimensions or sizes", identifier.c_str(), ""); return; } - arrayLimitCheck(loc, identifier, type.getArraySize()); + if (existingType.isExplicitlySizedArray()) { + // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size + if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize())) + error(loc, "redeclaration of array with size", identifier.c_str(), ""); + return; + } + + arrayLimitCheck(loc, identifier, type.getOuterArraySize()); existingType.updateArraySizes(type); @@ -2954,7 +3006,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray()) error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), ""); else if (newType.isArray()) - arrayLimitCheck(loc, member->type->getFieldName(), newType.getArraySize()); + arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize()); if (newType.getQualifier().isMemory()) error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); if (newType.getQualifier().hasLayout()) @@ -2990,10 +3042,10 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT else if (type.isArray()) { if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize) error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), ""); - else if (type.isExplicitlySizedArray() && type.getArraySize() != arraySizes->getOuterSize()) + else if (type.isExplicitlySizedArray() && type.getArraySizes() != *arraySizes) error(loc, "cannot change array size of redeclared block", blockName.c_str(), ""); else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize) - type.changeArraySize(arraySizes->getOuterSize()); + type.changeOuterArraySize(arraySizes->getOuterSize()); } symbolTable.insert(*block); @@ -3224,7 +3276,7 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable); } -// Do limit checks against for all built-in arrays. +// Do limit checks for built-in arrays. void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size) { if (identifier.compare("gl_TexCoord") == 0) @@ -3806,7 +3858,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if (type.getBasicType() == EbtSampler) { int lastBinding = qualifier.layoutBinding; if (type.isArray()) - lastBinding += type.getArraySize(); + lastBinding += type.getCumulativeArraySize(); if (lastBinding >= resources.maxCombinedTextureImageUnits) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); } @@ -3990,7 +4042,7 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) // Check for overlap int numOffsets = 4; if (symbol.getType().isArray()) - numOffsets *= symbol.getType().getArraySize(); + numOffsets *= symbol.getType().getCumulativeArraySize(); int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets); if (repeated >= 0) error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated); @@ -4138,6 +4190,9 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType // Returns a subtree node that computes an initializer, if needed. // Returns nullptr if there is no code to execute for initialization. // +// 'publicType' is the type part of the declaration (to the left) +// 'arraySizes' is the arrayness tagged on the identifier (to the right) +// TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer) { TType type(publicType); @@ -4170,13 +4225,12 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden if (arraySizes || type.isArray()) { // Arrayness is potentially coming both from the type and from the // variable: "int[] a[];" or just one or the other. - // For now, arrays of arrays aren't supported, so it's just one or the - // other. Move it to the type, so all arrayness is part of the type. + // Merge it all to the type, so all arrayness is part of the type. arrayDimCheck(loc, &type, arraySizes); - if (arraySizes) - type.setArraySizes(arraySizes); + arrayDimMerge(type, arraySizes); - arrayUnsizedCheck(loc, type.getQualifier(), type.getArraySize(), initializer != nullptr); + // Check that implicit sizing is only where allowed. + arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr); if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type)) declareArray(loc, identifier, type, symbol, newDeclaration); @@ -4299,10 +4353,21 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp return nullptr; } - // Fix arrayness if variable is unsized, getting size from the initializer - if (initializer->getType().isArray() && initializer->getType().isExplicitlySizedArray() && + // Fix outer arrayness if variable is unsized, getting size from the initializer + if (initializer->getType().isExplicitlySizedArray() && variable->getType().isImplicitlySizedArray()) - variable->getWritableType().changeArraySize(initializer->getType().getArraySize()); + variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize()); + + // Inner arrayness can also get set by an initializer + if (initializer->getType().isArrayOfArrays() && variable->getType().isArrayOfArrays() && + initializer->getType().getArraySizes()->getNumDims() == + variable->getType().getArraySizes()->getNumDims()) { + // adopt unsized sizes from the initializer's sizes + for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) { + if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) + variable->getWritableType().getArraySizes().setDimSize(d, initializer->getType().getArraySizes()->getDimSize(d)); + } + } // Uniform and global consts require a constant initializer if (qualifier == EvqUniform && initializer->getType().getQualifier().storage != EvqConst) { @@ -4390,9 +4455,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate. // Later on, initializer execution code will deal with array size logic. TType arrayType; - arrayType.shallowCopy(type); - arrayType.setArraySizes(type); - arrayType.changeArraySize((int)initList->getSequence().size()); + arrayType.shallowCopy(type); // sharing struct stuff is fine + arrayType.newArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below + + // edit array sizes to fill in unsized dimensions + arrayType.changeOuterArraySize((int)initList->getSequence().size()); + TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped(); + if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() && + arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) { + for (int d = 1; d < arrayType.getArraySizes().getNumDims(); ++d) { + if (arrayType.getArraySizes().getDimSize(d) == UnsizedArraySize) + arrayType.getArraySizes().setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1)); + } + } + TType elementType(arrayType, 0); // dereferenced type for (size_t i = 0; i < initList->getSequence().size(); ++i) { initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped()); @@ -4455,9 +4531,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* memberTypes = type.getStruct()->begin(); TType elementType; - elementType.shallowCopy(type); - if (type.isArray()) - elementType.dereference(); + if (type.isArray()) { + TType dereferenced(type, 0); + elementType.shallowCopy(dereferenced); + } else + elementType.shallowCopy(type); bool singleArg; if (aggrNode) { @@ -4471,11 +4549,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* TIntermTyped *newNode; if (singleArg) { // If structure constructor or array constructor is being called - // for only one parameter inside the structure, we need to call constructStruct function once. + // for only one parameter inside the structure, we need to call constructAggregate function once. if (type.isArray()) - newNode = constructStruct(node, elementType, 1, node->getLoc()); + newNode = constructAggregate(node, elementType, 1, node->getLoc()); else if (op == EOpConstructStruct) - newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc()); + newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc()); else newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false); @@ -4501,9 +4579,9 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* for (TIntermSequence::iterator p = sequenceVector.begin(); p != sequenceVector.end(); p++, paramCount++) { if (type.isArray()) - newNode = constructStruct(*p, elementType, paramCount+1, node->getLoc()); + newNode = constructAggregate(*p, elementType, paramCount+1, node->getLoc()); else if (op == EOpConstructStruct) - newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc()); + newNode = constructAggregate(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc()); else newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true); @@ -4610,12 +4688,12 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T return intermediate.setAggregateOperator(newNode, op, type, loc); } -// This function tests for the type of the parameters to the structures constructors. Raises +// This function tests for the type of the parameters to the structure or array constructor. Raises // an error message if the expected type does not match the parameter passed to the constructor. // // Returns nullptr for an error or the input node itself if the expected and the given parameter types match. // -TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc) +TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc) { TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped()); if (! converted || converted->getType() != type) { @@ -4635,9 +4713,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con { blockStageIoCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier); - if (arraySizes) - arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes->getOuterSize(), false); - arrayDimCheck(loc, arraySizes, nullptr); + if (arraySizes) { + arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false); + arrayDimCheck(loc, arraySizes, 0); + } // fix and check for member storage qualifiers and types that don't belong within a block for (unsigned int member = 0; member < typeList.size(); ++member) { @@ -4766,7 +4845,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con TType blockType(&typeList, *blockName, currentBlockQualifier); if (arraySizes) - blockType.setArraySizes(arraySizes); + blockType.newArraySizes(*arraySizes); else ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index e008c0f..81c9eac 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -138,10 +138,11 @@ public: bool arrayError(const TSourceLoc&, const TType&); void arraySizeRequiredCheck(const TSourceLoc&, int size); void structArrayCheck(const TSourceLoc&, const TType& structure); - void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, int size, bool initializer); + void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer); void arrayOfArrayVersionCheck(const TSourceLoc&); - void arrayDimCheck(const TSourceLoc&, TArraySizes* sizes1, TArraySizes* sizes2); - void arrayDimCheck(const TSourceLoc&, const TType*, TArraySizes*); + void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2); + void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*); + void arrayDimMerge(TType& type, const TArraySizes* sizes); bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType); void boolCheck(const TSourceLoc&, const TIntermTyped*); void boolCheck(const TSourceLoc&, const TPublicType&); @@ -189,7 +190,7 @@ public: void declareTypeDefaults(const TSourceLoc&, const TPublicType&); TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator); - TIntermTyped* constructStruct(TIntermNode*, const TType&, int, const TSourceLoc&); + TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); void blockStageIoCheck(const TSourceLoc&, const TQualifier&); diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index e07a984..3a401ec 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -113,7 +113,7 @@ void TType::buildMangledName(TString& mangledName) const int maxSize = 11; char buf[maxSize]; for (int i = 0; i < arraySizes->getNumDims(); ++i) { - snprintf(buf, maxSize, "%d", (*arraySizes)[i]); + snprintf(buf, maxSize, "%d", arraySizes->getDimSize(i)); mangledName += '['; mangledName += buf; mangledName += ']'; diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 2726014..0c87757 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -691,7 +691,7 @@ declaration // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); - parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); + parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); $$ = 0; } | block_structure SEMICOLON { @@ -1240,7 +1240,7 @@ array_specifier : LEFT_BRACKET RIGHT_BRACKET { $$.loc = $1.loc; $$.arraySizes = new TArraySizes; - $$.arraySizes->setOuterSize(0); + $$.arraySizes->addInnerSize(); } | LEFT_BRACKET constant_expression RIGHT_BRACKET { $$.loc = $1.loc; @@ -1248,18 +1248,18 @@ array_specifier int size; parseContext.arraySizeCheck($2->getLoc(), $2, size); - $$.arraySizes->setOuterSize(size); + $$.arraySizes->addInnerSize(size); } | array_specifier LEFT_BRACKET RIGHT_BRACKET { $$ = $1; - $$.arraySizes->setOuterSize(0); + $$.arraySizes->addInnerSize(); } | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET { $$ = $1; int size; parseContext.arraySizeCheck($3->getLoc(), $3, size); - $$.arraySizes->setOuterSize(size); + $$.arraySizes->addInnerSize(size); } ; @@ -1903,19 +1903,19 @@ precision_qualifier parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "highp precision qualifier"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); if (parseContext.profile == EEsProfile) - $$.qualifier.precision = EpqHigh; + $$.qualifier.precision = EpqHigh; } | MEDIUM_PRECISION { parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "mediump precision qualifier"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); if (parseContext.profile == EEsProfile) - $$.qualifier.precision = EpqMedium; + $$.qualifier.precision = EpqMedium; } | LOW_PRECISION { parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "lowp precision qualifier"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); if (parseContext.profile == EEsProfile) - $$.qualifier.precision = EpqLow; + $$.qualifier.precision = EpqLow; } ; @@ -2020,7 +2020,7 @@ struct_declarator $$.type = new TType(EbtVoid); $$.loc = $1.loc; $$.type->setFieldName(*$1.string); - $$.type->setArraySizes($2.arraySizes); + $$.type->newArraySizes(*$2.arraySizes); } ; @@ -2354,7 +2354,7 @@ jump_statement $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc); } } else - $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc); + $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc); } | DISCARD SEMICOLON { parseContext.requireStage($1.loc, EShLangFragment, "discard"); diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index eafe135..751d0c3 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -240,9 +240,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) { if (type.isImplicitlySizedArray() && unitType.isArray()) { - int newImplicitArraySize = unitType.getArraySize(); - if (newImplicitArraySize == 0) - newImplicitArraySize = unitType.getImplicitArraySize(); + int newImplicitArraySize = unitType.isImplicitlySizedArray() ? unitType.getImplicitArraySize() : unitType.getOuterArraySize(); if (newImplicitArraySize > type.getImplicitArraySize ()) type.setImplicitArraySize(newImplicitArraySize); } @@ -623,7 +621,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ int size; if (qualifier.isUniformOrBuffer()) { if (type.isArray()) - size = type.getArraySize(); + size = type.getCumulativeArraySize(); else size = 1; } else { @@ -693,12 +691,13 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const // "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n // consecutive locations..." if (type.isArray()) { + // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness TType elementType(type, 0); if (type.isImplicitlySizedArray()) { // TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early. return computeTypeLocationSize(elementType); } else - return type.getArraySize() * computeTypeLocationSize(elementType); + return type.getOuterArraySize() * computeTypeLocationSize(elementType); } // "The locations consumed by block and structure members are determined by applying the rules above @@ -783,10 +782,11 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains // that component's size. Aggregate types are flattened down to the component // level to get this sequence of components." - if (type.isArray()) { + if (type.isArray()) { + // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness assert(type.isExplicitlySizedArray()); TType elementType(type, 0); - return type.getArraySize() * computeTypeXfbSize(elementType, containsDouble); + return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble); } if (type.isStruct()) { @@ -913,12 +913,13 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140) // rules 4, 6, and 8 if (type.isArray()) { + // TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness TType derefType(type, 0); alignment = getBaseAlignment(derefType, size, std140); if (std140) alignment = std::max(baseAlignmentVec4Std140, alignment); RoundToPow2(size, alignment); - size *= type.getArraySize(); + size *= type.getOuterArraySize(); return alignment; } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index 3d96743..85caff7 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -166,7 +166,7 @@ public: switch (visitNode->getOp()) { case EOpIndexIndirect: // Visit all the indices of this array, and for each one add on the remaining dereferencing - for (int i = 0; i < visitNode->getLeft()->getType().getArraySize(); ++i) { + for (int i = 0; i < visitNode->getLeft()->getType().getOuterArraySize(); ++i) { TString newBaseName = name; if (baseType.getBasicType() != EbtBlock) newBaseName.append(TString("[") + String(i) + "]"); @@ -201,7 +201,7 @@ public: if (terminalType->isArray()) { // Visit all the indices of this array, and for each one, // fully explode the remaining aggregate to dereference - for (int i = 0; i < terminalType->getArraySize(); ++i) { + for (int i = 0; i < terminalType->getOuterArraySize(); ++i) { TString newBaseName = name; newBaseName.append(TString("[") + String(i) + "]"); TType derefType(*terminalType, 0); @@ -286,7 +286,7 @@ public: anonymous = IsAnonymous(base->getName()); if (base->getType().isArray()) { assert(! anonymous); - for (int e = 0; e < base->getType().getArraySize(); ++e) + for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e) blockIndex = addBlockName(base->getType().getTypeName() + "[" + String(e) + "]", getBlockSize(base->getType())); } else blockIndex = addBlockName(base->getType().getTypeName(), getBlockSize(base->getType())); @@ -610,7 +610,7 @@ public: int mapToGlArraySize(const TType& type) { - return type.isArray() ? type.getArraySize() : 1; + return type.isArray() ? type.getOuterArraySize() : 1; } typedef std::list TFunctionStack; -- 2.7.4