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.es3fUniformApiTests');
23 goog.require('framework.common.tcuSurface');
24 goog.require('framework.common.tcuTestCase');
25 goog.require('framework.common.tcuTexture');
26 goog.require('framework.delibs.debase.deMath');
27 goog.require('framework.delibs.debase.deRandom');
28 goog.require('framework.delibs.debase.deString');
29 goog.require('framework.opengl.gluDrawUtil');
30 goog.require('framework.opengl.gluShaderProgram');
31 goog.require('framework.opengl.gluShaderUtil');
32 goog.require('framework.opengl.gluTexture');
33 goog.require('framework.opengl.gluVarType');
35 goog.scope(function() {
37 var es3fUniformApiTests = functional.gles3.es3fUniformApiTests;
38 var gluDrawUtil = framework.opengl.gluDrawUtil;
39 var gluShaderUtil = framework.opengl.gluShaderUtil;
40 var gluShaderProgram = framework.opengl.gluShaderProgram;
41 var gluTexture = framework.opengl.gluTexture;
42 var gluVarType = framework.opengl.gluVarType;
43 var tcuTestCase = framework.common.tcuTestCase;
44 var tcuSurface = framework.common.tcuSurface;
45 var tcuTexture = framework.common.tcuTexture;
46 var deMath = framework.delibs.debase.deMath;
47 var deString = framework.delibs.debase.deString;
48 var deRandom = framework.delibs.debase.deRandom;
50 /** @type {WebGL2RenderingContext} */ var gl;
52 /** @typedef {function(gluShaderUtil.DataType): boolean} */
53 es3fUniformApiTests.dataTypePredicate;
55 /** @type {number} */ es3fUniformApiTests.MAX_RENDER_WIDTH = 32;
56 /** @type {number} */ es3fUniformApiTests.MAX_RENDER_HEIGHT = 32;
57 /** @type {number} */ es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS = 16;
59 /** @type {Array<gluShaderUtil.DataType>} */ es3fUniformApiTests.s_testDataTypes = [
60 gluShaderUtil.DataType.FLOAT,
61 gluShaderUtil.DataType.FLOAT_VEC2,
62 gluShaderUtil.DataType.FLOAT_VEC3,
63 gluShaderUtil.DataType.FLOAT_VEC4,
64 gluShaderUtil.DataType.FLOAT_MAT2,
65 gluShaderUtil.DataType.FLOAT_MAT2X3,
66 gluShaderUtil.DataType.FLOAT_MAT2X4,
67 gluShaderUtil.DataType.FLOAT_MAT3X2,
68 gluShaderUtil.DataType.FLOAT_MAT3,
69 gluShaderUtil.DataType.FLOAT_MAT3X4,
70 gluShaderUtil.DataType.FLOAT_MAT4X2,
71 gluShaderUtil.DataType.FLOAT_MAT4X3,
72 gluShaderUtil.DataType.FLOAT_MAT4,
74 gluShaderUtil.DataType.INT,
75 gluShaderUtil.DataType.INT_VEC2,
76 gluShaderUtil.DataType.INT_VEC3,
77 gluShaderUtil.DataType.INT_VEC4,
79 gluShaderUtil.DataType.UINT,
80 gluShaderUtil.DataType.UINT_VEC2,
81 gluShaderUtil.DataType.UINT_VEC3,
82 gluShaderUtil.DataType.UINT_VEC4,
84 gluShaderUtil.DataType.BOOL,
85 gluShaderUtil.DataType.BOOL_VEC2,
86 gluShaderUtil.DataType.BOOL_VEC3,
87 gluShaderUtil.DataType.BOOL_VEC4,
89 gluShaderUtil.DataType.SAMPLER_2D,
90 gluShaderUtil.DataType.SAMPLER_CUBE
91 // \note We don't test all sampler types here.
95 * Returns a substring from the beginning to the last occurence of the
97 * @param {string} str The string in which to search
98 * @param {string} c A single character
101 es3fUniformApiTests.beforeLast = function(str, c) {
102 return str.substring(0, str.lastIndexOf(c));
106 * es3fUniformApiTests.fillWithColor
107 * @param {tcuTexture.PixelBufferAccess} access ,
108 * @param {Array<number>} color Array of four color components.
110 es3fUniformApiTests.fillWithColor = function(access, color) {
111 for (var z = 0; z < access.getDepth(); z++)
112 for (var y = 0; y < access.getHeight(); y++)
113 for (var x = 0; x < access.getWidth(); x++)
114 access.setPixel(color, x, y, z);
118 * @param {gluShaderUtil.DataType} type
121 es3fUniformApiTests.getSamplerNumLookupDimensions = function(type) {
123 case gluShaderUtil.DataType.SAMPLER_2D:
124 case gluShaderUtil.DataType.INT_SAMPLER_2D:
125 case gluShaderUtil.DataType.UINT_SAMPLER_2D:
128 case gluShaderUtil.DataType.SAMPLER_3D:
129 case gluShaderUtil.DataType.INT_SAMPLER_3D:
130 case gluShaderUtil.DataType.UINT_SAMPLER_3D:
131 case gluShaderUtil.DataType.SAMPLER_2D_SHADOW:
132 case gluShaderUtil.DataType.SAMPLER_2D_ARRAY:
133 case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY:
134 case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY:
135 case gluShaderUtil.DataType.SAMPLER_CUBE:
136 case gluShaderUtil.DataType.INT_SAMPLER_CUBE:
137 case gluShaderUtil.DataType.UINT_SAMPLER_CUBE:
140 case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW:
141 case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW:
145 throw new Error('es3fUniformApiTests.getSamplerNumLookupDimensions - Invalid type');
150 * @param {gluShaderUtil.DataType} type
151 * @return {gluShaderUtil.DataType}
153 es3fUniformApiTests.getSamplerLookupReturnType = function(type) {
155 case gluShaderUtil.DataType.SAMPLER_2D:
156 case gluShaderUtil.DataType.SAMPLER_CUBE:
157 case gluShaderUtil.DataType.SAMPLER_2D_ARRAY:
158 case gluShaderUtil.DataType.SAMPLER_3D:
159 return gluShaderUtil.DataType.FLOAT_VEC4;
161 case gluShaderUtil.DataType.UINT_SAMPLER_2D:
162 case gluShaderUtil.DataType.UINT_SAMPLER_CUBE:
163 case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY:
164 case gluShaderUtil.DataType.UINT_SAMPLER_3D:
165 return gluShaderUtil.DataType.UINT_VEC4;
167 case gluShaderUtil.DataType.INT_SAMPLER_2D:
168 case gluShaderUtil.DataType.INT_SAMPLER_CUBE:
169 case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY:
170 case gluShaderUtil.DataType.INT_SAMPLER_3D:
171 return gluShaderUtil.DataType.INT_VEC4;
173 case gluShaderUtil.DataType.SAMPLER_2D_SHADOW:
174 case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW:
175 case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW:
176 return gluShaderUtil.DataType.FLOAT;
179 throw new Error('es3fUniformApiTests.getSamplerLookupReturnType - Invalid type');
184 * @param {gluShaderUtil.DataType} T DataType to compare the type. Used to be a template param
185 * @param {gluShaderUtil.DataType} t
188 es3fUniformApiTests.dataTypeEquals = function(T, t) {
193 * @param {number} N Row number. Used to be a template parameter
194 * @param {gluShaderUtil.DataType} t
197 es3fUniformApiTests.dataTypeIsMatrixWithNRows = function(N, t) {
198 return gluShaderUtil.isDataTypeMatrix(t) && gluShaderUtil.getDataTypeMatrixNumRows(t) == N;
202 * @param {gluVarType.VarType} type
203 * @param {es3fUniformApiTests.dataTypePredicate} predicate
206 es3fUniformApiTests.typeContainsMatchingBasicType = function(type, predicate) {
207 if (type.isBasicType())
208 return predicate(type.getBasicType());
209 else if (type.isArrayType())
210 return es3fUniformApiTests.typeContainsMatchingBasicType(type.getElementType(), predicate);
212 assertMsgOptions(type.isStructType(), 'es3fUniformApiTests.typeContainsMatchingBasicType - not a struct type', false, true);
213 /** @type {gluVarType.StructType} */ var structType = type.getStruct();
214 for (var i = 0; i < structType.getSize(); i++)
215 if (es3fUniformApiTests.typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
222 * @param {Array<gluShaderUtil.DataType>} dst
223 * @param {gluVarType.VarType} type
225 es3fUniformApiTests.getDistinctSamplerTypes = function(dst, type) {
226 if (type.isBasicType()) {
227 /** @type {gluShaderUtil.DataType} */ var basicType = type.getBasicType();
228 if (gluShaderUtil.isDataTypeSampler(basicType) && dst.indexOf(basicType) == -1)
230 } else if (type.isArrayType())
231 es3fUniformApiTests.getDistinctSamplerTypes(dst, type.getElementType());
233 assertMsgOptions(type.isStructType(), 'es3fUniformApiTests.getDistinctSamplerTypes - not a struct type', false, true);
234 /** @type {gluVarType.StructType} */ var structType = type.getStruct();
235 for (var i = 0; i < structType.getSize(); i++)
236 es3fUniformApiTests.getDistinctSamplerTypes(dst, structType.getMember(i).getType());
241 * @param {gluVarType.VarType} type
244 es3fUniformApiTests.getNumSamplersInType = function(type) {
245 if (type.isBasicType())
246 return gluShaderUtil.isDataTypeSampler(type.getBasicType()) ? 1 : 0;
247 else if (type.isArrayType())
248 return es3fUniformApiTests.getNumSamplersInType(type.getElementType()) * type.getArraySize();
250 assertMsgOptions(type.isStructType(), 'es3fUniformApiTests.getNumSamplersInType - not a struct type', false, true);
251 /** @type {gluVarType.StructType} */ var structType = type.getStruct();
252 /** @type {number} */ var sum = 0;
253 for (var i = 0; i < structType.getSize(); i++)
254 sum += es3fUniformApiTests.getNumSamplersInType(structType.getMember(i).getType());
259 /** @typedef { {type: gluVarType.VarType, ndx: number}} */
260 es3fUniformApiTests.VarTypeWithIndex;
263 * @param {number} maxDepth
264 * @param {number} curStructIdx Out parameter, instead returning it in the VarTypeWithIndex structure.
265 * @param {Array<gluVarType.StructType>} structTypesDst
266 * @param {deRandom.Random} rnd
267 * @return {es3fUniformApiTests.VarTypeWithIndex}
269 es3fUniformApiTests.generateRandomType = function(maxDepth, curStructIdx, structTypesDst, rnd) {
270 /** @type {boolean} */ var isStruct = maxDepth > 0 && rnd.getFloat() < 0.2;
271 /** @type {boolean} */ var isArray = rnd.getFloat() < 0.3;
274 /** @type {number} */ var numMembers = rnd.getInt(1, 5);
275 /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + curStructIdx++);
277 for (var i = 0; i < numMembers; i++) {
278 /** @type {es3fUniformApiTests.VarTypeWithIndex} */ var typeWithIndex = es3fUniformApiTests.generateRandomType(maxDepth - 1, curStructIdx, structTypesDst, rnd);
279 curStructIdx = typeWithIndex.ndx;
280 structType.addMember('m' + i, typeWithIndex.type);
283 structTypesDst.push(structType);
285 type: gluVarType.newTypeArray(gluVarType.newTypeStruct(structType), rnd.getInt(1, 5)),
289 type: gluVarType.newTypeStruct(structType),
293 /** @type {gluShaderUtil.DataType} */ var basicType = es3fUniformApiTests.s_testDataTypes[rnd.getInt(0, es3fUniformApiTests.s_testDataTypes.length - 1)];
294 /** @type {gluShaderUtil.precision} */ var precision;
295 if (!gluShaderUtil.isDataTypeBoolOrBVec(basicType))
296 precision = gluShaderUtil.precision.PRECISION_MEDIUMP;
298 type: gluVarType.newTypeArray(gluVarType.newTypeBasic(basicType, precision), rnd.getInt(1, 5)),
302 type: gluVarType.newTypeBasic(basicType, precision),
309 * es3fUniformApiTests.SamplerV structure
312 es3fUniformApiTests.SamplerV = function() {
314 /** @type {number} */ unit: 0,
315 /** @type {Array<number>} */ fillColor: []
320 * es3fUniformApiTests.VarValue class. may contain different types.
323 es3fUniformApiTests.VarValue = function() {
324 /** @type {gluShaderUtil.DataType} */ this.type;
325 /** @type {Array<number | boolean> | es3fUniformApiTests.SamplerV} */ this.val = [];
331 es3fUniformApiTests.CaseShaderType = {
338 * es3fUniformApiTests.Uniform struct.
339 * @param {string} name_
340 * @param {gluVarType.VarType} type_
343 es3fUniformApiTests.Uniform = function(name_, type_) {
344 /** @type {string} */ this.name = name_;
345 /** @type {gluVarType.VarType} */ this.type = type_;
348 // A set of uniforms, along with related struct types.
350 * class es3fUniformApiTests.UniformCollection
353 es3fUniformApiTests.UniformCollection = function() {
354 /** @type {Array<es3fUniformApiTests.Uniform>} */ this.m_uniforms = [];
355 /** @type {Array<gluVarType.StructType>} */ this.m_structTypes = [];
361 es3fUniformApiTests.UniformCollection.prototype.getNumUniforms = function() {return this.m_uniforms.length;};
366 es3fUniformApiTests.UniformCollection.prototype.getNumStructTypes = function() {return this.m_structTypes.length;};
369 * @param {number} ndx
370 * @return {es3fUniformApiTests.Uniform}
372 es3fUniformApiTests.UniformCollection.prototype.getUniform = function(ndx) {return this.m_uniforms[ndx];};
375 * @param {number} ndx
376 * @return {gluVarType.StructType}
378 es3fUniformApiTests.UniformCollection.prototype.getStructType = function(ndx) {return this.m_structTypes[ndx];};
381 * @param {es3fUniformApiTests.Uniform} uniform
383 es3fUniformApiTests.UniformCollection.prototype.addUniform = function(uniform) {this.m_uniforms.push(uniform);};
386 * @param {gluVarType.StructType} type
388 es3fUniformApiTests.UniformCollection.prototype.addStructType = function(type) {this.m_structTypes.push(type);};
390 // Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
391 // \note receiver takes ownership of the struct types.
393 * @param {es3fUniformApiTests.UniformCollection} receiver
395 es3fUniformApiTests.UniformCollection.prototype.moveContents = function(receiver) {
396 for (var i = 0; i < this.m_uniforms.length; i++)
397 receiver.addUniform(this.m_uniforms[i]);
398 this.m_uniforms.length = 0;
400 for (var i = 0; i < this.m_structTypes.length; i++)
401 receiver.addStructType(this.m_structTypes[i]);
402 this.m_structTypes.length = 0;
406 * @param {es3fUniformApiTests.dataTypePredicate} predicate
409 es3fUniformApiTests.UniformCollection.prototype.containsMatchingBasicType = function(predicate) {
410 for (var i = 0; i < this.m_uniforms.length; i++)
411 if (es3fUniformApiTests.typeContainsMatchingBasicType(this.m_uniforms[i].type, predicate))
417 * @return {Array<gluShaderUtil.DataType>}
419 es3fUniformApiTests.UniformCollection.prototype.getSamplerTypes = function() {
420 /** @type {Array<gluShaderUtil.DataType>} */ var samplerTypes = [];
421 for (var i = 0; i < this.m_uniforms.length; i++)
422 es3fUniformApiTests.getDistinctSamplerTypes(samplerTypes, this.m_uniforms[i].type);
429 es3fUniformApiTests.UniformCollection.prototype.containsSeveralSamplerTypes = function() {
430 return this.getSamplerTypes().length > 1;
436 es3fUniformApiTests.UniformCollection.prototype.getNumSamplers = function() {
438 for (var i = 0; i < this.m_uniforms.length; i++)
439 sum += es3fUniformApiTests.getNumSamplersInType(this.m_uniforms[i].type);
444 * @param {gluShaderUtil.DataType} type
445 * @param {string=} nameSuffix
446 * @return {es3fUniformApiTests.UniformCollection}
448 es3fUniformApiTests.UniformCollection.basic = function(type, nameSuffix) {
449 if (nameSuffix === undefined) nameSuffix = '';
450 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
451 /** @type {gluShaderUtil.precision} */ var prec;
452 if (!gluShaderUtil.isDataTypeBoolOrBVec(type))
453 prec = gluShaderUtil.precision.PRECISION_MEDIUMP;
454 res.m_uniforms.push(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeBasic(type, prec)));
459 * @param {gluShaderUtil.DataType} type
460 * @param {string=} nameSuffix
461 * @return {es3fUniformApiTests.UniformCollection}
463 es3fUniformApiTests.UniformCollection.basicArray = function(type, nameSuffix) {
464 if (nameSuffix === undefined) nameSuffix = '';
465 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
466 /** @type {gluShaderUtil.precision} */ var prec;
467 if (!gluShaderUtil.isDataTypeBoolOrBVec(type))
468 prec = gluShaderUtil.precision.PRECISION_MEDIUMP;
469 res.m_uniforms.push(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeArray(gluVarType.newTypeBasic(type, prec), 3)));
474 * @param {gluShaderUtil.DataType} type0
475 * @param {gluShaderUtil.DataType} type1
476 * @param {boolean} containsArrays
477 * @param {string=} nameSuffix
478 * @return {es3fUniformApiTests.UniformCollection}
480 es3fUniformApiTests.UniformCollection.basicStruct = function(type0, type1, containsArrays, nameSuffix) {
481 if (nameSuffix === undefined) nameSuffix = '';
482 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
483 /** @type {gluShaderUtil.precision} */ var prec0;
484 if (!gluShaderUtil.isDataTypeBoolOrBVec(type0))
485 prec0 = gluShaderUtil.precision.PRECISION_MEDIUMP;
486 /** @type {gluShaderUtil.precision} */ var prec1;
487 if (!gluShaderUtil.isDataTypeBoolOrBVec(type1))
488 prec1 = gluShaderUtil.precision.PRECISION_MEDIUMP;
490 /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + nameSuffix);
491 structType.addMember('m0', gluVarType.newTypeBasic(type0, prec0));
492 structType.addMember('m1', gluVarType.newTypeBasic(type1, prec1));
493 if (containsArrays) {
494 structType.addMember('m2', gluVarType.newTypeArray(gluVarType.newTypeBasic(type0, prec0), 3));
495 structType.addMember('m3', gluVarType.newTypeArray(gluVarType.newTypeBasic(type1, prec1), 3));
498 res.addStructType(structType);
499 res.addUniform(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeStruct(structType)));
505 * @param {gluShaderUtil.DataType} type0
506 * @param {gluShaderUtil.DataType} type1
507 * @param {boolean} containsArrays
508 * @param {string=} nameSuffix
509 * @return {es3fUniformApiTests.UniformCollection}
511 es3fUniformApiTests.UniformCollection.structInArray = function(type0, type1, containsArrays, nameSuffix) {
512 if (nameSuffix === undefined) nameSuffix = '';
513 /** @type {es3fUniformApiTests.UniformCollection} */ var res = es3fUniformApiTests.UniformCollection.basicStruct(type0, type1, containsArrays, nameSuffix);
514 res.getUniform(0).type = gluVarType.newTypeArray(res.getUniform(0).type, 3);
519 * @param {gluShaderUtil.DataType} type0
520 * @param {gluShaderUtil.DataType} type1
521 * @param {string=} nameSuffix
522 * @return {es3fUniformApiTests.UniformCollection}
524 es3fUniformApiTests.UniformCollection.nestedArraysStructs = function(type0, type1, nameSuffix) {
525 if (nameSuffix === undefined) nameSuffix = '';
526 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
527 /** @type {gluShaderUtil.precision} */ var prec0;
528 if (!gluShaderUtil.isDataTypeBoolOrBVec(type0))
529 prec0 = gluShaderUtil.precision.PRECISION_MEDIUMP;
530 /** @type {gluShaderUtil.precision} */ var prec1;
531 if (!gluShaderUtil.isDataTypeBoolOrBVec(type1))
532 prec1 = gluShaderUtil.precision.PRECISION_MEDIUMP;
533 /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + nameSuffix);
534 /** @type {gluVarType.StructType} */ var subStructType = gluVarType.newStructType('subStructType' + nameSuffix);
535 /** @type {gluVarType.StructType} */ var subSubStructType = gluVarType.newStructType('subSubStructType' + nameSuffix);
537 subSubStructType.addMember('mss0', gluVarType.newTypeBasic(type0, prec0));
538 subSubStructType.addMember('mss1', gluVarType.newTypeBasic(type1, prec1));
540 subStructType.addMember('ms0', gluVarType.newTypeBasic(type1, prec1));
541 subStructType.addMember('ms1', gluVarType.newTypeArray(gluVarType.newTypeBasic(type0, prec0), 2));
542 subStructType.addMember('ms2', gluVarType.newTypeArray(gluVarType.newTypeStruct(subSubStructType), 2));
544 structType.addMember('m0', gluVarType.newTypeBasic(type0, prec0));
545 structType.addMember('m1', gluVarType.newTypeStruct(subStructType));
546 structType.addMember('m2', gluVarType.newTypeBasic(type1, prec1));
548 res.addStructType(subSubStructType);
549 res.addStructType(subStructType);
550 res.addStructType(structType);
552 res.addUniform(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeStruct(structType)));
558 * @param {string=} nameSuffix
559 * @return {es3fUniformApiTests.UniformCollection}
561 es3fUniformApiTests.UniformCollection.multipleBasic = function(nameSuffix) {
562 if (nameSuffix === undefined) nameSuffix = '';
563 /** @type {Array<gluShaderUtil.DataType>} */ var types = [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.INT_VEC3, gluShaderUtil.DataType.UINT_VEC4, gluShaderUtil.DataType.FLOAT_MAT3, gluShaderUtil.DataType.BOOL_VEC2];
564 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
566 for (var i = 0; i < types.length; i++) {
567 /** @type {es3fUniformApiTests.UniformCollection} */ var sub = es3fUniformApiTests.UniformCollection.basic(types[i], '_' + i + nameSuffix);
568 sub.moveContents(res);
575 * @param {string=} nameSuffix
576 * @return {es3fUniformApiTests.UniformCollection}
578 es3fUniformApiTests.UniformCollection.multipleBasicArray = function(nameSuffix) {
579 if (nameSuffix === undefined) nameSuffix = '';
580 /** @type {Array<gluShaderUtil.DataType>} */ var types = [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.INT_VEC3, gluShaderUtil.DataType.BOOL_VEC2];
581 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
583 for (var i = 0; i < types.length; i++) {
584 /** @type {es3fUniformApiTests.UniformCollection} */ var sub = es3fUniformApiTests.UniformCollection.basicArray(types[i], '_' + i + nameSuffix);
585 sub.moveContents(res);
592 * @param {string=} nameSuffix
593 * @return {es3fUniformApiTests.UniformCollection}
595 es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs = function(nameSuffix) {
596 if (nameSuffix === undefined) nameSuffix = '';
597 /** @type {Array<gluShaderUtil.DataType>} */ var types0 = [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.INT, gluShaderUtil.DataType.BOOL_VEC4];
598 /** @type {Array<gluShaderUtil.DataType>} */ var types1 = [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.INT_VEC4, gluShaderUtil.DataType.BOOL];
599 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
601 assertMsgOptions(types0.length == types1.length, 'es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs - lengths are not the same', false, true);
603 for (var i = 0; i < types0.length; i++) {
604 /** @type {es3fUniformApiTests.UniformCollection} */ var sub = es3fUniformApiTests.UniformCollection.nestedArraysStructs(types0[i], types1[i], '_' + i + nameSuffix);
605 sub.moveContents(res);
612 * @param {number} seed
613 * @return {es3fUniformApiTests.UniformCollection}
615 es3fUniformApiTests.UniformCollection.random = function(seed) {
616 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(seed);
617 /** @type {number} */ var numUniforms = rnd.getInt(1, 5);
618 /** @type {number} */ var structIdx = 0;
619 /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
621 for (var i = 0; i < numUniforms; i++) {
622 /** @type {Array<gluVarType.StructType>} */ var structTypes = [];
623 /** @type {es3fUniformApiTests.Uniform} */ var uniform = new es3fUniformApiTests.Uniform('u_var' + i, new gluVarType.VarType());
625 // \note Discard uniforms that would cause number of samplers to exceed es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS.
627 var temp = es3fUniformApiTests.generateRandomType(3, structIdx, structTypes, rnd);
628 structIdx = temp.ndx;
629 uniform.type = temp.type;
630 } while (res.getNumSamplers() + es3fUniformApiTests.getNumSamplersInType(uniform.type) > es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS);
632 res.addUniform(uniform);
633 for (var j = 0; j < structTypes.length; j++)
634 res.addStructType(structTypes[j]);
641 * @param {es3fUniformApiTests.VarValue} sampler
642 * @return {es3fUniformApiTests.VarValue}
644 es3fUniformApiTests.getSamplerFillValue = function(sampler) {
645 assertMsgOptions(gluShaderUtil.isDataTypeSampler(sampler.type), 'es3fUniformApiTests.getSamplerFillValue - not a sampler type', false, true);
647 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
648 result.type = es3fUniformApiTests.getSamplerLookupReturnType(sampler.type);
650 switch (result.type) {
651 case gluShaderUtil.DataType.FLOAT_VEC4:
652 for (var i = 0; i < 4; i++)
653 result.val[i] = sampler.val.samplerV.fillColor[i];
655 case gluShaderUtil.DataType.UINT_VEC4:
656 for (var i = 0; i < 4; i++)
657 result.val[i] = sampler.val.samplerV.fillColor[i];
659 case gluShaderUtil.DataType.INT_VEC4:
660 for (var i = 0; i < 4; i++)
661 result.val[i] = sampler.val.samplerV.fillColor[i];
663 case gluShaderUtil.DataType.FLOAT:
664 result.val[0] = sampler.val.samplerV.fillColor[0];
667 throw new Error('es3fUniformApiTests.getSamplerFillValue - Invalid type');
674 * @param {es3fUniformApiTests.VarValue} sampler
675 * @return {es3fUniformApiTests.VarValue}
677 es3fUniformApiTests.getSamplerUnitValue = function(sampler) {
678 assertMsgOptions(gluShaderUtil.isDataTypeSampler(sampler.type), 'es3fUniformApiTests.getSamplerUnitValue - not a sampler type', false, true);
680 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
681 result.type = gluShaderUtil.DataType.INT;
682 result.val[0] = sampler.val.samplerV.unit;
688 * @param {gluShaderUtil.DataType} original
689 * @return {gluShaderUtil.DataType}
691 es3fUniformApiTests.getDataTypeTransposedMatrix = function(original) {
692 return gluShaderUtil.getDataTypeMatrix(gluShaderUtil.getDataTypeMatrixNumRows(original), gluShaderUtil.getDataTypeMatrixNumColumns(original));
696 * @param {es3fUniformApiTests.VarValue} original
697 * @return {es3fUniformApiTests.VarValue}
699 es3fUniformApiTests.getTransposeMatrix = function(original) {
700 assertMsgOptions(gluShaderUtil.isDataTypeMatrix(original.type), 'es3fUniformApiTests.getTransposeMatrix - not a matrix', false, true);
702 /** @type {number} */ var rows = gluShaderUtil.getDataTypeMatrixNumRows(original.type);
703 /** @type {number} */ var cols = gluShaderUtil.getDataTypeMatrixNumColumns(original.type);
704 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
705 result.type = es3fUniformApiTests.getDataTypeTransposedMatrix(original.type);
707 for (var i = 0; i < rows; i++)
708 for (var j = 0; j < cols; j++)
709 result.val[i * cols + j] = original.val[j * rows + i];
715 * @param {es3fUniformApiTests.VarValue} value
718 es3fUniformApiTests.shaderVarValueStr = function(value) {
719 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(value.type);
720 /** @type {string} */ var result = '';
723 result += gluShaderUtil.getDataTypeName(value.type) + '(';
725 for (var i = 0; i < numElems; i++) {
729 if (gluShaderUtil.isDataTypeFloatOrVec(value.type) || gluShaderUtil.isDataTypeMatrix(value.type))
730 result += value.val[i].toFixed(2);
731 else if (gluShaderUtil.isDataTypeIntOrIVec((value.type)))
732 result += value.val[i];
733 else if (gluShaderUtil.isDataTypeUintOrUVec((value.type)))
734 result += value.val[i] + 'u';
735 else if (gluShaderUtil.isDataTypeBoolOrBVec((value.type)))
736 result += value.val[i] ? 'true' : 'false';
737 else if (gluShaderUtil.isDataTypeSampler((value.type)))
738 result += es3fUniformApiTests.shaderVarValueStr(es3fUniformApiTests.getSamplerFillValue(value));
740 throw new Error('es3fUniformApiTests.shaderVarValueStr - invalid type');
750 * @param {es3fUniformApiTests.VarValue} value
753 es3fUniformApiTests.apiVarValueStr = function(value) {
754 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(value.type);
755 /** @type {string} */ var result = '';
760 for (var i = 0; i < numElems; i++) {
764 if (gluShaderUtil.isDataTypeFloatOrVec(value.type) || gluShaderUtil.isDataTypeMatrix(value.type))
765 result += value.val[i].toFixed(2);
766 else if (gluShaderUtil.isDataTypeIntOrIVec(value.type) ||
767 gluShaderUtil.isDataTypeUintOrUVec(value.type))
768 result += value.val[i];
769 else if (gluShaderUtil.isDataTypeBoolOrBVec(value.type))
770 result += value.val[i] ? 'true' : 'false';
771 else if (gluShaderUtil.isDataTypeSampler(value.type))
772 result += value.val.samplerV.unit;
774 throw new Error('es3fUniformApiTests.apiVarValueStr - Invalid type');
783 // samplerUnit used if type is a sampler type. \note Samplers' unit numbers are not randomized.
785 * @param {gluShaderUtil.DataType} type
786 * @param {deRandom.Random} rnd
787 * @param {number=} samplerUnit
788 * @return {es3fUniformApiTests.VarValue}
790 es3fUniformApiTests.generateRandomVarValue = function(type, rnd, samplerUnit) {
791 if (samplerUnit === undefined) samplerUnit = -1;
792 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(type);
793 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
797 (samplerUnit >= 0) == (gluShaderUtil.isDataTypeSampler(type)),
798 'es3fUniformApiTests.generateRandomVarValue - sampler units do not match type', false, true
801 if (gluShaderUtil.isDataTypeFloatOrVec(type) || gluShaderUtil.isDataTypeMatrix(type)) {
802 for (var i = 0; i < numElems; i++)
803 result.val[i] = rnd.getFloat(-10.0, 10.0);
804 } else if (gluShaderUtil.isDataTypeIntOrIVec(type)) {
805 for (var i = 0; i < numElems; i++)
806 result.val[i] = rnd.getInt(-10, 10);
807 } else if (gluShaderUtil.isDataTypeUintOrUVec(type)) {
808 for (var i = 0; i < numElems; i++)
809 result.val[i] = rnd.getInt(0, 10);
810 } else if (gluShaderUtil.isDataTypeBoolOrBVec(type)) {
811 for (var i = 0; i < numElems; i++)
812 result.val[i] = rnd.getBool();
813 } else if (gluShaderUtil.isDataTypeSampler(type)) {
814 /** @type {gluShaderUtil.DataType} */ var texResultType = es3fUniformApiTests.getSamplerLookupReturnType(type);
815 /** @type {gluShaderUtil.DataType} */ var texResultScalarType = gluShaderUtil.getDataTypeScalarTypeAsDataType(texResultType);
816 /** @type {number} */ var texResultNumDims = gluShaderUtil.getDataTypeScalarSize(texResultType);
818 result.val = new es3fUniformApiTests.SamplerV();
819 result.val.samplerV.unit = samplerUnit;
821 for (var i = 0; i < texResultNumDims; i++) {
822 switch (texResultScalarType) {
823 case gluShaderUtil.DataType.FLOAT: result.val.samplerV.fillColor[i] = rnd.getFloat(0.0, 1.0); break;
824 case gluShaderUtil.DataType.INT: result.val.samplerV.fillColor[i] = rnd.getInt(-10, 10); break;
825 case gluShaderUtil.DataType.UINT: result.val.samplerV.fillColor[i] = rnd.getInt(0, 10); break;
827 throw new Error('es3fUniformApiTests.generateRandomVarValue - Invalid scalar type');
831 throw new Error('es3fUniformApiTests.generateRandomVarValue - Invalid type');
837 * @param {gluShaderUtil.DataType} type
838 * @return {es3fUniformApiTests.VarValue}
840 es3fUniformApiTests.generateZeroVarValue = function(type) {
841 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(type);
842 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
845 if (gluShaderUtil.isDataTypeFloatOrVec(type) || gluShaderUtil.isDataTypeMatrix(type)) {
846 for (var i = 0; i < numElems; i++)
848 } else if (gluShaderUtil.isDataTypeIntOrIVec(type)) {
849 for (var i = 0; i < numElems; i++)
851 } else if (gluShaderUtil.isDataTypeUintOrUVec(type)) {
852 for (var i = 0; i < numElems; i++)
854 } else if (gluShaderUtil.isDataTypeBoolOrBVec(type)) {
855 for (var i = 0; i < numElems; i++)
856 result.val[i] = false;
857 } else if (gluShaderUtil.isDataTypeSampler(type)) {
858 /** @type {gluShaderUtil.DataType} */ var texResultType = es3fUniformApiTests.getSamplerLookupReturnType(type);
859 /** @type {gluShaderUtil.DataType} */ var texResultScalarType = gluShaderUtil.getDataTypeScalarTypeAsDataType(texResultType);
860 /** @type {number} */ var texResultNumDims = gluShaderUtil.getDataTypeScalarSize(texResultType);
862 result.val = new es3fUniformApiTests.SamplerV();
863 result.val.samplerV.unit = 0;
865 for (var i = 0; i < texResultNumDims; i++) {
866 switch (texResultScalarType) {
867 case gluShaderUtil.DataType.FLOAT: result.val.samplerV.fillColor[i] = 0.12 * i; break;
868 case gluShaderUtil.DataType.INT: result.val.samplerV.fillColor[i] = -2 + i; break;
869 case gluShaderUtil.DataType.UINT: result.val.samplerV.fillColor[i] = 4 + i; break;
871 throw new Error('es3fUniformApiTests.generateZeroVarValue - Invalid scalar type');
875 throw new Error('es3fUniformApiTests.generateZeroVarValue - Invalid type');
881 * @param {es3fUniformApiTests.VarValue} a
882 * @param {es3fUniformApiTests.VarValue} b
885 es3fUniformApiTests.apiVarValueEquals = function(a, b) {
886 /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(a.type);
887 /** @type {number} */ var floatThreshold = 0.05;
889 assertMsgOptions(a.type == b.type, 'es3fUniformApiTests.apiVarValueEquals - types are different', false, true);
891 if (gluShaderUtil.isDataTypeFloatOrVec(a.type) || gluShaderUtil.isDataTypeMatrix(a.type)) {
892 for (var i = 0; i < size; i++)
893 if (Math.abs(a.val[i] - b.val[i]) >= floatThreshold)
895 } else if (gluShaderUtil.isDataTypeIntOrIVec(a.type)) {
896 for (var i = 0; i < size; i++)
897 if (a.val[i] != b.val[i])
899 } else if (gluShaderUtil.isDataTypeUintOrUVec(a.type)) {
900 for (var i = 0; i < size; i++)
901 if (a.val[i] != b.val[i])
903 } else if (gluShaderUtil.isDataTypeBoolOrBVec(a.type)) {
904 for (var i = 0; i < size; i++)
905 if (a.val[i] != b.val[i])
907 } else if (gluShaderUtil.isDataTypeSampler(a.type)) {
908 if (a.val.samplerV.unit != b.val.samplerV.unit)
911 throw new Error('es3fUniformApiTests.apiVarValueEquals - Invalid type');
917 * @param {es3fUniformApiTests.VarValue} boolValue
918 * @param {gluShaderUtil.DataType} targetScalarType
919 * @param {deRandom.Random} rnd
920 * @return {es3fUniformApiTests.VarValue}
922 es3fUniformApiTests.getRandomBoolRepresentation = function(boolValue, targetScalarType, rnd) {
924 gluShaderUtil.isDataTypeBoolOrBVec(boolValue.type),
925 'es3fUniformApiTests.getRandomBoolRepresentation - Data type not boolean or boolean vector',
930 /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(boolValue.type);
931 /** @type {gluShaderUtil.DataType} */ var targetType = size == 1 ? targetScalarType : gluShaderUtil.getDataTypeVector(targetScalarType, size);
932 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
933 result.type = targetType;
935 switch (targetScalarType) {
936 case gluShaderUtil.DataType.INT:
937 for (var i = 0; i < size; i++) {
938 if (boolValue.val[i]) {
939 result.val[i] = rnd.getInt(-10, 10);
940 if (result.val[i] == 0)
947 case gluShaderUtil.DataType.UINT:
948 for (var i = 0; i < size; i++) {
949 if (boolValue.val[i])
950 result.val[i] = rnd.getInt(1, 10);
956 case gluShaderUtil.DataType.FLOAT:
957 for (var i = 0; i < size; i++) {
958 if (boolValue.val[i]) {
959 result.val[i] = rnd.getFloat(-10.0, 10.0);
960 if (result.val[i] == 0.0)
968 throw new Error('es3fUniformApiTests.getRandomBoolRepresentation - Invalid type');
975 * @param {es3fUniformApiTests.CaseShaderType} type
978 es3fUniformApiTests.getCaseShaderTypeName = function(type) {
980 case es3fUniformApiTests.CaseShaderType.VERTEX: return 'vertex';
981 case es3fUniformApiTests.CaseShaderType.FRAGMENT: return 'fragment';
982 case es3fUniformApiTests.CaseShaderType.BOTH: return 'both';
984 throw new Error('es3fUniformApiTests.getCaseShaderTypeName - Invalid shader type');
989 * @param {number} seed
992 es3fUniformApiTests.randomCaseShaderType = function(seed) {
993 return (new deRandom.Random(seed)).getInt(0, Object.keys(es3fUniformApiTests.CaseShaderType).length - 1);
996 //es3fUniformApiTests.UniformCase definitions
999 * es3fUniformApiTests.Feature - Implemented as a function to create an object without unwanted properties.
1002 es3fUniformApiTests.Feature = function() {
1003 // ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
1004 this.ARRAYUSAGE_ONLY_MIDDLE_INDEX = false;
1006 // UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glUniform1f(), where possible. If not given, use pass-by-pointer versions.
1007 this.UNIFORMFUNC_VALUE = false;
1009 // MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major.
1010 this.MATRIXMODE_ROWMAJOR = false;
1012 // ARRAYASSIGN: how basic-type arrays are assigned with glUniform*(). If none given, assign each element of an array separately.
1013 this.ARRAYASSIGN_FULL = false; //!< Assign all elements of an array with one glUniform*().
1014 this.ARRAYASSIGN_BLOCKS_OF_TWO = false; //!< Assign two elements per one glUniform*().
1016 // UNIFORMUSAGE_EVERY_OTHER: use about half of the uniforms. If not given, use all uniforms (except that some array indices may be omitted according to ARRAYUSAGE).
1017 this.UNIFORMUSAGE_EVERY_OTHER = false;
1019 // BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
1020 this.BOOLEANAPITYPE_INT = false;
1021 this.BOOLEANAPITYPE_UINT = false;
1023 // UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values.
1024 this.UNIFORMVALUE_ZERO = false;
1026 // ARRAY_FIRST_ELEM_NAME_NO_INDEX: in certain API functions, when referring to the first element of an array, use just the array name without [0] at the end.
1027 this.ARRAY_FIRST_ELEM_NAME_NO_INDEX = false;
1030 // A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
1033 * @param {string} name_
1034 * @param {gluShaderUtil.DataType} type_
1035 * @param {boolean} isUsedInShader_
1036 * @param {es3fUniformApiTests.VarValue} finalValue_
1037 * @param {string=} rootName_
1038 * @param {number=} elemNdx_
1039 * @param {number=} rootSize_
1041 es3fUniformApiTests.BasicUniform = function(name_, type_, isUsedInShader_, finalValue_, rootName_, elemNdx_, rootSize_) {
1042 /** @type {string} */ this.name = name_;
1043 /** @type {gluShaderUtil.DataType} */ this.type = type_;
1044 /** @type {boolean} */ this.isUsedInShader = isUsedInShader_;
1045 /** @type {es3fUniformApiTests.VarValue} */ this.finalValue = finalValue_; //!< The value we ultimately want to set for this uniform.
1047 /** @type {string} */ this.rootName = rootName_ === undefined ? name_ : rootName_; //!< If this is a member of a basic-typed array, rootName is the name of that array with "[0]" appended. Otherwise it equals name.
1048 /** @type {number} */ this.elemNdx = elemNdx_ === undefined ? -1 : elemNdx_; //!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
1049 /** @type {number} */ this.rootSize = rootSize_ === undefined ? 1 : rootSize_; //!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
1053 * @param {Array<es3fUniformApiTests.BasicUniform>} vec
1054 * @param {string} name
1055 * @return {es3fUniformApiTests.BasicUniform}
1057 es3fUniformApiTests.BasicUniform.findWithName = function(vec, name) {
1058 for (var i = 0; i < vec.length; i++) {
1059 if (vec[i].name == name)
1065 // Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniforms().
1068 * @param {string} name_
1069 * @param {gluShaderUtil.DataType} type_
1070 * @param {boolean} used
1072 es3fUniformApiTests.BasicUniformReportRef = function(name_, type_, used) {
1073 /** @type {string} */ this.name = name_;
1074 // \note minSize and maxSize are for arrays and can be distinct since implementations are allowed, but not required, to trim the inactive end indices of arrays.
1075 /** @type {number} */ this.minSize = 1;
1076 /** @type {number} */ this.maxSize = 1;
1077 /** @type {gluShaderUtil.DataType} */ this.type = type_;
1078 /** @type {boolean} */ this.isUsedInShader = used;
1082 * To be used after constructor
1083 * @param {number} minS
1084 * @param {number} maxS
1085 * @return {es3fUniformApiTests.BasicUniformReportRef}
1087 es3fUniformApiTests.BasicUniformReportRef.prototype.constructor_A = function(minS, maxS) {
1088 this.minSize = minS;
1089 this.maxSize = maxS;
1092 this.minSize <= this.maxSize,
1093 'es3fUniformApiTests.BasicUniformReportRef.prototype.constructor_A - min size not smaller or equal than max size',
1101 // Info that is actually reported by glGetActiveUniform() or glGetActiveUniforms().
1104 * @param {string} name_
1105 * @param {number} nameLength_
1106 * @param {number} size_
1107 * @param {gluShaderUtil.DataType} type_
1108 * @param {number} index_
1110 es3fUniformApiTests.BasicUniformReportGL = function(name_, nameLength_, size_, type_, index_) {
1112 this.nameLength = nameLength_;
1115 this.index = index_;
1119 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} vec
1120 * @param {string} name
1121 * @return {es3fUniformApiTests.BasicUniformReportGL}
1123 es3fUniformApiTests.BasicUniformReportGL.findWithName = function(vec, name) {
1124 for (var i = 0; i < vec.length; i++) {
1125 if (vec[i].name == name)
1132 * es3fUniformApiTests.UniformCase class, inherits from TestCase class
1134 * @param {string} name
1135 * @param {string} description
1136 * @extends {tcuTestCase.DeqpTest}
1138 es3fUniformApiTests.UniformCase = function(name, description) { // \note Randomizes caseType, uniformCollection and features.
1139 tcuTestCase.DeqpTest.call(this, name, description);
1141 /** @type {es3fUniformApiTests.Feature} */ this.m_features;
1142 /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ this.m_uniformCollection;
1144 /** @type {number} */ this.m_caseShaderType = 0;
1146 /** @type {Array<gluTexture.Texture2D>} */ this.m_textures2d = [];
1147 /** @type {Array<gluTexture.TextureCube>} */ this.m_texturesCube = [];
1148 /** @type {Array<number>} */ this.m_filledTextureUnits = [];
1151 es3fUniformApiTests.UniformCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
1152 /** es3fUniformApiTests.UniformCase prototype restore */
1153 es3fUniformApiTests.UniformCase.prototype.constructor = es3fUniformApiTests.UniformCase;
1156 * es3fUniformApiTests.UniformCase newC. Creates a es3fUniformApiTests.UniformCase. Use after constructor.
1157 * @param {number} seed
1158 * @return {es3fUniformApiTests.UniformCase}
1160 es3fUniformApiTests.UniformCase.prototype.newC = function(seed) {
1161 this.m_features = this.randomFeatures(seed);
1162 this.m_uniformCollection = es3fUniformApiTests.UniformCollection.random(seed);
1163 this.m_caseShaderType = es3fUniformApiTests.randomCaseShaderType(seed);
1169 * es3fUniformApiTests.UniformCase new_B (static). Creates a es3fUniformApiTests.UniformCase
1170 * @param {string} name
1171 * @param {string} description
1172 * @param {number} seed
1173 * @return {es3fUniformApiTests.UniformCase}
1175 es3fUniformApiTests.UniformCase.new_C = function(name, description, seed) {
1176 var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newC(seed);
1182 * es3fUniformApiTests.UniformCase new_B. Creates a es3fUniformApiTests.UniformCase. Use after constructor.
1183 * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
1184 * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
1185 * @param {es3fUniformApiTests.Feature} features
1186 * @return {es3fUniformApiTests.UniformCase}
1188 es3fUniformApiTests.UniformCase.prototype.newB = function(caseShaderType, uniformCollection, features) {
1189 this.m_caseShaderType = caseShaderType;
1190 this.m_uniformCollection = uniformCollection;
1191 this.m_features = features;
1197 * es3fUniformApiTests.UniformCase new_B (static). Creates a es3fUniformApiTests.UniformCase
1198 * @param {string} name
1199 * @param {string} description
1200 * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
1201 * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
1202 * @param {es3fUniformApiTests.Feature} features
1203 * @return {es3fUniformApiTests.UniformCase}
1205 es3fUniformApiTests.UniformCase.new_B = function(name, description, caseShaderType, uniformCollection, features) {
1206 var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newB(caseShaderType, uniformCollection, features);
1212 * es3fUniformApiTests.UniformCase new_A. Creates a es3fUniformApiTests.UniformCase. Use after constructor.
1213 * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
1214 * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
1215 * @return {es3fUniformApiTests.UniformCase}
1217 es3fUniformApiTests.UniformCase.prototype.newA = function(caseShaderType, uniformCollection) {
1218 this.m_caseShaderType = caseShaderType;
1219 this.m_uniformCollection = uniformCollection;
1220 this.m_features = null;
1226 * es3fUniformApiTests.UniformCase new_A (static). Creates a es3fUniformApiTests.UniformCase
1227 * @param {string} name
1228 * @param {string} description
1229 * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
1230 * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
1231 * @return {es3fUniformApiTests.UniformCase}
1233 es3fUniformApiTests.UniformCase.new_A = function(name, description, caseShaderType, uniformCollection) {
1234 var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newA(caseShaderType, uniformCollection);
1240 * @param {number} seed
1241 * @return {es3fUniformApiTests.Feature}
1243 es3fUniformApiTests.UniformCase.prototype.randomFeatures = function(seed) {
1244 /** @type {es3fUniformApiTests.Feature} */ var result = new es3fUniformApiTests.Feature();
1246 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(seed);
1248 result.ARRAYUSAGE_ONLY_MIDDLE_INDEX = rnd.getBool();
1249 result.UNIFORMFUNC_VALUE = rnd.getBool();
1250 result.MATRIXMODE_ROWMAJOR = rnd.getBool();
1251 result.ARRAYASSIGN_FULL = rnd.getBool();
1252 result.ARRAYASSIGN_BLOCKS_OF_TWO = !result.ARRAYASSIGN_FULL;
1253 result.UNIFORMUSAGE_EVERY_OTHER = rnd.getBool();
1254 result.BOOLEANAPITYPE_INT = rnd.getBool();
1255 result.BOOLEANAPITYPE_UINT = !result.BOOLEANAPITYPE_INT;
1256 result.UNIFORMVALUE_ZERO = rnd.getBool();
1262 * Initialize the es3fUniformApiTests.UniformCase
1264 es3fUniformApiTests.UniformCase.prototype.init = function() {
1265 /** @type {number} */ var numSamplerUniforms = this.m_uniformCollection.getNumSamplers();
1266 /** @type {number} */ var vertexTexUnitsRequired = this.m_caseShaderType != es3fUniformApiTests.CaseShaderType.FRAGMENT ? numSamplerUniforms : 0;
1267 /** @type {number} */ var fragmentTexUnitsRequired = this.m_caseShaderType != es3fUniformApiTests.CaseShaderType.VERTEX ? numSamplerUniforms : 0;
1268 /** @type {number} */ var combinedTexUnitsRequired = vertexTexUnitsRequired + fragmentTexUnitsRequired;
1269 var vertexTexUnitsSupported = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS));
1270 var fragmentTexUnitsSupported = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
1271 var combinedTexUnitsSupported = /** @type {number} */ (gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));
1274 numSamplerUniforms <= es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS,
1275 'es3fUniformApiTests.UniformCase.prototype.init - sampler uniforms exceed MAX_NUM_SAMPLER_UNIFORMS',
1280 if (vertexTexUnitsRequired > vertexTexUnitsSupported)
1281 testFailedOptions('' + vertexTexUnitsRequired + ' vertex texture units required, ' + vertexTexUnitsSupported + ' supported', true);
1282 if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
1283 testFailedOptions('' + fragmentTexUnitsRequired + ' fragment texture units required, ' + fragmentTexUnitsSupported + ' supported', true);
1284 if (combinedTexUnitsRequired > combinedTexUnitsSupported)
1285 testFailedOptions('' + combinedTexUnitsRequired + ' combined texture units required, ' + combinedTexUnitsSupported + ' supported', true);
1289 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniformsDst
1290 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsDst
1291 * @param {gluVarType.VarType} varType
1292 * @param {string} varName
1293 * @param {boolean} isParentActive
1294 * @param {number} samplerUnitCounter
1295 * @param {deRandom.Random} rnd
1296 * @return {number} Used to be output parameter. Sampler unit count
1298 es3fUniformApiTests.UniformCase.prototype.generateBasicUniforms = function(basicUniformsDst, basicUniformReportsDst, varType, varName, isParentActive, samplerUnitCounter, rnd) {
1299 /** @type {es3fUniformApiTests.VarValue} */ var value;
1301 if (varType.isBasicType()) {
1302 /** @type {boolean} */ var isActive = isParentActive && (this.m_features.UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.length % 2 == 0 : true);
1303 /** @type {gluShaderUtil.DataType} */ var type = varType.getBasicType();
1304 value = this.m_features.UNIFORMVALUE_ZERO ? es3fUniformApiTests.generateZeroVarValue(type) :
1305 gluShaderUtil.isDataTypeSampler(type) ? es3fUniformApiTests.generateRandomVarValue(type, rnd, samplerUnitCounter++) :
1306 es3fUniformApiTests.generateRandomVarValue(varType.getBasicType(), rnd);
1308 basicUniformsDst.push(new es3fUniformApiTests.BasicUniform(varName, varType.getBasicType(), isActive, value));
1309 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportRef(varName, varType.getBasicType(), isActive));
1310 } else if (varType.isArrayType()) {
1311 /** @type {number} */ var size = varType.getArraySize();
1312 /** @type {string} */ var arrayRootName = '' + varName + '[0]';
1313 /** @type {Array<boolean>} */ var isElemActive = [];
1315 for (var elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++) {
1316 /** @type {string} */ var indexedName = '' + varName + '[' + elemNdx + ']';
1317 /** @type {boolean} */ var isCurElemActive = isParentActive &&
1318 (this.m_features.UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.length % 2 == 0 : true) &&
1319 (this.m_features.ARRAYUSAGE_ONLY_MIDDLE_INDEX ? elemNdx == Math.floor(size / 2) : true);
1321 isElemActive.push(isCurElemActive);
1323 if (varType.getElementType().isBasicType()) {
1324 // \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
1325 /** @type {gluShaderUtil.DataType} */ var elemBasicType = varType.getElementType().getBasicType();
1326 value = this.m_features.UNIFORMVALUE_ZERO ? es3fUniformApiTests.generateZeroVarValue(elemBasicType) :
1327 gluShaderUtil.isDataTypeSampler(elemBasicType) ? es3fUniformApiTests.generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++) :
1328 es3fUniformApiTests.generateRandomVarValue(elemBasicType, rnd);
1330 basicUniformsDst.push(new es3fUniformApiTests.BasicUniform(indexedName, elemBasicType, isCurElemActive, value, arrayRootName, elemNdx, size));
1332 samplerUnitCounter = this.generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName, isCurElemActive, samplerUnitCounter, rnd);
1335 if (varType.getElementType().isBasicType()) {
1336 /** @type {number} */ var minSize;
1337 for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize - 1]; minSize--) {}
1339 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportRef(arrayRootName, varType.getElementType().getBasicType(), isParentActive && minSize > 0).constructor_A(minSize, size));
1343 varType.isStructType(),
1344 'es3fUniformApiTests.UniformCase.prototype.generateBasicUniforms - not a struct type',
1349 /** @type {gluVarType.StructType} */ var structType = varType.getStruct();
1351 for (var i = 0; i < structType.getSize(); i++) {
1352 /** @type {gluVarType.StructMember} */ var member = structType.getMember(i);
1353 /** @type {string} */ var memberFullName = '' + varName + '.' + member.getName();
1355 samplerUnitCounter = this.generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName, isParentActive, samplerUnitCounter, rnd);
1359 return samplerUnitCounter;
1363 * @param {string} dst
1366 es3fUniformApiTests.UniformCase.prototype.writeUniformDefinitions = function(dst) {
1367 for (var i = 0; i < this.m_uniformCollection.getNumStructTypes(); i++)
1368 dst += gluVarType.declareStructType(this.m_uniformCollection.getStructType(i), 0) + ';\n';
1370 for (var i = 0; i < this.m_uniformCollection.getNumUniforms(); i++)
1371 dst += 'uniform ' + gluVarType.declareVariable(this.m_uniformCollection.getUniform(i).type, this.m_uniformCollection.getUniform(i).name, 0) + ';\n';
1375 var compareFuncs = [{
1376 requiringTypes: [gluShaderUtil.isDataTypeFloatOrVec, gluShaderUtil.isDataTypeMatrix],
1377 definition: 'mediump float compare_float (mediump float a, mediump float b) { return abs(a - b) < 0.05 ? 1.0 : 0.0; }'
1380 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC2, t);},
1381 function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(2, t);}
1383 definition: 'mediump float compare_vec2 (mediump vec2 a, mediump vec2 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y); }'
1386 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC3, t);},
1387 function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(3, t);}
1389 definition: 'mediump float compare_vec3 (mediump vec3 a, mediump vec3 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }'
1392 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC4, t);},
1393 function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(4, t);}],
1394 definition: 'mediump float compare_vec4 (mediump vec4 a, mediump vec4 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z)*compare_float(a.w, b.w); }'
1397 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2, t);},
1398 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1400 definition: 'mediump float compare_mat2 (mediump mat2 a, mediump mat2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1]); }'
1403 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2X3, t);},
1404 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1406 definition: 'mediump float compare_mat2x3 (mediump mat2x3 a, mediump mat2x3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1]); }'
1409 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2X4, t);},
1410 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1412 definition: 'mediump float compare_mat2x4 (mediump mat2x4 a, mediump mat2x4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1]); }'
1415 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3X2, t);},
1416 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1418 definition: 'mediump float compare_mat3x2 (mediump mat3x2 a, mediump mat3x2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }'
1421 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3, t);},
1422 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1424 definition: 'mediump float compare_mat3 (mediump mat3 a, mediump mat3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }'
1427 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3X4, t);},
1428 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1430 definition: 'mediump float compare_mat3x4 (mediump mat3x4 a, mediump mat3x4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }'
1433 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4X2, t);},
1434 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1436 definition: 'mediump float compare_mat4x2 (mediump mat4x2 a, mediump mat4x2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }'
1439 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4X3, t);},
1440 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1442 definition: 'mediump float compare_mat4x3 (mediump mat4x3 a, mediump mat4x3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }'
1445 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4, t);},
1446 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1448 definition: 'mediump float compare_mat4 (mediump mat4 a, mediump mat4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2])*compare_vec4(a[3], b[3]); }'
1451 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT, t);},
1452 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1454 definition: 'mediump float compare_int (mediump int a, mediump int b) { return a == b ? 1.0 : 0.0; }'
1457 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC2, t);},
1458 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1460 definition: 'mediump float compare_ivec2 (mediump ivec2 a, mediump ivec2 b) { return a == b ? 1.0 : 0.0; }'
1463 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC3, t);},
1464 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1466 definition: 'mediump float compare_ivec3 (mediump ivec3 a, mediump ivec3 b) { return a == b ? 1.0 : 0.0; }'
1469 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC4, t);},
1470 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1472 definition: 'mediump float compare_ivec4 (mediump ivec4 a, mediump ivec4 b) { return a == b ? 1.0 : 0.0; }'
1475 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT, t);},
1476 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1478 definition: 'mediump float compare_uint (mediump uint a, mediump uint b) { return a == b ? 1.0 : 0.0; }'
1481 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC2, t);},
1482 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1484 definition: 'mediump float compare_uvec2 (mediump uvec2 a, mediump uvec2 b) { return a == b ? 1.0 : 0.0; }'
1487 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC3, t);},
1488 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1490 definition: 'mediump float compare_uvec3 (mediump uvec3 a, mediump uvec3 b) { return a == b ? 1.0 : 0.0; }'
1493 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC4, t);},
1494 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1496 definition: 'mediump float compare_uvec4 (mediump uvec4 a, mediump uvec4 b) { return a == b ? 1.0 : 0.0; }'
1499 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL, t);},
1500 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1502 definition: 'mediump float compare_bool (bool a, bool b) { return a == b ? 1.0 : 0.0; }'
1505 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC2, t);},
1506 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1508 definition: 'mediump float compare_bvec2 (bvec2 a, bvec2 b) { return a == b ? 1.0 : 0.0; }'
1511 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC3, t);},
1512 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1514 definition: 'mediump float compare_bvec3 (bvec3 a, bvec3 b) { return a == b ? 1.0 : 0.0; }'
1517 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC4, t);},
1518 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
1520 definition: 'mediump float compare_bvec4 (bvec4 a, bvec4 b) { return a == b ? 1.0 : 0.0; }'
1524 /** @type {Array<gluShaderUtil.DataType>} */ var samplerTypes = this.m_uniformCollection.getSamplerTypes();
1526 for (var compFuncNdx = 0; compFuncNdx < compareFuncs.length; compFuncNdx++) {
1527 /** @type {Array<es3fUniformApiTests.dataTypePredicate>} */ var typeReq = compareFuncs[compFuncNdx].requiringTypes;
1528 /** @type {boolean} */ var containsTypeSampler = false;
1530 for (var i = 0; i < samplerTypes.length; i++) {
1531 if (gluShaderUtil.isDataTypeSampler(samplerTypes[i])) {
1532 /** @type {gluShaderUtil.DataType} */ var retType = es3fUniformApiTests.getSamplerLookupReturnType(samplerTypes[i]);
1533 if (typeReq[0](retType) || typeReq[1](retType)) {
1534 containsTypeSampler = true;
1540 if (containsTypeSampler || this.m_uniformCollection.containsMatchingBasicType(typeReq[0]) || this.m_uniformCollection.containsMatchingBasicType(typeReq[1]))
1541 dst += compareFuncs[compFuncNdx].definition + '\n';
1548 * @param {string} dst
1549 * @param {es3fUniformApiTests.BasicUniform} uniform
1550 * @return {string} Used to write the string in the output parameter
1552 es3fUniformApiTests.UniformCase.prototype.writeUniformCompareExpr = function(dst, uniform) {
1553 if (gluShaderUtil.isDataTypeSampler(uniform.type))
1554 dst += 'compare_' + gluShaderUtil.getDataTypeName(es3fUniformApiTests.getSamplerLookupReturnType(uniform.type)) + '(texture(' + uniform.name + ', vec' + es3fUniformApiTests.getSamplerNumLookupDimensions(uniform.type) + '(0.0))'; //WebGL2.0
1556 dst += 'compare_' + gluShaderUtil.getDataTypeName(uniform.type) + '(' + uniform.name;
1558 dst += ', ' + es3fUniformApiTests.shaderVarValueStr(uniform.finalValue) + ')';
1564 * @param {string} dst
1565 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
1566 * @param {string} variableName
1567 * @return {string} Used to write the string in the output parameter
1569 es3fUniformApiTests.UniformCase.prototype.writeUniformComparisons = function(dst, basicUniforms, variableName) {
1570 for (var i = 0; i < basicUniforms.length; i++) {
1571 /** @type {es3fUniformApiTests.BasicUniform} */ var unif = basicUniforms[i];
1573 if (unif.isUsedInShader) {
1574 dst += '\t' + variableName + ' *= ';
1575 dst = this.writeUniformCompareExpr(dst, basicUniforms[i]);
1578 dst += '\t// UNUSED: ' + basicUniforms[i].name + '\n';
1585 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
1588 es3fUniformApiTests.UniformCase.prototype.generateVertexSource = function(basicUniforms) {
1589 /** @type {boolean} */ var isVertexCase = this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.VERTEX || this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.BOTH;
1590 /** @type {string} */ var result = '';
1592 result += '#version 300 es\n' +
1593 'in highp vec4 a_position;\n' +
1594 'out mediump float v_vtxOut;\n' +
1598 result = this.writeUniformDefinitions(result);
1601 'void main (void)\n' +
1603 ' gl_Position = a_position;\n' +
1604 ' v_vtxOut = 1.0;\n';
1607 result = this.writeUniformComparisons(result, basicUniforms, 'v_vtxOut');
1615 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
1618 es3fUniformApiTests.UniformCase.prototype.generateFragmentSource = function(basicUniforms) {
1619 /**@type {boolean} */ var isFragmentCase = this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.FRAGMENT || this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.BOTH;
1620 /**@type {string} */ var result = '';
1622 result += '#version 300 es\n' +
1623 'in mediump float v_vtxOut;\n' +
1627 result = this.writeUniformDefinitions(result);
1630 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
1632 'void main (void)\n' +
1634 ' mediump float result = v_vtxOut;\n';
1637 result = this.writeUniformComparisons(result, basicUniforms, 'result');
1639 result += ' dEQP_FragColor = vec4(result, result, result, 1.0);\n' +
1646 * @param {es3fUniformApiTests.VarValue} value
1648 es3fUniformApiTests.UniformCase.prototype.setupTexture = function(value) {
1649 // \note No handling for samplers other than 2D or cube.
1652 es3fUniformApiTests.getSamplerLookupReturnType(value.type) == gluShaderUtil.DataType.FLOAT_VEC4,
1653 'es3fUniformApiTests.UniformCase.prototype.setupTexture - sampler return type should be vec4f', false, true
1656 /** @type {number} */ var width = 32;
1657 /** @type {number} */ var height = 32;
1658 /** @type {Array<number>} */ var color = value.val.samplerV.fillColor;
1659 /** @type {tcuTexture.TextureCube} */ var refTexture;
1660 /** @type {gluTexture.TextureCube} */ var texture;
1662 if (value.type == gluShaderUtil.DataType.SAMPLER_2D) {
1663 texture = gluTexture.texture2DFromFormat(gl, gl.RGBA, gl.UNSIGNED_BYTE, width, height);
1664 refTexture = texture.getRefTexture();
1665 this.m_textures2d.push(texture);
1667 refTexture.allocLevel(0);
1668 es3fUniformApiTests.fillWithColor(refTexture.getLevel(0), color);
1670 gl.activeTexture(gl.TEXTURE0 + value.val.samplerV.unit);
1671 this.m_filledTextureUnits.push(value.val.samplerV.unit);
1673 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1674 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1675 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
1676 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
1677 } else if (value.type == gluShaderUtil.DataType.SAMPLER_CUBE) {
1678 assertMsgOptions(width == height, 'es3fUniformApiTests.UniformCase.prototype.setupTexture - non square texture', false, true);
1680 texture = gluTexture.cubeFromFormat(gl, gl.RGBA, gl.UNSIGNED_BYTE, width);
1681 refTexture = texture.getRefTexture();
1682 this.m_texturesCube.push(texture);
1684 for (var face in tcuTexture.CubeFace) {
1685 refTexture.allocLevel(tcuTexture.CubeFace[face], 0);
1686 es3fUniformApiTests.fillWithColor(refTexture.getLevelFace(0, tcuTexture.CubeFace[face]), color);
1689 gl.activeTexture(gl.TEXTURE0 + value.val.samplerV.unit);
1690 this.m_filledTextureUnits.push(value.val.samplerV.unit);
1692 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1693 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1694 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
1695 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
1697 throw new Error('es3fUniformApiTests.UniformCase.prototype.setupTexture - Invalid sampler type');
1701 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} basicUniformReportsDst
1702 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
1703 * @param {WebGLProgram} programGL
1706 es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne = function(basicUniformReportsDst, basicUniformReportsRef, programGL) {
1707 /** @type {WebGLProgram} */ var numActiveUniforms;
1708 /** @type {boolean} */ var success = true;
1710 numActiveUniforms = /** @type {WebGLProgram} */ (gl.getProgramParameter(programGL, gl.ACTIVE_UNIFORMS));
1711 bufferedLogToConsole('// Number of active uniforms reported: ' + numActiveUniforms);
1713 for (var unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++) {
1714 /** @type {number} (GLint)*/ var reportedSize = -1;
1715 /** @type {number} (GLenum)*/ var reportedTypeGL = gl.NONE;
1716 /** @type {gluShaderUtil.DataType} */ var reportedType;
1717 /** @type {string} */ var reportedNameStr;
1718 /** @type {WebGLActiveInfo} */ var activeInfo;
1720 activeInfo = gl.getActiveUniform(programGL, unifNdx);
1722 reportedNameStr = activeInfo.name;
1723 reportedTypeGL = activeInfo.type;
1724 reportedSize = activeInfo.size;
1726 reportedType = gluShaderUtil.getDataTypeFromGLType(reportedTypeGL);
1728 checkMessage(reportedType !== undefined, 'Invalid uniform type');
1730 bufferedLogToConsole('// Got name = ' + reportedNameStr + ', size = ' + reportedSize + ', type = ' + gluShaderUtil.getDataTypeName(reportedType));
1732 // Ignore built-in uniforms.
1733 if (reportedNameStr.indexOf('gl_') == -1) {
1734 /** @type {number} */ var referenceNdx;
1735 for (referenceNdx = 0; referenceNdx < basicUniformReportsRef.length; referenceNdx++) {
1736 if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
1740 if (referenceNdx >= basicUniformReportsRef.length) {
1741 bufferedLogToConsole('// FAILURE: invalid non-built-in uniform name reported');
1744 /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var reference = basicUniformReportsRef[referenceNdx];
1747 reference.type !== undefined,
1748 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - type is undefined',
1753 reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader),
1754 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - uniform min size does not match usage in shader',
1759 reference.minSize <= reference.maxSize,
1760 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - uniform min size bigger than max size',
1765 if (es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, reportedNameStr) !== null) {
1766 bufferedLogToConsole('// FAILURE: same uniform name reported twice');
1770 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportGL(reportedNameStr, reportedNameStr.length, reportedSize, reportedType, unifNdx));
1772 if (reportedType != reference.type) {
1773 bufferedLogToConsole('// FAILURE: wrong type reported, should be ' + gluShaderUtil.getDataTypeName(reference.type));
1776 if (reportedSize < reference.minSize || reportedSize > reference.maxSize) {
1777 bufferedLogToConsole('// FAILURE: wrong size reported, should be ' +
1778 (reference.minSize == reference.maxSize ? reference.minSize : 'in the range [' + reference.minSize + ', ' + reference.maxSize + ']'));
1786 for (var i = 0; i < basicUniformReportsRef.length; i++) {
1787 /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var expected = basicUniformReportsRef[i];
1788 if (expected.isUsedInShader && es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, expected.name) === null) {
1789 bufferedLogToConsole('// FAILURE: uniform with name ' + expected.name + ' was not reported by GL');
1798 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} basicUniformReportsDst
1799 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
1800 * @param {WebGLProgram} programGL
1803 es3fUniformApiTests.UniformCase.prototype.getActiveUniforms = function(basicUniformReportsDst, basicUniformReportsRef, programGL) {
1804 /** @type {Array<string>} */ var queryNames = new Array(basicUniformReportsRef.length);
1805 /** @type {Array<string>} */ var queryNamesC = new Array(basicUniformReportsRef.length);
1806 /** @type {Array<number>} (GLuint) */ var uniformIndices = new Array(basicUniformReportsRef.length);
1807 /** @type {Array<number>} */ var validUniformIndices = []; // This shall have the same contents, and in same order, as uniformIndices, but with gl.INVALID_INDEX entries removed.
1808 /** @type {boolean} */ var success = true;
1810 for (var i = 0; i < basicUniformReportsRef.length; i++) {
1811 /** @type {string} */ var name = basicUniformReportsRef[i].name;
1812 queryNames[i] = this.m_features.ARRAY_FIRST_ELEM_NAME_NO_INDEX && name[name.length - 1] == ']' ? es3fUniformApiTests.beforeLast(name, '[') : name;
1813 queryNamesC[i] = queryNames[i];
1816 uniformIndices = gl.getUniformIndices(programGL, queryNamesC);
1818 for (var i = 0; i < uniformIndices.length; i++) {
1819 if (uniformIndices[i] != gl.INVALID_INDEX)
1820 validUniformIndices.push(uniformIndices[i]);
1822 if (basicUniformReportsRef[i].isUsedInShader) {
1823 bufferedLogToConsole('// FAILURE: uniform with name ' + basicUniformReportsRef[i].name + ' received gl.INVALID_INDEX');
1829 if (validUniformIndices.length > 0) {
1830 /** @type {Array<string>} */ var uniformNameBuf = new Array(validUniformIndices.length);
1831 /** @type {Array<number>} (GLint) */ var uniformSizeBuf = new Array(validUniformIndices.length);
1832 /** @type {Array<number>} (GLint) */ var uniformTypeBuf = new Array(validUniformIndices.length);
1834 uniformSizeBuf = gl.getActiveUniforms(programGL, validUniformIndices, gl.UNIFORM_SIZE);
1835 uniformTypeBuf = gl.getActiveUniforms(programGL, validUniformIndices, gl.UNIFORM_TYPE);
1837 /** @type {number} */ var validNdx = -1; // Keeps the corresponding index to validUniformIndices while unifNdx is the index to uniformIndices.
1838 for (var unifNdx = 0; unifNdx < uniformIndices.length; unifNdx++) {
1839 if (uniformIndices[unifNdx] == gl.INVALID_INDEX)
1844 /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var reference = basicUniformReportsRef[unifNdx];
1845 /** @type {number} */ var reportedIndex = validUniformIndices[validNdx];
1846 /** @type {number} */ var reportedNameLength = reference.name.length;
1847 /** @type {number} */ var reportedSize = uniformSizeBuf[validNdx];
1848 /** @type {gluShaderUtil.DataType} */ var reportedType = gluShaderUtil.getDataTypeFromGLType(uniformTypeBuf[validNdx]);
1849 /** @type {string} */ var reportedNameStr = reference.name;
1851 bufferedLogToConsole('// Got name size = ' + reportedSize +
1852 ', type = ' + gluShaderUtil.getDataTypeName(reportedType) +
1853 ' for the uniform at index ' + reportedIndex + ' (' + reference.name + ')');
1856 reference.type !== undefined,
1857 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - type is undefined',
1862 reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader),
1863 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - uniform min size does not match usage in shader',
1868 reference.minSize <= reference.maxSize,
1869 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - uniform min size bigger than max size',
1874 if (es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, reportedNameStr) !== null) {
1875 bufferedLogToConsole('// FAILURE: same uniform name reported twice');
1878 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportGL(reference.name, reportedNameLength, reportedSize, reportedType, reportedIndex));
1880 if (reportedType != reference.type) {
1881 bufferedLogToConsole('// FAILURE: wrong type reported, should be ' + gluShaderUtil.getDataTypeName(reference.type));
1885 if (reportedSize < reference.minSize || reportedSize > reference.maxSize) {
1886 bufferedLogToConsole('// FAILURE: wrong size reported, should be ' +
1887 (reference.minSize == reference.maxSize ? reference.minSize : 'in the range [' + reference.minSize + ', ' + reference.maxSize + ']'));
1898 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} uniformResults
1899 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} uniformsResults
1902 es3fUniformApiTests.UniformCase.prototype.uniformVsUniformsComparison = function(uniformResults, uniformsResults) {
1903 /** @type {boolean} */ var success = true;
1904 /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformsResult;
1906 for (var uniformResultNdx = 0; uniformResultNdx < uniformResults.length; uniformResultNdx++) {
1907 /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformResult = uniformResults[uniformResultNdx];
1908 /** @type {string} */ var uniformName = uniformResult.name;
1909 uniformsResult = es3fUniformApiTests.BasicUniformReportGL.findWithName(uniformsResults, uniformName);
1911 if (uniformsResult !== null) {
1912 bufferedLogToConsole('// Checking uniform ' + uniformName);
1914 if (uniformResult.index != uniformsResult.index) {
1915 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetUniformIndices() gave different indices for uniform ' + uniformName);
1918 if (uniformResult.nameLength != uniformsResult.nameLength) {
1919 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave incompatible name lengths for uniform ' + uniformName);
1922 if (uniformResult.size != uniformsResult.size) {
1923 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave different sizes for uniform ' + uniformName);
1926 if (uniformResult.type != uniformsResult.type) {
1927 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave different types for uniform ' + uniformName);
1931 bufferedLogToConsole('// FAILURE: uniform ' + uniformName + ' was reported active by glGetActiveUniform() but not by glGetUniformIndices()');
1936 for (var uniformsResultNdx = 0; uniformsResultNdx < uniformsResults.length; uniformsResultNdx++) {
1937 uniformsResult = uniformsResults[uniformsResultNdx];
1938 /** @type {string} */ var uniformsName = uniformsResult.name;
1939 /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformsResultIt = es3fUniformApiTests.BasicUniformReportGL.findWithName(uniformsResults, uniformsName);
1941 if (uniformsResultIt === null) {
1942 bufferedLogToConsole('// FAILURE: uniform ' + uniformsName + ' was reported active by glGetUniformIndices() but not by glGetActiveUniform()');
1951 * @param {Array<es3fUniformApiTests.VarValue>} valuesDst
1952 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
1953 * @param {WebGLProgram} programGL
1956 es3fUniformApiTests.UniformCase.prototype.getUniforms = function(valuesDst, basicUniforms, programGL) {
1957 /** @type {boolean} */ var success = true;
1959 for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
1960 /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
1961 /** @type {string} */ var queryName = this.m_features.ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? es3fUniformApiTests.beforeLast(uniform.name, '[') : uniform.name;
1962 /** @type {WebGLUniformLocation} */ var location = gl.getUniformLocation(programGL, queryName);
1963 /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(uniform.type);
1964 /** @type {es3fUniformApiTests.VarValue} */ var value = new es3fUniformApiTests.VarValue();
1967 value.type = gluShaderUtil.DataType.INVALID;
1968 valuesDst.push(value);
1969 if (uniform.isUsedInShader) {
1970 bufferedLogToConsole('// FAILURE: ' + uniform.name + ' was used in shader, but has location -1');
1976 value.type = uniform.type;
1978 var result = /** @type {number} */ (gl.getUniform(programGL, location));
1980 if (gluShaderUtil.isDataTypeSampler(uniform.type)) {
1981 value.val = new es3fUniformApiTests.SamplerV();
1982 value.val.samplerV.unit = result;
1984 value.val = /** @type {Array<number>} */ (result.length === undefined ? [result] : result);
1986 valuesDst.push(value);
1988 bufferedLogToConsole('// Got ' + uniform.name + ' value ' + es3fUniformApiTests.apiVarValueStr(value));
1995 * @param {Array<es3fUniformApiTests.VarValue>} values
1996 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
1999 es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues = function(values, basicUniforms) {
2000 /** @type {boolean} */ var success = true;
2003 values.length == basicUniforms.length,
2004 'es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues - lengths do not match',
2009 for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
2010 /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
2011 /** @type {es3fUniformApiTests.VarValue} */ var unifValue = values[unifNdx];
2012 /** @type {number} */ var valSize = gluShaderUtil.getDataTypeScalarSize(uniform.type);
2014 bufferedLogToConsole('// Checking uniform ' + uniform.name);
2016 if (unifValue.type == gluShaderUtil.DataType.INVALID) // This happens when glGetUniformLocation() returned -1.
2019 var CHECK_UNIFORM = function(ZERO) {
2021 for (var i = 0; i < valSize; i++) {
2022 if (unifValue.val[i] != ZERO) {
2023 bufferedLogToConsole('// FAILURE: uniform ' + uniform.name + ' has non-zero initial value');
2030 if (gluShaderUtil.isDataTypeFloatOrVec(uniform.type) || gluShaderUtil.isDataTypeMatrix(uniform.type))
2032 else if (gluShaderUtil.isDataTypeIntOrIVec(uniform.type))
2034 else if (gluShaderUtil.isDataTypeUintOrUVec(uniform.type))
2036 else if (gluShaderUtil.isDataTypeBoolOrBVec(uniform.type))
2037 CHECK_UNIFORM(false);
2038 else if (gluShaderUtil.isDataTypeSampler(uniform.type)) {
2039 if (unifValue.val.samplerV.unit != 0) {
2040 bufferedLogToConsole('// FAILURE: uniform ' + uniform.name + ' has non-zero initial value');
2044 throw new Error('es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues - invalid uniform type');
2051 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
2052 * @param {WebGLProgram} programGL
2053 * @param {deRandom.Random} rnd
2055 es3fUniformApiTests.UniformCase.prototype.assignUniforms = function(basicUniforms, programGL, rnd) {
2056 /** @type {boolean} */ var transpose = false; //No support to transpose uniform matrices in WebGL, must always be false. (this.m_features.MATRIXMODE_ROWMAJOR) != 0;
2057 /** @type {boolean} (GLboolean) */ var transposeGL = transpose;
2058 /** @type {gluShaderUtil.DataType} */ var boolApiType = this.m_features.BOOLEANAPITYPE_INT ? gluShaderUtil.DataType.INT :
2059 this.m_features.BOOLEANAPITYPE_UINT ? gluShaderUtil.DataType.UINT :
2060 gluShaderUtil.DataType.FLOAT;
2062 for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
2063 /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
2064 /** @type {boolean} */ var isArrayMember = uniform.elemNdx >= 0;
2065 /** @type {string} */ var queryName = this.m_features.ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? es3fUniformApiTests.beforeLast(uniform.name, '[') : uniform.name;
2066 /** @type {number} */ var numValuesToAssign = !isArrayMember ? 1 :
2067 this.m_features.ARRAYASSIGN_FULL ? (uniform.elemNdx == 0 ? uniform.rootSize : 0) :
2068 this.m_features.ARRAYASSIGN_BLOCKS_OF_TWO ? (uniform.elemNdx % 2 == 0 ? 2 : 0) :
2069 /* Default: assign array elements separately */ 1;
2072 numValuesToAssign >= 0,
2073 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - number of values to assign not a positive integer',
2078 numValuesToAssign == 1 || isArrayMember,
2079 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - not an array member and number of values to assign not 1',
2084 if (numValuesToAssign == 0) {
2085 bufferedLogToConsole('// es3fUniformApiTests.Uniform ' + uniform.name + ' is covered by another glUniform*v() call to the same array');
2089 /** @type {WebGLUniformLocation} */ var location = gl.getUniformLocation(programGL, queryName);
2090 /** @type {number} */ var typeSize = gluShaderUtil.getDataTypeScalarSize(uniform.type);
2091 /** @type {boolean} */ var assignByValue = this.m_features.UNIFORMFUNC_VALUE && !gluShaderUtil.isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
2092 /** @type {Array<es3fUniformApiTests.VarValue>} */ var valuesToAssign = [];
2093 /** @type {Array<number>} */ var buffer;
2095 for (var i = 0; i < numValuesToAssign; i++) {
2096 /** @type {string} */ var curName = isArrayMember ? es3fUniformApiTests.beforeLast(uniform.rootName, '[') + '[' + (uniform.elemNdx + i) + ']' : uniform.name;
2097 /** @type {es3fUniformApiTests.VarValue} */ var unifValue = new es3fUniformApiTests.VarValue();
2099 if (isArrayMember) {
2100 /** @type {es3fUniformApiTests.BasicUniform} */ var elemUnif = es3fUniformApiTests.BasicUniform.findWithName(basicUniforms, curName);
2101 if (elemUnif === null)
2103 unifValue = elemUnif.finalValue;
2105 unifValue = uniform.finalValue;
2107 /** @type {es3fUniformApiTests.VarValue} */ var apiValue = gluShaderUtil.isDataTypeBoolOrBVec(unifValue.type) ? es3fUniformApiTests.getRandomBoolRepresentation(unifValue, boolApiType, rnd) :
2108 gluShaderUtil.isDataTypeSampler(unifValue.type) ? es3fUniformApiTests.getSamplerUnitValue(unifValue) :
2111 valuesToAssign.push(gluShaderUtil.isDataTypeMatrix(apiValue.type) && transpose ? es3fUniformApiTests.getTransposeMatrix(apiValue) : apiValue);
2113 if (gluShaderUtil.isDataTypeBoolOrBVec(uniform.type))
2114 bufferedLogToConsole('// Using type ' + gluShaderUtil.getDataTypeName(boolApiType) + ' to set boolean value ' + es3fUniformApiTests.apiVarValueStr(unifValue) + ' for ' + curName);
2115 else if (gluShaderUtil.isDataTypeSampler(uniform.type))
2116 bufferedLogToConsole('// Texture for the sampler uniform ' + curName + ' will be filled with color ' + es3fUniformApiTests.apiVarValueStr(es3fUniformApiTests.getSamplerFillValue(uniform.finalValue)));
2120 valuesToAssign.length > 0,
2121 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - values quantity less than one',
2126 if (gluShaderUtil.isDataTypeFloatOrVec(valuesToAssign[0].type)) {
2127 if (assignByValue) {
2129 case 1: gl.uniform1f(location, valuesToAssign[0].val[0]); break;
2130 case 2: gl.uniform2f(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1]); break;
2131 case 3: gl.uniform3f(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2]); break;
2132 case 4: gl.uniform4f(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2], valuesToAssign[0].val[3]); break;
2134 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
2137 buffer = new Array(valuesToAssign.length * typeSize);
2138 for (var i = 0; i < buffer.length; i++)
2139 buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
2142 case 1: gl.uniform1fv(location, buffer); break;
2143 case 2: gl.uniform2fv(location, buffer); break;
2144 case 3: gl.uniform3fv(location, buffer); break;
2145 case 4: gl.uniform4fv(location, buffer); break;
2147 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
2150 } else if (gluShaderUtil.isDataTypeMatrix(valuesToAssign[0].type)) {
2153 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - assigning by value in matrix type',
2157 buffer = new Array(valuesToAssign.length * typeSize);
2158 for (var i = 0; i < buffer.length; i++)
2159 buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
2161 switch (uniform.type) {
2162 case gluShaderUtil.DataType.FLOAT_MAT2: gl.uniformMatrix2fv(location, transposeGL, new Float32Array(buffer)); break;
2163 case gluShaderUtil.DataType.FLOAT_MAT3: gl.uniformMatrix3fv(location, transposeGL, new Float32Array(buffer)); break;
2164 case gluShaderUtil.DataType.FLOAT_MAT4: gl.uniformMatrix4fv(location, transposeGL, new Float32Array(buffer)); break;
2165 case gluShaderUtil.DataType.FLOAT_MAT2X3: gl.uniformMatrix2x3fv(location, transposeGL, new Float32Array(buffer)); break;
2166 case gluShaderUtil.DataType.FLOAT_MAT2X4: gl.uniformMatrix2x4fv(location, transposeGL, new Float32Array(buffer)); break;
2167 case gluShaderUtil.DataType.FLOAT_MAT3X2: gl.uniformMatrix3x2fv(location, transposeGL, new Float32Array(buffer)); break;
2168 case gluShaderUtil.DataType.FLOAT_MAT3X4: gl.uniformMatrix3x4fv(location, transposeGL, new Float32Array(buffer)); break;
2169 case gluShaderUtil.DataType.FLOAT_MAT4X2: gl.uniformMatrix4x2fv(location, transposeGL, new Float32Array(buffer)); break;
2170 case gluShaderUtil.DataType.FLOAT_MAT4X3: gl.uniformMatrix4x3fv(location, transposeGL, new Float32Array(buffer)); break;
2172 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid uniform type');
2174 } else if (gluShaderUtil.isDataTypeIntOrIVec(valuesToAssign[0].type)) {
2175 if (assignByValue) {
2177 case 1: gl.uniform1i(location, valuesToAssign[0].val[0]); break;
2178 case 2: gl.uniform2i(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1]); break;
2179 case 3: gl.uniform3i(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2]); break;
2180 case 4: gl.uniform4i(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2], valuesToAssign[0].val[3]); break;
2182 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
2185 buffer = new Array(valuesToAssign.length * typeSize);
2186 for (var i = 0; i < buffer.length; i++)
2187 buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
2190 case 1: gl.uniform1iv(location, buffer); break;
2191 case 2: gl.uniform2iv(location, buffer); break;
2192 case 3: gl.uniform3iv(location, buffer); break;
2193 case 4: gl.uniform4iv(location, buffer); break;
2195 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
2198 } else if (gluShaderUtil.isDataTypeUintOrUVec(valuesToAssign[0].type)) {
2199 if (assignByValue) {
2201 case 1: gl.uniform1ui(location, valuesToAssign[0].val[0]); break;
2202 case 2: gl.uniform2ui(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1]); break;
2203 case 3: gl.uniform3ui(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2]); break;
2204 case 4: gl.uniform4ui(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2], valuesToAssign[0].val[3]); break;
2206 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
2209 buffer = new Array(valuesToAssign.length * typeSize);
2210 for (var i = 0; i < buffer.length; i++)
2211 buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
2214 case 1: gl.uniform1uiv(location, buffer); break;
2215 case 2: gl.uniform2uiv(location, buffer); break;
2216 case 3: gl.uniform3uiv(location, buffer); break;
2217 case 4: gl.uniform4uiv(location, buffer); break;
2219 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
2222 } else if (gluShaderUtil.isDataTypeSampler(valuesToAssign[0].type)) {
2224 gl.uniform1i(location, uniform.finalValue.val.samplerV.unit);
2226 var unit = /** @type {Array<number>} */ (uniform.finalValue.val);
2227 gl.uniform1iv(location, unit);
2230 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid uniform type');
2235 * @param {Array<es3fUniformApiTests.VarValue>} values
2236 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
2239 es3fUniformApiTests.UniformCase.prototype.compareUniformValues = function(values, basicUniforms) {
2240 /** @type {boolean} */ var success = true;
2242 for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
2243 /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
2244 /** @type {es3fUniformApiTests.VarValue} */ var unifValue = values[unifNdx];
2246 bufferedLogToConsole('// Checking uniform ' + uniform.name);
2248 if (unifValue.type == gluShaderUtil.DataType.INVALID) // This happens when glGetUniformLocation() returned -1.
2251 if (!es3fUniformApiTests.apiVarValueEquals(unifValue, uniform.finalValue)) {
2252 bufferedLogToConsole('// FAILURE: value obtained with glGetUniform*() for uniform ' + uniform.name + ' differs from value set with glUniform*()');
2260 /** @const @type {number} */ es3fUniformApiTests.VIEWPORT_WIDTH = 128;
2261 /** @const @type {number} */ es3fUniformApiTests.VIEWPORT_HEIGHT = 128;
2264 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
2265 * @param {gluShaderProgram.ShaderProgram} program
2266 * @param {deRandom.Random} rnd
2269 es3fUniformApiTests.UniformCase.prototype.renderTest = function(basicUniforms, program, rnd) {
2270 //const tcu::RenderTarget& renderTarget = m_context.getRenderTarget();
2271 /** @const */ var viewportW = Math.min(gl.canvas.width, es3fUniformApiTests.VIEWPORT_WIDTH);
2272 /** @const */ var viewportH = Math.min(gl.canvas.height, es3fUniformApiTests.VIEWPORT_HEIGHT);
2273 /** @const */ var viewportX = rnd.getInt(0, gl.canvas.width - viewportW);
2274 /** @const */ var viewportY = rnd.getInt(0, gl.canvas.height - viewportH);
2275 /** @type {tcuSurface.Surface} */ var renderedImg = new tcuSurface.Surface(viewportW, viewportH);
2277 // Assert that no two samplers of different types have the same texture unit - this is an error in GL.
2278 for (var i = 0; i < basicUniforms.length; i++) {
2279 if (gluShaderUtil.isDataTypeSampler(basicUniforms[i].type)) {
2280 for (var j = 0; j < i; j++) {
2281 if (gluShaderUtil.isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
2283 basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit,
2284 'es3fUniformApiTests.UniformCase.prototype.renderTest - sampler units have the same texture unit',
2291 for (var i = 0; i < basicUniforms.length; i++) {
2292 if (gluShaderUtil.isDataTypeSampler(basicUniforms[i].type) && this.m_filledTextureUnits.indexOf(basicUniforms[i].finalValue.val) == -1) {
2293 bufferedLogToConsole('// Filling texture at unit ' + es3fUniformApiTests.apiVarValueStr(basicUniforms[i].finalValue) + ' with color ' + es3fUniformApiTests.shaderVarValueStr(basicUniforms[i].finalValue));
2294 this.setupTexture(basicUniforms[i].finalValue);
2298 gl.viewport(viewportX, viewportY, viewportW, viewportH);
2300 /** @type {Float32Array} */ var position = new Float32Array([
2301 -1.0, -1.0, 0.0, 1.0,
2302 -1.0, 1.0, 0.0, 1.0,
2303 1.0, -1.0, 0.0, 1.0,
2307 /** @type {Uint16Array} */
2308 var indices = new Uint16Array([0, 1, 2, 2, 1, 3]);
2310 /** @type {number} */ var posLoc = gl.getAttribLocation(program.getProgram(), 'a_position');
2311 gl.enableVertexAttribArray(posLoc);
2313 var gl_position_buffer = gl.createBuffer();
2314 gl.bindBuffer(gl.ARRAY_BUFFER, gl_position_buffer);
2315 gl.bufferData(gl.ARRAY_BUFFER, position, gl.STATIC_DRAW);
2316 gl.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0);
2318 var gl_index_buffer = gl.createBuffer();
2319 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl_index_buffer);
2320 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
2322 gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
2324 renderedImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
2326 /** @type {number} */ var numFailedPixels = 0;
2327 var whitePixel = new gluDrawUtil.Pixel([255.0, 255.0, 255.0, 255.0]);
2328 for (var y = 0; y < renderedImg.getHeight(); y++) {
2329 for (var x = 0; x < renderedImg.getWidth(); x++) {
2330 var currentPixel = new gluDrawUtil.Pixel(renderedImg.getPixel(x, y));
2331 if (!whitePixel.equals(currentPixel))
2332 numFailedPixels += 1;
2336 if (numFailedPixels > 0) {
2337 //TODO: log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
2338 bufferedLogToConsole('FAILURE: image comparison failed, got ' + numFailedPixels + ' non-white pixels');
2341 bufferedLogToConsole('Success: got all-white pixels (all uniforms have correct values)');
2347 * @return {tcuTestCase.IterateResult}
2349 es3fUniformApiTests.UniformCase.prototype.iterate = function() {
2350 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ deRandom.getBaseSeed());
2351 /** @type {Array<es3fUniformApiTests.BasicUniform>} */ var basicUniforms = [];
2352 /** @type {Array<es3fUniformApiTests.BasicUniformReportRef>} */ var basicUniformReportsRef = [];
2354 /** @type {number} */ var samplerUnitCounter = 0;
2355 for (var i = 0; i < this.m_uniformCollection.getNumUniforms(); i++)
2356 samplerUnitCounter = this.generateBasicUniforms(basicUniforms, basicUniformReportsRef, this.m_uniformCollection.getUniform(i).type, this.m_uniformCollection.getUniform(i).name, true, samplerUnitCounter, rnd);
2358 /** @type {string} */ var vertexSource = this.generateVertexSource(basicUniforms);
2359 /** @type {string} */ var fragmentSource = this.generateFragmentSource(basicUniforms);
2360 /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexSource, fragmentSource));
2362 bufferedLogToConsole(program.getProgramInfo().infoLog);
2364 if (!program.isOk()) {
2365 testFailedOptions('Compile failed', false);
2366 return tcuTestCase.IterateResult.STOP;
2369 gl.useProgram(program.getProgram());
2371 /** @type {boolean} */ var success = this.test(basicUniforms, basicUniformReportsRef, program, rnd);
2372 assertMsgOptions(success, '', true, false);
2374 return tcuTestCase.IterateResult.STOP;
2380 es3fUniformApiTests.CaseType = {
2381 UNIFORM: 0, //!< Check info returned by glGetActiveUniform().
2382 INDICES_UNIFORMSIV: 1, //!< Check info returned by glGetUniformIndices() + glGetActiveUniforms(). TODO: Check 'IV' part
2383 CONSISTENCY: 2 //!< Query info with both above methods, and check consistency.
2387 * es3fUniformApiTests.UniformInfoQueryCase class
2389 * @param {string} name
2390 * @param {string} description
2391 * @param {es3fUniformApiTests.CaseShaderType} shaderType
2392 * @param {es3fUniformApiTests.UniformCollection} uniformCollection
2393 * @param {es3fUniformApiTests.CaseType} caseType
2394 * @param {es3fUniformApiTests.Feature} additionalFeatures
2395 * @extends {es3fUniformApiTests.UniformCase}
2397 es3fUniformApiTests.UniformInfoQueryCase = function(name, description, shaderType, uniformCollection, caseType, additionalFeatures) {
2398 es3fUniformApiTests.UniformCase.call(this, name, description);
2399 this.newB(shaderType, uniformCollection, additionalFeatures);
2400 /** @type {es3fUniformApiTests.CaseType} */ this.m_caseType = caseType;
2403 es3fUniformApiTests.UniformInfoQueryCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype);
2404 /** Constructor restore */
2405 es3fUniformApiTests.UniformInfoQueryCase.prototype.constructor = es3fUniformApiTests.UniformInfoQueryCase;
2408 * @param {es3fUniformApiTests.CaseType} caseType
2411 es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeName = function(caseType) {
2413 case es3fUniformApiTests.CaseType.UNIFORM: return 'active_uniform';
2414 case es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV: return 'indices_active_uniformsiv';
2415 case es3fUniformApiTests.CaseType.CONSISTENCY: return 'consistency';
2417 throw new Error('Invalid type');
2422 * @param {es3fUniformApiTests.CaseType} caseType
2425 es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeDescription = function(caseType) {
2427 case es3fUniformApiTests.CaseType.UNIFORM: return 'Test glGetActiveUniform()';
2428 case es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV: return 'Test glGetUniformIndices() along with glGetActiveUniforms()';
2429 case es3fUniformApiTests.CaseType.CONSISTENCY: return 'Check consistency between results from glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniforms()';
2431 throw new Error('Invalid type');
2435 // \note Although this is only used in UniformApiTest::es3fUniformApiTests.init, it needs to be defined here as it's used as a template argument.
2438 * @param {?string} name
2439 * @param {es3fUniformApiTests.UniformCollection} uniformCollection_
2441 es3fUniformApiTests.UniformCollectionCase = function(name, uniformCollection_) {
2442 /** @type {string} */ this.namePrefix = name ? name + '_' : '';
2443 /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ this.uniformCollection = uniformCollection_;
2447 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
2448 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
2449 * @param {gluShaderProgram.ShaderProgram} program
2450 * @param {deRandom.Random} rnd
2453 es3fUniformApiTests.UniformInfoQueryCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) {
2454 /** @type {WebGLProgram} */ var programGL = program.getProgram();
2455 /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var basicUniformReportsUniform = [];
2456 /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var basicUniformReportsUniforms = [];
2457 /** @type {boolean} */ var success;
2459 if (this.m_caseType == es3fUniformApiTests.CaseType.UNIFORM || this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) {
2462 //TODO:: const ScopedLogSection section(log, "InfoGetActiveUniform", "es3fUniformApiTests.Uniform information queries with glGetActiveUniform()");
2463 success = this.getActiveUniformsOneByOne(basicUniformReportsUniform, basicUniformReportsRef, programGL);
2466 if (this.m_caseType == es3fUniformApiTests.CaseType.UNIFORM)
2470 this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY,
2471 'es3fUniformApiTests.UniformInfoQueryCase.prototype.test - case type is not consistency',
2475 bufferedLogToConsole('// Note: this is a consistency case, so ignoring above failure(s)');
2480 if (this.m_caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV || this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) {
2483 //TODO: const ScopedLogSection section(log, "InfoGetActiveUniforms", "es3fUniformApiTests.Uniform information queries with glGetUniformIndices() and glGetActiveUniforms()");
2484 success = this.getActiveUniforms(basicUniformReportsUniforms, basicUniformReportsRef, programGL);
2487 if (this.m_caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV)
2491 this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY,
2492 'es3fUniformApiTests.UniformInfoQueryCase.prototype.test - case type is not consistency',
2496 bufferedLogToConsole('// Note: this is a consistency case, so ignoring above failure(s)');
2501 if (this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) {
2504 //TODO: const ScopedLogSection section(log, "CompareUniformVsUniforms", "Comparison of results from glGetActiveUniform() and glGetActiveUniforms()");
2505 success = this.uniformVsUniformsComparison(basicUniformReportsUniform, basicUniformReportsUniforms);
2517 es3fUniformApiTests.ValueToCheck = {
2518 INITIAL: 0, //!< Verify the initial values of the uniforms (i.e. check that they're zero).
2519 ASSIGNED: 1 //!< Assign values to uniforms with glUniform*(), and check those.
2525 es3fUniformApiTests.CheckMethod = {
2526 GET_UNIFORM: 0, //!< Check values with glGetUniform*().
2527 RENDER: 1 //!< Check values by rendering with the value-checking shader.
2533 es3fUniformApiTests.AssignMethod = {
2539 * es3fUniformApiTests.UniformValueCase test class
2541 * @param {string} name
2542 * @param {string} description
2543 * @param {es3fUniformApiTests.CaseShaderType} shaderType
2544 * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
2545 * @param {es3fUniformApiTests.ValueToCheck} valueToCheck
2546 * @param {es3fUniformApiTests.CheckMethod} checkMethod
2547 * @param {?es3fUniformApiTests.AssignMethod} assignMethod
2548 * @param {es3fUniformApiTests.Feature} additionalFeatures
2549 * @extends {es3fUniformApiTests.UniformCase}
2551 es3fUniformApiTests.UniformValueCase = function(name, description, shaderType, uniformCollection, valueToCheck, checkMethod, assignMethod, additionalFeatures) {
2552 es3fUniformApiTests.UniformCase.call(this, name, description);
2554 additionalFeatures.UNIFORMVALUE_ZERO |= valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL;
2555 additionalFeatures.UNIFORMFUNC_VALUE |= assignMethod == es3fUniformApiTests.AssignMethod.VALUE;
2556 this.newB(shaderType, uniformCollection, additionalFeatures);
2558 this.m_valueToCheck = valueToCheck;
2559 this.m_checkMethod = checkMethod;
2562 !(assignMethod === undefined && valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED),
2563 'es3fUniformApiTests.UniformValueCase - assign method is undefined when value to check requires it',
2569 es3fUniformApiTests.UniformValueCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype);
2570 /** Constructor restore */
2571 es3fUniformApiTests.UniformValueCase.prototype.constructor = es3fUniformApiTests.UniformValueCase;
2574 * @param {es3fUniformApiTests.ValueToCheck} valueToCheck
2577 es3fUniformApiTests.UniformValueCase.getValueToCheckName = function(valueToCheck) {
2578 switch (valueToCheck) {
2579 case es3fUniformApiTests.ValueToCheck.INITIAL: return 'initial';
2580 case es3fUniformApiTests.ValueToCheck.ASSIGNED: return 'assigned';
2581 default: throw new Error('es3fUniformApiTests.UniformValueCase.getValueToCheckName - Invalid value to check option');
2586 * @param {es3fUniformApiTests.ValueToCheck} valueToCheck
2589 es3fUniformApiTests.UniformValueCase.getValueToCheckDescription = function(valueToCheck) {
2590 switch (valueToCheck) {
2591 case es3fUniformApiTests.ValueToCheck.INITIAL: return 'Check initial uniform values (zeros)';
2592 case es3fUniformApiTests.ValueToCheck.ASSIGNED: return 'Check assigned uniform values';
2593 default: throw new Error('es3fUniformApiTests.UniformValueCase.getValueToCheckDescription - Invalid value to check option');
2598 * @param {es3fUniformApiTests.CheckMethod} checkMethod
2601 es3fUniformApiTests.UniformValueCase.getCheckMethodName = function(checkMethod) {
2602 switch (checkMethod) {
2603 case es3fUniformApiTests.CheckMethod.GET_UNIFORM: return 'get_uniform';
2604 case es3fUniformApiTests.CheckMethod.RENDER: return 'render';
2605 default: throw new Error('es3fUniformApiTests.UniformValueCase.getCheckMethodName - Invalid check method');
2610 * @param {es3fUniformApiTests.CheckMethod} checkMethod
2613 es3fUniformApiTests.UniformValueCase.getCheckMethodDescription = function(checkMethod) {
2614 switch (checkMethod) {
2615 case es3fUniformApiTests.CheckMethod.GET_UNIFORM: return 'Verify values with glGetUniform*()';
2616 case es3fUniformApiTests.CheckMethod.RENDER: return 'Verify values by rendering';
2617 default: throw new Error('es3fUniformApiTests.UniformValueCase.getCheckMethodDescription - Invalid check method');
2622 * @param {es3fUniformApiTests.AssignMethod} assignMethod
2625 es3fUniformApiTests.UniformValueCase.getAssignMethodName = function(assignMethod) {
2626 switch (assignMethod) {
2627 case es3fUniformApiTests.AssignMethod.POINTER: return 'by_pointer';
2628 case es3fUniformApiTests.AssignMethod.VALUE: return 'by_value';
2629 default: throw new Error('es3fUniformApiTests.UniformValueCase.getAssignMethodName - Invalid assign method');
2634 * @param {es3fUniformApiTests.AssignMethod} assignMethod
2637 es3fUniformApiTests.UniformValueCase.getAssignMethodDescription = function(assignMethod) {
2638 switch (assignMethod) {
2639 case es3fUniformApiTests.AssignMethod.POINTER: return 'Assign values by-pointer';
2640 case es3fUniformApiTests.AssignMethod.VALUE: return 'Assign values by-value';
2641 default: throw new Error('es3fUniformApiTests.UniformValueCase.getAssignMethodDescription - Invalid assign method');
2646 * es3fUniformApiTests.UniformValueCase test function
2647 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
2648 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
2649 * @param {gluShaderProgram.ShaderProgram} program
2650 * @param {deRandom.Random} rnd
2653 es3fUniformApiTests.UniformValueCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) {
2654 /** @type {WebGLProgram} */ var programGL = program.getProgram();
2656 if (this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED) {
2657 //TODO: const ScopedLogSection section(log, "UniformAssign", "es3fUniformApiTests.Uniform value assignments");
2658 this.assignUniforms(basicUniforms, programGL, rnd);
2661 this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL,
2662 'es3fUniformApiTests.UniformValueCase.prototype.test - value to check not initial',
2666 /** @type {boolean}*/ var success;
2668 if (this.m_checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM) {
2669 /** @type {Array<es3fUniformApiTests.VarValue>} */ var values = [];
2671 //TODO: const ScopedLogSection section(log, "GetUniforms", "es3fUniformApiTests.Uniform value query");
2672 success = this.getUniforms(values, basicUniforms, program.getProgram());
2677 if (this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED) {
2678 //TODO: const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
2679 success = this.compareUniformValues(values, basicUniforms);
2685 this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL,
2686 'es3fUniformApiTests.UniformValueCase.prototype.test - value to check not initial',
2690 //TODO: const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)");
2691 success = this.checkUniformDefaultValues(values, basicUniforms);
2698 this.m_checkMethod == es3fUniformApiTests.CheckMethod.RENDER,
2699 'es3fUniformApiTests.UniformValueCase.prototype.test - check method different than RENDER',
2703 //TODO: const ScopedLogSection section(log, "RenderTest", "Render test");
2704 success = this.renderTest(basicUniforms, program, rnd);
2714 * es3fUniformApiTests.RandomUniformCase test class
2716 * @param {string} name
2717 * @param {string} description
2718 * @param {number} seed
2719 * @extends {es3fUniformApiTests.UniformCase}
2721 es3fUniformApiTests.RandomUniformCase = function(name, description, seed) {
2722 es3fUniformApiTests.UniformCase.call(this, name, description);
2723 this.newC(seed ^ deRandom.getBaseSeed());
2726 es3fUniformApiTests.RandomUniformCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype);
2727 /** Constructor restore */
2728 es3fUniformApiTests.RandomUniformCase.prototype.constructor = es3fUniformApiTests.RandomUniformCase;
2731 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
2732 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
2733 * @param {gluShaderProgram.ShaderProgram} program
2734 * @param {deRandom.Random} rnd
2737 es3fUniformApiTests.RandomUniformCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) {
2738 // \note Different sampler types may not be bound to same unit when rendering.
2739 /** @type {boolean}*/ var renderingPossible = !this.m_features.UNIFORMVALUE_ZERO || !this.m_uniformCollection.containsSeveralSamplerTypes();
2741 /** @type {boolean} */ var performGetActiveUniforms = rnd.getBool();
2742 /** @type {boolean} */ var performGetActiveUniformsiv = rnd.getBool();
2743 /** @type {boolean} */ var performUniformVsUniformsivComparison = performGetActiveUniforms && performGetActiveUniformsiv && rnd.getBool();
2744 /** @type {boolean} */ var performGetUniforms = rnd.getBool();
2745 /** @type {boolean} */ var performCheckUniformDefaultValues = performGetUniforms && rnd.getBool();
2746 /** @type {boolean} */ var performAssignUniforms = rnd.getBool();
2747 /** @type {boolean} */ var performCompareUniformValues = performGetUniforms && performAssignUniforms && rnd.getBool();
2748 /** @type {boolean} */ var performRenderTest = renderingPossible && performAssignUniforms && rnd.getBool();
2749 /** @type {WebGLProgram} */ var programGL = program.getProgram();
2751 if (!(performGetActiveUniforms || performGetActiveUniformsiv || performUniformVsUniformsivComparison || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest))
2752 performGetActiveUniforms = true; // Do something at least.
2754 var PERFORM_AND_CHECK = function(CALL, SECTION_NAME, SECTION_DESCRIPTION) {
2755 //TODO: const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION));
2756 /** @type {boolean} */ var success = CALL();
2761 /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var reportsUniform = [];
2762 /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var reportsUniformsiv = [];
2764 var current = this; //To use "this" in anonymous function.
2766 if (performGetActiveUniforms)
2767 PERFORM_AND_CHECK(function() {current.getActiveUniformsOneByOne(reportsUniform, basicUniformReportsRef, programGL);}, 'InfoGetActiveUniform', 'es3fUniformApiTests.Uniform information queries with glGetActiveUniform()');
2769 if (performGetActiveUniformsiv)
2770 PERFORM_AND_CHECK(function() {current.getActiveUniforms(reportsUniformsiv, basicUniformReportsRef, programGL);}, 'InfoGetActiveUniformsiv', 'es3fUniformApiTests.Uniform information queries with glGetIndices() and glGetActiveUniformsiv()');
2772 if (performUniformVsUniformsivComparison)
2773 PERFORM_AND_CHECK(function() {current.uniformVsUniformsComparison(reportsUniform, reportsUniformsiv);}, 'CompareUniformVsUniformsiv', 'Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()');
2775 /** @type {Array<es3fUniformApiTests.VarValue>} */ var uniformDefaultValues = [];
2777 if (performGetUniforms)
2778 PERFORM_AND_CHECK(function() {current.getUniforms(uniformDefaultValues, basicUniforms, programGL);}, 'GetUniformDefaults', 'es3fUniformApiTests.Uniform default value query');
2780 if (performCheckUniformDefaultValues)
2781 PERFORM_AND_CHECK(function() {current.checkUniformDefaultValues(uniformDefaultValues, basicUniforms);}, 'DefaultValueCheck', 'Verify that the uniforms have correct initial values (zeros)');
2783 /** @type {Array<es3fUniformApiTests.VarValue>} */ var uniformValues = [];
2785 if (performAssignUniforms) {
2786 //TODO: const ScopedLogSection section(log, "UniformAssign", "es3fUniformApiTests.Uniform value assignments");
2787 this.assignUniforms(basicUniforms, programGL, rnd);
2790 if (performCompareUniformValues) {
2791 PERFORM_AND_CHECK(function() {current.getUniforms(uniformValues, basicUniforms, programGL);}, 'GetUniforms', 'es3fUniformApiTests.Uniform value query');
2792 PERFORM_AND_CHECK(function() {current.compareUniformValues(uniformValues, basicUniforms);}, 'ValueCheck', 'Verify that the reported values match the assigned values');
2795 if (performRenderTest)
2796 PERFORM_AND_CHECK(function() {current.renderTest(basicUniforms, program, rnd);}, 'RenderTest', 'Render test');
2802 * Initializes the tests to be performed.
2804 es3fUniformApiTests.init = function() {
2805 var state = tcuTestCase.runner;
2806 var testGroup = state.testCases;
2808 // Generate sets of UniformCollections that are used by several cases.
2812 var UniformCollections = {
2818 NESTED_STRUCTS_ARRAYS: 5,
2820 MULTIPLE_BASIC_ARRAY: 7,
2821 MULTIPLE_NESTED_STRUCTS_ARRAYS: 8
2827 var UniformCollectionGroup = function() {
2828 /** @type {string} */ this.name = '';
2829 /** @type {Array<es3fUniformApiTests.UniformCollectionCase>} */ this.cases = [];
2832 /** @type {Array<UniformCollectionGroup>} */ var defaultUniformCollections = new Array(Object.keys(UniformCollections).length);
2834 /** @type {string} */ var name;
2837 for (var i = 0; i < defaultUniformCollections.length; i++) defaultUniformCollections[i] = new UniformCollectionGroup();
2839 defaultUniformCollections[UniformCollections.BASIC].name = 'basic';
2840 defaultUniformCollections[UniformCollections.BASIC_ARRAY].name = 'basic_array';
2841 defaultUniformCollections[UniformCollections.BASIC_STRUCT].name = 'basic_struct';
2842 defaultUniformCollections[UniformCollections.STRUCT_IN_ARRAY].name = 'struct_in_array';
2843 defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT].name = 'array_in_struct';
2844 defaultUniformCollections[UniformCollections.NESTED_STRUCTS_ARRAYS].name = 'nested_structs_arrays';
2845 defaultUniformCollections[UniformCollections.MULTIPLE_BASIC].name = 'multiple_basic';
2846 defaultUniformCollections[UniformCollections.MULTIPLE_BASIC_ARRAY].name = 'multiple_basic_array';
2847 defaultUniformCollections[UniformCollections.MULTIPLE_NESTED_STRUCTS_ARRAYS].name = 'multiple_nested_structs_arrays';
2849 for (var dataTypeNdx = 0; dataTypeNdx < es3fUniformApiTests.s_testDataTypes.length; dataTypeNdx++) {
2850 /** @type {gluShaderUtil.DataType} */ var dataType = es3fUniformApiTests.s_testDataTypes[dataTypeNdx];
2851 /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(dataType);
2853 defaultUniformCollections[UniformCollections.BASIC].cases.push(new es3fUniformApiTests.UniformCollectionCase(typeName, es3fUniformApiTests.UniformCollection.basic(dataType)));
2855 if (gluShaderUtil.isDataTypeScalar(dataType) ||
2856 (gluShaderUtil.isDataTypeVector(dataType) && gluShaderUtil.getDataTypeScalarSize(dataType) == 4) ||
2857 dataType == gluShaderUtil.DataType.FLOAT_MAT4 ||
2858 dataType == gluShaderUtil.DataType.SAMPLER_2D)
2859 defaultUniformCollections[UniformCollections.BASIC_ARRAY].cases.push(new es3fUniformApiTests.UniformCollectionCase(typeName, es3fUniformApiTests.UniformCollection.basicArray(dataType)));
2861 if (gluShaderUtil.isDataTypeScalar(dataType) ||
2862 dataType == gluShaderUtil.DataType.FLOAT_MAT4 ||
2863 dataType == gluShaderUtil.DataType.SAMPLER_2D) {
2864 /** @type {gluShaderUtil.DataType} */ var secondDataType;
2865 if (gluShaderUtil.isDataTypeScalar(dataType))
2866 secondDataType = gluShaderUtil.getDataTypeVector(dataType, 4);
2867 else if (dataType == gluShaderUtil.DataType.FLOAT_MAT4)
2868 secondDataType = gluShaderUtil.DataType.FLOAT_MAT2;
2869 else if (dataType == gluShaderUtil.DataType.SAMPLER_2D)
2870 secondDataType = gluShaderUtil.DataType.SAMPLER_CUBE;
2873 secondDataType !== undefined,
2874 'es3fUniformApiTests.init - second data type undefined',
2878 /** @type {string} */ var secondTypeName = gluShaderUtil.getDataTypeName(secondDataType);
2879 name = typeName + '_' + secondTypeName;
2881 defaultUniformCollections[UniformCollections.BASIC_STRUCT].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.basicStruct(dataType, secondDataType, false)));
2882 defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.basicStruct(dataType, secondDataType, true)));
2883 defaultUniformCollections[UniformCollections.STRUCT_IN_ARRAY].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.structInArray(dataType, secondDataType, false)));
2884 defaultUniformCollections[UniformCollections.NESTED_STRUCTS_ARRAYS].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.nestedArraysStructs(dataType, secondDataType)));
2887 defaultUniformCollections[UniformCollections.MULTIPLE_BASIC].cases.push(new es3fUniformApiTests.UniformCollectionCase(null, es3fUniformApiTests.UniformCollection.multipleBasic()));
2888 defaultUniformCollections[UniformCollections.MULTIPLE_BASIC_ARRAY].cases.push(new es3fUniformApiTests.UniformCollectionCase(null, es3fUniformApiTests.UniformCollection.multipleBasicArray()));
2889 defaultUniformCollections[UniformCollections.MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push(new es3fUniformApiTests.UniformCollectionCase(null, es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs()));
2891 // Info-query cases (check info returned by e.g. glGetActiveUniforms()).
2894 /** @type {tcuTestCase.DeqpTest} */
2895 var infoQueryGroup = tcuTestCase.newTest('info_query', 'Test uniform info querying functions');
2896 testGroup.addChild(infoQueryGroup);
2898 /** @type {UniformCollectionGroup} */ var collectionGroup;
2899 /** @type {es3fUniformApiTests.UniformCollectionCase} */ var collectionCase;
2900 /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ var uniformCollection;
2901 /** @type {es3fUniformApiTests.Feature} */ var features;
2902 /** @type {tcuTestCase.DeqpTest} */ var collectionTestGroup;
2903 /** @type {string} */ var collName;
2904 /** @type {es3fUniformApiTests.CheckMethod} */ var checkMethod;
2905 /** @type {tcuTestCase.DeqpTest} */ var checkMethodGroup;
2906 /** @type {string} */ var collectionGroupName;
2907 /** @type {boolean} */ var containsBooleans;
2908 /** @type {boolean} */ var varyBoolApiType;
2909 /** @type {number} */ var numBoolVariations;
2910 /** @type {es3fUniformApiTests.Feature} */ var booleanTypeFeat;
2911 /** @type {string} */ var booleanTypeName;
2912 /** @type {tcuTestCase.DeqpTest} */ var unusedUniformsGroup;
2914 /** @type {Array<string>} */ var shaderTypes = Object.keys(es3fUniformApiTests.CaseShaderType);
2916 for (var caseTypeI in es3fUniformApiTests.CaseType) {
2917 /** @type {es3fUniformApiTests.CaseType} */ var caseType = es3fUniformApiTests.CaseType[caseTypeI];
2918 /** @type {tcuTestCase.DeqpTest} */
2919 var caseTypeGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeName(caseType), es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeDescription(caseType));
2920 infoQueryGroup.addChild(caseTypeGroup);
2922 for (var collectionGroupNdx = 0; collectionGroupNdx < Object.keys(UniformCollections).length; collectionGroupNdx++) {
2923 var numArrayFirstElemNameCases = caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV && collectionGroupNdx == UniformCollections.BASIC_ARRAY ? 2 : 1;
2925 for (var referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++) {
2926 collectionGroup = defaultUniformCollections[collectionGroupNdx];
2927 collectionGroupName = collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? '' : '_first_elem_without_brackets');
2928 collectionTestGroup = tcuTestCase.newTest(collectionGroupName, '');
2929 caseTypeGroup.addChild(collectionTestGroup);
2931 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
2932 collectionCase = collectionGroup.cases[collectionNdx];
2934 for (var i = 0; i < shaderTypes.length; i++) {
2935 name = collectionCase.namePrefix + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
2936 uniformCollection = collectionCase.uniformCollection;
2938 features = new es3fUniformApiTests.Feature();
2939 features.ARRAY_FIRST_ELEM_NAME_NO_INDEX = referToFirstArrayElemWithoutIndexI != 0;
2941 collectionTestGroup.addChild(new es3fUniformApiTests.UniformInfoQueryCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, caseType, features));
2947 // Info-querying cases when unused uniforms are present.
2949 unusedUniformsGroup = tcuTestCase.newTest('unused_uniforms', 'Test with unused uniforms');
2950 caseTypeGroup.addChild(unusedUniformsGroup);
2952 collectionGroup = defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT];
2954 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
2955 collectionCase = collectionGroup.cases[collectionNdx];
2956 collName = collectionCase.namePrefix;
2957 uniformCollection = collectionCase.uniformCollection;
2959 for (var i = 0; i < shaderTypes.length; i++) {
2960 name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
2962 features = new es3fUniformApiTests.Feature();
2963 features.UNIFORMUSAGE_EVERY_OTHER = true;
2964 features.ARRAYUSAGE_ONLY_MIDDLE_INDEX = true;
2966 unusedUniformsGroup.addChild(new es3fUniformApiTests.UniformInfoQueryCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, caseType, features));
2971 // Cases testing uniform values.
2973 // Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.
2975 /** @type {tcuTestCase.DeqpTest} */ var initialValuesGroup = tcuTestCase.newTest(
2976 'value.' + es3fUniformApiTests.UniformValueCase.getValueToCheckName(es3fUniformApiTests.ValueToCheck.INITIAL),
2977 es3fUniformApiTests.UniformValueCase.getValueToCheckDescription(es3fUniformApiTests.ValueToCheck.INITIAL));
2978 testGroup.addChild(initialValuesGroup);
2980 for (var checkMethodI in es3fUniformApiTests.CheckMethod) {
2981 checkMethod = es3fUniformApiTests.CheckMethod[checkMethodI];
2982 checkMethodGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformValueCase.getCheckMethodName(checkMethod), es3fUniformApiTests.UniformValueCase.getCheckMethodDescription(checkMethod));
2983 initialValuesGroup.addChild(checkMethodGroup);
2985 for (var collectionGroupNdx = 0; collectionGroupNdx < Object.keys(UniformCollections).length; collectionGroupNdx++) {
2986 collectionGroup = defaultUniformCollections[collectionGroupNdx];
2987 collectionTestGroup = tcuTestCase.newTest(collectionGroup.name, '');
2988 checkMethodGroup.addChild(collectionTestGroup);
2990 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
2991 collectionCase = collectionGroup.cases[collectionNdx];
2992 collName = collectionCase.namePrefix;
2993 uniformCollection = collectionCase.uniformCollection;
2994 containsBooleans = uniformCollection.containsMatchingBasicType(gluShaderUtil.isDataTypeBoolOrBVec);
2995 varyBoolApiType = checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM && containsBooleans &&
2996 (collectionGroupNdx == UniformCollections.BASIC || collectionGroupNdx == UniformCollections.BASIC_ARRAY);
2997 numBoolVariations = varyBoolApiType ? 3 : 1;
2999 if (checkMethod == es3fUniformApiTests.CheckMethod.RENDER && uniformCollection.containsSeveralSamplerTypes())
3000 continue; // \note Samplers' initial API values (i.e. their texture units) are 0, and no two samplers of different types shall have same unit when rendering.
3002 for (var booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++) {
3003 booleanTypeFeat = new es3fUniformApiTests.Feature();
3004 booleanTypeFeat.BOOLEANAPITYPE_INT = booleanTypeI == 1;
3005 booleanTypeFeat.BOOLEANAPITYPE_UINT = booleanTypeI == 2;
3007 booleanTypeName = booleanTypeI == 1 ? 'int' :
3008 booleanTypeI == 2 ? 'uint' :
3010 /** @type {string} */ var nameWithApiType = varyBoolApiType ? collName + 'api_' + booleanTypeName + '_' : collName;
3012 for (var i = 0; i < shaderTypes.length; i++) {
3013 name = nameWithApiType + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
3014 collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
3015 es3fUniformApiTests.ValueToCheck.INITIAL, checkMethod, null, booleanTypeFeat));
3022 // Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.
3024 /** @type {tcuTestCase.DeqpTest} */ var assignedValuesGroup = tcuTestCase.newTest(
3025 'value.' + es3fUniformApiTests.UniformValueCase.getValueToCheckName(es3fUniformApiTests.ValueToCheck.ASSIGNED),
3026 es3fUniformApiTests.UniformValueCase.getValueToCheckDescription(es3fUniformApiTests.ValueToCheck.ASSIGNED));
3027 testGroup.addChild(assignedValuesGroup);
3029 for (var assignMethodI in es3fUniformApiTests.AssignMethod) {
3030 /** @type {es3fUniformApiTests.AssignMethod} */ var assignMethod = es3fUniformApiTests.AssignMethod[assignMethodI];
3031 /** @type {tcuTestCase.DeqpTest} */ var assignMethodGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformValueCase.getAssignMethodName(assignMethod), es3fUniformApiTests.UniformValueCase.getAssignMethodDescription(assignMethod));
3032 assignedValuesGroup.addChild(assignMethodGroup);
3034 for (var checkMethodI in es3fUniformApiTests.CheckMethod) {
3035 checkMethod = es3fUniformApiTests.CheckMethod[checkMethodI];
3036 checkMethodGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformValueCase.getCheckMethodName(checkMethod), es3fUniformApiTests.UniformValueCase.getCheckMethodDescription(checkMethod));
3037 assignMethodGroup.addChild(checkMethodGroup);
3039 for (var collectionGroupNdx = 0; collectionGroupNdx < Object.keys(UniformCollections).length; collectionGroupNdx++) {
3040 /** @type {number} */ var numArrayFirstElemNameCases = checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM && collectionGroupNdx == UniformCollections.BASIC_ARRAY ? 2 : 1;
3042 for (var referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++) {
3043 collectionGroup = defaultUniformCollections[collectionGroupNdx];
3044 collectionGroupName = collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? '' : '_first_elem_without_brackets');
3045 collectionTestGroup = tcuTestCase.newTest(collectionGroupName, '');
3046 checkMethodGroup.addChild(collectionTestGroup);
3048 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
3049 collectionCase = collectionGroup.cases[collectionNdx];
3050 collName = collectionCase.namePrefix;
3051 uniformCollection = collectionCase.uniformCollection;
3052 containsBooleans = uniformCollection.containsMatchingBasicType(gluShaderUtil.isDataTypeBoolOrBVec);
3053 varyBoolApiType = checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM && containsBooleans &&
3054 (collectionGroupNdx == UniformCollections.BASIC || collectionGroupNdx == UniformCollections.BASIC_ARRAY);
3055 numBoolVariations = varyBoolApiType ? 3 : 1;
3056 /** @type {boolean} */ var containsMatrices = uniformCollection.containsMatchingBasicType(gluShaderUtil.isDataTypeMatrix);
3057 /** @type {boolean} */ var varyMatrixMode = containsMatrices &&
3058 (collectionGroupNdx == UniformCollections.BASIC || collectionGroupNdx == UniformCollections.BASIC_ARRAY);
3059 /** @type {number} */ var numMatVariations = varyMatrixMode ? 2 : 1;
3061 if (containsMatrices && assignMethod != es3fUniformApiTests.AssignMethod.POINTER)
3064 for (var booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++) {
3065 booleanTypeFeat = new es3fUniformApiTests.Feature();
3066 booleanTypeFeat.BOOLEANAPITYPE_INT = booleanTypeI == 1;
3067 booleanTypeFeat.BOOLEANAPITYPE_UINT = booleanTypeI == 2;
3069 booleanTypeName = booleanTypeI == 1 ? 'int' :
3070 booleanTypeI == 2 ? 'uint' :
3072 /** @type {string} */ var nameWithBoolType = varyBoolApiType ? collName + 'api_' + booleanTypeName + '_' : collName;
3074 for (var matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++) {
3075 /** @type {string} */ var nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? 'row_major_' : '');
3077 for (var i = 0; i < shaderTypes.length; i++) {
3078 name = nameWithMatrixType + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
3080 booleanTypeFeat.ARRAY_FIRST_ELEM_NAME_NO_INDEX = referToFirstArrayElemWithoutIndexI != 0;
3081 booleanTypeFeat.MATRIXMODE_ROWMAJOR = matrixTypeI == 1;
3083 collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
3084 es3fUniformApiTests.ValueToCheck.ASSIGNED, checkMethod, assignMethod, booleanTypeFeat));
3094 // Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).
3096 /** @type {es3fUniformApiTests.Feature} */ var arrayAssignFullMode = new es3fUniformApiTests.Feature();
3097 arrayAssignFullMode.ARRAYASSIGN_FULL = true;
3099 /** @type {es3fUniformApiTests.Feature} */ var arrayAssignBlocksOfTwo = new es3fUniformApiTests.Feature();
3100 arrayAssignFullMode.ARRAYASSIGN_BLOCKS_OF_TWO = true;
3102 var arrayAssignGroups =
3103 [{arrayAssignMode: arrayAssignFullMode, name: 'basic_array_assign_full', description: 'Assign entire basic-type arrays per glUniform*v() call'}, {arrayAssignMode: arrayAssignBlocksOfTwo, name: 'basic_array_assign_partial', description: 'Assign two elements of a basic-type array per glUniform*v() call'}
3106 for (var arrayAssignGroupNdx = 0; arrayAssignGroupNdx < arrayAssignGroups.length; arrayAssignGroupNdx++) {
3107 /** @type {es3fUniformApiTests.Feature} */ var arrayAssignMode = arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
3108 /** @type {string} */ var groupName = arrayAssignGroups[arrayAssignGroupNdx].name;
3109 /** @type {string} */ var groupDesc = arrayAssignGroups[arrayAssignGroupNdx].description;
3111 /** @type {tcuTestCase.DeqpTest} */ var curArrayAssignGroup = tcuTestCase.newTest(groupName, groupDesc);
3112 assignedValuesGroup.addChild(curArrayAssignGroup);
3114 /** @type {Array<number>} */ var basicArrayCollectionGroups = [UniformCollections.BASIC_ARRAY, UniformCollections.ARRAY_IN_STRUCT, UniformCollections.MULTIPLE_BASIC_ARRAY];
3116 for (var collectionGroupNdx = 0; collectionGroupNdx < basicArrayCollectionGroups.length; collectionGroupNdx++) {
3117 collectionGroup = defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
3118 collectionTestGroup = tcuTestCase.newTest(collectionGroup.name, '');
3119 curArrayAssignGroup.addChild(collectionTestGroup);
3121 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
3122 collectionCase = collectionGroup.cases[collectionNdx];
3123 collName = collectionCase.namePrefix;
3124 uniformCollection = collectionCase.uniformCollection;
3126 for (var i = 0; i < shaderTypes.length; i++) {
3127 name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
3128 collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
3129 es3fUniformApiTests.ValueToCheck.ASSIGNED, es3fUniformApiTests.CheckMethod.GET_UNIFORM, es3fUniformApiTests.AssignMethod.POINTER,
3136 // Value checking cases when unused uniforms are present.
3138 unusedUniformsGroup = tcuTestCase.newTest('unused_uniforms', 'Test with unused uniforms');
3139 assignedValuesGroup.addChild(unusedUniformsGroup);
3141 collectionGroup = defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT];
3143 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
3144 collectionCase = collectionGroup.cases[collectionNdx];
3145 collName = collectionCase.namePrefix;
3146 uniformCollection = collectionCase.uniformCollection;
3148 for (var i = 0; i < shaderTypes.length; i++) {
3149 name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
3151 features = new es3fUniformApiTests.Feature();
3152 features.ARRAYUSAGE_ONLY_MIDDLE_INDEX = true;
3153 features.UNIFORMUSAGE_EVERY_OTHER = true;
3155 unusedUniformsGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
3156 es3fUniformApiTests.ValueToCheck.ASSIGNED, es3fUniformApiTests.CheckMethod.GET_UNIFORM, es3fUniformApiTests.AssignMethod.POINTER,
3163 /** @type {number} */ var numRandomCases = 100;
3164 /** @type {tcuTestCase.DeqpTest} */ var randomGroup = tcuTestCase.newTest('random', 'Random cases');
3165 testGroup.addChild(randomGroup);
3167 for (var ndx = 0; ndx < numRandomCases; ndx++)
3168 randomGroup.addChild(new es3fUniformApiTests.RandomUniformCase('' + ndx, '', ndx));
3172 * Create and execute the test cases
3173 * @param {WebGL2RenderingContext} context
3175 es3fUniformApiTests.run = function(context, range) {
3177 //Set up Test Root parameters
3178 var testName = 'uniform_api';
3179 var testDescription = 'es3fUniformApiTests.Uniform API Tests';
3180 var state = tcuTestCase.runner;
3182 state.testName = testName;
3183 state.testCases = tcuTestCase.newTest(testName, testDescription, null);
3185 //Set up name and description of this test series.
3186 setCurrentTestName(testName);
3187 description(testDescription);
3191 es3fUniformApiTests.init();
3193 state.setRange(range);
3195 tcuTestCase.runTestCases();
3198 testFailedOptions('Failed to es3fUniformApiTests.run tests', false);
3199 tcuTestCase.runner.terminate();