#X1. Type: float[5] // An array type with 5 elements #X2. Return value: float[5] func() { ... } // Function with a 5-element array return value #X3. Array constructor: float[3] (1.0, 2.0, 5.5) // 3-element array with given elements # // Fails with array of matrices! #X4. As unnamed parameter: void func(float[5]); #X5. Variable declaration: float[5] a; // Equivalent to float a[5]; (?) #X6. Empty brackets: float x[] = float[] (1.0, 2.0, 3.0); // Size of x is 3 # float y[] = float[3] (1.0, 2.0, 3.0); // Size of y is 3 (equivalent) # float z[] = y; // Size of z is 3 #X7. Testing that 2-dimensional arrays don't work: float a[5][3]; // Illegal # float[5] a[3]; // Illegal #X8. Testing that array declaration with dynamic variables as array size won't work. #X9. Testing length() operator: z.length(); // Returns 3 for z defined before #X10. Test C/C++ style {}-constructor #X11. Test struct arrays #X12. Test array element access at initialization with const/dynamic values group constructor "Array constructors" case float3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(7.4, -1.0, 2.0) | vec3(3.0, 1.6, -2.0) ]; output vec3 out0 = [ vec3(2.0, 0.5, 1.0) | vec3(2.0, 7.4, -1.0) | vec3(-2.0, 3.0, 1.6) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} float[3] x; x = float[3] (in0.z, in0.x, in0.y); out0 = vec3(x[0], x[1], x[2]); ${OUTPUT} } "" end case float4 version 300 es values { input vec4 in0 = [ vec4(0.5, 1.0, 2.0, 0.2) | vec4(7.4, -1.0, 2.0, -1.3) | vec4(3.0, 1.6, -2.0, 0.5) ]; output vec4 out0 = [ vec4(2.0, 0.5, 0.2, 1.0) | vec4(2.0, 7.4, -1.3, -1.0) | vec4(-2.0, 3.0, 0.5, 1.6) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} float[4] x; x = float[4] (in0.z, in0.x, in0.w, in0.y); out0 = vec4(x[0], x[1], x[2], x[3]); ${OUTPUT} } "" end case int3 version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) | ivec3(7, -1, 2) | ivec3(3, 1, -2) ]; output ivec3 out0 = [ ivec3(2, 0, 1) | ivec3(2, 7, -1) | ivec3(-2, 3, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} int[3] x; x = int[3] (in0.z, in0.x, in0.y); out0 = ivec3(x[0], x[1], x[2]); ${OUTPUT} } "" end case int4 version 300 es values { input ivec4 in0 = [ ivec4(0, 1, 2, 0) | ivec4(7, -1, 2, -1) | ivec4(3, 1, -2, 0) ]; output ivec4 out0 = [ ivec4(2, 0, 0, 1) | ivec4(2, 7, -1, -1) | ivec4(-2, 3, 0, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} int[4] x; x = int[4] (in0.z, in0.x, in0.w, in0.y); out0 = ivec4(x[0], x[1], x[2], x[3]); ${OUTPUT} } "" end case bool3 version 300 es values { input bvec3 in0 = [ bvec3(true, true, false) ]; output bvec3 out0 = [ bvec3(false, true, true) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} bool[3] x; x = bool[3] (in0.z, in0.x, in0.y); out0 = bvec3(x[0], x[1], x[2]); ${OUTPUT} } "" end case bool4 version 300 es values { input bvec4 in0 = [ bvec4(true, true, false, false) ]; output bvec4 out0 = [ bvec4(false, true, true, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} bool[4] x; x = bool[4] (in0.z, in0.x, in0.y, in0.w); out0 = bvec4(x[0], x[1], x[2], x[3]); ${OUTPUT} } "" end case struct3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output vec3 out0 = [ vec3(2.0, -0.5, -1.0) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} struct test { float f; vec3 v; }; test a = test(in0.z, vec3(in0.x, in0.y, in0.z)); test b = test(in0.y, vec3(-in0.z, -in0.x, -in0.y)); test c = test(in0.x, vec3(-in0.y, in0.z, -in0.x)); test[3] x = test[3] (a, b, c); out0 = vec3(x[0].f, x[1].v.y, x[2].v.x); ${OUTPUT} } "" end case struct4 version 300 es values { input vec4 in0 = [ vec4(0.5, 1.0, 2.0, 1.5) ]; output vec4 out0 = [ vec4(2.0, -0.5, -1.0, -1.5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} struct test { float f; vec3 v; }; test a = test(in0.z, vec3(in0.x, in0.y, in0.z)); test b = test(in0.y, vec3(-in0.z, -in0.x, -in0.y)); test c = test(in0.x, vec3(-in0.y, in0.z, -in0.x)); test d = test(-in0.w, vec3(-in0.w, -in0.x, -in0.z)); test[4] x = test[4] (a, b, c, d); out0 = vec4(x[0].f, x[1].v.y, x[2].v.x, x[3].v.x); ${OUTPUT} } "" end case float_vec3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(7.4, -1.0, 2.0) | vec3(3.0, 1.6, -2.0) ]; output vec3 out0 = [ vec3(0.5, -2.0, 1.0) | vec3(7.4, -2.0, -1.0) | vec3(3.0, 2.0, 1.6) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} vec3[3] x; x = vec3[3] ( vec3(in0.x, in0.y, in0.z) , vec3(-in0.y, -in0.z, -in0.x), vec3(in0.z, in0.x, in0.y) ); out0 = vec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } "" end case int_vec3 version 300 es values { input ivec3 in0 = [ ivec3(5, 1, 2) | ivec3(7, -1, 2) | ivec3(3, 1, -2) ]; output ivec3 out0 = [ ivec3(5, -2, 1) | ivec3(7, -2, -1) | ivec3(3, 2, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} ivec3[3] x; x = ivec3[3] ( ivec3(in0.x, in0.y, in0.z) , ivec3(-in0.y, -in0.z, -in0.x), ivec3(in0.z, in0.x, in0.y) ); out0 = ivec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } "" end case bool_vec3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) ]; output bvec3 out0 = [ bvec3(true, true, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} bvec3[3] x; x = bvec3[3] ( bvec3(in0.x, in0.y, in0.z) , bvec3(in0.y, in0.z, in0.x), bvec3(in0.z, in0.x, in0.y) ); out0 = bvec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } "" end case float_mat3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-1.5, 0.0, -2.3) ]; output vec3 out0 = [ vec3(0.5, -1.0, 1.0) | vec3(-1.5, 0.0, 0.0) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} mat3[3] a = mat3[3] ( mat3( in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z) , mat3( in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y) , mat3( -in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x) ); mat3 a0 = a[0]; mat3 a1 = a[1]; mat3 a2 = a[2]; float ret0 = a0[2][0]; float ret1 = a1[0][2]; float ret2 = a2[1][2]; out0 = vec3(ret0, ret1, ret2); ${OUTPUT} } "" end case int_mat3 version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) | ivec3(-1, 0, -2) ]; output ivec3 out0 = [ ivec3(0, -1, 1) | ivec3(-1, 0, 0) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} mat3[3] a = mat3[3] ( mat3( in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z) , mat3( in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y) , mat3( -in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x) ); mat3 a0 = a[0]; mat3 a1 = a[1]; mat3 a2 = a[2]; float ret0 = a0[2][0]; float ret1 = a1[0][2]; float ret2 = a2[1][2]; out0 = ivec3(ret0, ret1, ret2); ${OUTPUT} } "" end case bool_mat3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) ]; output bvec3 out0 = [ bvec3(true, false, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} mat3[3] a = mat3[3] ( mat3( in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z) , mat3( in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y) , mat3( in0.z, in0.z, in0.z, in0.y, in0.y, in0.y, in0.x, in0.x, in0.x) ); mat3 a0 = a[0]; mat3 a1 = a[1]; mat3 a2 = a[2]; float ret0 = a0[2][0]; float ret1 = a1[0][2]; float ret2 = a2[1][2]; out0 = bvec3(ret0, ret1, ret2); ${OUTPUT} } "" end end # type group return "Arrays as return value" case float version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(7.4, -1.0, 2.0) | vec3(3.0, 1.6, -2.0) ]; output vec3 out0 = [ vec3(2.0, -0.5, 1.0) | vec3(2.0, -7.4, -1.0) | vec3(-2.0, -3.0, 1.6) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} float[3] func(vec3 a) { return float[3] (a.z, -a.x, a.y); } void main() { ${SETUP} float[3] x = func(in0); out0 = vec3(x[0], x[1], x[2]); ${OUTPUT} } "" end case int version 300 es values { input ivec3 in0 = [ ivec3(4, 1, 2) | ivec3(7, -1, 2) | ivec3(3, 1, -2) ]; output ivec3 out0 = [ ivec3(2, -4, 1) | ivec3(2, -7, -1) | ivec3(-2, -3, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} int[3] func(ivec3 a) { return int[3] (a.z, -a.x, a.y); } void main() { ${SETUP} int[3] x = func(in0); out0 = ivec3(x[0], x[1], x[2]); ${OUTPUT} } "" end case bool version 300 es values { input bvec3 in0 = [ bvec3(false, true, true) ]; output bvec3 out0 = [ bvec3(true, false, true) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} bool[3] func(bvec3 a) { return bool[3] (a.z, a.x, a.y); } void main() { ${SETUP} bool[3] x = func(in0); out0 = bvec3(x[0], x[1], x[2]); ${OUTPUT} } "" end case float_vec3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-0.5, 11.2, -1.0) ]; output vec3 out0 = [ vec3(1.0, 0.5, -2.0) | vec3(11.2, -0.5, 1.0) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} vec3[3] func(vec3[3] a) { return vec3[3] (a[1], a[2], a[0]); } void main() { ${SETUP} vec3[3] x = vec3[3](vec3(in0.x, in0.y, -in0.z) , vec3(in0.y, -in0.z, in0.x) , vec3(-in0.z, in0.x, in0.y) ); x = func(x); out0 = vec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } "" end case struct version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output vec3 out0 = [ vec3(-1.0, 2.0, 0.5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} struct test { float f; vec3 v; }; test[3] func(test[3] a) { return test[3] (a[1], a[2], a[0]); } void main() { ${SETUP} test a = test(in0.z, vec3(in0.x, in0.y, in0.z)); test b = test(in0.y, vec3(-in0.z, -in0.x, -in0.y)); test c = test(in0.x, vec3(-in0.y, in0.z, -in0.x)); test[3] t = test[3] (a, b, c); test[3] x = func(t); out0 = vec3(x[0].v.z, x[1].v.y, x[2].v.x); ${OUTPUT} } "" end case int_vec3 version 300 es values { input ivec3 in0 = [ ivec3(5, 1, 2) | ivec3(-5, 11, -1) ]; output ivec3 out0 = [ ivec3(1, 5, -2) | ivec3(11, -5, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} ivec3[3] func(ivec3[3] a) { return ivec3[3] (a[1], a[2], a[0]); } void main() { ${SETUP} ivec3[3] x = ivec3[3]( ivec3(in0.x, in0.y, -in0.z) , ivec3(in0.y, -in0.z, in0.x) , ivec3(-in0.z, in0.x, in0.y) ); x = func(x); out0 = ivec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } "" end case bool_vec3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, false) ]; output bvec3 out0 = [ bvec3(false, true, false) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} bvec3[3] func(bvec3[3] a) { return bvec3[3] (a[1], a[2], a[0]); } void main() { ${SETUP} bvec3[3] x = bvec3[3]( bvec3(in0.x, in0.y, in0.z) , bvec3(in0.y, in0.z, in0.x) , bvec3(in0.z, in0.x, in0.y) ); x = func(x); out0 = bvec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } "" end case float_mat3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-1.5, 0.0, -2.3) ]; output vec3 out0 = [ vec3(2.0, -1.0, 2.0) | vec3(-2.3, 0.0, -2.3) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} mat3[3] func(mat3[3] x) { mat3[3] r; r[0] = x[1]; r[1] = x[2]; r[2] = x[0]; return r; } void main() { ${SETUP} mat3[3] a, b; a[0] = mat3(in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z); a[1] = mat3(in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y); a[2] = mat3(-in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x); b = func(a); mat3 b0 = b[0]; mat3 b1 = b[1]; mat3 b2 = b[2]; float ret0 = b0[0][0]; float ret1 = b1[1][1]; float ret2 = b2[2][2]; out0 = vec3(ret0, ret1, ret2); ${OUTPUT} } "" end case int_mat3 version 300 es values { input ivec3 in0 = [ ivec3(5, 1, 2) | ivec3(-1, 0, -2) ]; output ivec3 out0 = [ ivec3(2, -1, 2) | ivec3(-2, 0, -2) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} mat3[3] func(mat3[3] x) { mat3[3] r; r[0] = x[1]; r[1] = x[2]; r[2] = x[0]; return r; } void main() { ${SETUP} mat3[3] a, b; a[0] = mat3(in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z); a[1] = mat3(in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y); a[2] = mat3(-in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x); b = func(a); mat3 b0 = b[0]; mat3 b1 = b[1]; mat3 b2 = b[2]; float ret0 = b0[0][0]; float ret1 = b1[1][1]; float ret2 = b2[2][2]; out0 = ivec3(ret0, ret1, ret2); ${OUTPUT} } "" end case bool_mat3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) | bvec3(true, true, false) ]; output bvec3 out0 = [ bvec3(true, false, true) | bvec3(false, true, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} mat3[3] func(mat3[3] x) { mat3[3] r; r[0] = x[1]; r[1] = x[2]; r[2] = x[0]; return r; } void main() { ${SETUP} mat3[3] a, b; a[0] = mat3(in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z); a[1] = mat3(in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y); a[2] = mat3(in0.z, in0.z, in0.z, in0.y, in0.y, in0.y, in0.x, in0.x, in0.x); b = func(a); mat3 b0 = b[0]; mat3 b1 = b[1]; mat3 b2 = b[2]; float ret0 = b0[0][0]; float ret1 = b1[1][1]; float ret2 = b2[2][2]; out0 = bvec3(ret0, ret1, ret2); ${OUTPUT} } "" end end # return group unnamed_parameter "Array type as unnamed parameter of a function prototype" case float version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(7.4, -1.0, 2.0) | vec3(3.0, 1.6, -2.0) ]; output vec3 out0 = [ vec3(2.0, 0.5, 1.0) | vec3(2.0, 7.4, -1.0) | vec3(-2.0, 3.0, 1.6) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} float[3] func(float[3]); void main() { ${SETUP} float[3] a = float[3] (in0.x, in0.y, in0.z); float[3] b = func(a); out0 = vec3(b[0], b[1], b[2]); ${OUTPUT} } float[3] func(float[3] a) { return float[3] (a[2], a[0], a[1]); } "" end case int version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) | ivec3(7, -1, 2) | ivec3(3, 1, -2) ]; output ivec3 out0 = [ ivec3(2, 0, 1) | ivec3(2, 7, -1) | ivec3(-2, 3, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} int[3] func(int[3]); void main() { ${SETUP} int[3] a = int[3] (in0.x, in0.y, in0.z); int[3] b = func(a); out0 = ivec3(b[0], b[1], b[2]); ${OUTPUT} } int[3] func(int[3] a) { return int[3] (a[2], a[0], a[1]); } "" end case bool version 300 es values { input bvec3 in0 = [ bvec3(false, true, true) ]; output bvec3 out0 = [ bvec3(true, false, true) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} bool[3] func(bool[3]); void main() { ${SETUP} bool[3] a = bool[3] (in0.x, in0.y, in0.z); bool[3] b = func(a); out0 = bvec3(b[0], b[1], b[2]); ${OUTPUT} } bool[3] func(bool[3] a) { return bool[3] (a[2], a[0], a[1]); } "" end case struct version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output vec3 out0 = [ vec3(-1.0, 2.0, 0.5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} struct test { float f; vec3 v; }; test[3] func(test[3]); void main() { ${SETUP} test a = test(in0.z, vec3(in0.x, in0.y, in0.z)); test b = test(in0.y, vec3(-in0.z, -in0.x, -in0.y)); test c = test(in0.x, vec3(-in0.y, in0.z, -in0.x)); test[3] t = test[3] (a, b, c); test[3] x = func(t); out0 = vec3(x[0].v.z, x[1].v.y, x[2].v.x); ${OUTPUT} } test[3] func(test[3] a) { return test[3] (a[1], a[2], a[0]); } "" end case float_vec3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-0.5, 11.2, -1.0) ]; output vec3 out0 = [ vec3(1.0, 0.5, -2.0) | vec3(11.2, -0.5, 1.0) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} vec3[3] func(vec3[3]); void main() { ${SETUP} vec3[3] x = vec3[3](vec3(in0.x, in0.y, -in0.z) , vec3(in0.y, -in0.z, in0.x) , vec3(-in0.z, in0.x, in0.y) ); x = func(x); out0 = vec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } vec3[3] func(vec3[3] a) { return vec3[3] (a[1], a[2], a[0]); } "" end case int_vec3 version 300 es values { input ivec3 in0 = [ ivec3(5, 1, 2) | ivec3(-5, 11, -1) ]; output ivec3 out0 = [ ivec3(1, 5, -2) | ivec3(11, -5, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} ivec3[3] func(ivec3[3]); void main() { ${SETUP} ivec3[3] x = ivec3[3]( ivec3(in0.x, in0.y, -in0.z) , ivec3(in0.y, -in0.z, in0.x) , ivec3(-in0.z, in0.x, in0.y) ); x = func(x); out0 = ivec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } ivec3[3] func(ivec3[3] a) { return ivec3[3] (a[1], a[2], a[0]); } "" end case bool_vec3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, false) ]; output bvec3 out0 = [ bvec3(false, true, false) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} bvec3[3] func(bvec3[3]); void main() { ${SETUP} bvec3[3] x = bvec3[3]( bvec3(in0.x, in0.y, in0.z) , bvec3(in0.y, in0.z, in0.x) , bvec3(in0.z, in0.x, in0.y) ); x = func(x); out0 = bvec3(x[0].x, x[1].y, x[2].z); ${OUTPUT} } bvec3[3] func(bvec3[3] a) { return bvec3[3] (a[1], a[2], a[0]); } "" end case float_mat3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-1.5, 0.0, -2.3) ]; output vec3 out0 = [ vec3(2.0, -1.0, 2.0) | vec3(-2.3, 0.0, -2.3) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} mat3[3] func(mat3[3]); void main() { ${SETUP} mat3[3] a, b; a[0] = mat3(in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z); a[1] = mat3(in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y); a[2] = mat3(-in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x); b = func(a); mat3 b0 = b[0]; mat3 b1 = b[1]; mat3 b2 = b[2]; float ret0 = b0[0][0]; float ret1 = b1[1][1]; float ret2 = b2[2][2]; out0 = vec3(ret0, ret1, ret2); ${OUTPUT} } mat3[3] func(mat3[3] x) { mat3[3] r; r[0] = x[1]; r[1] = x[2]; r[2] = x[0]; return r; } "" end case int_mat3 version 300 es values { input ivec3 in0 = [ ivec3(5, 1, 2) | ivec3(-1, 0, -2) ]; output ivec3 out0 = [ ivec3(2, -1, 2) | ivec3(-2, 0, -2) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} mat3[3] func(mat3[3]); void main() { ${SETUP} mat3[3] a, b; a[0] = mat3(in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z); a[1] = mat3(in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y); a[2] = mat3(-in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x); b = func(a); mat3 b0 = b[0]; mat3 b1 = b[1]; mat3 b2 = b[2]; float ret0 = b0[0][0]; float ret1 = b1[1][1]; float ret2 = b2[2][2]; out0 = ivec3(ret0, ret1, ret2); ${OUTPUT} } mat3[3] func(mat3[3] x) { mat3[3] r; r[0] = x[1]; r[1] = x[2]; r[2] = x[0]; return r; } "" end case bool_mat3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) | bvec3(true, true, false) ]; output bvec3 out0 = [ bvec3(true, false, true) | bvec3(false, true, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} mat3[3] func(mat3[3]); void main() { ${SETUP} mat3[3] a, b; a[0] = mat3(in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z); a[1] = mat3(in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y); a[2] = mat3(in0.z, in0.z, in0.z, in0.y, in0.y, in0.y, in0.x, in0.x, in0.x); b = func(a); mat3 b0 = b[0]; mat3 b1 = b[1]; mat3 b2 = b[2]; float ret0 = b0[0][0]; float ret1 = b1[1][1]; float ret2 = b2[2][2]; out0 = bvec3(ret0, ret1, ret2); ${OUTPUT} } mat3[3] func(mat3[3] x) { mat3[3] r; r[0] = x[1]; r[1] = x[2]; r[2] = x[0]; return r; } "" end end # unnamed_parameter group declaration "Declaring arrays" case implicit_size_float version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(7.4, -1.0, 2.0) | vec3(3.0, 1.6, -2.0) ]; output vec3 out0 = [ vec3(2.0, 0.5, 1.0) | vec3(2.0, 7.4, -1.0) | vec3(-2.0, 3.0, 1.6) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} float[] x = float[] (in0.z, in0.x, in0.y); float[] y = x; out0 = vec3(y[0], y[1], y[2]); ${OUTPUT} } "" end case implicit_size_int version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) | ivec3(7, -1, 2) | ivec3(3, 1, -2) ]; output ivec3 out0 = [ ivec3(2, 0, 1) | ivec3(2, 7, -1) | ivec3(-2, 3, 1) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} int[] x = int[] (in0.z, in0.x, in0.y); int[] y = x; out0 = ivec3(y[0], y[1], y[2]); ${OUTPUT} } "" end case implicit_size_bool version 300 es values { input bvec3 in0 = [ bvec3(false, true, true) ]; output bvec3 out0 = [ bvec3(true, false, true) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} bool[] x = bool[] (in0.z, in0.x, in0.y); bool[] y = x; out0 = bvec3(y[0], y[1], y[2]); ${OUTPUT} } "" end case implicit_size_struct version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output vec3 out0 = [ vec3(-1.0, -0.5, 2.0) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} struct test { float f; vec3 v; }; void main() { ${SETUP} test a = test(in0.z, vec3(in0.x, in0.y, in0.z)); test b = test(in0.y, vec3(-in0.z, -in0.x, -in0.y)); test c = test(in0.x, vec3(-in0.y, in0.z, -in0.x)); test[] x = test[] (c, b, a); test[] y = x; out0 = vec3(y[0].v.x, y[1].v.y, y[2].v.z); ${OUTPUT} } "" end case implicit_size_float_vec3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-0.5, 11.2, -1.0) ]; output vec3 out0 = [ vec3(0.5, -2.0, 1.0) | vec3(-0.5, 1.0, 11.2) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} vec3[] x = vec3[] ( vec3(in0.x, in0.y, -in0.z) , vec3(in0.y, -in0.z, in0.x) , vec3(-in0.z, in0.x, in0.y) ); vec3[] y = x; out0 = vec3(y[0].x, y[1].y, y[2].z); ${OUTPUT} } "" end case implicit_size_int_ivec3 version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) | ivec3(5, 11, -1) ]; output ivec3 out0 = [ ivec3(0, -2, 1) | ivec3(5, 1, 11) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} ivec3[] x = ivec3[] ( ivec3(in0.x, in0.y, -in0.z) , ivec3(in0.y, -in0.z, in0.x) , ivec3(-in0.z, in0.x, in0.y) ); ivec3[] y = x; out0 = ivec3(y[0].x, y[1].y, y[2].z); ${OUTPUT} } "" end case implicit_size_bool_bvec3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) ]; output bvec3 out0 = [ bvec3(true, true, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} bvec3[] x = bvec3[] ( bvec3(in0.x, in0.y, in0.z) , bvec3(in0.y, in0.z, in0.x) , bvec3(in0.z, in0.x, in0.y) ); bvec3[] y = x; out0 = bvec3(y[0].x, y[1].y, y[2].z); ${OUTPUT} } "" end case implicit_size_float_mat3 version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) | vec3(-1.5, 0.0, -2.3) ]; output vec3 out0 = [ vec3(0.5, -1.0, 1.0) | vec3(-1.5, 0.0, 0.0) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} mat3[] a = mat3[] ( mat3( in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z) , mat3( in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y) , mat3( -in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x) ); mat3 a0 = a[0]; mat3 a1 = a[1]; mat3 a2 = a[2]; float ret0 = a0[2][0]; float ret1 = a1[0][2]; float ret2 = a2[1][2]; out0 = vec3(ret0, ret1, ret2); ${OUTPUT} } "" end case implicit_size_int_mat3 version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) | ivec3(-1, 0, -2) ]; output ivec3 out0 = [ ivec3(0, -1, 1) | ivec3(-1, 0, 0) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} mat3[] a = mat3[] ( mat3( in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z) , mat3( in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y, in0.z, in0.x, -in0.y) , mat3( -in0.z, -in0.z, in0.z, -in0.y, -in0.y, in0.y, -in0.x, -in0.x, in0.x) ); mat3 a0 = a[0]; mat3 a1 = a[1]; mat3 a2 = a[2]; float ret0 = a0[2][0]; float ret1 = a1[0][2]; float ret2 = a2[1][2]; out0 = ivec3(ret0, ret1, ret2); ${OUTPUT} } "" end case implicit_size_bool_mat3 version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) ]; output bvec3 out0 = [ bvec3(true, false, false) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} mat3[] a = mat3[] ( mat3( in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z) , mat3( in0.z, in0.x, in0.y, in0.z, in0.x, in0.y, in0.z, in0.x, in0.y) , mat3( in0.z, in0.z, in0.z, in0.y, in0.y, in0.y, in0.x, in0.x, in0.x) ); mat3 a0 = a[0]; mat3 a1 = a[1]; mat3 a2 = a[2]; float ret0 = a0[2][0]; float ret1 = a1[0][2]; float ret2 = a2[1][2]; out0 = bvec3(ret0, ret1, ret2); ${OUTPUT} } "" end case constant_expression_array_size version 300 es both "" #version 300 es precision mediump float; ${DECLARATIONS} const int a = 4; void main () { const int b = 5; float[a] array1; float[b] array2; float[array1.length()] array3; float[a+b] array4; ${OUTPUT} } "" end case constant_expression_array_access version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output vec3 out0 = [ vec3(-2.0, -1.0, -0.5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} const int a = 3; void main () { ${SETUP} const int b = 2; float x = float[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x) [a]; float y = float[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x) [b+2]; float z = float[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x) [5]; out0 = vec3(x, y, z); ${OUTPUT} } "" end case dynamic_expression_array_access version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; input ivec2 in1 = ivec2(3, 2); output vec3 out0 = [ vec3(-2.0, -1.0, -0.5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { ${SETUP} float x = float[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x) [in1.x]; float y = float[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x) [in1.y+2]; float z = float[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x) [in1.x+in1.y]; out0 = vec3(x, y, z); ${OUTPUT} } "" end case multiple_declarations_single_statement_explicit version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output vec3 out0 = [ vec3(2.0, -1.0, 0.5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { ${SETUP} float[] x = float[6] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x), y = float[2] (in0.x, -in0.y); out0 = vec3(x[2], y[1], x[0]); ${OUTPUT} } "" end case multiple_declarations_single_statement_implicit version 300 es values { input ivec3 in0 = [ ivec3(5, 1, 2) ]; output ivec3 out0 = [ ivec3(2, -1, 5) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { ${SETUP} int[] x = int[] (in0.x, in0.y, in0.z, -in0.z, -in0.y, -in0.x), y = int[] (in0.x, -in0.y); out0 = ivec3(x[2], y[1], x[0]); ${OUTPUT} } "" end end # declaration group length "Array length method" case float version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output ivec3 out0 = [ ivec3(3, 5, 13) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} float[] x = float[3] (in0.z, in0.x, in0.y); float[] y = float[] (in0.z, in0.x, in0.y, in0.x, in0.y); float[13] z; out0 = ivec3(x.length(), y.length(), z.length()); ${OUTPUT} } "" end case int version 300 es values { input ivec3 in0 = [ ivec3(0, 1, 2) ]; output ivec3 out0 = [ ivec3(3, 5, 13) ]; } both "" #version 300 es precision mediump int; precision mediump float; ${DECLARATIONS} void main() { ${SETUP} int[] x = int[3] (in0.z, in0.x, in0.y); int[] y = int[] (in0.z, in0.x, in0.y, in0.x, in0.y); int[13] z; out0 = ivec3(x.length(), y.length(), z.length()); ${OUTPUT} } "" end case bool version 300 es values { input bvec3 in0 = [ bvec3(true, false, true) ]; output ivec3 out0 = [ ivec3(3, 5, 13) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} void main() { ${SETUP} bool[] x = bool[3] (in0.z, in0.x, in0.y); bool[] y = bool[] (in0.z, in0.x, in0.y, in0.x, in0.y); bool[13] z; out0 = ivec3(x.length(), y.length(), z.length()); ${OUTPUT} } "" end case struct version 300 es values { input vec3 in0 = [ vec3(0.5, 1.0, 2.0) ]; output ivec3 out0 = [ ivec3(3, 5, 13) ]; } both "" #version 300 es precision mediump float; ${DECLARATIONS} struct test { float f; vec3 v; }; void main() { ${SETUP} test a = test(in0.z, vec3(in0.x, in0.y, in0.z)); test b = test(in0.y, vec3(-in0.z, -in0.x, -in0.y)); test c = test(in0.x, vec3(-in0.y, in0.z, -in0.x)); test[] x = test[3] (a, b, c); test[] y = test[] (c, a, b, b, a); test[13] z; out0 = ivec3(x.length(), y.length(), z.length()); ${OUTPUT} } "" end end # length group invalid "Invalid Functions" case multidimensional_array1 version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { float a[5][3]; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case multidimensional_array2 version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { float[5] a[3]; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case multidimensional_uniform_array version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} uniform float a[3][2]; void main () { ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case multidimensional_array_in_uniform_block version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} uniform MyBlock { float a[3][2]; }; void main () { ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case dynamic_expression_array_size version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { int a = 5; float[a] array; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case empty_declaration_without_var_name version 300 es expect compile_or_link_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { int[]; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case empty_declaration_with_var_name version 300 es expect compile_or_link_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { int[] a; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case constructor_c_style1 version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { float a[]; a = float[3] { 1.0, 2.0, 3.0 }; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case constructor_c_style2 version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { float a[5] = { 1.0, 2.0, 3.0 }; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case constructor_c_style3 version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { float a[] = float[3] { 1.0, 2.0, 3.0 }; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end case constructor_c_style4 version 300 es expect compile_fail both "" #version 300 es precision mediump float; ${DECLARATIONS} void main () { float a[3] = { 1.0, 2.0, 3.0 }; ${POSITION_FRAG_COLOR} = vec4(1.0); } "" end end # invalid # https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance2/glsl3/array-in-complex-expression.html group complex_expression "Arrays in complex expressions" case and_short_circuits version 300 es values { output int g = -1; } both "" #version 300 es precision mediump float; ${DECLARATIONS} int[2] plus() { ++g; return int[2](g, g); } bool minus() { --g; return false; } void main() { ${SETUP} g = 0; int a[2] = int[2](0, 0); // The plus() call must not be evaluated, since && short-circuits minus() && (a == plus()); ${OUTPUT} } "" end case or_short_circuits version 300 es values { output int g = -1; } both "" #version 300 es precision mediump float; ${DECLARATIONS} int[2] plus() { ++g; return int[2](g, g); } bool minus() { --g; return false; } void main() { ${SETUP} g = 0; int a[2] = int[2](0, 0); // The function call must not be evaluated, since && short-circuits minus() && (a == plus()); ${OUTPUT} } "" end case ternary_only_evaluates_one_operand version 300 es values { output int g = 0; } both "" #version 300 es precision mediump float; ${DECLARATIONS} int[2] plus() { ++g; return int[2](g, g); } void main() { ${SETUP} g = 0; int a[2] = int[2](0, 0); // The function call must not be evaluated, since the condition is true. (g == 0) ? true : (a == plus()); ${OUTPUT} } "" end case sequence_side_effects_affecting_compared_array_content version 300 es values { output bool success = true; } both "" #version 300 es precision mediump float; ${DECLARATIONS} int[2] func(int param) { return int[2](param, param); } void main() { ${SETUP} int a[2]; for (int i = 0; i < 2; ++i) { a[i] = 1; } int j = 0; // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9). // The function call that returns the array needs to be evaluated after ++j // for the expression to return the correct value (true). success = ((++j), (a == func(j))); ${OUTPUT} } "" end end # complex_expression