summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js1278
1 files changed, 1278 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js
new file mode 100644
index 0000000000..c08db90758
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js
@@ -0,0 +1,1278 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderIndexingTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuStringTemplate');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluTexture');
+goog.require('modules.shared.glsShaderRenderCase');
+
+goog.scope(function() {
+ /** @type {?WebGL2RenderingContext} */ var gl;
+ var es3fShaderIndexingTests = functional.gles3.es3fShaderIndexingTests;
+ var deMath = framework.delibs.debase.deMath;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuStringTemplate = framework.common.tcuStringTemplate;
+ /**
+ * @enum {number}
+ */
+ es3fShaderIndexingTests.IndexAccessType = {
+ STATIC: 0,
+ DYNAMIC: 1,
+ STATIC_LOOP: 2,
+ DYNAMIC_LOOP: 3
+ };
+
+ /**
+ * @param {es3fShaderIndexingTests.IndexAccessType} accessType
+ * @return {string}
+ */
+ es3fShaderIndexingTests.getIndexAccessTypeName = function(accessType) {
+ /** @type {Array<string>} */ var s_names = [
+ 'static',
+ 'dynamic',
+ 'static_loop',
+ 'dynamic_loop'
+ ];
+ return s_names[accessType];
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fShaderIndexingTests.VectorAccessType = {
+ DIRECT: 0,
+ COMPONENT: 1,
+ SUBSCRIPT_STATIC: 2,
+ SUBSCRIPT_DYNAMIC: 3,
+ SUBSCRIPT_STATIC_LOOP: 4,
+ SUBSCRIPT_DYNAMIC_LOOP: 5
+ };
+
+ /**
+ * @param {es3fShaderIndexingTests.VectorAccessType} accessType
+ * @return {string}
+ */
+ es3fShaderIndexingTests.getVectorAccessTypeName = function(accessType) {
+ /** @type {Array<string>} */ var s_names = [
+ 'direct',
+ 'component',
+ 'static_subscript',
+ 'dynamic_subscript',
+ 'static_loop_subscript',
+ 'dynamic_loop_subscript'
+ ];
+ assertMsgOptions(deMath.deInBounds32(accessType, 0, s_names.length), 'Index out of bounds', false, true);
+ return s_names[accessType];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsFloat = function(c) {
+ c.color[0] = 1.875 * c.coords[0];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsVec2 = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [0, 1]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsVec3 = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [0, 1, 2]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ c.color[2] = 1.875 * swizzled[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsVec4 = function(c) {
+ c.color = deMath.scale(c.coords, 1.875);
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getArrayCoordsEvalFunc = function(dataType) {
+ if (dataType === gluShaderUtil.DataType.FLOAT) return es3fShaderIndexingTests.evalArrayCoordsFloat;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalArrayCoordsVec2;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalArrayCoordsVec3;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalArrayCoordsVec4;
+ else throw new Error('Invalid data type.');
+ };
+
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformFloat = function(c) {
+ c.color[0] = 1.875 * c.constCoords[0];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformVec2 = function(c) {
+ var swizzled = deMath.swizzle(c.constCoords, [0, 1]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformVec3 = function(c) {
+ var swizzled = deMath.swizzle(c.constCoords, [0, 1, 2]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ c.color[2] = 1.875 * swizzled[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformVec4 = function(c) {
+ c.color = deMath.scale(c.constCoords, 1.875);
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getArrayUniformEvalFunc = function(dataType) {
+ if (dataType === gluShaderUtil.DataType.FLOAT) return es3fShaderIndexingTests.evalArrayUniformFloat;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalArrayUniformVec2;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalArrayUniformVec3;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalArrayUniformVec4;
+ else throw new Error('Invalid data type.');
+ };
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {function(glsShaderRenderCase.ShaderEvalContext)} evalFunc
+ * @param {string} vertShaderSource
+ * @param {string} fragShaderSource
+ */
+ es3fShaderIndexingTests.ShaderIndexingCase = function(name, description, isVertexCase, varType, evalFunc, vertShaderSource, fragShaderSource) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
+ /** @type {gluShaderUtil.DataType} */ this.m_varType = varType;
+ /** @type {string} */ this.m_vertShaderSource = vertShaderSource;
+ /** @type {string} */ this.m_fragShaderSource = fragShaderSource;
+ };
+
+ es3fShaderIndexingTests.ShaderIndexingCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderIndexingTests.ShaderIndexingCase.prototype.constructor = es3fShaderIndexingTests.ShaderIndexingCase;
+
+ /**
+ * @param {?WebGLProgram} programID
+ * @param {Array<number>} constCoords
+ */
+ es3fShaderIndexingTests.ShaderIndexingCase.prototype.setupUniforms = function(programID, constCoords) {
+ /** @type {(Array<number>|Float32Array)} */ var arr = [];
+ /** @type {Array<number>} */ var array1d = [];
+ /** @type {?WebGLUniformLocation} */ var arrLoc = gl.getUniformLocation(programID, 'u_arr');
+ if (arrLoc != null) {
+ if (this.m_varType === gluShaderUtil.DataType.FLOAT) {
+ arr[0] = constCoords[0];
+ arr[1] = constCoords[0] * 0.5;
+ arr[2] = constCoords[0] * 0.25;
+ arr[3] = constCoords[0] * 0.125;
+ gl.uniform1fv(arrLoc, arr);
+ }
+ else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC2) {
+ arr[0] = deMath.swizzle(constCoords, [0, 1]);
+ arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.5);
+ arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.25);
+ arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.125);
+ for (var i = 0; i < arr.length; i++)
+ array1d = array1d.concat(arr[i]);
+ gl.uniform2fv(arrLoc, array1d);
+ }
+ else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC3) {
+ arr[0] = deMath.swizzle(constCoords, [0, 1, 2]);
+ arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.5);
+ arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.25);
+ arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.125);
+ for (var i = 0; i < arr.length; i++)
+ array1d = array1d.concat(arr[i]);
+ gl.uniform3fv(arrLoc, array1d);
+ }
+ else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC4) {
+ arr[0] = deMath.swizzle(constCoords, [0,1,2,3]);
+ arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.5);
+ arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.25);
+ arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.125);
+ for (var i = 0; i < arr.length; i++)
+ array1d = array1d.concat(arr[i]);
+ gl.uniform4fv(arrLoc, array1d);
+ }
+ else
+ throw new Error('u_arr should not have location assigned in this test case');
+ }
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} vertAccess
+ * @param {es3fShaderIndexingTests.IndexAccessType} fragAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createVaryingArrayCase = function(caseName, description, varType, vertAccess, fragAccess) {
+ /** @type {string} */ var vtx = '';
+ vtx += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+
+ if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ vtx += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+ else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ vtx += 'uniform mediump int ui_four;\n';
+
+ vtx += 'out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n' +
+ '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ if (vertAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ vtx += ' var[0] = ${VAR_TYPE}(a_coords);\n' +
+ ' var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n' +
+ ' var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n' +
+ ' var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n';
+ }
+ else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ vtx += ' var[ui_zero] = ${VAR_TYPE}(a_coords);\n' +
+ ' var[ui_one] = ${VAR_TYPE}(a_coords) * 0.5;\n' +
+ ' var[ui_two] = ${VAR_TYPE}(a_coords) * 0.25;\n' +
+ ' var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n';
+ }
+ else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ vtx += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n' +
+ ' for (int i = 0; i < 4; i++)\n' +
+ ' {\n' +
+ ' var[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+ else {
+ assertMsgOptions(vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'Not Dynamic_Loop', false, true);
+ vtx += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n' +
+ ' for (int i = 0; i < ui_four; i++)\n' +
+ ' {\n' +
+ ' var[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+ vtx += '}\n';
+
+ /** @type {string} */ var frag = '';
+ frag += '#version 300 es\n' +
+ 'precision mediump int;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ frag += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+ else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ frag += 'uniform int ui_four;\n';
+
+ frag += 'in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n' +
+ '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
+
+ if (fragAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ frag += ' res += var[0];\n' +
+ ' res += var[1];\n' +
+ ' res += var[2];\n' +
+ ' res += var[3];\n';
+ }
+ else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ frag += ' res += var[ui_zero];\n' +
+ ' res += var[ui_one];\n' +
+ ' res += var[ui_two];\n' +
+ ' res += var[ui_three];\n';
+ }
+ else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ frag += ' for (int i = 0; i < 4; i++)\n' +
+ ' res += var[i];\n';
+ }
+ else {
+ assertMsgOptions(fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'Not Dynamic_Loop', false, true);
+ frag += ' for (int i = 0; i < ui_four; i++)\n' +
+ ' res += var[i];\n';
+ }
+ frag += ' o_color = vec4(res${PADDING});\n' +
+ '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params['VAR_TYPE'] = gluShaderUtil.getDataTypeName(varType);
+ params['ARRAY_LEN'] = '4';
+ params['PRECISION'] = 'mediump';
+
+ if (varType === gluShaderUtil.DataType.FLOAT)
+ params['PADDING'] = ', 0.0, 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getArrayCoordsEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, true, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createUniformArrayCase = function(caseName, description, isVertexCase, varType, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n';
+ vtx += 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ op += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ op += 'uniform mediump int ui_four;\n';
+
+ op += 'uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n';
+ vtx += 'void main()\n';
+ vtx += '{\n';
+ vtx += ' gl_Position = a_position;\n';
+
+ frag += '\n';
+ frag += 'void main()\n';
+ frag += '{\n';
+
+ // Read array.
+ op += ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' res += u_arr[0];\n';
+ op += ' res += u_arr[1];\n';
+ op += ' res += u_arr[2];\n';
+ op += ' res += u_arr[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' res += u_arr[ui_zero];\n';
+ op += ' res += u_arr[ui_one];\n';
+ op += ' res += u_arr[ui_two];\n';
+ op += ' res += u_arr[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < 4; i++)\n';
+ op += ' res += u_arr[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported.', false, true);
+ op += ' for (int i = 0; i < ui_four; i++)\n';
+ op += ' res += u_arr[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec4(res${PADDING});\n';
+ frag += ' o_color = v_color;\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res${PADDING});\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params['VAR_TYPE'] = gluShaderUtil.getDataTypeName(varType);
+ params['ARRAY_LEN'] = '4';
+ params['PRECISION'] = 'mediump';
+
+ if (varType === gluShaderUtil.DataType.FLOAT)
+ params['PADDING'] = ', 0.0, 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getArrayUniformEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} writeAccess
+ * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createTmpArrayCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ op += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ op += 'uniform mediump int ui_four;\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ // Write array.
+ if (isVertexCase)
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n';
+ else
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n';
+
+ op += ' ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n';
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' arr[0] = ${VAR_TYPE}(coords);\n' +
+ ' arr[1] = ${VAR_TYPE}(coords) * 0.5;\n' +
+ ' arr[2] = ${VAR_TYPE}(coords) * 0.25;\n' +
+ ' arr[3] = ${VAR_TYPE}(coords) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' arr[ui_zero] = ${VAR_TYPE}(coords);\n' +
+ ' arr[ui_one] = ${VAR_TYPE}(coords) * 0.5;\n' +
+ ' arr[ui_two] = ${VAR_TYPE}(coords) * 0.25;\n' +
+ ' arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < 4; i++)\n' +
+ ' {\n' +
+ ' arr[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+ else {
+ assertMsgOptions(writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'writeAccess not supported', false, true);
+ op += ' for (int i = 0; i < ui_four; i++)\n' +
+ ' {\n' +
+ ' arr[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+
+ // Read array.
+ op += ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' res += arr[0];\n' +
+ ' res += arr[1];\n' +
+ ' res += arr[2];\n' +
+ ' res += arr[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' res += arr[ui_zero];\n' +
+ ' res += arr[ui_one];\n' +
+ ' res += arr[ui_two];\n' +
+ ' res += arr[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < 4; i++)\n' +
+ ' res += arr[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported.', false, true);
+ op += ' for (int i = 0; i < ui_four; i++)\n' +
+ ' res += arr[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec4(res${PADDING});\n';
+ frag += ' o_color = v_color;\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res${PADDING});\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params["VAR_TYPE"] = gluShaderUtil.getDataTypeName(varType);
+ params["ARRAY_LEN"] = "4";
+ params["PRECISION"] = "mediump";
+
+ if (varType === gluShaderUtil.DataType.FLOAT)
+ params['PADDING'] = ', 0.0, 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getArrayCoordsEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ // VECTOR SUBSCRIPT.
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptVec2 = function(c) {
+ c.color[0] = c.coords[0] + 0.5 * c.coords[1];
+ c.color[1] = c.coords[0] + 0.5 * c.coords[1];
+ c.color[2] = c.coords[0] + 0.5 * c.coords[1];
+ };
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptVec3 = function(c) {
+ c.color[0] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
+ c.color[1] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
+ c.color[2] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
+ };
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptVec4 = function(c) {
+ c.color[0] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
+ c.color[1] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
+ c.color[2] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getVectorSubscriptEvalFunc = function(dataType) {
+ if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalSubscriptVec2;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalSubscriptVec3;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalSubscriptVec4;
+ else throw new Error('Invalid data type.');
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.VectorAccessType} writeAccess
+ * @param {es3fShaderIndexingTests.VectorAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createVectorSubscriptCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '' ;
+
+ /** @type {number} */ var vecLen = gluShaderUtil.getDataTypeScalarSize(varType);
+ /** @type {string} */ var vecLenName = glsShaderRenderCase.getIntUniformName(vecLen);
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec3 v_color;\n';
+ frag += 'in mediump vec3 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC ||
+ readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC){
+ op += 'uniform mediump int ui_zero';
+ if (vecLen >= 2) op += ', ui_one';
+ if (vecLen >= 3) op += ', ui_two';
+ if (vecLen >= 4) op += ', ui_three';
+ op += ';\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP ||
+ readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP)
+ op += 'uniform mediump int ' + vecLenName + ';\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ // Write vector.
+ if (isVertexCase)
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n';
+ else
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n';
+
+ op += ' ${PRECISION} ${VAR_TYPE} tmp;\n';
+ if (writeAccess === es3fShaderIndexingTests.VectorAccessType.DIRECT)
+ op += ' tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n';
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.COMPONENT) {
+ op += ' tmp.x = coords.x;\n';
+ if (vecLen >= 2) op += ' tmp.y = coords.y * 0.5;\n';
+ if (vecLen >= 3) op += ' tmp.z = coords.z * 0.25;\n';
+ if (vecLen >= 4) op += ' tmp.w = coords.w * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC) {
+ op += ' tmp[0] = coords.x;\n';
+ if (vecLen >= 2) op += ' tmp[1] = coords.y * 0.5;\n';
+ if (vecLen >= 3) op += ' tmp[2] = coords.z * 0.25;\n';
+ if (vecLen >= 4) op += ' tmp[3] = coords.w * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC) {
+ op += ' tmp[ui_zero] = coords.x;\n';
+ if (vecLen >= 2) op += ' tmp[ui_one] = coords.y * 0.5;\n';
+ if (vecLen >= 3) op += ' tmp[ui_two] = coords.z * 0.25;\n';
+ if (vecLen >= 4) op += ' tmp[ui_three] = coords.w * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + vecLen + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = coords.x;\n';
+ op += ' coords = coords.${ROT_SWIZZLE} * 0.5;\n';
+ op += ' }\n';
+ }
+ else {
+ assertMsgOptions(writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP, 'writeAccess not supported.', false, true);
+ op += ' for (int i = 0; i < ' + vecLenName + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = coords.x;\n';
+ op += ' coords = coords.${ROT_SWIZZLE} * 0.5;\n';
+ op += ' }\n';
+ }
+
+ // Read vector.
+ op += ' ${PRECISION} float res = 0.0;\n';
+ if (readAccess === es3fShaderIndexingTests.VectorAccessType.DIRECT)
+ op += ' res = dot(tmp, ${VAR_TYPE}(1.0));\n';
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.COMPONENT) {
+ op += ' res += tmp.x;\n';
+ if (vecLen >= 2) op += ' res += tmp.y;\n';
+ if (vecLen >= 3) op += ' res += tmp.z;\n';
+ if (vecLen >= 4) op += ' res += tmp.w;\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC) {
+ op += ' res += tmp[0];\n';
+ if (vecLen >= 2) op += ' res += tmp[1];\n';
+ if (vecLen >= 3) op += ' res += tmp[2];\n';
+ if (vecLen >= 4) op += ' res += tmp[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC) {
+ op += ' res += tmp[ui_zero];\n';
+ if (vecLen >= 2) op += ' res += tmp[ui_one];\n';
+ if (vecLen >= 3) op += ' res += tmp[ui_two];\n';
+ if (vecLen >= 4) op += ' res += tmp[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + vecLen + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP, 'readAccess not supported', false, true);
+ op += ' for (int i = 0; i < ' + vecLenName + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec3(res);\n';
+ frag += ' o_color = vec4(v_color.rgb, 1.0);\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(vec3(res), 1.0);\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Array<string>} */ var s_swizzles = ['', 'x', 'xy', 'xyz', 'xyzw'];
+ /** @type {Array<string>} */ var s_rotSwizzles = ['', 'x', 'yx', 'yzx', 'yzwx'];
+
+ /** @type {Object} */ var params = {};
+ params["VAR_TYPE"] = gluShaderUtil.getDataTypeName(varType);
+ params["PRECISION"] = "mediump";
+ params["SWIZZLE"] = s_swizzles[vecLen];
+ params["ROT_SWIZZLE"] = s_rotSwizzles[vecLen];
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getVectorSubscriptEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ // MATRIX SUBSCRIPT.
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat2 = function(c) {
+ var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
+ var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
+ c.color[0] = swizzle01[0] + 0.5 * swizzle12[0];
+ c.color[1] = swizzle01[1] + 0.5 * swizzle12[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat2x3 = function(c) {
+ var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
+ var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
+ c.color[0] = swizzle012[0] + 0.5 * swizzle123[0];
+ c.color[1] = swizzle012[1] + 0.5 * swizzle123[1];
+ c.color[2] = swizzle012[2] + 0.5 * swizzle123[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat2x4 = function(c) {
+ c.color = deMath.add(
+ deMath.swizzle(c.coords, [0,1,2,3]),
+ deMath.scale(deMath.swizzle(c.coords, [1,2,3,0]), 0.5));
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat3x2 = function(c) {
+ var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
+ var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
+ var swizzle23 = deMath.swizzle(c.coords, [2, 3]);
+ c.color[0] = swizzle01[0] + 0.5 * swizzle12[0] + 0.25 * swizzle23[0];
+ c.color[1] = swizzle01[1] + 0.5 * swizzle12[1] + 0.25 * swizzle23[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat3 = function(c) {
+ var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
+ var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
+ var swizzle230 = deMath.swizzle(c.coords, [2, 3, 0]);
+ c.color[0] = swizzle012[0] + 0.5 * swizzle123[0] + 0.25 * swizzle230[0];
+ c.color[1] = swizzle012[1] + 0.5 * swizzle123[1] + 0.25 * swizzle230[1];
+ c.color[2] = swizzle012[2] + 0.5 * swizzle123[2] + 0.25 * swizzle230[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat3x4 = function(c) {
+ var swizzle0123 = deMath.swizzle(c.coords, [0, 1, 2, 3]);
+ var swizzle1230 = deMath.swizzle(c.coords, [1, 2, 3, 0]);
+ var swizzle2301 = deMath.swizzle(c.coords, [2, 3, 0, 1]);
+ c.color = deMath.add(
+ swizzle0123,
+ deMath.add(
+ deMath.scale(swizzle1230, 0.5),
+ deMath.scale(swizzle2301, 0.25)));
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat4x2 = function(c) {
+ var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
+ var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
+ var swizzle23 = deMath.swizzle(c.coords, [2, 3]);
+ var swizzle30 = deMath.swizzle(c.coords, [3, 0]);
+ c.color[0] = swizzle01[0] + 0.5 * swizzle12[0] + 0.25 * swizzle23[0] + 0.125 * swizzle30[0];
+ c.color[1] = swizzle01[1] + 0.5 * swizzle12[1] + 0.25 * swizzle23[1] + 0.125 * swizzle30[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat4x3 = function(c) {
+ var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
+ var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
+ var swizzle230 = deMath.swizzle(c.coords, [2, 3, 0]);
+ var swizzle301 = deMath.swizzle(c.coords, [3, 0, 1]);
+ c.color[0] = swizzle012[0] + 0.5 * swizzle123[0] + 0.25 * swizzle230[0] + 0.125 * swizzle301[0];
+ c.color[1] = swizzle012[1] + 0.5 * swizzle123[1] + 0.25 * swizzle230[1] + 0.125 * swizzle301[1];
+ c.color[2] = swizzle012[2] + 0.5 * swizzle123[2] + 0.25 * swizzle230[2] + 0.125 * swizzle301[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat4 = function(c) {
+ var swizzle1230 = deMath.swizzle(c.coords, [1, 2, 3, 0]);
+ var swizzle2301 = deMath.swizzle(c.coords, [2, 3, 0, 1]);
+ var swizzle3012 = deMath.swizzle(c.coords, [3, 0, 1, 2]);
+ c.color = deMath.add(
+ c.coords,
+ deMath.add(
+ deMath.scale(swizzle1230, 0.5),
+ deMath.add(
+ deMath.scale(swizzle2301, 0.25),
+ deMath.scale(swizzle3012, 0.125))));
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getMatrixSubscriptEvalFunc = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT_MAT2: return es3fShaderIndexingTests.evalSubscriptMat2;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return es3fShaderIndexingTests.evalSubscriptMat2x3;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return es3fShaderIndexingTests.evalSubscriptMat2x4;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return es3fShaderIndexingTests.evalSubscriptMat3x2;
+ case gluShaderUtil.DataType.FLOAT_MAT3: return es3fShaderIndexingTests.evalSubscriptMat3;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return es3fShaderIndexingTests.evalSubscriptMat3x4;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return es3fShaderIndexingTests.evalSubscriptMat4x2;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return es3fShaderIndexingTests.evalSubscriptMat4x3;
+ case gluShaderUtil.DataType.FLOAT_MAT4: return es3fShaderIndexingTests.evalSubscriptMat4;
+ default:
+ throw new Error('Invalid data type.');
+ }
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} writeAccess
+ * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createMatrixSubscriptCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ /** @type {number} */ var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(varType);
+ /** @type {number} */ var numRows = gluShaderUtil.getDataTypeMatrixNumRows(varType);
+ /** @type {string} */ var matSizeName = glsShaderRenderCase.getIntUniformName(numCols);
+ /** @type {gluShaderUtil.DataType} */ var vecType = gluShaderUtil.getDataTypeFloatVec(numRows);
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += 'uniform mediump int ui_zero';
+ if (numCols >= 2) op += ', ui_one';
+ if (numCols >= 3) op += ', ui_two';
+ if (numCols >= 4) op += ', ui_three';
+ op += ';\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ op += 'uniform mediump int ' + matSizeName + ';\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ // Write matrix.
+ if (isVertexCase)
+ op += ' ${PRECISION} vec4 coords = a_coords;\n';
+ else
+ op += ' ${PRECISION} vec4 coords = v_coords;\n';
+
+ op += ' ${PRECISION} ${MAT_TYPE} tmp;\n';
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' tmp[0] = ${VEC_TYPE}(coords);\n';
+ if (numCols >= 2) op += ' tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n';
+ if (numCols >= 3) op += ' tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n';
+ if (numCols >= 4) op += ' tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' tmp[ui_zero] = ${VEC_TYPE}(coords);\n';
+ if (numCols >= 2) op += ' tmp[ui_one] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n';
+ if (numCols >= 3) op += ' tmp[ui_two] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n';
+ if (numCols >= 4) op += ' tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + numCols + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = ${VEC_TYPE}(coords);\n';
+ op += ' coords = coords.yzwx * 0.5;\n';
+ op += ' }\n';
+ }
+ else {
+ assertMsgOptions(writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'writeAccess not supported', false, true);
+ op += ' for (int i = 0; i < ' + matSizeName + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = ${VEC_TYPE}(coords);\n';
+ op += ' coords = coords.yzwx * 0.5;\n';
+ op += ' }\n';
+ }
+
+ // Read matrix.
+ op += ' ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n';
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' res += tmp[0];\n';
+ if (numCols >= 2) op += ' res += tmp[1];\n';
+ if (numCols >= 3) op += ' res += tmp[2];\n';
+ if (numCols >= 4) op += ' res += tmp[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' res += tmp[ui_zero];\n';
+ if (numCols >= 2) op += ' res += tmp[ui_one];\n';
+ if (numCols >= 3) op += ' res += tmp[ui_two];\n';
+ if (numCols >= 4) op += ' res += tmp[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + numCols + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported', false, true);
+ op += ' for (int i = 0; i < ' + matSizeName + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec4(res${PADDING});\n';
+ frag += ' o_color = v_color;\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res${PADDING});\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+
+ /** @type {Object} */ var params = {};
+ params['MAT_TYPE'] = gluShaderUtil.getDataTypeName(varType);
+ params['VEC_TYPE'] = gluShaderUtil.getDataTypeName(vecType);
+ params['PRECISION'] = "mediump";
+
+
+ if (numRows === 2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (numRows === 3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getMatrixSubscriptEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderIndexingTests.ShaderIndexingTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'indexing', 'Indexing Tests');
+ };
+
+ es3fShaderIndexingTests.ShaderIndexingTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderIndexingTests.ShaderIndexingTests.prototype.constructor = es3fShaderIndexingTests.ShaderIndexingTests;
+
+ es3fShaderIndexingTests.ShaderIndexingTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /** @type {Array<gluShaderProgram.shaderType>} */ var s_shaderTypes = [
+ gluShaderProgram.shaderType.VERTEX,
+ gluShaderProgram.shaderType.FRAGMENT
+ ];
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_floatAndVecTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4
+ ];
+ /** @type {string} */ var name;
+ /** @type {string} */ var desc;
+ /** @type {string} */ var shaderTypeName;
+ /** @type {boolean} */ var isVertexCase;
+ /** @type {gluShaderProgram.shaderType} */ var shaderType;
+ /** @type {string} */ var writeAccessName;
+ /** @type {string} */ var readAccessName;
+ // Varying array access cases.
+ /** @type {tcuTestCase.DeqpTest} */ var varyingGroup = tcuTestCase.newTest('varying_array', 'Varying array access tests.');
+ testGroup.addChild(varyingGroup);
+ /** @type {gluShaderUtil.DataType} */ var varType;
+ for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
+ varType = s_floatAndVecTypes[typeNdx];
+ for (var vertAccessStr in es3fShaderIndexingTests.IndexAccessType) {
+ for (var fragAccessStr in es3fShaderIndexingTests.IndexAccessType) {
+ var vertAccess = es3fShaderIndexingTests.IndexAccessType[vertAccessStr];
+ var fragAccess = es3fShaderIndexingTests.IndexAccessType[fragAccessStr];
+ /** @type {string} */ var vertAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(vertAccess);
+ /** @type {string} */ var fragAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(fragAccess);
+ name = gluShaderUtil.getDataTypeName(varType) + '_' + vertAccessName + '_write_' + fragAccessName + '_read';
+ desc = 'Varying array with ' + vertAccessName + ' write in vertex shader and ' + fragAccessName + ' read in fragment shader.';
+ varyingGroup.addChild(es3fShaderIndexingTests.createVaryingArrayCase(name, desc, varType, vertAccess, fragAccess));
+ }
+ }
+ }
+
+ // Uniform array access cases.
+ /** @type {tcuTestCase.DeqpTest} */ var uniformGroup = tcuTestCase.newTest("uniform_array", "Uniform array access tests.");
+ testGroup.addChild(uniformGroup);
+
+ for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
+ varType = s_floatAndVecTypes[typeNdx];
+ for (var readAccessStr in es3fShaderIndexingTests.IndexAccessType) {
+ var readAccess = es3fShaderIndexingTests.IndexAccessType[readAccessStr];
+ readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(readAccess);
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Uniform array with " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+ uniformGroup.addChild(es3fShaderIndexingTests.createUniformArrayCase(name, desc, isVertexCase, varType, readAccess));
+ }
+ }
+ }
+
+ // Temporary array access cases.
+ /** @type {tcuTestCase.DeqpTest} */ var tmpGroup = tcuTestCase.newTest("tmp_array", "Temporary array access tests.");
+ testGroup.addChild(tmpGroup);
+
+ for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
+ varType = s_floatAndVecTypes[typeNdx];
+ for (var writeAccess in es3fShaderIndexingTests.IndexAccessType) {
+ for (var readAccess in es3fShaderIndexingTests.IndexAccessType) {
+ writeAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[writeAccess]);
+ readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[readAccess]);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Temporary array with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = (shaderType === gluShaderProgram.shaderType.VERTEX);
+ tmpGroup.addChild(es3fShaderIndexingTests.createTmpArrayCase(name, desc, isVertexCase, varType, es3fShaderIndexingTests.IndexAccessType[writeAccess], es3fShaderIndexingTests.IndexAccessType[readAccess]));
+ }
+ }
+ }
+ }
+
+ // Vector indexing with subscripts.
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_vectorTypes = [
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4
+ ];
+
+ for (var typeNdx = 0; typeNdx < s_vectorTypes.length; typeNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var vecGroup = tcuTestCase.newTest("vector_subscript", "Vector subscript indexing.");
+ testGroup.addChild(vecGroup);
+
+ varType = s_vectorTypes[typeNdx];
+ for (var writeAccess in es3fShaderIndexingTests.VectorAccessType) {
+ for (var readAccess in es3fShaderIndexingTests.VectorAccessType) {
+ writeAccessName = es3fShaderIndexingTests.getVectorAccessTypeName(es3fShaderIndexingTests.VectorAccessType[writeAccess]);
+ readAccessName = es3fShaderIndexingTests.getVectorAccessTypeName(es3fShaderIndexingTests.VectorAccessType[readAccess]);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Vector subscript access with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+ vecGroup.addChild(es3fShaderIndexingTests.createVectorSubscriptCase(name, desc, isVertexCase, varType, es3fShaderIndexingTests.VectorAccessType[writeAccess], es3fShaderIndexingTests.VectorAccessType[readAccess]));
+ }
+ }
+ }
+ }
+
+ // Matrix indexing with subscripts.
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var matGroup = [
+ tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
+ tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
+ tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
+ ];
+ for (var ii = 0; ii < matGroup.length; ++ii) {
+ testGroup.addChild(matGroup[ii]);
+ }
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_matrixTypes = [
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4
+ ];
+
+ for (var typeNdx = 0; typeNdx < s_matrixTypes.length; typeNdx++) {
+ varType = s_matrixTypes[typeNdx];
+ for (var writeAccess in es3fShaderIndexingTests.IndexAccessType) {
+ for (var readAccess in es3fShaderIndexingTests.IndexAccessType) {
+ writeAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[writeAccess]);
+ readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[readAccess]);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Vector subscript access with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+ matGroup[typeNdx % matGroup.length].addChild(es3fShaderIndexingTests.createMatrixSubscriptCase(
+ name, desc, isVertexCase, varType, es3fShaderIndexingTests.IndexAccessType[writeAccess], es3fShaderIndexingTests.IndexAccessType[readAccess]));
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderIndexingTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderIndexingTests.ShaderIndexingTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderIndexingTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});