1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 goog.provide('functional.gles3.es3fShaderIndexingTests');
23 goog.require('framework.common.tcuImageCompare');
24 goog.require('framework.common.tcuStringTemplate');
25 goog.require('framework.common.tcuTestCase');
26 goog.require('framework.delibs.debase.deMath');
27 goog.require('framework.opengl.gluShaderUtil');
28 goog.require('framework.opengl.gluShaderProgram');
29 goog.require('framework.opengl.gluTexture');
30 goog.require('modules.shared.glsShaderRenderCase');
32 goog.scope(function() {
33 /** @type {?WebGL2RenderingContext} */ var gl;
34 var es3fShaderIndexingTests = functional.gles3.es3fShaderIndexingTests;
35 var deMath = framework.delibs.debase.deMath;
36 var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
37 var gluShaderUtil = framework.opengl.gluShaderUtil;
38 var gluTexture = framework.opengl.gluTexture;
39 var gluShaderProgram = framework.opengl.gluShaderProgram;
40 var tcuTestCase = framework.common.tcuTestCase;
41 var tcuStringTemplate = framework.common.tcuStringTemplate;
45 es3fShaderIndexingTests.IndexAccessType = {
53 * @param {es3fShaderIndexingTests.IndexAccessType} accessType
56 es3fShaderIndexingTests.getIndexAccessTypeName = function(accessType) {
57 /** @type {Array<string>} */ var s_names = [
63 return s_names[accessType];
69 es3fShaderIndexingTests.VectorAccessType = {
74 SUBSCRIPT_STATIC_LOOP: 4,
75 SUBSCRIPT_DYNAMIC_LOOP: 5
79 * @param {es3fShaderIndexingTests.VectorAccessType} accessType
82 es3fShaderIndexingTests.getVectorAccessTypeName = function(accessType) {
83 /** @type {Array<string>} */ var s_names = [
88 'static_loop_subscript',
89 'dynamic_loop_subscript'
91 assertMsgOptions(deMath.deInBounds32(accessType, 0, s_names.length), 'Index out of bounds', false, true);
92 return s_names[accessType];
95 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
96 es3fShaderIndexingTests.evalArrayCoordsFloat = function(c) {
97 c.color[0] = 1.875 * c.coords[0];
100 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
101 es3fShaderIndexingTests.evalArrayCoordsVec2 = function(c) {
102 var swizzled = deMath.swizzle(c.coords, [0, 1]);
103 c.color[0] = 1.875 * swizzled[0];
104 c.color[1] = 1.875 * swizzled[1];
107 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
108 es3fShaderIndexingTests.evalArrayCoordsVec3 = function(c) {
109 var swizzled = deMath.swizzle(c.coords, [0, 1, 2]);
110 c.color[0] = 1.875 * swizzled[0];
111 c.color[1] = 1.875 * swizzled[1];
112 c.color[2] = 1.875 * swizzled[2];
115 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
116 es3fShaderIndexingTests.evalArrayCoordsVec4 = function(c) {
117 c.color = deMath.scale(c.coords, 1.875);
121 * @param {gluShaderUtil.DataType} dataType
122 * @return {function(glsShaderRenderCase.ShaderEvalContext)}
124 es3fShaderIndexingTests.getArrayCoordsEvalFunc = function(dataType) {
125 if (dataType === gluShaderUtil.DataType.FLOAT) return es3fShaderIndexingTests.evalArrayCoordsFloat;
126 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalArrayCoordsVec2;
127 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalArrayCoordsVec3;
128 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalArrayCoordsVec4;
129 else throw new Error('Invalid data type.');
133 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
134 es3fShaderIndexingTests.evalArrayUniformFloat = function(c) {
135 c.color[0] = 1.875 * c.constCoords[0];
138 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
139 es3fShaderIndexingTests.evalArrayUniformVec2 = function(c) {
140 var swizzled = deMath.swizzle(c.constCoords, [0, 1]);
141 c.color[0] = 1.875 * swizzled[0];
142 c.color[1] = 1.875 * swizzled[1];
145 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
146 es3fShaderIndexingTests.evalArrayUniformVec3 = function(c) {
147 var swizzled = deMath.swizzle(c.constCoords, [0, 1, 2]);
148 c.color[0] = 1.875 * swizzled[0];
149 c.color[1] = 1.875 * swizzled[1];
150 c.color[2] = 1.875 * swizzled[2];
153 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
154 es3fShaderIndexingTests.evalArrayUniformVec4 = function(c) {
155 c.color = deMath.scale(c.constCoords, 1.875);
159 * @param {gluShaderUtil.DataType} dataType
160 * @return {function(glsShaderRenderCase.ShaderEvalContext)}
162 es3fShaderIndexingTests.getArrayUniformEvalFunc = function(dataType) {
163 if (dataType === gluShaderUtil.DataType.FLOAT) return es3fShaderIndexingTests.evalArrayUniformFloat;
164 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalArrayUniformVec2;
165 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalArrayUniformVec3;
166 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalArrayUniformVec4;
167 else throw new Error('Invalid data type.');
172 * @extends {glsShaderRenderCase.ShaderRenderCase}
173 * @param {string} name
174 * @param {string} description
175 * @param {boolean} isVertexCase
176 * @param {gluShaderUtil.DataType} varType
177 * @param {function(glsShaderRenderCase.ShaderEvalContext)} evalFunc
178 * @param {string} vertShaderSource
179 * @param {string} fragShaderSource
181 es3fShaderIndexingTests.ShaderIndexingCase = function(name, description, isVertexCase, varType, evalFunc, vertShaderSource, fragShaderSource) {
182 glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
183 /** @type {gluShaderUtil.DataType} */ this.m_varType = varType;
184 /** @type {string} */ this.m_vertShaderSource = vertShaderSource;
185 /** @type {string} */ this.m_fragShaderSource = fragShaderSource;
188 es3fShaderIndexingTests.ShaderIndexingCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
189 es3fShaderIndexingTests.ShaderIndexingCase.prototype.constructor = es3fShaderIndexingTests.ShaderIndexingCase;
192 * @param {?WebGLProgram} programID
193 * @param {Array<number>} constCoords
195 es3fShaderIndexingTests.ShaderIndexingCase.prototype.setupUniforms = function(programID, constCoords) {
196 /** @type {(Array<number>|Float32Array)} */ var arr = [];
197 /** @type {Array<number>} */ var array1d = [];
198 /** @type {?WebGLUniformLocation} */ var arrLoc = gl.getUniformLocation(programID, 'u_arr');
199 if (arrLoc != null) {
200 if (this.m_varType === gluShaderUtil.DataType.FLOAT) {
201 arr[0] = constCoords[0];
202 arr[1] = constCoords[0] * 0.5;
203 arr[2] = constCoords[0] * 0.25;
204 arr[3] = constCoords[0] * 0.125;
205 gl.uniform1fv(arrLoc, arr);
207 else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC2) {
208 arr[0] = deMath.swizzle(constCoords, [0, 1]);
209 arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.5);
210 arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.25);
211 arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.125);
212 for (var i = 0; i < arr.length; i++)
213 array1d = array1d.concat(arr[i]);
214 gl.uniform2fv(arrLoc, array1d);
216 else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC3) {
217 arr[0] = deMath.swizzle(constCoords, [0, 1, 2]);
218 arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.5);
219 arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.25);
220 arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.125);
221 for (var i = 0; i < arr.length; i++)
222 array1d = array1d.concat(arr[i]);
223 gl.uniform3fv(arrLoc, array1d);
225 else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC4) {
226 arr[0] = deMath.swizzle(constCoords, [0,1,2,3]);
227 arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.5);
228 arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.25);
229 arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.125);
230 for (var i = 0; i < arr.length; i++)
231 array1d = array1d.concat(arr[i]);
232 gl.uniform4fv(arrLoc, array1d);
235 throw new Error('u_arr should not have location assigned in this test case');
240 * @param {string} caseName
241 * @param {string} description
242 * @param {gluShaderUtil.DataType} varType
243 * @param {es3fShaderIndexingTests.IndexAccessType} vertAccess
244 * @param {es3fShaderIndexingTests.IndexAccessType} fragAccess
245 * @return {es3fShaderIndexingTests.ShaderIndexingCase}
247 es3fShaderIndexingTests.createVaryingArrayCase = function(caseName, description, varType, vertAccess, fragAccess) {
248 /** @type {string} */ var vtx = '';
249 vtx += '#version 300 es\n' +
250 'in highp vec4 a_position;\n' +
251 'in highp vec4 a_coords;\n';
253 if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
254 vtx += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
255 else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
256 vtx += 'uniform mediump int ui_four;\n';
258 vtx += 'out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n' +
262 ' gl_Position = a_position;\n';
264 if (vertAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
265 vtx += ' var[0] = ${VAR_TYPE}(a_coords);\n' +
266 ' var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n' +
267 ' var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n' +
268 ' var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n';
270 else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
271 vtx += ' var[ui_zero] = ${VAR_TYPE}(a_coords);\n' +
272 ' var[ui_one] = ${VAR_TYPE}(a_coords) * 0.5;\n' +
273 ' var[ui_two] = ${VAR_TYPE}(a_coords) * 0.25;\n' +
274 ' var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n';
276 else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
277 vtx += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n' +
278 ' for (int i = 0; i < 4; i++)\n' +
280 ' var[i] = ${VAR_TYPE}(coords);\n' +
281 ' coords = coords * 0.5;\n' +
285 assertMsgOptions(vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'Not Dynamic_Loop', false, true);
286 vtx += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n' +
287 ' for (int i = 0; i < ui_four; i++)\n' +
289 ' var[i] = ${VAR_TYPE}(coords);\n' +
290 ' coords = coords * 0.5;\n' +
295 /** @type {string} */ var frag = '';
296 frag += '#version 300 es\n' +
297 'precision mediump int;\n' +
298 'layout(location = 0) out mediump vec4 o_color;\n';
300 if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
301 frag += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
302 else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
303 frag += 'uniform int ui_four;\n';
305 frag += 'in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n' +
309 ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
311 if (fragAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
312 frag += ' res += var[0];\n' +
313 ' res += var[1];\n' +
314 ' res += var[2];\n' +
317 else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
318 frag += ' res += var[ui_zero];\n' +
319 ' res += var[ui_one];\n' +
320 ' res += var[ui_two];\n' +
321 ' res += var[ui_three];\n';
323 else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
324 frag += ' for (int i = 0; i < 4; i++)\n' +
328 assertMsgOptions(fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'Not Dynamic_Loop', false, true);
329 frag += ' for (int i = 0; i < ui_four; i++)\n' +
332 frag += ' o_color = vec4(res${PADDING});\n' +
335 // Fill in shader templates.
336 /** @type {Object} */ var params = {};
337 params['VAR_TYPE'] = gluShaderUtil.getDataTypeName(varType);
338 params['ARRAY_LEN'] = '4';
339 params['PRECISION'] = 'mediump';
341 if (varType === gluShaderUtil.DataType.FLOAT)
342 params['PADDING'] = ', 0.0, 0.0, 1.0';
343 else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
344 params['PADDING'] = ', 0.0, 1.0';
345 else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
346 params['PADDING'] = ', 1.0';
348 params['PADDING'] = '';
350 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
351 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
353 /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
354 var evalFunc = es3fShaderIndexingTests.getArrayCoordsEvalFunc(varType);
355 return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, true, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
359 * @param {string} caseName
360 * @param {string} description
361 * @param {boolean} isVertexCase
362 * @param {gluShaderUtil.DataType} varType
363 * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
364 * @return {es3fShaderIndexingTests.ShaderIndexingCase}
366 es3fShaderIndexingTests.createUniformArrayCase = function(caseName, description, isVertexCase, varType, readAccess) {
367 /** @type {string} */ var vtx = '';
368 /** @type {string} */ var frag = '';
369 /** @type {string} */ var op = '';
371 vtx += '#version 300 es\n';
372 frag += '#version 300 es\n';
374 vtx += 'in highp vec4 a_position;\n';
375 vtx += 'in highp vec4 a_coords;\n';
376 frag += 'layout(location = 0) out mediump vec4 o_color;\n';
379 vtx += 'out mediump vec4 v_color;\n';
380 frag += 'in mediump vec4 v_color;\n';
383 vtx += 'out mediump vec4 v_coords;\n';
384 frag += 'in mediump vec4 v_coords;\n';
387 if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
388 op += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
389 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
390 op += 'uniform mediump int ui_four;\n';
392 op += 'uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n';
394 vtx += isVertexCase ? op : '';
395 frag += isVertexCase ? '' : op;
399 vtx += 'void main()\n';
401 vtx += ' gl_Position = a_position;\n';
404 frag += 'void main()\n';
408 op += ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
409 if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
410 op += ' res += u_arr[0];\n';
411 op += ' res += u_arr[1];\n';
412 op += ' res += u_arr[2];\n';
413 op += ' res += u_arr[3];\n';
415 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
416 op += ' res += u_arr[ui_zero];\n';
417 op += ' res += u_arr[ui_one];\n';
418 op += ' res += u_arr[ui_two];\n';
419 op += ' res += u_arr[ui_three];\n';
421 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
422 op += ' for (int i = 0; i < 4; i++)\n';
423 op += ' res += u_arr[i];\n';
426 assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported.', false, true);
427 op += ' for (int i = 0; i < ui_four; i++)\n';
428 op += ' res += u_arr[i];\n';
431 vtx += isVertexCase ? op : '';
432 frag += isVertexCase ? '' : op;
436 vtx += ' v_color = vec4(res${PADDING});\n';
437 frag += ' o_color = v_color;\n';
440 vtx += ' v_coords = a_coords;\n';
441 frag += ' o_color = vec4(res${PADDING});\n';
447 // Fill in shader templates.
448 /** @type {Object} */ var params = {};
449 params['VAR_TYPE'] = gluShaderUtil.getDataTypeName(varType);
450 params['ARRAY_LEN'] = '4';
451 params['PRECISION'] = 'mediump';
453 if (varType === gluShaderUtil.DataType.FLOAT)
454 params['PADDING'] = ', 0.0, 0.0, 1.0';
455 else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
456 params['PADDING'] = ', 0.0, 1.0';
457 else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
458 params['PADDING'] = ', 1.0';
460 params['PADDING'] = '';
463 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
464 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
466 /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
467 var evalFunc = es3fShaderIndexingTests.getArrayUniformEvalFunc(varType);
468 return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
472 * @param {string} caseName
473 * @param {string} description
474 * @param {boolean} isVertexCase
475 * @param {gluShaderUtil.DataType} varType
476 * @param {es3fShaderIndexingTests.IndexAccessType} writeAccess
477 * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
478 * @return {es3fShaderIndexingTests.ShaderIndexingCase}
480 es3fShaderIndexingTests.createTmpArrayCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
481 /** @type {string} */ var vtx = '';
482 /** @type {string} */ var frag = '';
483 /** @type {string} */ var op = '';
485 vtx += '#version 300 es\n';
486 frag += '#version 300 es\n';
488 vtx += 'in highp vec4 a_position;\n' +
489 'in highp vec4 a_coords;\n';
490 frag += 'layout(location = 0) out mediump vec4 o_color;\n';
493 vtx += 'out mediump vec4 v_color;\n';
494 frag += 'in mediump vec4 v_color;\n';
497 vtx += 'out mediump vec4 v_coords;\n';
498 frag += 'in mediump vec4 v_coords;\n';
501 if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
502 op += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
504 if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
505 op += 'uniform mediump int ui_four;\n';
507 vtx += isVertexCase ? op : '';
508 frag += isVertexCase ? '' : op;
514 ' gl_Position = a_position;\n';
522 op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n';
524 op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n';
526 op += ' ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n';
527 if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
528 op += ' arr[0] = ${VAR_TYPE}(coords);\n' +
529 ' arr[1] = ${VAR_TYPE}(coords) * 0.5;\n' +
530 ' arr[2] = ${VAR_TYPE}(coords) * 0.25;\n' +
531 ' arr[3] = ${VAR_TYPE}(coords) * 0.125;\n';
533 else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
534 op += ' arr[ui_zero] = ${VAR_TYPE}(coords);\n' +
535 ' arr[ui_one] = ${VAR_TYPE}(coords) * 0.5;\n' +
536 ' arr[ui_two] = ${VAR_TYPE}(coords) * 0.25;\n' +
537 ' arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n';
539 else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
540 op += ' for (int i = 0; i < 4; i++)\n' +
542 ' arr[i] = ${VAR_TYPE}(coords);\n' +
543 ' coords = coords * 0.5;\n' +
547 assertMsgOptions(writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'writeAccess not supported', false, true);
548 op += ' for (int i = 0; i < ui_four; i++)\n' +
550 ' arr[i] = ${VAR_TYPE}(coords);\n' +
551 ' coords = coords * 0.5;\n' +
556 op += ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
557 if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
558 op += ' res += arr[0];\n' +
559 ' res += arr[1];\n' +
560 ' res += arr[2];\n' +
563 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
564 op += ' res += arr[ui_zero];\n' +
565 ' res += arr[ui_one];\n' +
566 ' res += arr[ui_two];\n' +
567 ' res += arr[ui_three];\n';
569 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
570 op += ' for (int i = 0; i < 4; i++)\n' +
574 assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported.', false, true);
575 op += ' for (int i = 0; i < ui_four; i++)\n' +
579 vtx += isVertexCase ? op : '';
580 frag += isVertexCase ? '' : op;
584 vtx += ' v_color = vec4(res${PADDING});\n';
585 frag += ' o_color = v_color;\n';
588 vtx += ' v_coords = a_coords;\n';
589 frag += ' o_color = vec4(res${PADDING});\n';
595 // Fill in shader templates.
596 /** @type {Object} */ var params = {};
597 params["VAR_TYPE"] = gluShaderUtil.getDataTypeName(varType);
598 params["ARRAY_LEN"] = "4";
599 params["PRECISION"] = "mediump";
601 if (varType === gluShaderUtil.DataType.FLOAT)
602 params['PADDING'] = ', 0.0, 0.0, 1.0';
603 else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
604 params['PADDING'] = ', 0.0, 1.0';
605 else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
606 params['PADDING'] = ', 1.0';
608 params['PADDING'] = '';
610 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
611 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
613 /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
614 var evalFunc = es3fShaderIndexingTests.getArrayCoordsEvalFunc(varType);
615 return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
620 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
621 es3fShaderIndexingTests.evalSubscriptVec2 = function(c) {
622 c.color[0] = c.coords[0] + 0.5 * c.coords[1];
623 c.color[1] = c.coords[0] + 0.5 * c.coords[1];
624 c.color[2] = c.coords[0] + 0.5 * c.coords[1];
626 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
627 es3fShaderIndexingTests.evalSubscriptVec3 = function(c) {
628 c.color[0] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
629 c.color[1] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
630 c.color[2] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
632 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
633 es3fShaderIndexingTests.evalSubscriptVec4 = function(c) {
634 c.color[0] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
635 c.color[1] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
636 c.color[2] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
640 * @param {gluShaderUtil.DataType} dataType
641 * @return {function(glsShaderRenderCase.ShaderEvalContext)}
643 es3fShaderIndexingTests.getVectorSubscriptEvalFunc = function(dataType) {
644 if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalSubscriptVec2;
645 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalSubscriptVec3;
646 else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalSubscriptVec4;
647 else throw new Error('Invalid data type.');
651 * @param {string} caseName
652 * @param {string} description
653 * @param {boolean} isVertexCase
654 * @param {gluShaderUtil.DataType} varType
655 * @param {es3fShaderIndexingTests.VectorAccessType} writeAccess
656 * @param {es3fShaderIndexingTests.VectorAccessType} readAccess
657 * @return {es3fShaderIndexingTests.ShaderIndexingCase}
659 es3fShaderIndexingTests.createVectorSubscriptCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
660 /** @type {string} */ var vtx = '';
661 /** @type {string} */ var frag = '';
662 /** @type {string} */ var op = '' ;
664 /** @type {number} */ var vecLen = gluShaderUtil.getDataTypeScalarSize(varType);
665 /** @type {string} */ var vecLenName = glsShaderRenderCase.getIntUniformName(vecLen);
667 vtx += '#version 300 es\n';
668 frag += '#version 300 es\n';
670 vtx += 'in highp vec4 a_position;\n' +
671 'in highp vec4 a_coords;\n';
672 frag += 'layout(location = 0) out mediump vec4 o_color;\n';
675 vtx += 'out mediump vec3 v_color;\n';
676 frag += 'in mediump vec3 v_color;\n';
679 vtx += 'out mediump vec4 v_coords;\n';
680 frag += 'in mediump vec4 v_coords;\n';
683 if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC ||
684 readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC){
685 op += 'uniform mediump int ui_zero';
686 if (vecLen >= 2) op += ', ui_one';
687 if (vecLen >= 3) op += ', ui_two';
688 if (vecLen >= 4) op += ', ui_three';
692 if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP ||
693 readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP)
694 op += 'uniform mediump int ' + vecLenName + ';\n';
696 vtx += isVertexCase ? op : '';
697 frag += isVertexCase ? '' : op;
703 ' gl_Position = a_position;\n';
711 op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n';
713 op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n';
715 op += ' ${PRECISION} ${VAR_TYPE} tmp;\n';
716 if (writeAccess === es3fShaderIndexingTests.VectorAccessType.DIRECT)
717 op += ' tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n';
718 else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.COMPONENT) {
719 op += ' tmp.x = coords.x;\n';
720 if (vecLen >= 2) op += ' tmp.y = coords.y * 0.5;\n';
721 if (vecLen >= 3) op += ' tmp.z = coords.z * 0.25;\n';
722 if (vecLen >= 4) op += ' tmp.w = coords.w * 0.125;\n';
724 else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC) {
725 op += ' tmp[0] = coords.x;\n';
726 if (vecLen >= 2) op += ' tmp[1] = coords.y * 0.5;\n';
727 if (vecLen >= 3) op += ' tmp[2] = coords.z * 0.25;\n';
728 if (vecLen >= 4) op += ' tmp[3] = coords.w * 0.125;\n';
730 else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC) {
731 op += ' tmp[ui_zero] = coords.x;\n';
732 if (vecLen >= 2) op += ' tmp[ui_one] = coords.y * 0.5;\n';
733 if (vecLen >= 3) op += ' tmp[ui_two] = coords.z * 0.25;\n';
734 if (vecLen >= 4) op += ' tmp[ui_three] = coords.w * 0.125;\n';
736 else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC_LOOP) {
737 op += ' for (int i = 0; i < ' + vecLen + '; i++)\n';
739 op += ' tmp[i] = coords.x;\n';
740 op += ' coords = coords.${ROT_SWIZZLE} * 0.5;\n';
744 assertMsgOptions(writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP, 'writeAccess not supported.', false, true);
745 op += ' for (int i = 0; i < ' + vecLenName + '; i++)\n';
747 op += ' tmp[i] = coords.x;\n';
748 op += ' coords = coords.${ROT_SWIZZLE} * 0.5;\n';
753 op += ' ${PRECISION} float res = 0.0;\n';
754 if (readAccess === es3fShaderIndexingTests.VectorAccessType.DIRECT)
755 op += ' res = dot(tmp, ${VAR_TYPE}(1.0));\n';
756 else if (readAccess === es3fShaderIndexingTests.VectorAccessType.COMPONENT) {
757 op += ' res += tmp.x;\n';
758 if (vecLen >= 2) op += ' res += tmp.y;\n';
759 if (vecLen >= 3) op += ' res += tmp.z;\n';
760 if (vecLen >= 4) op += ' res += tmp.w;\n';
762 else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC) {
763 op += ' res += tmp[0];\n';
764 if (vecLen >= 2) op += ' res += tmp[1];\n';
765 if (vecLen >= 3) op += ' res += tmp[2];\n';
766 if (vecLen >= 4) op += ' res += tmp[3];\n';
768 else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC) {
769 op += ' res += tmp[ui_zero];\n';
770 if (vecLen >= 2) op += ' res += tmp[ui_one];\n';
771 if (vecLen >= 3) op += ' res += tmp[ui_two];\n';
772 if (vecLen >= 4) op += ' res += tmp[ui_three];\n';
774 else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC_LOOP) {
775 op += ' for (int i = 0; i < ' + vecLen + '; i++)\n';
776 op += ' res += tmp[i];\n';
779 assertMsgOptions(readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP, 'readAccess not supported', false, true);
780 op += ' for (int i = 0; i < ' + vecLenName + '; i++)\n';
781 op += ' res += tmp[i];\n';
784 vtx += isVertexCase ? op : '';
785 frag += isVertexCase ? '' : op;
789 vtx += ' v_color = vec3(res);\n';
790 frag += ' o_color = vec4(v_color.rgb, 1.0);\n';
793 vtx += ' v_coords = a_coords;\n';
794 frag += ' o_color = vec4(vec3(res), 1.0);\n';
800 // Fill in shader templates.
801 /** @type {Array<string>} */ var s_swizzles = ['', 'x', 'xy', 'xyz', 'xyzw'];
802 /** @type {Array<string>} */ var s_rotSwizzles = ['', 'x', 'yx', 'yzx', 'yzwx'];
804 /** @type {Object} */ var params = {};
805 params["VAR_TYPE"] = gluShaderUtil.getDataTypeName(varType);
806 params["PRECISION"] = "mediump";
807 params["SWIZZLE"] = s_swizzles[vecLen];
808 params["ROT_SWIZZLE"] = s_rotSwizzles[vecLen];
810 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
811 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
813 /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
814 var evalFunc = es3fShaderIndexingTests.getVectorSubscriptEvalFunc(varType);
815 return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
820 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
821 es3fShaderIndexingTests.evalSubscriptMat2 = function(c) {
822 var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
823 var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
824 c.color[0] = swizzle01[0] + 0.5 * swizzle12[0];
825 c.color[1] = swizzle01[1] + 0.5 * swizzle12[1];
828 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
829 es3fShaderIndexingTests.evalSubscriptMat2x3 = function(c) {
830 var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
831 var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
832 c.color[0] = swizzle012[0] + 0.5 * swizzle123[0];
833 c.color[1] = swizzle012[1] + 0.5 * swizzle123[1];
834 c.color[2] = swizzle012[2] + 0.5 * swizzle123[2];
837 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
838 es3fShaderIndexingTests.evalSubscriptMat2x4 = function(c) {
839 c.color = deMath.add(
840 deMath.swizzle(c.coords, [0,1,2,3]),
841 deMath.scale(deMath.swizzle(c.coords, [1,2,3,0]), 0.5));
844 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
845 es3fShaderIndexingTests.evalSubscriptMat3x2 = function(c) {
846 var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
847 var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
848 var swizzle23 = deMath.swizzle(c.coords, [2, 3]);
849 c.color[0] = swizzle01[0] + 0.5 * swizzle12[0] + 0.25 * swizzle23[0];
850 c.color[1] = swizzle01[1] + 0.5 * swizzle12[1] + 0.25 * swizzle23[1];
853 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
854 es3fShaderIndexingTests.evalSubscriptMat3 = function(c) {
855 var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
856 var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
857 var swizzle230 = deMath.swizzle(c.coords, [2, 3, 0]);
858 c.color[0] = swizzle012[0] + 0.5 * swizzle123[0] + 0.25 * swizzle230[0];
859 c.color[1] = swizzle012[1] + 0.5 * swizzle123[1] + 0.25 * swizzle230[1];
860 c.color[2] = swizzle012[2] + 0.5 * swizzle123[2] + 0.25 * swizzle230[2];
863 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
864 es3fShaderIndexingTests.evalSubscriptMat3x4 = function(c) {
865 var swizzle0123 = deMath.swizzle(c.coords, [0, 1, 2, 3]);
866 var swizzle1230 = deMath.swizzle(c.coords, [1, 2, 3, 0]);
867 var swizzle2301 = deMath.swizzle(c.coords, [2, 3, 0, 1]);
868 c.color = deMath.add(
871 deMath.scale(swizzle1230, 0.5),
872 deMath.scale(swizzle2301, 0.25)));
875 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
876 es3fShaderIndexingTests.evalSubscriptMat4x2 = function(c) {
877 var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
878 var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
879 var swizzle23 = deMath.swizzle(c.coords, [2, 3]);
880 var swizzle30 = deMath.swizzle(c.coords, [3, 0]);
881 c.color[0] = swizzle01[0] + 0.5 * swizzle12[0] + 0.25 * swizzle23[0] + 0.125 * swizzle30[0];
882 c.color[1] = swizzle01[1] + 0.5 * swizzle12[1] + 0.25 * swizzle23[1] + 0.125 * swizzle30[1];
885 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
886 es3fShaderIndexingTests.evalSubscriptMat4x3 = function(c) {
887 var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
888 var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
889 var swizzle230 = deMath.swizzle(c.coords, [2, 3, 0]);
890 var swizzle301 = deMath.swizzle(c.coords, [3, 0, 1]);
891 c.color[0] = swizzle012[0] + 0.5 * swizzle123[0] + 0.25 * swizzle230[0] + 0.125 * swizzle301[0];
892 c.color[1] = swizzle012[1] + 0.5 * swizzle123[1] + 0.25 * swizzle230[1] + 0.125 * swizzle301[1];
893 c.color[2] = swizzle012[2] + 0.5 * swizzle123[2] + 0.25 * swizzle230[2] + 0.125 * swizzle301[2];
896 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
897 es3fShaderIndexingTests.evalSubscriptMat4 = function(c) {
898 var swizzle1230 = deMath.swizzle(c.coords, [1, 2, 3, 0]);
899 var swizzle2301 = deMath.swizzle(c.coords, [2, 3, 0, 1]);
900 var swizzle3012 = deMath.swizzle(c.coords, [3, 0, 1, 2]);
901 c.color = deMath.add(
904 deMath.scale(swizzle1230, 0.5),
906 deMath.scale(swizzle2301, 0.25),
907 deMath.scale(swizzle3012, 0.125))));
911 * @param {gluShaderUtil.DataType} dataType
912 * @return {function(glsShaderRenderCase.ShaderEvalContext)}
914 es3fShaderIndexingTests.getMatrixSubscriptEvalFunc = function(dataType) {
916 case gluShaderUtil.DataType.FLOAT_MAT2: return es3fShaderIndexingTests.evalSubscriptMat2;
917 case gluShaderUtil.DataType.FLOAT_MAT2X3: return es3fShaderIndexingTests.evalSubscriptMat2x3;
918 case gluShaderUtil.DataType.FLOAT_MAT2X4: return es3fShaderIndexingTests.evalSubscriptMat2x4;
919 case gluShaderUtil.DataType.FLOAT_MAT3X2: return es3fShaderIndexingTests.evalSubscriptMat3x2;
920 case gluShaderUtil.DataType.FLOAT_MAT3: return es3fShaderIndexingTests.evalSubscriptMat3;
921 case gluShaderUtil.DataType.FLOAT_MAT3X4: return es3fShaderIndexingTests.evalSubscriptMat3x4;
922 case gluShaderUtil.DataType.FLOAT_MAT4X2: return es3fShaderIndexingTests.evalSubscriptMat4x2;
923 case gluShaderUtil.DataType.FLOAT_MAT4X3: return es3fShaderIndexingTests.evalSubscriptMat4x3;
924 case gluShaderUtil.DataType.FLOAT_MAT4: return es3fShaderIndexingTests.evalSubscriptMat4;
926 throw new Error('Invalid data type.');
931 * @param {string} caseName
932 * @param {string} description
933 * @param {boolean} isVertexCase
934 * @param {gluShaderUtil.DataType} varType
935 * @param {es3fShaderIndexingTests.IndexAccessType} writeAccess
936 * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
937 * @return {es3fShaderIndexingTests.ShaderIndexingCase}
939 es3fShaderIndexingTests.createMatrixSubscriptCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
940 /** @type {string} */ var vtx = '';
941 /** @type {string} */ var frag = '';
942 /** @type {string} */ var op = '';
944 /** @type {number} */ var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(varType);
945 /** @type {number} */ var numRows = gluShaderUtil.getDataTypeMatrixNumRows(varType);
946 /** @type {string} */ var matSizeName = glsShaderRenderCase.getIntUniformName(numCols);
947 /** @type {gluShaderUtil.DataType} */ var vecType = gluShaderUtil.getDataTypeFloatVec(numRows);
949 vtx += '#version 300 es\n';
950 frag += '#version 300 es\n';
952 vtx += 'in highp vec4 a_position;\n' +
953 'in highp vec4 a_coords;\n';
954 frag += 'layout(location = 0) out mediump vec4 o_color;\n';
957 vtx += 'out mediump vec4 v_color;\n';
958 frag += 'in mediump vec4 v_color;\n';
961 vtx += 'out mediump vec4 v_coords;\n';
962 frag += 'in mediump vec4 v_coords;\n';
965 if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
966 op += 'uniform mediump int ui_zero';
967 if (numCols >= 2) op += ', ui_one';
968 if (numCols >= 3) op += ', ui_two';
969 if (numCols >= 4) op += ', ui_three';
973 if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
974 op += 'uniform mediump int ' + matSizeName + ';\n';
976 vtx += isVertexCase ? op : '';
977 frag += isVertexCase ? '' : op;
983 ' gl_Position = a_position;\n';
991 op += ' ${PRECISION} vec4 coords = a_coords;\n';
993 op += ' ${PRECISION} vec4 coords = v_coords;\n';
995 op += ' ${PRECISION} ${MAT_TYPE} tmp;\n';
996 if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
997 op += ' tmp[0] = ${VEC_TYPE}(coords);\n';
998 if (numCols >= 2) op += ' tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n';
999 if (numCols >= 3) op += ' tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n';
1000 if (numCols >= 4) op += ' tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n';
1002 else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
1003 op += ' tmp[ui_zero] = ${VEC_TYPE}(coords);\n';
1004 if (numCols >= 2) op += ' tmp[ui_one] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n';
1005 if (numCols >= 3) op += ' tmp[ui_two] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n';
1006 if (numCols >= 4) op += ' tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n';
1008 else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
1009 op += ' for (int i = 0; i < ' + numCols + '; i++)\n';
1011 op += ' tmp[i] = ${VEC_TYPE}(coords);\n';
1012 op += ' coords = coords.yzwx * 0.5;\n';
1016 assertMsgOptions(writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'writeAccess not supported', false, true);
1017 op += ' for (int i = 0; i < ' + matSizeName + '; i++)\n';
1019 op += ' tmp[i] = ${VEC_TYPE}(coords);\n';
1020 op += ' coords = coords.yzwx * 0.5;\n';
1025 op += ' ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n';
1026 if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
1027 op += ' res += tmp[0];\n';
1028 if (numCols >= 2) op += ' res += tmp[1];\n';
1029 if (numCols >= 3) op += ' res += tmp[2];\n';
1030 if (numCols >= 4) op += ' res += tmp[3];\n';
1032 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
1033 op += ' res += tmp[ui_zero];\n';
1034 if (numCols >= 2) op += ' res += tmp[ui_one];\n';
1035 if (numCols >= 3) op += ' res += tmp[ui_two];\n';
1036 if (numCols >= 4) op += ' res += tmp[ui_three];\n';
1038 else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
1039 op += ' for (int i = 0; i < ' + numCols + '; i++)\n';
1040 op += ' res += tmp[i];\n';
1043 assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported', false, true);
1044 op += ' for (int i = 0; i < ' + matSizeName + '; i++)\n';
1045 op += ' res += tmp[i];\n';
1048 vtx += isVertexCase ? op : '';
1049 frag += isVertexCase ? '' : op;
1053 vtx += ' v_color = vec4(res${PADDING});\n';
1054 frag += ' o_color = v_color;\n';
1057 vtx += ' v_coords = a_coords;\n';
1058 frag += ' o_color = vec4(res${PADDING});\n';
1064 // Fill in shader templates.
1066 /** @type {Object} */ var params = {};
1067 params['MAT_TYPE'] = gluShaderUtil.getDataTypeName(varType);
1068 params['VEC_TYPE'] = gluShaderUtil.getDataTypeName(vecType);
1069 params['PRECISION'] = "mediump";
1073 params['PADDING'] = ', 0.0, 1.0';
1074 else if (numRows === 3)
1075 params['PADDING'] = ', 1.0';
1077 params['PADDING'] = '';
1079 /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
1080 /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
1082 /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
1083 var evalFunc = es3fShaderIndexingTests.getMatrixSubscriptEvalFunc(varType);
1084 return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
1089 * @extends {tcuTestCase.DeqpTest}
1091 es3fShaderIndexingTests.ShaderIndexingTests = function() {
1092 tcuTestCase.DeqpTest.call(this, 'indexing', 'Indexing Tests');
1095 es3fShaderIndexingTests.ShaderIndexingTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
1096 es3fShaderIndexingTests.ShaderIndexingTests.prototype.constructor = es3fShaderIndexingTests.ShaderIndexingTests;
1098 es3fShaderIndexingTests.ShaderIndexingTests.prototype.init = function() {
1099 var testGroup = tcuTestCase.runner.testCases;
1100 /** @type {Array<gluShaderProgram.shaderType>} */ var s_shaderTypes = [
1101 gluShaderProgram.shaderType.VERTEX,
1102 gluShaderProgram.shaderType.FRAGMENT
1104 /** @type {Array<gluShaderUtil.DataType>} */ var s_floatAndVecTypes = [
1105 gluShaderUtil.DataType.FLOAT,
1106 gluShaderUtil.DataType.FLOAT_VEC2,
1107 gluShaderUtil.DataType.FLOAT_VEC3,
1108 gluShaderUtil.DataType.FLOAT_VEC4
1110 /** @type {string} */ var name;
1111 /** @type {string} */ var desc;
1112 /** @type {string} */ var shaderTypeName;
1113 /** @type {boolean} */ var isVertexCase;
1114 /** @type {gluShaderProgram.shaderType} */ var shaderType;
1115 /** @type {string} */ var writeAccessName;
1116 /** @type {string} */ var readAccessName;
1117 // Varying array access cases.
1118 /** @type {tcuTestCase.DeqpTest} */ var varyingGroup = tcuTestCase.newTest('varying_array', 'Varying array access tests.');
1119 testGroup.addChild(varyingGroup);
1120 /** @type {gluShaderUtil.DataType} */ var varType;
1121 for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
1122 varType = s_floatAndVecTypes[typeNdx];
1123 for (var vertAccessStr in es3fShaderIndexingTests.IndexAccessType) {
1124 for (var fragAccessStr in es3fShaderIndexingTests.IndexAccessType) {
1125 var vertAccess = es3fShaderIndexingTests.IndexAccessType[vertAccessStr];
1126 var fragAccess = es3fShaderIndexingTests.IndexAccessType[fragAccessStr];
1127 /** @type {string} */ var vertAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(vertAccess);
1128 /** @type {string} */ var fragAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(fragAccess);
1129 name = gluShaderUtil.getDataTypeName(varType) + '_' + vertAccessName + '_write_' + fragAccessName + '_read';
1130 desc = 'Varying array with ' + vertAccessName + ' write in vertex shader and ' + fragAccessName + ' read in fragment shader.';
1131 varyingGroup.addChild(es3fShaderIndexingTests.createVaryingArrayCase(name, desc, varType, vertAccess, fragAccess));
1136 // Uniform array access cases.
1137 /** @type {tcuTestCase.DeqpTest} */ var uniformGroup = tcuTestCase.newTest("uniform_array", "Uniform array access tests.");
1138 testGroup.addChild(uniformGroup);
1140 for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
1141 varType = s_floatAndVecTypes[typeNdx];
1142 for (var readAccessStr in es3fShaderIndexingTests.IndexAccessType) {
1143 var readAccess = es3fShaderIndexingTests.IndexAccessType[readAccessStr];
1144 readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(readAccess);
1145 for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
1146 shaderType = s_shaderTypes[shaderTypeNdx];
1147 shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
1148 name = gluShaderUtil.getDataTypeName(varType) + "_" + readAccessName + "_read_" + shaderTypeName;
1149 desc = "Uniform array with " + readAccessName + " read in " + shaderTypeName + " shader.";
1150 isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
1151 uniformGroup.addChild(es3fShaderIndexingTests.createUniformArrayCase(name, desc, isVertexCase, varType, readAccess));
1156 // Temporary array access cases.
1157 /** @type {tcuTestCase.DeqpTest} */ var tmpGroup = tcuTestCase.newTest("tmp_array", "Temporary array access tests.");
1158 testGroup.addChild(tmpGroup);
1160 for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
1161 varType = s_floatAndVecTypes[typeNdx];
1162 for (var writeAccess in es3fShaderIndexingTests.IndexAccessType) {
1163 for (var readAccess in es3fShaderIndexingTests.IndexAccessType) {
1164 writeAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[writeAccess]);
1165 readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[readAccess]);
1167 for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
1168 shaderType = s_shaderTypes[shaderTypeNdx];
1169 shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
1170 name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
1171 desc = "Temporary array with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
1172 isVertexCase = (shaderType === gluShaderProgram.shaderType.VERTEX);
1173 tmpGroup.addChild(es3fShaderIndexingTests.createTmpArrayCase(name, desc, isVertexCase, varType, es3fShaderIndexingTests.IndexAccessType[writeAccess], es3fShaderIndexingTests.IndexAccessType[readAccess]));
1179 // Vector indexing with subscripts.
1181 /** @type {Array<gluShaderUtil.DataType>} */ var s_vectorTypes = [
1182 gluShaderUtil.DataType.FLOAT_VEC2,
1183 gluShaderUtil.DataType.FLOAT_VEC3,
1184 gluShaderUtil.DataType.FLOAT_VEC4
1187 for (var typeNdx = 0; typeNdx < s_vectorTypes.length; typeNdx++) {
1188 /** @type {tcuTestCase.DeqpTest} */ var vecGroup = tcuTestCase.newTest("vector_subscript", "Vector subscript indexing.");
1189 testGroup.addChild(vecGroup);
1191 varType = s_vectorTypes[typeNdx];
1192 for (var writeAccess in es3fShaderIndexingTests.VectorAccessType) {
1193 for (var readAccess in es3fShaderIndexingTests.VectorAccessType) {
1194 writeAccessName = es3fShaderIndexingTests.getVectorAccessTypeName(es3fShaderIndexingTests.VectorAccessType[writeAccess]);
1195 readAccessName = es3fShaderIndexingTests.getVectorAccessTypeName(es3fShaderIndexingTests.VectorAccessType[readAccess]);
1197 for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
1198 shaderType = s_shaderTypes[shaderTypeNdx];
1199 shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
1200 name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
1201 desc = "Vector subscript access with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
1202 isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
1203 vecGroup.addChild(es3fShaderIndexingTests.createVectorSubscriptCase(name, desc, isVertexCase, varType, es3fShaderIndexingTests.VectorAccessType[writeAccess], es3fShaderIndexingTests.VectorAccessType[readAccess]));
1209 // Matrix indexing with subscripts.
1210 /** @type {Array<tcuTestCase.DeqpTest>} */ var matGroup = [
1211 tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
1212 tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
1213 tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
1215 for (var ii = 0; ii < matGroup.length; ++ii) {
1216 testGroup.addChild(matGroup[ii]);
1219 /** @type {Array<gluShaderUtil.DataType>} */ var s_matrixTypes = [
1220 gluShaderUtil.DataType.FLOAT_MAT2,
1221 gluShaderUtil.DataType.FLOAT_MAT2X3,
1222 gluShaderUtil.DataType.FLOAT_MAT2X4,
1223 gluShaderUtil.DataType.FLOAT_MAT3X2,
1224 gluShaderUtil.DataType.FLOAT_MAT3,
1225 gluShaderUtil.DataType.FLOAT_MAT3X4,
1226 gluShaderUtil.DataType.FLOAT_MAT4X2,
1227 gluShaderUtil.DataType.FLOAT_MAT4X3,
1228 gluShaderUtil.DataType.FLOAT_MAT4
1231 for (var typeNdx = 0; typeNdx < s_matrixTypes.length; typeNdx++) {
1232 varType = s_matrixTypes[typeNdx];
1233 for (var writeAccess in es3fShaderIndexingTests.IndexAccessType) {
1234 for (var readAccess in es3fShaderIndexingTests.IndexAccessType) {
1235 writeAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[writeAccess]);
1236 readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[readAccess]);
1238 for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
1239 shaderType = s_shaderTypes[shaderTypeNdx];
1240 shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
1241 name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
1242 desc = "Vector subscript access with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
1243 isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
1244 matGroup[typeNdx % matGroup.length].addChild(es3fShaderIndexingTests.createMatrixSubscriptCase(
1245 name, desc, isVertexCase, varType, es3fShaderIndexingTests.IndexAccessType[writeAccess], es3fShaderIndexingTests.IndexAccessType[readAccess]));
1254 * @param {WebGL2RenderingContext} context
1256 es3fShaderIndexingTests.run = function(context, range) {
1258 //Set up Test Root parameters
1259 var state = tcuTestCase.runner;
1260 state.setRoot(new es3fShaderIndexingTests.ShaderIndexingTests());
1262 //Set up name and description of this test series.
1263 setCurrentTestName(state.testCases.fullName());
1264 description(state.testCases.getDescription());
1268 state.setRange(range);
1270 tcuTestCase.runTestCases();
1273 testFailedOptions('Failed to es3fShaderIndexingTests.run tests', false);
1274 tcuTestCase.runner.terminate();