From a06bd527ca0e21e401f36b6062481bf76f5b067b Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Fri, 11 Sep 2015 15:15:23 -0600 Subject: [PATCH 1/4] SPV: Correct generation of transparent offsets for implicitly assigned offsets. --- SPIRV/GlslangToSpv.cpp | 2 +- glslang/Include/revision.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 302db80a..cc027383 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -1426,7 +1426,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty int nextOffset; updateMemberOffset(type, glslangType, offset, nextOffset); if (offset >= 0) - builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutOffset); + builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset); offset = nextOffset; } diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index f9349893..37a027a4 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "3.0.746" -#define GLSLANG_DATE "09-Sep-2015" +#define GLSLANG_REVISION "3.0.747" +#define GLSLANG_DATE "11-Sep-2015" From 9312269d09fd4d8333e48f49def9a0e7bb57f9ad Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Fri, 11 Sep 2015 15:25:38 -0600 Subject: [PATCH 2/4] Front-end Arrays of arrays: Add ES-specific checks and tests. AoA should be quite close to done now. --- Test/310.comp | 2 + Test/310.frag | 2 + Test/310AofA.vert | 101 +++ Test/430.comp | 2 +- Test/baseResults/300.frag.out | 3 +- Test/baseResults/300.vert.out | 2 +- Test/baseResults/310.comp.out | 4 +- Test/baseResults/310.frag.out | 5 +- Test/baseResults/310AofA.vert.out | 592 +++++++++++++++++- .../310implicitSizeArrayError.vert.out | 2 +- Test/baseResults/430.comp.out | 3 +- glslang/Include/arrays.h | 1 + glslang/Include/revision.h | 2 +- glslang/MachineIndependent/ParseHelper.cpp | 36 +- glslang/MachineIndependent/ParseHelper.h | 4 +- glslang/MachineIndependent/glslang.y | 14 +- 16 files changed, 742 insertions(+), 33 deletions(-) diff --git a/Test/310.comp b/Test/310.comp index 4c2cfd71..d6b2c97d 100644 --- a/Test/310.comp +++ b/Test/310.comp @@ -236,3 +236,5 @@ float t__; // ERROR, no __ until revision 310 // ERROR, no __ until revision 310 #define __D + +shared vec4 arr[2][3][4]; diff --git a/Test/310.frag b/Test/310.frag index 116a0a73..78f13f60 100644 --- a/Test/310.frag +++ b/Test/310.frag @@ -427,3 +427,5 @@ layout(blend_support_hsl_luminosity) struct badS {int i;}; // ERROR, only on layout(blend_support_hsl_luminosity) void blendFoo() { } // ERROR, only on standalone void blendFoo(layout(blend_support_hsl_luminosity) vec3 v) { } // ERROR, only on standalone layout(blend_support_flizbit) out; // ERROR, no flizbit + +out vec4 outAA[2][2]; // ERROR diff --git a/Test/310AofA.vert b/Test/310AofA.vert index eb68d893..a196388d 100644 --- a/Test/310AofA.vert +++ b/Test/310AofA.vert @@ -12,3 +12,104 @@ void main() { int[NY][NX] d; f(false, 12.1, uint[NZ](uint(0),uint(1),uint(1),uint(2)), d); } + +buffer b { + float u[]; // ERROR + vec4 v[]; +} name[3]; + +uniform ub { + float u; + vec4 v[]; // ERROR +} uname[3]; + +buffer b2 { + float u; + vec4 v[][]; // ERROR +} name2[3]; + +buffer b3 { + float u; + vec4 v[][7]; +} name3[3]; + +// General arrays of arrays + +float[4][5][6] many[1][2][3]; + +float gu[][7]; // ERROR, size required +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 foo2() +{ + { + 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))); + + 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[5][7]; + u[5][2] = 5.0; // ERROR + foo(u); + + vec4 badAss[3]; + name[1].v[-1]; // ERROR + name[1].v[1] = vec4(4.3); + name[1].v = badAss; // ERROR, bad assignemnt + + name3[0].v[1].length(); // 7 + name3[0].v.length(); // run time +} + +struct badS { + int sa[]; // ERROR + int a[][]; // ERROR + int b[][2]; // ERROR + int c[2][]; // ERROR + int d[][4]; // ERROR +}; + +in float inArray[2][3]; // ERROR +out float outArray[2][3]; // ERROR + +uniform ubaa { + int a; +} ubaaname[2][3]; // ERROR diff --git a/Test/430.comp b/Test/430.comp index 663fddec..0929432b 100644 --- a/Test/430.comp +++ b/Test/430.comp @@ -20,7 +20,7 @@ buffer ShaderStorageBlock buffer InvalidShaderStorageBlock { - float values[]; // ERROR + float values[]; int value; } invalid; diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out index b175028e..a21667e6 100644 --- a/Test/baseResults/300.frag.out +++ b/Test/baseResults/300.frag.out @@ -26,6 +26,7 @@ ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled 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 ERROR: 0:100: 'arrays of arrays' : not supported for this version or the enabled extensions +ERROR: 0:100: 'array-of-array of block' : not supported with this profile: es ERROR: 0:111: 'variable indexing fragment shader ouput array' : not supported with this profile: es ERROR: 0:119: '==' : can't use with samplers or structs containing samplers ERROR: 0:120: '!=' : can't use with samplers or structs containing samplers @@ -42,7 +43,7 @@ ERROR: 0:157: 'invariant' : can only apply to an output ERROR: 0:158: 'invariant' : can only apply to an output ERROR: 0:160: 'imageBuffer' : Reserved word. ERROR: 0:160: '' : syntax error -ERROR: 43 compilation errors. No code generated. +ERROR: 44 compilation errors. No code generated. Shader version: 300 diff --git a/Test/baseResults/300.vert.out b/Test/baseResults/300.vert.out index cb861f6c..d3d7cba3 100644 --- a/Test/baseResults/300.vert.out +++ b/Test/baseResults/300.vert.out @@ -17,7 +17,7 @@ ERROR: 0:56: '#error' : GL_ES is set ERROR: 0:62: '' : array size required ERROR: 0:63: '' : array size required ERROR: 0:64: '' : array size required -ERROR: 0:65: 'implicitly-sized array in a block' : not supported with this profile: es +ERROR: 0:65: '' : array size required ERROR: 0:67: '' : array size required ERROR: 0:76: 'invariant' : cannot change qualification after use ERROR: 0:78: 'invariant' : can only apply to an output diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out index 645b2ccd..f3775e37 100644 --- a/Test/baseResults/310.comp.out +++ b/Test/baseResults/310.comp.out @@ -2,7 +2,7 @@ Warning, version 310 is not yet complete; most version-specific features are present, but some are missing. ERROR: 0:4: 'local_size' : cannot change previously set size ERROR: 0:5: 'local_size' : too large; see gl_MaxComputeWorkGroupSize -ERROR: 0:23: 'values' : only the last member of a buffer block can be run-time sized +ERROR: 0:23: '' : array size required ERROR: 0:39: 'in' : global storage input qualifier cannot be used in a compute shader ERROR: 0:39: 'location qualifier on input' : not supported in this stage: compute ERROR: 0:40: 'in' : global storage input qualifier cannot be used in a compute shader @@ -502,6 +502,7 @@ ERROR: node is still EOpNull! 0:? 'inbi' (in block{in highp int a}) 0:? 'outbi' (out block{out highp int a}) 0:? 't__' (global highp float) +0:? 'arr' (shared 2-element array of 3-element array of 4-element array of highp 4-component vector of float) Linked compute stage: @@ -928,4 +929,5 @@ ERROR: node is still EOpNull! 0:? 'inbi' (in block{in highp int a}) 0:? 'outbi' (out block{out highp int a}) 0:? 't__' (global highp float) +0:? 'arr' (shared 2-element array of 3-element array of 4-element array of highp 4-component vector of float) diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out index 910cd9c5..9769eb6a 100644 --- a/Test/baseResults/310.frag.out +++ b/Test/baseResults/310.frag.out @@ -129,7 +129,8 @@ ERROR: 0:426: 'blend equation' : can only apply to a standalone qualifier ERROR: 0:427: 'blend equation' : can only apply to a standalone qualifier ERROR: 0:428: 'blend equation' : can only apply to a standalone qualifier ERROR: 0:429: 'blend_support' : unknown blend equation -ERROR: 121 compilation errors. No code generated. +ERROR: 0:431: 'fragment-shader array-of-array output' : not supported with this profile: es +ERROR: 122 compilation errors. No code generated. Shader version: 310 @@ -1006,6 +1007,7 @@ ERROR: node is still EOpNull! 0:? 'colorfsi' (flat sample in mediump 4-component vector of float) 0:? 'sampInArray' (smooth sample in 4-element array of mediump 3-component vector of float) 0:? 'badout' (out mediump 4-component vector of float) +0:? 'outAA' (out 2-element array of 2-element array of mediump 4-component vector of float) Linked fragment stage: @@ -1886,4 +1888,5 @@ ERROR: node is still EOpNull! 0:? 'colorfsi' (flat sample in mediump 4-component vector of float) 0:? 'sampInArray' (smooth sample in 4-element array of mediump 3-component vector of float) 0:? 'badout' (out mediump 4-component vector of float) +0:? 'outAA' (out 2-element array of 2-element array of mediump 4-component vector of float) diff --git a/Test/baseResults/310AofA.vert.out b/Test/baseResults/310AofA.vert.out index 63598fcf..476646ca 100644 --- a/Test/baseResults/310AofA.vert.out +++ b/Test/baseResults/310AofA.vert.out @@ -1,8 +1,32 @@ 310AofA.vert Warning, version 310 is not yet complete; most version-specific features are present, but some are missing. +ERROR: 0:17: '' : array size required +ERROR: 0:23: '' : array size required +ERROR: 0:28: '[]' : only outermost dimension of an array of arrays can be implicitly sized +ERROR: 0:40: '' : array size required +ERROR: 0:48: 'constructor' : constructing non-array constituent from array argument +ERROR: 0:49: 'constructior' : array constructor argument not correct type to construct array element +ERROR: 0:62: '[' : array index out of range '4' +ERROR: 0:78: 'assign' : cannot convert from 'global 4-element array of 7-element array of highp float' to 'global 5-element array of 7-element array of highp float' +ERROR: 0:79: 'assign' : cannot convert from 'global 4-element array of 7-element array of highp float' to 'global implicitly-sized array of 7-element array of highp float' +ERROR: 0:81: 'foo' : no matching overloaded function found +ERROR: 0:86: '==' : wrong operand types: no operation '==' exists that takes a left-hand operand of type 'global 4-element array of 7-element array of highp float' and a right operand of type 'global 5-element array of 7-element array of highp float' (or there is no acceptable conversion) +ERROR: 0:90: '[' : array index out of range '5' +ERROR: 0:94: '[' : index out of range '-1' +ERROR: 0:96: 'assign' : cannot convert from 'temp 3-element array of highp 4-component vector of float' to 'layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float' +ERROR: 0:103: '' : array size required +ERROR: 0:104: '' : array size required +ERROR: 0:105: '' : array size required +ERROR: 0:106: '' : array size required +ERROR: 0:107: '' : array size required +ERROR: 0:110: 'vertex input arrays' : not supported with this profile: es +ERROR: 0:111: 'vertex-shader array-of-array output' : not supported with this profile: es +ERROR: 0:113: 'array-of-array of block' : not supported with this profile: es +ERROR: 22 compilation errors. No code generated. + Shader version: 310 -0:? Sequence +ERROR: node is still EOpNull! 0:8 Function Definition: f(b1;f1;u1[4];i1[3][2]; (global void) 0:8 Function Parameters: 0:8 'a' (in bool) @@ -23,7 +47,289 @@ Shader version: 310 0:13 1 (const uint) 0:13 2 (const uint) 0:13 'd' (temp 3-element array of 2-element array of highp int) +0:44 Function Definition: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:44 Function Parameters: +0:44 'a' (in 5-element array of 7-element array of highp float) +0:? Sequence +0:47 move second child to first child (temp 7-element array of highp float) +0:47 'r' (temp 7-element array of highp float) +0:47 direct index (temp 7-element array of highp float) +0:47 'a' (in 5-element array of 7-element array of highp float) +0:47 Constant: +0:47 2 (const int) +0:48 Constant: +0:48 0.000000 +0:49 Constant: +0:49 0.000000 +0:50 Branch: Return with expression +0:50 Construct float (temp 4-element array of 7-element array of float) +0:50 direct index (temp 7-element array of highp float) +0:50 'a' (in 5-element array of 7-element array of highp float) +0:50 Constant: +0:50 0 (const int) +0:50 direct index (temp 7-element array of highp float) +0:50 'a' (in 5-element array of 7-element array of highp float) +0:50 Constant: +0:50 1 (const int) +0:50 'r' (temp 7-element array of highp float) +0:50 direct index (temp 7-element array of highp float) +0:50 'a' (in 5-element array of 7-element array of highp float) +0:50 Constant: +0:50 3 (const int) +0:51 Branch: Return with expression +0:51 Construct float (temp 4-element array of 7-element array of float) +0:51 direct index (temp 7-element array of highp float) +0:51 'a' (in 5-element array of 7-element array of highp float) +0:51 Constant: +0:51 0 (const int) +0:51 direct index (temp 7-element array of highp float) +0:51 'a' (in 5-element array of 7-element array of highp float) +0:51 Constant: +0:51 1 (const int) +0:51 'r' (temp 7-element array of highp float) +0:51 direct index (temp 7-element array of highp float) +0:51 'a' (in 5-element array of 7-element array of highp float) +0:51 Constant: +0:51 3 (const int) +0:52 Branch: Return with expression +0:52 Construct float (temp 4-element array of 7-element array of float) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 0 (const int) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 1 (const int) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 2 (const int) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 3 (const int) +0:55 Function Definition: bar(f1[5][7]; (global void) +0:55 Function Parameters: +0:55 '' (in 5-element array of 7-element array of highp float) +0:57 Function Definition: foo2( (global void) +0:57 Function Parameters: +0:? Sequence +0:? Sequence +0:62 move second child to first child (temp highp float) +0:62 direct index (temp highp float) +0:62 direct index (temp 2-element array of highp float) +0:62 direct index (temp 4-element array of 2-element array of highp float) +0:62 'gu' (temp 3-element array of 4-element array of 2-element array of highp float) +0:62 Constant: +0:62 2 (const int) +0:62 Constant: +0:62 4 (const int) +0:62 Constant: +0:62 1 (const int) +0:62 Constant: +0:62 4.000000 +0:64 Sequence +0:64 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:64 'ca4' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:66 Constant: +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:67 Sequence +0:67 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:67 'caim' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:69 Constant: +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:70 Sequence +0:70 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:70 'caim2' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:72 Constant: +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:73 Sequence +0:73 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:73 'caim3' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:75 Constant: +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:77 move second child to first child (temp 4-element array of 7-element array of highp float) +0:77 'g4' (global 4-element array of 7-element array of highp float) +0:77 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:77 'g5' (global 5-element array of 7-element array of highp float) +0:78 'g5' (global 5-element array of 7-element array of highp float) +0:79 'gu' (global implicitly-sized array of 7-element array of highp float) +0:81 Constant: +0:81 0.000000 +0:82 Function Call: bar(f1[5][7]; (global void) +0:82 'g5' (global 5-element array of 7-element array of highp float) +0:84 Test condition and select (temp void) +0:84 Condition +0:84 Compare Equal (temp bool) +0:84 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:84 'g5' (global 5-element array of 7-element array of highp float) +0:84 'g4' (global 4-element array of 7-element array of highp float) +0:84 true case is null +0:86 Test condition and select (temp void) +0:86 Condition +0:86 Constant: +0:86 false (const bool) +0:86 true case is null +0:90 move second child to first child (temp highp float) +0:90 direct index (temp highp float) +0:90 direct index (temp 7-element array of highp float) +0:90 'u' (temp 5-element array of 7-element array of highp float) +0:90 Constant: +0:90 5 (const int) +0:90 Constant: +0:90 2 (const int) +0:90 Constant: +0:90 5.000000 +0:91 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:91 'u' (temp 5-element array of 7-element array of highp float) +0:94 direct index (layout(column_major shared ) temp highp 4-component vector of float) +0:94 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float) +0:94 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:94 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:94 Constant: +0:94 1 (const int) +0:94 Constant: +0:94 1 (const int) +0:94 Constant: +0:94 -1 (const int) +0:95 move second child to first child (temp highp 4-component vector of float) +0:95 direct index (layout(column_major shared ) temp highp 4-component vector of float) +0:95 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float) +0:95 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:95 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:95 Constant: +0:95 1 (const int) +0:95 Constant: +0:95 1 (const int) +0:95 Constant: +0:95 1 (const int) +0:95 Constant: +0:95 4.300000 +0:95 4.300000 +0:95 4.300000 +0:95 4.300000 +0:96 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float) +0:96 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:96 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:96 Constant: +0:96 1 (const int) +0:96 Constant: +0:96 1 (const int) +0:98 Constant: +0:98 7 (const int) +0:99 array length (temp highp int) +0:99 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float) +0:99 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v}) +0:99 'name3' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v}) +0:99 Constant: +0:99 0 (const int) +0:99 Constant: +0:99 1 (const int) 0:? Linker Objects +0:? 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:? 'uname' (layout(column_major shared ) uniform 3-element array of block{layout(column_major shared ) uniform highp float u, layout(column_major shared ) uniform implicitly-sized array of highp 4-component vector of float v}) +0:? 'name2' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of implicitly-sized array of highp 4-component vector of float v}) +0:? 'name3' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v}) +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 highp float) +0:? 'gu' (global implicitly-sized array of 7-element array of highp float) +0:? 'g4' (global 4-element array of 7-element array of highp float) +0:? 'g5' (global 5-element array of 7-element array of highp float) +0:? 'inArray' (in 2-element array of 3-element array of highp float) +0:? 'outArray' (smooth out 2-element array of 3-element array of highp float) +0:? 'ubaaname' (layout(column_major shared ) uniform 2-element array of 3-element array of block{layout(column_major shared ) uniform highp int a}) 0:? 'gl_VertexID' (gl_VertexId highp int VertexId) 0:? 'gl_InstanceID' (gl_InstanceId highp int InstanceId) @@ -32,7 +338,7 @@ Linked vertex stage: Shader version: 310 -0:? Sequence +ERROR: node is still EOpNull! 0:8 Function Definition: f(b1;f1;u1[4];i1[3][2]; (global void) 0:8 Function Parameters: 0:8 'a' (in bool) @@ -53,7 +359,289 @@ Shader version: 310 0:13 1 (const uint) 0:13 2 (const uint) 0:13 'd' (temp 3-element array of 2-element array of highp int) +0:44 Function Definition: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:44 Function Parameters: +0:44 'a' (in 5-element array of 7-element array of highp float) +0:? Sequence +0:47 move second child to first child (temp 7-element array of highp float) +0:47 'r' (temp 7-element array of highp float) +0:47 direct index (temp 7-element array of highp float) +0:47 'a' (in 5-element array of 7-element array of highp float) +0:47 Constant: +0:47 2 (const int) +0:48 Constant: +0:48 0.000000 +0:49 Constant: +0:49 0.000000 +0:50 Branch: Return with expression +0:50 Construct float (temp 4-element array of 7-element array of float) +0:50 direct index (temp 7-element array of highp float) +0:50 'a' (in 5-element array of 7-element array of highp float) +0:50 Constant: +0:50 0 (const int) +0:50 direct index (temp 7-element array of highp float) +0:50 'a' (in 5-element array of 7-element array of highp float) +0:50 Constant: +0:50 1 (const int) +0:50 'r' (temp 7-element array of highp float) +0:50 direct index (temp 7-element array of highp float) +0:50 'a' (in 5-element array of 7-element array of highp float) +0:50 Constant: +0:50 3 (const int) +0:51 Branch: Return with expression +0:51 Construct float (temp 4-element array of 7-element array of float) +0:51 direct index (temp 7-element array of highp float) +0:51 'a' (in 5-element array of 7-element array of highp float) +0:51 Constant: +0:51 0 (const int) +0:51 direct index (temp 7-element array of highp float) +0:51 'a' (in 5-element array of 7-element array of highp float) +0:51 Constant: +0:51 1 (const int) +0:51 'r' (temp 7-element array of highp float) +0:51 direct index (temp 7-element array of highp float) +0:51 'a' (in 5-element array of 7-element array of highp float) +0:51 Constant: +0:51 3 (const int) +0:52 Branch: Return with expression +0:52 Construct float (temp 4-element array of 7-element array of float) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 0 (const int) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 1 (const int) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 2 (const int) +0:52 direct index (temp 7-element array of highp float) +0:52 'a' (in 5-element array of 7-element array of highp float) +0:52 Constant: +0:52 3 (const int) +0:55 Function Definition: bar(f1[5][7]; (global void) +0:55 Function Parameters: +0:55 '' (in 5-element array of 7-element array of highp float) +0:57 Function Definition: foo2( (global void) +0:57 Function Parameters: +0:? Sequence +0:? Sequence +0:62 move second child to first child (temp highp float) +0:62 direct index (temp highp float) +0:62 direct index (temp 2-element array of highp float) +0:62 direct index (temp 4-element array of 2-element array of highp float) +0:62 'gu' (temp 3-element array of 4-element array of 2-element array of highp float) +0:62 Constant: +0:62 2 (const int) +0:62 Constant: +0:62 4 (const int) +0:62 Constant: +0:62 1 (const int) +0:62 Constant: +0:62 4.000000 +0:64 Sequence +0:64 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:64 'ca4' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:66 Constant: +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 0.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:66 1.000000 +0:67 Sequence +0:67 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:67 'caim' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:69 Constant: +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 4.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:69 2.000000 +0:70 Sequence +0:70 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:70 'caim2' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:72 Constant: +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 4.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:72 2.000000 +0:73 Sequence +0:73 move second child to first child (temp 3-element array of 2-element array of highp 4-component vector of float) +0:73 'caim3' (temp 3-element array of 2-element array of highp 4-component vector of float) +0:75 Constant: +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 4.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:75 2.000000 +0:77 move second child to first child (temp 4-element array of 7-element array of highp float) +0:77 'g4' (global 4-element array of 7-element array of highp float) +0:77 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:77 'g5' (global 5-element array of 7-element array of highp float) +0:78 'g5' (global 5-element array of 7-element array of highp float) +0:79 'gu' (global 1-element array of 7-element array of highp float) +0:81 Constant: +0:81 0.000000 +0:82 Function Call: bar(f1[5][7]; (global void) +0:82 'g5' (global 5-element array of 7-element array of highp float) +0:84 Test condition and select (temp void) +0:84 Condition +0:84 Compare Equal (temp bool) +0:84 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:84 'g5' (global 5-element array of 7-element array of highp float) +0:84 'g4' (global 4-element array of 7-element array of highp float) +0:84 true case is null +0:86 Test condition and select (temp void) +0:86 Condition +0:86 Constant: +0:86 false (const bool) +0:86 true case is null +0:90 move second child to first child (temp highp float) +0:90 direct index (temp highp float) +0:90 direct index (temp 7-element array of highp float) +0:90 'u' (temp 5-element array of 7-element array of highp float) +0:90 Constant: +0:90 5 (const int) +0:90 Constant: +0:90 2 (const int) +0:90 Constant: +0:90 5.000000 +0:91 Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of highp float) +0:91 'u' (temp 5-element array of 7-element array of highp float) +0:94 direct index (layout(column_major shared ) temp highp 4-component vector of float) +0:94 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float) +0:94 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:94 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:94 Constant: +0:94 1 (const int) +0:94 Constant: +0:94 1 (const int) +0:94 Constant: +0:94 -1 (const int) +0:95 move second child to first child (temp highp 4-component vector of float) +0:95 direct index (layout(column_major shared ) temp highp 4-component vector of float) +0:95 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float) +0:95 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:95 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:95 Constant: +0:95 1 (const int) +0:95 Constant: +0:95 1 (const int) +0:95 Constant: +0:95 1 (const int) +0:95 Constant: +0:95 4.300000 +0:95 4.300000 +0:95 4.300000 +0:95 4.300000 +0:96 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float) +0:96 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:96 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:96 Constant: +0:96 1 (const int) +0:96 Constant: +0:96 1 (const int) +0:98 Constant: +0:98 7 (const int) +0:99 array length (temp highp int) +0:99 v: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float) +0:99 direct index (layout(column_major shared ) temp block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v}) +0:99 'name3' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v}) +0:99 Constant: +0:99 0 (const int) +0:99 Constant: +0:99 1 (const int) 0:? Linker Objects +0:? 'name' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer implicitly-sized array of highp float u, layout(column_major shared ) buffer implicitly-sized array of highp 4-component vector of float v}) +0:? 'uname' (layout(column_major shared ) uniform 3-element array of block{layout(column_major shared ) uniform highp float u, layout(column_major shared ) uniform 1-element array of highp 4-component vector of float v}) +0:? 'name2' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of implicitly-sized array of highp 4-component vector of float v}) +0:? 'name3' (layout(column_major shared ) buffer 3-element array of block{layout(column_major shared ) buffer highp float u, layout(column_major shared ) buffer implicitly-sized array of 7-element array of highp 4-component vector of float v}) +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 highp float) +0:? 'gu' (global 1-element array of 7-element array of highp float) +0:? 'g4' (global 4-element array of 7-element array of highp float) +0:? 'g5' (global 5-element array of 7-element array of highp float) +0:? 'inArray' (in 2-element array of 3-element array of highp float) +0:? 'outArray' (smooth out 2-element array of 3-element array of highp float) +0:? 'ubaaname' (layout(column_major shared ) uniform 2-element array of 3-element array of block{layout(column_major shared ) uniform highp int a}) 0:? 'gl_VertexID' (gl_VertexId highp int VertexId) 0:? 'gl_InstanceID' (gl_InstanceId highp int InstanceId) diff --git a/Test/baseResults/310implicitSizeArrayError.vert.out b/Test/baseResults/310implicitSizeArrayError.vert.out index 958b668f..a3b98f33 100644 --- a/Test/baseResults/310implicitSizeArrayError.vert.out +++ b/Test/baseResults/310implicitSizeArrayError.vert.out @@ -1,6 +1,6 @@ 310implicitSizeArrayError.vert Warning, version 310 is not yet complete; most version-specific features are present, but some are missing. -ERROR: 0:3: 'implicitly-sized array in a block' : not supported with this profile: es +ERROR: 0:3: '' : array size required ERROR: 1 compilation errors. No code generated. diff --git a/Test/baseResults/430.comp.out b/Test/baseResults/430.comp.out index 29f0f87b..538caa0a 100644 --- a/Test/baseResults/430.comp.out +++ b/Test/baseResults/430.comp.out @@ -2,7 +2,6 @@ Warning, version 430 is not yet complete; most version-specific features are present, but some are missing. ERROR: 0:4: 'local_size' : cannot change previously set size ERROR: 0:5: 'local_size' : too large; see gl_MaxComputeWorkGroupSize -ERROR: 0:23: 'values' : only the last member of a buffer block can be run-time sized ERROR: 0:43: 'in' : global storage input qualifier cannot be used in a compute shader ERROR: 0:43: 'location qualifier on input' : not supported in this stage: compute ERROR: 0:44: 'in' : global storage input qualifier cannot be used in a compute shader @@ -17,7 +16,7 @@ ERROR: 0:65: 'assign' : l-value required "ro" (can't modify a readonly buffer) ERROR: 0:77: '=' : cannot convert from 'temp double' to 'temp int' ERROR: 0:81: 'input block' : not supported in this stage: compute ERROR: 0:85: 'output block' : not supported in this stage: compute -ERROR: 17 compilation errors. No code generated. +ERROR: 16 compilation errors. No code generated. Shader version: 430 diff --git a/glslang/Include/arrays.h b/glslang/Include/arrays.h index cc2cdab2..1d8ec435 100644 --- a/glslang/Include/arrays.h +++ b/glslang/Include/arrays.h @@ -224,6 +224,7 @@ struct TArraySizes { return false; } + bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); } void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); } void dereference() { sizes.pop_front(); } void copyDereferenced(const TArraySizes& rhs) diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 37a027a4..abb7f139 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "3.0.747" +#define GLSLANG_REVISION "3.0.748" #define GLSLANG_DATE "11-Sep-2015" diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index e0f13fbf..4ab1c9f0 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2738,16 +2738,20 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type) else if (type.isStruct()) requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input"); } + if (type.getQualifier().storage == EvqVaryingOut && language == EShLangFragment) { + if (type.isArrayOfArrays()) + requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array output"); + } return false; } // -// Require array to have size +// Require array to be completely sized // -void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, int size) +void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes) { - if (size == UnsizedArraySize) + if (arraySizes.isImplicit()) error(loc, "array size required", "", ""); } @@ -2756,12 +2760,12 @@ void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& typ const TTypeList& structure = *type.getStruct(); for (int m = 0; m < (int)structure.size(); ++m) { const TType& member = *structure[m].type; - if (member.isArray() && ! member.isExplicitlySizedArray()) - arraySizeRequiredCheck(structure[m].loc, 0); + if (member.isArray()) + arraySizeRequiredCheck(structure[m].loc, *member.getArraySizes()); } } -void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer) +void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember) { assert(arraySizes); @@ -2783,6 +2787,12 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q // for ES, if size isn't coming from an initializer, it has to be explicitly declared now, // with very few exceptions + + // last member of ssbo block exception: + if (qualifier.storage == EvqBuffer && lastMember) + return; + + // implicitly-sized io exceptions: switch (language) { case EShLangGeometry: if (qualifier.storage == EvqVaryingIn) @@ -2805,7 +2815,7 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q break; } - arraySizeRequiredCheck(loc, arraySizes->getOuterSize()); + arraySizeRequiredCheck(loc, *arraySizes); } void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc) @@ -4463,7 +4473,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden arrayDimMerge(type, arraySizes); // Check that implicit sizing is only where allowed. - arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr); + arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false); if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type)) declareArray(loc, identifier, type, symbol, newDeclaration); @@ -4947,8 +4957,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con blockStageIoCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier); if (arraySizes) { - arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false); + arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false, false); arrayDimCheck(loc, arraySizes, 0); + if (arraySizes->getNumDims() > 1) + requireProfile(loc, ~EEsProfile, "array-of-array of block"); } // fix and check for member storage qualifiers and types that don't belong within a block @@ -4962,10 +4974,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con memberQualifier.storage = currentBlockQualifier.storage; if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary())) error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), ""); - if (memberType.isRuntimeSizedArray() && member < typeList.size() - 1) - error(memberLoc, "only the last member of a buffer block can be run-time sized", memberType.getFieldName().c_str(), ""); - if (memberType.isImplicitlySizedArray()) - requireProfile(memberLoc, ~EEsProfile, "implicitly-sized array in a block"); + if (memberType.isArray()) + arrayUnsizedCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1); if (memberQualifier.hasOffset()) { requireProfile(memberLoc, ~EEsProfile, "offset on block member"); profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member"); diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 17a5b3fd..771a43e2 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -137,9 +137,9 @@ public: void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, int& size); bool arrayQualifierError(const TSourceLoc&, const TQualifier&); bool arrayError(const TSourceLoc&, const TType&); - void arraySizeRequiredCheck(const TSourceLoc&, int size); + void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); void structArrayCheck(const TSourceLoc&, const TType& structure); - void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer); + void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember); void arrayOfArrayVersionCheck(const TSourceLoc&); void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2); void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*); diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 0c877577..e7eb3202 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -798,7 +798,7 @@ function_header GetStorageQualifierString($1.qualifier.storage), ""); } if ($1.arraySizes) - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); // Add the function as a prototype after parsing it (we do not support recursion) TFunction *function; @@ -814,7 +814,7 @@ parameter_declarator if ($1.arraySizes) { parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); } if ($1.basicType == EbtVoid) { parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), ""); @@ -829,11 +829,11 @@ parameter_declarator if ($1.arraySizes) { parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); } parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes); - parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($3.loc, *$3.arraySizes); parseContext.reservedErrorCheck($2.loc, *$2.string); $1.arraySizes = $3.arraySizes; @@ -893,7 +893,7 @@ parameter_type_specifier TParameter param = { 0, new TType($1) }; $$.param = param; if ($1.arraySizes) - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); } ; @@ -1962,7 +1962,7 @@ struct_declaration parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); } $$ = $2; @@ -1981,7 +1981,7 @@ struct_declaration parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getOuterSize()); + parseContext.arraySizeRequiredCheck($2.loc, *$2.arraySizes); } $$ = $3; From c9a808319a60e935e8087bafae16cc07a4ed3a2b Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sat, 12 Sep 2015 12:17:44 -0600 Subject: [PATCH 3/4] SPV arrays: Add support for runtime-sized array types and arrays of arrays. This includes run-time block.member.length() (OpArrayLength). --- SPIRV/GlslangToSpv.cpp | 52 ++++++---- SPIRV/SpvBuilder.cpp | 12 ++- SPIRV/SpvBuilder.h | 1 + Test/baseResults/spv.310.comp.out | 119 +++++++++++++++++++++- Test/baseResults/spv.AofA.frag.out | 154 +++++++++++++++++++++++++++++ Test/spv.310.comp | 10 +- Test/spv.AofA.frag | 43 ++++++++ Test/test-spirv-list | 1 + glslang/Include/revision.h | 4 +- 9 files changed, 369 insertions(+), 27 deletions(-) create mode 100644 Test/baseResults/spv.AofA.frag.out create mode 100644 Test/spv.AofA.frag diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index cc027383..4c7c17c1 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -680,6 +680,24 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI } // Non-texturing. + + if (node->getOp() == glslang::EOpArrayLength) { + // Quite special; won't want to evaluate the operand. + + // Normal .length() would have been constant folded by the front-end. + // So, this has to be block.lastMember.length(). + // SPV wants "block" as the operand, go get it. + assert(node->getOperand()->getType().isRuntimeSizedArray()); + glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); + block->traverse(this); + spv::Id length = builder.createUnaryOp(spv::OpArrayLength, builder.makeIntType(32), builder.accessChainGetLValue()); + + builder.clearAccessChain(); + builder.setAccessChainRValue(length); + + return false; + } + // Start by evaluating the operand builder.clearAccessChain(); @@ -967,17 +985,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // which can be emitted by the one in createBinaryOperation() binOp = glslang::EOpMod; break; - case glslang::EOpArrayLength: - { - glslang::TIntermTyped* typedNode = node->getSequence()[0]->getAsTyped(); - assert(typedNode); - spv::Id length = builder.makeIntConstant(typedNode->getType().getOuterArraySize()); - - builder.clearAccessChain(); - builder.setAccessChainRValue(length); - - return false; - } case glslang::EOpEmitVertex: case glslang::EOpEndPrimitive: case glslang::EOpBarrier: @@ -1468,14 +1475,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty } if (type.isArray()) { - unsigned arraySize; - if (! type.isExplicitlySizedArray()) { - spv::MissingFunctionality("Unsized array"); - arraySize = 8; - } else - arraySize = type.getOuterArraySize(); - spvType = builder.makeArrayType(spvType, arraySize); + // Do all but the outer dimension + for (int dim = type.getArraySizes()->getNumDims() - 1; dim > 0; --dim) { + assert(type.getArraySizes()->getDimSize(dim) > 0); + spvType = builder.makeArrayType(spvType, type.getArraySizes()->getDimSize(dim)); + } + // Do the outer dimension, which might not be known for a runtime-sized array + if (type.isRuntimeSizedArray()) { + spvType = builder.makeRuntimeArray(spvType); + } else { + assert(type.getOuterArraySize() > 0); + spvType = builder.makeArrayType(spvType, type.getOuterArraySize()); + } + + // TODO: layout still needs to be done hierarchically for arrays of arrays, which + // may still require additional "link time" support from the front-end + // for arrays of arrays if (explicitLayout) builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type)); } diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index f544f21a..953b6046 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -264,6 +264,16 @@ Id Builder::makeArrayType(Id element, unsigned size) return type->getResultId(); } +Id Builder::makeRuntimeArray(Id element) +{ + Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeRuntimeArray); + type->addIdOperand(element); + constantsTypesGlobals.push_back(type); + module.mapInstruction(type); + + return type->getResultId(); +} + Id Builder::makeFunctionType(Id returnType, std::vector& paramTypes) { // try to find it @@ -280,7 +290,7 @@ Id Builder::makeFunctionType(Id returnType, std::vector& paramTypes) } } if (! mismatch) - return type->getResultId(); + return type->getResultId(); } // not found, make it diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index de9686cd..1ceb9c69 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -102,6 +102,7 @@ public: Id makeVectorType(Id component, int size); Id makeMatrixType(Id component, int cols, int rows); Id makeArrayType(Id element, unsigned size); + Id makeRuntimeArray(Id element); Id makeFunctionType(Id returnType, std::vector& paramTypes); Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format); Id makeSampledImageType(Id imageType); diff --git a/Test/baseResults/spv.310.comp.out b/Test/baseResults/spv.310.comp.out index d1f8a9ae..9fbb2d58 100644 --- a/Test/baseResults/spv.310.comp.out +++ b/Test/baseResults/spv.310.comp.out @@ -5,4 +5,121 @@ Warning, version 310 is not yet complete; most version-specific features are pre Linked compute stage: -Missing functionality: Unsized array +// Module Version 99 +// Generated by (magic number): 51a00bb +// Id's are bound by 72 + + Source ESSL 310 + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint GLCompute 4 "main" + Name 4 "main" + Name 14 "outb" + MemberName 14(outb) 0 "f" + MemberName 14(outb) 1 "g" + MemberName 14(outb) 2 "h" + MemberName 14(outb) 3 "uns" + Name 16 "outbname" + Name 20 "s" + Name 25 "outbna" + MemberName 25(outbna) 0 "k" + MemberName 25(outbna) 1 "na" + Name 27 "outbnamena" + Name 47 "i" + Name 53 "outs" + MemberName 53(outs) 0 "s" + MemberName 53(outs) 1 "va" + Name 55 "outnames" + Name 59 "gl_LocalInvocationID" + Decorate 14(outb) GLSLShared + Decorate 14(outb) BufferBlock + Decorate 25(outbna) GLSLShared + Decorate 25(outbna) BufferBlock + Decorate 53(outs) GLSLShared + Decorate 53(outs) BufferBlock + Decorate 59(gl_LocalInvocationID) BuiltIn LocalInvocationId + Decorate 71 BuiltIn WorkgroupSize + Decorate 71 NoStaticUse + 2: TypeVoid + 3: TypeFunction 2 + 7: TypeInt 32 0 + 8: 7(int) Constant 1 + 9: 7(int) Constant 1023 + 10: 7(int) Constant 0 + 11: TypeFloat 32 + 12: TypeVector 11(float) 3 + 13: TypeRuntimeArray 12(fvec3) + 14(outb): TypeStruct 11(float) 11(float) 11(float) 13 + 15: TypePointer Uniform 14(outb) + 16(outbname): 15(ptr) Variable Uniform + 17: TypeInt 32 1 + 18: 17(int) Constant 0 + 19: TypePointer WorkgroupLocal 11(float) + 20(s): 19(ptr) Variable WorkgroupLocal + 22: TypePointer Uniform 11(float) + 24: TypeVector 11(float) 4 + 25(outbna): TypeStruct 17(int) 24(fvec4) + 26: TypePointer Uniform 25(outbna) + 27(outbnamena): 26(ptr) Variable Uniform + 28: 17(int) Constant 1 + 31: TypePointer Uniform 24(fvec4) + 33: TypeRuntimeArray 12(fvec3) + 34: 17(int) Constant 3 + 35: 17(int) Constant 18 + 36: TypePointer Uniform 12(fvec3) + 40: TypeRuntimeArray 12(fvec3) + 41: 17(int) Constant 17 + 42: 11(float) Constant 1077936128 + 43: 12(fvec3) ConstantComposite 42 42 42 + 45: TypeRuntimeArray 12(fvec3) + 46: TypePointer WorkgroupLocal 17(int) + 47(i): 46(ptr) Variable WorkgroupLocal + 52: TypeRuntimeArray 24(fvec4) + 53(outs): TypeStruct 17(int) 52 + 54: TypePointer Uniform 53(outs) + 55(outnames): 54(ptr) Variable Uniform + 56: TypeRuntimeArray 24(fvec4) + 57: TypeVector 7(int) 3 + 58: TypePointer Input 57(ivec3) +59(gl_LocalInvocationID): 58(ptr) Variable Input + 66: TypePointer Uniform 17(int) + 68: 7(int) Constant 16 + 69: 7(int) Constant 32 + 70: 7(int) Constant 4 + 71: 57(ivec3) ConstantComposite 68 69 70 + 4(main): 2 Function None 3 + 5: Label + MemoryBarrier 8 9 + ControlBarrier 8 8 10 + 21: 11(float) Load 20(s) + 23: 22(ptr) AccessChain 16(outbname) 18 + Store 23 21 + 29: 11(float) Load 20(s) + 30: 24(fvec4) CompositeConstruct 29 29 29 29 + 32: 31(ptr) AccessChain 27(outbnamena) 28 + Store 32 30 + 37: 36(ptr) AccessChain 16(outbname) 34 35 + 38: 12(fvec3) Load 37 + 39: 11(float) CompositeExtract 38 0 + Store 20(s) 39 + 44: 36(ptr) AccessChain 16(outbname) 34 41 + Store 44 43 + 48: 17(int) Load 47(i) + 49: 11(float) Load 20(s) + 50: 12(fvec3) CompositeConstruct 49 49 49 + 51: 36(ptr) AccessChain 16(outbname) 34 48 + Store 51 50 + 60: 57(ivec3) Load 59(gl_LocalInvocationID) + 61: 7(int) CompositeExtract 60 0 + 62: 11(float) Load 20(s) + 63: 24(fvec4) CompositeConstruct 62 62 62 62 + 64: 31(ptr) AccessChain 55(outnames) 28 61 + Store 64 63 + 65: 17(int) ArrayLength 16(outbname) + 67: 66(ptr) AccessChain 55(outnames) 18 + Store 67 65 + Branch 6 + 6: Label + Return + FunctionEnd diff --git a/Test/baseResults/spv.AofA.frag.out b/Test/baseResults/spv.AofA.frag.out new file mode 100644 index 00000000..bda0df34 --- /dev/null +++ b/Test/baseResults/spv.AofA.frag.out @@ -0,0 +1,154 @@ +spv.AofA.frag +Warning, version 430 is not yet complete; most version-specific features are present, but some are missing. + + +Linked fragment stage: + + +// Module Version 99 +// Generated by (magic number): 51a00bb +// Id's are bound by 104 + + Source GLSL 430 + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" + ExecutionMode 4 OriginLowerLeft + Name 4 "main" + Name 18 "foo(f1[5][7];" + Name 17 "a" + Name 21 "r" + Name 39 "outfloat" + Name 42 "g4" + Name 44 "g5" + Name 45 "param" + Name 48 "u" + Name 52 "param" + Name 66 "many" + Name 68 "i" + Name 70 "j" + Name 72 "k" + Name 78 "infloat" + Name 94 "uAofA" + MemberName 94(uAofA) 0 "f" + Name 98 "nameAofA" + Decorate 44(g5) Smooth + Decorate 78(infloat) Smooth + Decorate 94(uAofA) GLSLShared + Decorate 94(uAofA) Block + 2: TypeVoid + 3: TypeFunction 2 + 7: TypeFloat 32 + 8: TypeInt 32 0 + 9: 8(int) Constant 7 + 10: TypeArray 7(float) 9 + 11: 8(int) Constant 5 + 12: TypeArray 10 11 + 13: TypePointer Function 12 + 14: 8(int) Constant 4 + 15: TypeArray 10 14 + 16: TypeFunction 15 13(ptr) + 20: TypePointer Function 10 + 22: TypeInt 32 1 + 23: 22(int) Constant 2 + 26: 22(int) Constant 0 + 29: 22(int) Constant 1 + 33: 22(int) Constant 3 + 38: TypePointer Output 7(float) + 39(outfloat): 38(ptr) Variable Output + 40: 7(float) Constant 0 + 41: TypePointer PrivateGlobal 15 + 42(g4): 41(ptr) Variable PrivateGlobal + 43: TypePointer Input 12 + 44(g5): 43(ptr) Variable Input + 49: 7(float) Constant 1077936128 + 50: TypePointer Function 7(float) + 55: 8(int) Constant 6 + 56: TypeArray 7(float) 55 + 57: TypeArray 56 11 + 58: TypeArray 57 14 + 59: 8(int) Constant 3 + 60: TypeArray 58 59 + 61: 8(int) Constant 2 + 62: TypeArray 60 61 + 63: 8(int) Constant 1 + 64: TypeArray 62 63 + 65: TypePointer PrivateGlobal 64 + 66(many): 65(ptr) Variable PrivateGlobal + 67: TypePointer UniformConstant 22(int) + 68(i): 67(ptr) Variable UniformConstant + 70(j): 67(ptr) Variable UniformConstant + 72(k): 67(ptr) Variable UniformConstant + 77: TypePointer Input 7(float) + 78(infloat): 77(ptr) Variable Input + 80: TypePointer PrivateGlobal 7(float) + 92: TypeArray 7(float) 14 + 93: TypeArray 92 61 + 94(uAofA): TypeStruct 93 + 95: TypeArray 94(uAofA) 11 + 96: TypeArray 95 59 + 97: TypePointer Uniform 96 + 98(nameAofA): 97(ptr) Variable Uniform + 99: TypePointer Uniform 7(float) + 4(main): 2 Function None 3 + 5: Label + 45(param): 13(ptr) Variable Function + 48(u): 13(ptr) Variable Function + 52(param): 13(ptr) Variable Function + Store 39(outfloat) 40 + 46: 12 Load 44(g5) + Store 45(param) 46 + 47: 15 FunctionCall 18(foo(f1[5][7];) 45(param) + Store 42(g4) 47 + 51: 50(ptr) AccessChain 48(u) 23 23 + Store 51 49 + 53: 12 Load 48(u) + Store 52(param) 53 + 54: 15 FunctionCall 18(foo(f1[5][7];) 52(param) + 69: 22(int) Load 68(i) + 71: 22(int) Load 70(j) + 73: 22(int) Load 72(k) + 74: 22(int) Load 68(i) + 75: 22(int) Load 70(j) + 76: 22(int) Load 72(k) + 79: 7(float) Load 78(infloat) + 81: 80(ptr) AccessChain 66(many) 69 71 73 74 75 76 + Store 81 79 + 82: 22(int) Load 70(j) + 83: 22(int) Load 70(j) + 84: 22(int) Load 70(j) + 85: 22(int) Load 70(j) + 86: 22(int) Load 70(j) + 87: 22(int) Load 70(j) + 88: 80(ptr) AccessChain 66(many) 82 83 84 85 86 87 + 89: 7(float) Load 88 + 90: 7(float) Load 39(outfloat) + 91: 7(float) FAdd 90 89 + Store 39(outfloat) 91 + 100: 99(ptr) AccessChain 98(nameAofA) 29 23 26 26 33 + 101: 7(float) Load 100 + 102: 7(float) Load 39(outfloat) + 103: 7(float) FAdd 102 101 + Store 39(outfloat) 103 + Branch 6 + 6: Label + Return + FunctionEnd +18(foo(f1[5][7];): 15 Function None 16 + 17(a): 13(ptr) FunctionParameter + 19: Label + 21(r): 20(ptr) Variable Function + 24: 20(ptr) AccessChain 17(a) 23 + 25: 10 Load 24 + Store 21(r) 25 + 27: 20(ptr) AccessChain 17(a) 26 + 28: 10 Load 27 + 30: 20(ptr) AccessChain 17(a) 29 + 31: 10 Load 30 + 32: 10 Load 21(r) + 34: 20(ptr) AccessChain 17(a) 33 + 35: 10 Load 34 + 36: 15 CompositeConstruct 28 31 32 35 + ReturnValue 36 + FunctionEnd diff --git a/Test/spv.310.comp b/Test/spv.310.comp index 45116361..bd183e04 100644 --- a/Test/spv.310.comp +++ b/Test/spv.310.comp @@ -11,9 +11,7 @@ buffer outb { float f; float g; float h; - vec3 uns[]; // this makes it look like the "second" set of 3 floats in a struct, which LLVM - // takes advantage of when optimizing, giving confusing results, like thinking - // &outbname.uns[18].x == &outbname[9].uns.x + vec3 uns[]; } outbname; buffer outbna { @@ -22,6 +20,7 @@ buffer outbna { } outbnamena; buffer outs { + int s; vec4 va[]; } outnames; @@ -30,8 +29,9 @@ void main() barrier(); outbname.f = s; outbnamena.na = vec4(s); - s = outbname.uns[18].x; // TODO: see note above - //outbname.uns[17] = vec3(3.0); // TODO: see note above, this one bitcasts, which isn't handled + s = outbname.uns[18].x; + outbname.uns[17] = vec3(3.0); outbname.uns[i] = vec3(s); outnames.va[gl_LocalInvocationID.x] = vec4(s); + outnames.s = outbname.uns.length(); } diff --git a/Test/spv.AofA.frag b/Test/spv.AofA.frag new file mode 100644 index 00000000..606d73b0 --- /dev/null +++ b/Test/spv.AofA.frag @@ -0,0 +1,43 @@ +#version 430 + +in float infloat; +out float outfloat; + +uniform uAofA { + float f[2][4]; +} nameAofA[3][5]; + +float[4][5][6] many[1][2][3]; + +float g4[4][7]; +in float g5[5][7]; + +uniform int i, j, k; + +float[4][7] foo(float a[5][7]) +{ + float r[7]; + r = a[2]; + + return float[4][7](a[0], a[1], r, a[3]); +} + +void main() +{ + outfloat = 0.0; + + g4 = foo(g5); + +// if (foo(g5) == g4) +// ++outfloat; + + float u[][7]; + u[2][2] = 3.0; + float u[5][7]; + + foo(u); + + many[i][j][k][i][j][k] = infloat; + outfloat += many[j][j][j][j][j][j]; + outfloat += nameAofA[1][2].f[0][3]; +} diff --git a/Test/test-spirv-list b/Test/test-spirv-list index ccfa0686..a7d8c8de 100644 --- a/Test/test-spirv-list +++ b/Test/test-spirv-list @@ -79,3 +79,4 @@ spv.varyingArrayIndirect.frag spv.voidFunction.frag spv.whileLoop.frag spv.atomic.comp +spv.AofA.frag diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index abb7f139..cd2e5473 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "3.0.748" -#define GLSLANG_DATE "11-Sep-2015" +#define GLSLANG_REVISION "3.0.750" +#define GLSLANG_DATE "13-Sep-2015" From fa668dad99d04389664a38e83bf7b9655ca03865 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sun, 13 Sep 2015 14:46:30 -0600 Subject: [PATCH 4/4] SPV: Reduce spurious type generation by removing intermediate types in the middle of access chains. This generally simplifies access chain generation, with far fewer type conversions. It is particularly important to future SPIR-V changes where there is less aggregate type uniqueness due to carrying different layout information with the type. --- SPIRV/GlslangToSpv.cpp | 50 +++++----- SPIRV/SpvBuilder.cpp | 51 +++++----- SPIRV/SpvBuilder.h | 18 ++-- Test/baseResults/spv.310.comp.out | 108 +++++++++++----------- Test/baseResults/spv.Operations.frag.out | 10 +- Test/baseResults/spv.accessChain.frag.out | 24 ++--- Test/baseResults/spv.double.comp.out | 8 +- Test/baseResults/spv.forLoop.frag.out | 12 +-- 8 files changed, 144 insertions(+), 137 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 4c7c17c1..0240dea0 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -530,12 +530,12 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // evaluate the right builder.clearAccessChain(); node->getRight()->traverse(this); - spv::Id rValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType())); + spv::Id rValue = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType())); if (node->getOp() != glslang::EOpAssign) { // the left is also an r-value builder.setAccessChain(lValue); - spv::Id leftRValue = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType())); + spv::Id leftRValue = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType())); // do the operation rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()), @@ -587,10 +587,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // so short circuit the access-chain stuff with a swizzle. std::vector swizzle; swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()); - builder.accessChainPushSwizzle(swizzle); + builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType())); } else { // normal case for indexing array or structure or block - builder.accessChainPush(builder.makeIntConstant(index), convertGlslangToSpvType(node->getType())); + builder.accessChainPush(builder.makeIntConstant(index)); } } return false; @@ -611,15 +611,15 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // compute the next index in the chain builder.clearAccessChain(); node->getRight()->traverse(this); - spv::Id index = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType())); + spv::Id index = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType())); // restore the saved access chain builder.setAccessChain(partial); if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) - builder.accessChainPushComponent(index); + builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType())); else - builder.accessChainPush(index, convertGlslangToSpvType(node->getType())); + builder.accessChainPush(index); } return false; case glslang::EOpVectorSwizzle: @@ -629,7 +629,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T std::vector swizzle; for (int i = 0; i < (int)swizzleSequence.size(); ++i) swizzle.push_back(swizzleSequence[i]->getAsConstantUnion()->getConstArray()[0].getIConst()); - builder.accessChainPushSwizzle(swizzle); + builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType())); } return false; default: @@ -641,11 +641,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // Get the operands builder.clearAccessChain(); node->getLeft()->traverse(this); - spv::Id left = builder.accessChainLoad(TranslatePrecisionDecoration(node->getLeft()->getType())); + spv::Id left = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType())); builder.clearAccessChain(); node->getRight()->traverse(this); - spv::Id right = builder.accessChainLoad(TranslatePrecisionDecoration(node->getRight()->getType())); + spv::Id right = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType())); spv::Id result; spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); @@ -702,7 +702,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI builder.clearAccessChain(); node->getOperand()->traverse(this); - spv::Id operand = builder.accessChainLoad(TranslatePrecisionDecoration(node->getOperand()->getType())); + spv::Id operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType())); spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); @@ -1038,11 +1038,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.clearAccessChain(); left->traverse(this); - spv::Id leftId = builder.accessChainLoad(TranslatePrecisionDecoration(left->getType())); + spv::Id leftId = builder.accessChainLoad(convertGlslangToSpvType(left->getType())); builder.clearAccessChain(); right->traverse(this); - spv::Id rightId = builder.accessChainLoad(TranslatePrecisionDecoration(right->getType())); + spv::Id rightId = builder.accessChainLoad(convertGlslangToSpvType(right->getType())); result = createBinaryOperation(binOp, precision, convertGlslangToSpvType(node->getType()), leftId, rightId, @@ -1084,7 +1084,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (lvalue) operands.push_back(builder.accessChainGetLValue()); else - operands.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangOperands[arg]->getAsTyped()->getType()))); + operands.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangOperands[arg]->getAsTyped()->getType()))); } if (atomic) { @@ -1134,13 +1134,13 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang node->getCondition()->traverse(this); // make an "if" based on the value created by the condition - spv::Builder::If ifBuilder(builder.accessChainLoad(spv::NoPrecision), builder); + spv::Builder::If ifBuilder(builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getType())), builder); if (node->getTrueBlock()) { // emit the "then" statement node->getTrueBlock()->traverse(this); if (result) - builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getTrueBlock()->getAsTyped()->getType())), result); + builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getTrueBlock()->getAsTyped()->getType())), result); } if (node->getFalseBlock()) { @@ -1148,7 +1148,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // emit the "else" statement node->getFalseBlock()->traverse(this); if (result) - builder.createStore(builder.accessChainLoad(TranslatePrecisionDecoration(node->getFalseBlock()->getAsTyped()->getType())), result); + builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getFalseBlock()->getAsTyped()->getType())), result); } ifBuilder.makeEndIf(); @@ -1169,7 +1169,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T { // emit and get the condition before doing anything with switch node->getCondition()->traverse(this); - spv::Id selector = builder.accessChainLoad(TranslatePrecisionDecoration(node->getCondition()->getAsTyped()->getType())); + spv::Id selector = builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getAsTyped()->getType())); // browse the children to sort out code segments int defaultSegment = -1; @@ -1233,7 +1233,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn if (node->getTest()) { node->getTest()->traverse(this); // the AST only contained the test computation, not the branch, we have to add it - spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType())); + spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); builder.createLoopTestBranch(condition); } else { builder.createBranchToBody(); @@ -1279,7 +1279,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T if (inMain) builder.makeMainReturn(); else if (node->getExpression()) - builder.makeReturn(false, builder.accessChainLoad(TranslatePrecisionDecoration(node->getExpression()->getType()))); + builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType()))); else builder.makeReturn(); @@ -1664,7 +1664,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence& for (int i = 0; i < (int)glslangArguments.size(); ++i) { builder.clearAccessChain(); glslangArguments[i]->traverse(this); - arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArguments[i]->getAsTyped()->getType()))); + arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType()))); } } @@ -1672,7 +1672,7 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std { builder.clearAccessChain(); node.getOperand()->traverse(this); - arguments.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(node.getAsTyped()->getType()))); + arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(node.getOperand()->getType()))); } spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node) @@ -1806,17 +1806,19 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg // 1. Evaluate the arguments std::vector lValues; std::vector rValues; + std::vector argTypes; for (int a = 0; a < (int)glslangArgs.size(); ++a) { // build l-value builder.clearAccessChain(); glslangArgs[a]->traverse(this); + argTypes.push_back(convertGlslangToSpvType(glslangArgs[a]->getAsTyped()->getType())); // keep outputs as l-values, evaluate input-only as r-values if (qualifiers[a] != glslang::EvqConstReadOnly) { // save l-value lValues.push_back(builder.getAccessChain()); } else { // process r-value - rValues.push_back(builder.accessChainLoad(TranslatePrecisionDecoration(glslangArgs[a]->getAsTyped()->getType()))); + rValues.push_back(builder.accessChainLoad(argTypes.back())); } } @@ -1836,7 +1838,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) { // need to copy the input into output space builder.setAccessChain(lValues[lValueCount]); - spv::Id copy = builder.accessChainLoad(spv::NoPrecision); // TODO: get precision + spv::Id copy = builder.accessChainLoad(argTypes[a]); builder.createStore(copy, arg); } ++lValueCount; diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 953b6046..9913b0b6 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1957,18 +1957,23 @@ void Builder::createBranchToLoopHeaderFromInside(const Loop& loop) void Builder::clearAccessChain() { - accessChain.base = 0; + accessChain.base = NoResult; accessChain.indexChain.clear(); - accessChain.instr = 0; + accessChain.instr = NoResult; accessChain.swizzle.clear(); - accessChain.component = 0; - accessChain.resultType = NoType; + accessChain.component = NoResult; + accessChain.preSwizzleBaseType = NoType; accessChain.isRValue = false; } // Comments in header -void Builder::accessChainPushSwizzle(std::vector& swizzle) +void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType) { + // swizzles can be stacked in GLSL, but simplified to a single + // one here; the base type doesn't change + if (accessChain.preSwizzleBaseType == NoType) + accessChain.preSwizzleBaseType = preSwizzleBaseType; + // if needed, propagate the swizzle for the current access chain if (accessChain.swizzle.size()) { std::vector oldSwizzle = accessChain.swizzle; @@ -1990,7 +1995,7 @@ void Builder::accessChainStore(Id rvalue) Id base = collapseAccessChain(); - if (accessChain.swizzle.size() && accessChain.component) + if (accessChain.swizzle.size() && accessChain.component != NoResult) MissingFunctionality("simultaneous l-value swizzle and dynamic component selection"); // If swizzle exists, it is out-of-order or not full, we must load the target vector, @@ -2002,7 +2007,7 @@ void Builder::accessChainStore(Id rvalue) } // dynamic component selection - if (accessChain.component) { + if (accessChain.component != NoResult) { Id tempBaseId = (source == NoResult) ? createLoad(base) : source; source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue, accessChain.component); } @@ -2014,13 +2019,15 @@ void Builder::accessChainStore(Id rvalue) } // Comments in header -Id Builder::accessChainLoad(Decoration /*precision*/) +Id Builder::accessChainLoad(Id resultType) { Id id; if (accessChain.isRValue) { if (accessChain.indexChain.size() > 0) { mergeAccessChainSwizzle(); // TODO: optimization: look at applying this optimization more widely + Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType; + // if all the accesses are constants, we can use OpCompositeExtract std::vector indexes; bool constant = true; @@ -2034,7 +2041,7 @@ Id Builder::accessChainLoad(Decoration /*precision*/) } if (constant) - id = createCompositeExtract(accessChain.base, accessChain.resultType, indexes); + id = createCompositeExtract(accessChain.base, swizzleBase, indexes); else { // make a new function variable for this r-value Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable"); @@ -2057,24 +2064,22 @@ Id Builder::accessChainLoad(Decoration /*precision*/) } // Done, unless there are swizzles to do - if (accessChain.swizzle.size() == 0 && accessChain.component == 0) + if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult) return id; - Id componentType = getScalarTypeId(accessChain.resultType); - // Do remaining swizzling // First, static swizzling if (accessChain.swizzle.size()) { // static swizzle - Id resultType = componentType; + Id swizzledType = getScalarTypeId(getTypeId(id)); if (accessChain.swizzle.size() > 1) - resultType = makeVectorType(componentType, (int)accessChain.swizzle.size()); - id = createRvalueSwizzle(resultType, id, accessChain.swizzle); + swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size()); + id = createRvalueSwizzle(swizzledType, id, accessChain.swizzle); } // dynamic single-component selection - if (accessChain.component) - id = createVectorExtractDynamic(id, componentType, accessChain.component); + if (accessChain.component != NoResult) + id = createVectorExtractDynamic(id, resultType, accessChain.component); return id; } @@ -2089,7 +2094,7 @@ Id Builder::accessChainGetLValue() // extract and insert elements to perform writeMask and/or swizzle. This does not // go with getting a direct l-value pointer. assert(accessChain.swizzle.size() == 0); - assert(accessChain.component == spv::NoResult); + assert(accessChain.component == NoResult); return lvalue; } @@ -2170,7 +2175,7 @@ void Builder::simplifyAccessChainSwizzle() { // If the swizzle has fewer components than the vector, it is subsetting, and must stay // to preserve that fact. - if (getNumTypeComponents(accessChain.resultType) > (int)accessChain.swizzle.size()) + if (getNumTypeComponents(accessChain.preSwizzleBaseType) > (int)accessChain.swizzle.size()) return; // if components are out of order, it is a swizzle @@ -2181,6 +2186,8 @@ void Builder::simplifyAccessChainSwizzle() // otherwise, there is no need to track this swizzle accessChain.swizzle.clear(); + if (accessChain.component == NoResult) + accessChain.preSwizzleBaseType = NoType; } // clear out swizzle if it can become part of the indexes @@ -2188,12 +2195,12 @@ void Builder::mergeAccessChainSwizzle() { // is there even a chance of doing something? Need a single-component swizzle if ((accessChain.swizzle.size() > 1) || - (accessChain.swizzle.size() == 0 && accessChain.component == 0)) + (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)) return; // TODO: optimization: remove this, but for now confine this to non-dynamic accesses // (the above test is correct when this is removed.) - if (accessChain.component) + if (accessChain.component != NoResult) return; // move the swizzle over to the indexes @@ -2201,10 +2208,10 @@ void Builder::mergeAccessChainSwizzle() accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front())); else accessChain.indexChain.push_back(accessChain.component); - accessChain.resultType = getScalarTypeId(accessChain.resultType); // now there is no need to track this swizzle accessChain.component = NoResult; + accessChain.preSwizzleBaseType = NoType; accessChain.swizzle.clear(); } diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 1ceb9c69..f81f9ed2 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -431,7 +431,7 @@ public: Id instr; // the instruction that generates this access chain std::vector swizzle; Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle - Id resultType; // dereferenced type, to be exclusive of swizzles + Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present bool isRValue; }; @@ -452,7 +452,6 @@ public: { assert(isPointer(lValue)); accessChain.base = lValue; - accessChain.resultType = getContainedTypeId(getTypeId(lValue)); } // set new base value as an r-value @@ -460,27 +459,30 @@ public: { accessChain.isRValue = true; accessChain.base = rValue; - accessChain.resultType = getTypeId(rValue); } // push offset onto the end of the chain - void accessChainPush(Id offset, Id newType) + void accessChainPush(Id offset) { accessChain.indexChain.push_back(offset); - accessChain.resultType = newType; } // push new swizzle onto the end of any existing swizzle, merging into a single swizzle - void accessChainPushSwizzle(std::vector& swizzle); + void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType); // push a variable component selection onto the access chain; supporting only one, so unsided - void accessChainPushComponent(Id component) { accessChain.component = component; } + void accessChainPushComponent(Id component, Id preSwizzleBaseType) + { + accessChain.component = component; + if (accessChain.preSwizzleBaseType == NoType) + accessChain.preSwizzleBaseType = preSwizzleBaseType; + } // use accessChain and swizzle to store value void accessChainStore(Id rvalue); // use accessChain and swizzle to load an r-value - Id accessChainLoad(Decoration precision); + Id accessChainLoad(Id ResultType); // get the direct pointer for an l-value Id accessChainGetLValue(); diff --git a/Test/baseResults/spv.310.comp.out b/Test/baseResults/spv.310.comp.out index 9fbb2d58..b8c7b884 100644 --- a/Test/baseResults/spv.310.comp.out +++ b/Test/baseResults/spv.310.comp.out @@ -7,7 +7,7 @@ Linked compute stage: // Module Version 99 // Generated by (magic number): 51a00bb -// Id's are bound by 72 +// Id's are bound by 68 Source ESSL 310 Capability Shader @@ -26,21 +26,21 @@ Linked compute stage: MemberName 25(outbna) 0 "k" MemberName 25(outbna) 1 "na" Name 27 "outbnamena" - Name 47 "i" - Name 53 "outs" - MemberName 53(outs) 0 "s" - MemberName 53(outs) 1 "va" - Name 55 "outnames" - Name 59 "gl_LocalInvocationID" + Name 44 "i" + Name 50 "outs" + MemberName 50(outs) 0 "s" + MemberName 50(outs) 1 "va" + Name 52 "outnames" + Name 55 "gl_LocalInvocationID" Decorate 14(outb) GLSLShared Decorate 14(outb) BufferBlock Decorate 25(outbna) GLSLShared Decorate 25(outbna) BufferBlock - Decorate 53(outs) GLSLShared - Decorate 53(outs) BufferBlock - Decorate 59(gl_LocalInvocationID) BuiltIn LocalInvocationId - Decorate 71 BuiltIn WorkgroupSize - Decorate 71 NoStaticUse + Decorate 50(outs) GLSLShared + Decorate 50(outs) BufferBlock + Decorate 55(gl_LocalInvocationID) BuiltIn LocalInvocationId + Decorate 67 BuiltIn WorkgroupSize + Decorate 67 NoStaticUse 2: TypeVoid 3: TypeFunction 2 7: TypeInt 32 0 @@ -64,30 +64,26 @@ Linked compute stage: 27(outbnamena): 26(ptr) Variable Uniform 28: 17(int) Constant 1 31: TypePointer Uniform 24(fvec4) - 33: TypeRuntimeArray 12(fvec3) - 34: 17(int) Constant 3 - 35: 17(int) Constant 18 - 36: TypePointer Uniform 12(fvec3) - 40: TypeRuntimeArray 12(fvec3) - 41: 17(int) Constant 17 - 42: 11(float) Constant 1077936128 - 43: 12(fvec3) ConstantComposite 42 42 42 - 45: TypeRuntimeArray 12(fvec3) - 46: TypePointer WorkgroupLocal 17(int) - 47(i): 46(ptr) Variable WorkgroupLocal - 52: TypeRuntimeArray 24(fvec4) - 53(outs): TypeStruct 17(int) 52 - 54: TypePointer Uniform 53(outs) - 55(outnames): 54(ptr) Variable Uniform - 56: TypeRuntimeArray 24(fvec4) - 57: TypeVector 7(int) 3 - 58: TypePointer Input 57(ivec3) -59(gl_LocalInvocationID): 58(ptr) Variable Input - 66: TypePointer Uniform 17(int) - 68: 7(int) Constant 16 - 69: 7(int) Constant 32 - 70: 7(int) Constant 4 - 71: 57(ivec3) ConstantComposite 68 69 70 + 33: 17(int) Constant 3 + 34: 17(int) Constant 18 + 35: TypePointer Uniform 12(fvec3) + 39: 17(int) Constant 17 + 40: 11(float) Constant 1077936128 + 41: 12(fvec3) ConstantComposite 40 40 40 + 43: TypePointer WorkgroupLocal 17(int) + 44(i): 43(ptr) Variable WorkgroupLocal + 49: TypeRuntimeArray 24(fvec4) + 50(outs): TypeStruct 17(int) 49 + 51: TypePointer Uniform 50(outs) + 52(outnames): 51(ptr) Variable Uniform + 53: TypeVector 7(int) 3 + 54: TypePointer Input 53(ivec3) +55(gl_LocalInvocationID): 54(ptr) Variable Input + 62: TypePointer Uniform 17(int) + 64: 7(int) Constant 16 + 65: 7(int) Constant 32 + 66: 7(int) Constant 4 + 67: 53(ivec3) ConstantComposite 64 65 66 4(main): 2 Function None 3 5: Label MemoryBarrier 8 9 @@ -99,26 +95,26 @@ Linked compute stage: 30: 24(fvec4) CompositeConstruct 29 29 29 29 32: 31(ptr) AccessChain 27(outbnamena) 28 Store 32 30 - 37: 36(ptr) AccessChain 16(outbname) 34 35 - 38: 12(fvec3) Load 37 - 39: 11(float) CompositeExtract 38 0 - Store 20(s) 39 - 44: 36(ptr) AccessChain 16(outbname) 34 41 - Store 44 43 - 48: 17(int) Load 47(i) - 49: 11(float) Load 20(s) - 50: 12(fvec3) CompositeConstruct 49 49 49 - 51: 36(ptr) AccessChain 16(outbname) 34 48 - Store 51 50 - 60: 57(ivec3) Load 59(gl_LocalInvocationID) - 61: 7(int) CompositeExtract 60 0 - 62: 11(float) Load 20(s) - 63: 24(fvec4) CompositeConstruct 62 62 62 62 - 64: 31(ptr) AccessChain 55(outnames) 28 61 - Store 64 63 - 65: 17(int) ArrayLength 16(outbname) - 67: 66(ptr) AccessChain 55(outnames) 18 - Store 67 65 + 36: 35(ptr) AccessChain 16(outbname) 33 34 + 37: 12(fvec3) Load 36 + 38: 11(float) CompositeExtract 37 0 + Store 20(s) 38 + 42: 35(ptr) AccessChain 16(outbname) 33 39 + Store 42 41 + 45: 17(int) Load 44(i) + 46: 11(float) Load 20(s) + 47: 12(fvec3) CompositeConstruct 46 46 46 + 48: 35(ptr) AccessChain 16(outbname) 33 45 + Store 48 47 + 56: 53(ivec3) Load 55(gl_LocalInvocationID) + 57: 7(int) CompositeExtract 56 0 + 58: 11(float) Load 20(s) + 59: 24(fvec4) CompositeConstruct 58 58 58 58 + 60: 31(ptr) AccessChain 52(outnames) 28 57 + Store 60 59 + 61: 17(int) ArrayLength 16(outbname) + 63: 62(ptr) AccessChain 52(outnames) 18 + Store 63 61 Branch 6 6: Label Return diff --git a/Test/baseResults/spv.Operations.frag.out b/Test/baseResults/spv.Operations.frag.out index 9858f85f..909bb23d 100755 --- a/Test/baseResults/spv.Operations.frag.out +++ b/Test/baseResults/spv.Operations.frag.out @@ -51,7 +51,7 @@ Linked fragment stage: 292: 19(int) Constant 2 299: 19(int) Constant 1 301: TypePointer Function 7(float) - 332: TypeVector 7(float) 3 + 331: TypeVector 7(float) 3 347: 7(float) Constant 1073741824 354: 7(float) Constant 1065353216 359: 19(int) Constant 66 @@ -434,11 +434,11 @@ Linked fragment stage: 329: 7(float) Load 302(f) 330: 7(float) FAdd 329 328 Store 302(f) 330 - 331: 8(fvec4) Load 10(v) - 333: 332(fvec3) VectorShuffle 331 331 0 1 2 + 332: 8(fvec4) Load 10(v) + 333: 331(fvec3) VectorShuffle 332 332 0 1 2 334: 8(fvec4) Load 10(v) - 335: 332(fvec3) VectorShuffle 334 334 0 1 2 - 336: 332(fvec3) ExtInst 1(GLSL.std.450) 67(Cross) 333 335 + 335: 331(fvec3) VectorShuffle 334 334 0 1 2 + 336: 331(fvec3) ExtInst 1(GLSL.std.450) 67(Cross) 333 335 337: 7(float) CompositeExtract 336 0 338: 7(float) Load 302(f) 339: 7(float) FAdd 338 337 diff --git a/Test/baseResults/spv.accessChain.frag.out b/Test/baseResults/spv.accessChain.frag.out index f45cc343..c280bffd 100755 --- a/Test/baseResults/spv.accessChain.frag.out +++ b/Test/baseResults/spv.accessChain.frag.out @@ -86,7 +86,7 @@ Linked fragment stage: 67: 14(int) Constant 0 68: TypeInt 32 0 69: 68(int) Constant 0 - 97: TypeVector 7(float) 2 + 96: TypeVector 7(float) 2 110: 68(int) Constant 2 142: 7(float) Constant 0 143: 8(fvec3) ConstantComposite 142 142 142 @@ -227,8 +227,8 @@ Linked fragment stage: 34(comp): 15(ptr) FunctionParameter 36: Label 95: 14(int) Load 34(comp) - 96: 8(fvec3) CompositeExtract 33(i) 0 - 98: 97(fvec2) VectorShuffle 96 96 1 0 + 97: 8(fvec3) CompositeExtract 33(i) 0 + 98: 96(fvec2) VectorShuffle 97 97 1 0 99: 7(float) VectorExtractDynamic 98 95 100: 8(fvec3) Load 66(OutColor) 101: 8(fvec3) CompositeConstruct 99 99 99 @@ -241,10 +241,10 @@ Linked fragment stage: 38(comp): 15(ptr) FunctionParameter 40: Label 103: 8(fvec3) CompositeExtract 37(i) 0 - 104: 97(fvec2) VectorShuffle 103 103 0 1 + 104: 96(fvec2) VectorShuffle 103 103 0 1 105: 8(fvec3) Load 66(OutColor) - 106: 97(fvec2) VectorShuffle 105 105 0 1 - 107: 97(fvec2) FAdd 106 104 + 106: 96(fvec2) VectorShuffle 105 105 0 1 + 107: 96(fvec2) FAdd 106 104 108: 8(fvec3) Load 66(OutColor) 109: 8(fvec3) VectorShuffle 108 107 3 4 2 Store 66(OutColor) 109 @@ -279,10 +279,10 @@ Linked fragment stage: 50(comp): 15(ptr) FunctionParameter 52: Label 121: 8(fvec3) CompositeExtract 49(i) 0 - 122: 97(fvec2) VectorShuffle 121 121 0 1 + 122: 96(fvec2) VectorShuffle 121 121 0 1 123: 8(fvec3) Load 66(OutColor) - 124: 97(fvec2) VectorShuffle 123 123 2 1 - 125: 97(fvec2) FAdd 124 122 + 124: 96(fvec2) VectorShuffle 123 123 2 1 + 125: 96(fvec2) FAdd 124 122 126: 8(fvec3) Load 66(OutColor) 127: 8(fvec3) VectorShuffle 126 125 0 4 3 Store 66(OutColor) 127 @@ -293,10 +293,10 @@ Linked fragment stage: 54(comp): 15(ptr) FunctionParameter 56: Label 128: 8(fvec3) CompositeExtract 53(i) 0 - 129: 97(fvec2) VectorShuffle 128 128 0 1 + 129: 96(fvec2) VectorShuffle 128 128 0 1 130: 8(fvec3) Load 66(OutColor) - 131: 97(fvec2) VectorShuffle 130 130 0 2 - 132: 97(fvec2) FAdd 131 129 + 131: 96(fvec2) VectorShuffle 130 130 0 2 + 132: 96(fvec2) FAdd 131 129 133: 8(fvec3) Load 66(OutColor) 134: 8(fvec3) VectorShuffle 133 132 3 1 4 Store 66(OutColor) 134 diff --git a/Test/baseResults/spv.double.comp.out b/Test/baseResults/spv.double.comp.out index 3f2ca156..d77bc0c0 100755 --- a/Test/baseResults/spv.double.comp.out +++ b/Test/baseResults/spv.double.comp.out @@ -57,7 +57,7 @@ Linked compute stage: 25: TypeVector 24(int) 3 26: TypePointer Input 25(ivec3) 27(gl_GlobalInvocationID): 26(ptr) Variable Input - 29: TypeVector 24(int) 2 + 28: TypeVector 24(int) 2 32: TypePointer Function 8(float) 34(gl_LocalInvocationID): 26(ptr) Variable Input 38: 12(int) Constant 8 @@ -86,12 +86,12 @@ Linked compute stage: Store 16 14 20: 19(ptr) AccessChain 11(bufInst) 17 Store 20 18 - 28: 25(ivec3) Load 27(gl_GlobalInvocationID) - 30: 29(ivec2) VectorShuffle 28 28 0 1 + 29: 25(ivec3) Load 27(gl_GlobalInvocationID) + 30: 28(ivec2) VectorShuffle 29 29 0 1 31: 21(ivec2) Bitcast 30 Store 23(storePos) 31 35: 25(ivec3) Load 34(gl_LocalInvocationID) - 36: 29(ivec2) VectorShuffle 35 35 0 1 + 36: 28(ivec2) VectorShuffle 35 35 0 1 37: 21(ivec2) Bitcast 36 39: 21(ivec2) CompositeConstruct 38 38 40: 21(ivec2) ISub 37 39 diff --git a/Test/baseResults/spv.forLoop.frag.out b/Test/baseResults/spv.forLoop.frag.out index 972ecead..75949a04 100755 --- a/Test/baseResults/spv.forLoop.frag.out +++ b/Test/baseResults/spv.forLoop.frag.out @@ -58,7 +58,7 @@ Linked fragment stage: 50: TypePointer UniformConstant 49(ivec4) 51(v4): 50(ptr) Variable UniformConstant 71: 48(int) Constant 4 - 86: TypeVector 7(float) 3 + 85: TypeVector 7(float) 3 97: TypePointer Input 7(float) 98(f): 97(ptr) Variable Input 116: 14(int) Constant 16 @@ -145,8 +145,8 @@ Linked fragment stage: 82: 8(fvec4) Load 36(gl_FragColor) 83: 8(fvec4) FAdd 82 81 Store 36(gl_FragColor) 83 - 85: 8(fvec4) Load 12(BaseColor) - 87: 86(fvec3) VectorShuffle 85 85 0 1 2 + 86: 8(fvec4) Load 12(BaseColor) + 87: 85(fvec3) VectorShuffle 86 86 0 1 2 88: 8(fvec4) Load 84(r) 89: 8(fvec4) VectorShuffle 88 87 4 5 6 3 Store 84(r) 89 @@ -169,10 +169,10 @@ Linked fragment stage: Branch 91 92: Label 104: 8(fvec4) Load 84(r) - 105: 86(fvec3) VectorShuffle 104 104 0 1 2 + 105: 85(fvec3) VectorShuffle 104 104 0 1 2 106: 8(fvec4) Load 36(gl_FragColor) - 107: 86(fvec3) VectorShuffle 106 106 0 1 2 - 108: 86(fvec3) FAdd 107 105 + 107: 85(fvec3) VectorShuffle 106 106 0 1 2 + 108: 85(fvec3) FAdd 107 105 109: 8(fvec4) Load 36(gl_FragColor) 110: 8(fvec4) VectorShuffle 109 108 4 5 6 3 Store 36(gl_FragColor) 110