es3fUniformApiTests.js (165934B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 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 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 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. 18 * 19 */ 20 21 'use strict'; 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'); 34 35 goog.scope(function() { 36 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; 49 50 /** @type {WebGL2RenderingContext} */ var gl; 51 52 /** @typedef {function(gluShaderUtil.DataType): boolean} */ 53 es3fUniformApiTests.dataTypePredicate; 54 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; 58 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, 73 74 gluShaderUtil.DataType.INT, 75 gluShaderUtil.DataType.INT_VEC2, 76 gluShaderUtil.DataType.INT_VEC3, 77 gluShaderUtil.DataType.INT_VEC4, 78 79 gluShaderUtil.DataType.UINT, 80 gluShaderUtil.DataType.UINT_VEC2, 81 gluShaderUtil.DataType.UINT_VEC3, 82 gluShaderUtil.DataType.UINT_VEC4, 83 84 gluShaderUtil.DataType.BOOL, 85 gluShaderUtil.DataType.BOOL_VEC2, 86 gluShaderUtil.DataType.BOOL_VEC3, 87 gluShaderUtil.DataType.BOOL_VEC4, 88 89 gluShaderUtil.DataType.SAMPLER_2D, 90 gluShaderUtil.DataType.SAMPLER_CUBE 91 // \note We don't test all sampler types here. 92 ]; 93 94 /** 95 * Returns a substring from the beginning to the last occurence of the 96 * specified character 97 * @param {string} str The string in which to search 98 * @param {string} c A single character 99 * @return {string} 100 */ 101 es3fUniformApiTests.beforeLast = function(str, c) { 102 return str.substring(0, str.lastIndexOf(c)); 103 }; 104 105 /** 106 * es3fUniformApiTests.fillWithColor 107 * @param {tcuTexture.PixelBufferAccess} access , 108 * @param {Array<number>} color Array of four color components. 109 */ 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); 115 }; 116 117 /** 118 * @param {gluShaderUtil.DataType} type 119 * @return {number} 120 */ 121 es3fUniformApiTests.getSamplerNumLookupDimensions = function(type) { 122 switch (type) { 123 case gluShaderUtil.DataType.SAMPLER_2D: 124 case gluShaderUtil.DataType.INT_SAMPLER_2D: 125 case gluShaderUtil.DataType.UINT_SAMPLER_2D: 126 return 2; 127 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: 138 return 3; 139 140 case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW: 141 case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW: 142 return 4; 143 144 default: 145 throw new Error('es3fUniformApiTests.getSamplerNumLookupDimensions - Invalid type'); 146 } 147 }; 148 149 /** 150 * @param {gluShaderUtil.DataType} type 151 * @return {gluShaderUtil.DataType} 152 */ 153 es3fUniformApiTests.getSamplerLookupReturnType = function(type) { 154 switch (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; 160 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; 166 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; 172 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; 177 178 default: 179 throw new Error('es3fUniformApiTests.getSamplerLookupReturnType - Invalid type'); 180 } 181 }; 182 183 /** 184 * @param {gluShaderUtil.DataType} T DataType to compare the type. Used to be a template param 185 * @param {gluShaderUtil.DataType} t 186 * @return {boolean} 187 */ 188 es3fUniformApiTests.dataTypeEquals = function(T, t) { 189 return t == T; 190 }; 191 192 /** 193 * @param {number} N Row number. Used to be a template parameter 194 * @param {gluShaderUtil.DataType} t 195 * @return {boolean} 196 */ 197 es3fUniformApiTests.dataTypeIsMatrixWithNRows = function(N, t) { 198 return gluShaderUtil.isDataTypeMatrix(t) && gluShaderUtil.getDataTypeMatrixNumRows(t) == N; 199 }; 200 201 /** 202 * @param {gluVarType.VarType} type 203 * @param {es3fUniformApiTests.dataTypePredicate} predicate 204 * @return {boolean} 205 */ 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); 211 else { 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)) 216 return true; 217 return false; 218 } 219 }; 220 221 /** 222 * @param {Array<gluShaderUtil.DataType>} dst 223 * @param {gluVarType.VarType} type 224 */ 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) 229 dst.push(basicType); 230 } else if (type.isArrayType()) 231 es3fUniformApiTests.getDistinctSamplerTypes(dst, type.getElementType()); 232 else { 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()); 237 } 238 }; 239 240 /** 241 * @param {gluVarType.VarType} type 242 * @return {number} 243 */ 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(); 249 else { 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()); 255 return sum; 256 } 257 }; 258 259 /** @typedef { {type: gluVarType.VarType, ndx: number}} */ 260 es3fUniformApiTests.VarTypeWithIndex; 261 262 /** 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} 268 */ 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; 272 273 if (isStruct) { 274 /** @type {number} */ var numMembers = rnd.getInt(1, 5); 275 /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + curStructIdx++); 276 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); 281 } 282 283 structTypesDst.push(structType); 284 return (isArray ? { 285 type: gluVarType.newTypeArray(gluVarType.newTypeStruct(structType), rnd.getInt(1, 5)), 286 ndx: curStructIdx 287 } 288 : { 289 type: gluVarType.newTypeStruct(structType), 290 ndx: curStructIdx 291 }); 292 } else { 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; 297 return (isArray ? { 298 type: gluVarType.newTypeArray(gluVarType.newTypeBasic(basicType, precision), rnd.getInt(1, 5)), 299 ndx: curStructIdx 300 } 301 : { 302 type: gluVarType.newTypeBasic(basicType, precision), 303 ndx: curStructIdx 304 }); 305 } 306 }; 307 308 /** 309 * es3fUniformApiTests.SamplerV structure 310 * @constructor 311 */ 312 es3fUniformApiTests.SamplerV = function() { 313 this.samplerV = { 314 /** @type {number} */ unit: 0, 315 /** @type {Array<number>} */ fillColor: [] 316 }; 317 }; 318 319 /** 320 * es3fUniformApiTests.VarValue class. may contain different types. 321 * @constructor 322 */ 323 es3fUniformApiTests.VarValue = function() { 324 /** @type {gluShaderUtil.DataType} */ this.type; 325 /** @type {Array<number | boolean> | es3fUniformApiTests.SamplerV} */ this.val = []; 326 }; 327 328 /** 329 * @enum {number} 330 */ 331 es3fUniformApiTests.CaseShaderType = { 332 VERTEX: 0, 333 FRAGMENT: 1, 334 BOTH: 2 335 }; 336 337 /** 338 * es3fUniformApiTests.Uniform struct. 339 * @param {string} name_ 340 * @param {gluVarType.VarType} type_ 341 * @constructor 342 */ 343 es3fUniformApiTests.Uniform = function(name_, type_) { 344 /** @type {string} */ this.name = name_; 345 /** @type {gluVarType.VarType} */ this.type = type_; 346 }; 347 348 // A set of uniforms, along with related struct types. 349 /** 350 * class es3fUniformApiTests.UniformCollection 351 * @constructor 352 */ 353 es3fUniformApiTests.UniformCollection = function() { 354 /** @type {Array<es3fUniformApiTests.Uniform>} */ this.m_uniforms = []; 355 /** @type {Array<gluVarType.StructType>} */ this.m_structTypes = []; 356 }; 357 358 /** 359 * @return {number} 360 */ 361 es3fUniformApiTests.UniformCollection.prototype.getNumUniforms = function() {return this.m_uniforms.length;}; 362 363 /** 364 * @return {number} 365 */ 366 es3fUniformApiTests.UniformCollection.prototype.getNumStructTypes = function() {return this.m_structTypes.length;}; 367 368 /** 369 * @param {number} ndx 370 * @return {es3fUniformApiTests.Uniform} 371 */ 372 es3fUniformApiTests.UniformCollection.prototype.getUniform = function(ndx) {return this.m_uniforms[ndx];}; 373 374 /** 375 * @param {number} ndx 376 * @return {gluVarType.StructType} 377 */ 378 es3fUniformApiTests.UniformCollection.prototype.getStructType = function(ndx) {return this.m_structTypes[ndx];}; 379 380 /** 381 * @param {es3fUniformApiTests.Uniform} uniform 382 */ 383 es3fUniformApiTests.UniformCollection.prototype.addUniform = function(uniform) {this.m_uniforms.push(uniform);}; 384 385 /** 386 * @param {gluVarType.StructType} type 387 */ 388 es3fUniformApiTests.UniformCollection.prototype.addStructType = function(type) {this.m_structTypes.push(type);}; 389 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. 392 /** 393 * @param {es3fUniformApiTests.UniformCollection} receiver 394 */ 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; 399 400 for (var i = 0; i < this.m_structTypes.length; i++) 401 receiver.addStructType(this.m_structTypes[i]); 402 this.m_structTypes.length = 0; 403 }; 404 405 /** 406 * @param {es3fUniformApiTests.dataTypePredicate} predicate 407 * @return {boolean} 408 */ 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)) 412 return true; 413 return false; 414 }; 415 416 /** 417 * @return {Array<gluShaderUtil.DataType>} 418 */ 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); 423 return samplerTypes; 424 }; 425 426 /** 427 * @return {boolean} 428 */ 429 es3fUniformApiTests.UniformCollection.prototype.containsSeveralSamplerTypes = function() { 430 return this.getSamplerTypes().length > 1; 431 }; 432 433 /** 434 * @return {number} 435 */ 436 es3fUniformApiTests.UniformCollection.prototype.getNumSamplers = function() { 437 var sum = 0; 438 for (var i = 0; i < this.m_uniforms.length; i++) 439 sum += es3fUniformApiTests.getNumSamplersInType(this.m_uniforms[i].type); 440 return sum; 441 }; 442 443 /** 444 * @param {gluShaderUtil.DataType} type 445 * @param {string=} nameSuffix 446 * @return {es3fUniformApiTests.UniformCollection} 447 */ 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))); 455 return res; 456 }; 457 458 /** 459 * @param {gluShaderUtil.DataType} type 460 * @param {string=} nameSuffix 461 * @return {es3fUniformApiTests.UniformCollection} 462 */ 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))); 470 return res; 471 }; 472 473 /** 474 * @param {gluShaderUtil.DataType} type0 475 * @param {gluShaderUtil.DataType} type1 476 * @param {boolean} containsArrays 477 * @param {string=} nameSuffix 478 * @return {es3fUniformApiTests.UniformCollection} 479 */ 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; 489 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)); 496 } 497 498 res.addStructType(structType); 499 res.addUniform(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeStruct(structType))); 500 501 return res; 502 }; 503 504 /** 505 * @param {gluShaderUtil.DataType} type0 506 * @param {gluShaderUtil.DataType} type1 507 * @param {boolean} containsArrays 508 * @param {string=} nameSuffix 509 * @return {es3fUniformApiTests.UniformCollection} 510 */ 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); 515 return res; 516 }; 517 518 /** 519 * @param {gluShaderUtil.DataType} type0 520 * @param {gluShaderUtil.DataType} type1 521 * @param {string=} nameSuffix 522 * @return {es3fUniformApiTests.UniformCollection} 523 */ 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); 536 537 subSubStructType.addMember('mss0', gluVarType.newTypeBasic(type0, prec0)); 538 subSubStructType.addMember('mss1', gluVarType.newTypeBasic(type1, prec1)); 539 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)); 543 544 structType.addMember('m0', gluVarType.newTypeBasic(type0, prec0)); 545 structType.addMember('m1', gluVarType.newTypeStruct(subStructType)); 546 structType.addMember('m2', gluVarType.newTypeBasic(type1, prec1)); 547 548 res.addStructType(subSubStructType); 549 res.addStructType(subStructType); 550 res.addStructType(structType); 551 552 res.addUniform(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeStruct(structType))); 553 554 return res; 555 }; 556 557 /** 558 * @param {string=} nameSuffix 559 * @return {es3fUniformApiTests.UniformCollection} 560 */ 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(); 565 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); 569 } 570 571 return res; 572 }; 573 574 /** 575 * @param {string=} nameSuffix 576 * @return {es3fUniformApiTests.UniformCollection} 577 */ 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(); 582 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); 586 } 587 588 return res; 589 }; 590 591 /** 592 * @param {string=} nameSuffix 593 * @return {es3fUniformApiTests.UniformCollection} 594 */ 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(); 600 601 assertMsgOptions(types0.length == types1.length, 'es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs - lengths are not the same', false, true); 602 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); 606 } 607 608 return res; 609 }; 610 611 /** 612 * @param {number} seed 613 * @return {es3fUniformApiTests.UniformCollection} 614 */ 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(); 620 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()); 624 625 // \note Discard uniforms that would cause number of samplers to exceed es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS. 626 do { 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); 631 632 res.addUniform(uniform); 633 for (var j = 0; j < structTypes.length; j++) 634 res.addStructType(structTypes[j]); 635 } 636 637 return res; 638 }; 639 640 /** 641 * @param {es3fUniformApiTests.VarValue} sampler 642 * @return {es3fUniformApiTests.VarValue} 643 */ 644 es3fUniformApiTests.getSamplerFillValue = function(sampler) { 645 assertMsgOptions(gluShaderUtil.isDataTypeSampler(sampler.type), 'es3fUniformApiTests.getSamplerFillValue - not a sampler type', false, true); 646 647 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue(); 648 result.type = es3fUniformApiTests.getSamplerLookupReturnType(sampler.type); 649 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]; 654 break; 655 case gluShaderUtil.DataType.UINT_VEC4: 656 for (var i = 0; i < 4; i++) 657 result.val[i] = sampler.val.samplerV.fillColor[i]; 658 break; 659 case gluShaderUtil.DataType.INT_VEC4: 660 for (var i = 0; i < 4; i++) 661 result.val[i] = sampler.val.samplerV.fillColor[i]; 662 break; 663 case gluShaderUtil.DataType.FLOAT: 664 result.val[0] = sampler.val.samplerV.fillColor[0]; 665 break; 666 default: 667 throw new Error('es3fUniformApiTests.getSamplerFillValue - Invalid type'); 668 } 669 670 return result; 671 }; 672 673 /** 674 * @param {es3fUniformApiTests.VarValue} sampler 675 * @return {es3fUniformApiTests.VarValue} 676 */ 677 es3fUniformApiTests.getSamplerUnitValue = function(sampler) { 678 assertMsgOptions(gluShaderUtil.isDataTypeSampler(sampler.type), 'es3fUniformApiTests.getSamplerUnitValue - not a sampler type', false, true); 679 680 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue(); 681 result.type = gluShaderUtil.DataType.INT; 682 result.val[0] = sampler.val.samplerV.unit; 683 684 return result; 685 }; 686 687 /** 688 * @param {gluShaderUtil.DataType} original 689 * @return {gluShaderUtil.DataType} 690 */ 691 es3fUniformApiTests.getDataTypeTransposedMatrix = function(original) { 692 return gluShaderUtil.getDataTypeMatrix(gluShaderUtil.getDataTypeMatrixNumRows(original), gluShaderUtil.getDataTypeMatrixNumColumns(original)); 693 }; 694 695 /** 696 * @param {es3fUniformApiTests.VarValue} original 697 * @return {es3fUniformApiTests.VarValue} 698 */ 699 es3fUniformApiTests.getTransposeMatrix = function(original) { 700 assertMsgOptions(gluShaderUtil.isDataTypeMatrix(original.type), 'es3fUniformApiTests.getTransposeMatrix - not a matrix', false, true); 701 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); 706 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]; 710 711 return result; 712 }; 713 714 /** 715 * @param {es3fUniformApiTests.VarValue} value 716 * @return {string} 717 */ 718 es3fUniformApiTests.shaderVarValueStr = function(value) { 719 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(value.type); 720 /** @type {string} */ var result = ''; 721 722 if (numElems > 1) 723 result += gluShaderUtil.getDataTypeName(value.type) + '('; 724 725 for (var i = 0; i < numElems; i++) { 726 if (i > 0) 727 result += ', '; 728 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)); 739 else 740 throw new Error('es3fUniformApiTests.shaderVarValueStr - invalid type'); 741 } 742 743 if (numElems > 1) 744 result += ')'; 745 746 return result; 747 }; 748 749 /** 750 * @param {es3fUniformApiTests.VarValue} value 751 * @return {string} 752 */ 753 es3fUniformApiTests.apiVarValueStr = function(value) { 754 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(value.type); 755 /** @type {string} */ var result = ''; 756 757 if (numElems > 1) 758 result += '('; 759 760 for (var i = 0; i < numElems; i++) { 761 if (i > 0) 762 result += ', '; 763 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; 773 else 774 throw new Error('es3fUniformApiTests.apiVarValueStr - Invalid type'); 775 } 776 777 if (numElems > 1) 778 result += ')'; 779 780 return result; 781 }; 782 783 // samplerUnit used if type is a sampler type. \note Samplers' unit numbers are not randomized. 784 /** 785 * @param {gluShaderUtil.DataType} type 786 * @param {deRandom.Random} rnd 787 * @param {number=} samplerUnit 788 * @return {es3fUniformApiTests.VarValue} 789 */ 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(); 794 result.type = type; 795 796 assertMsgOptions( 797 (samplerUnit >= 0) == (gluShaderUtil.isDataTypeSampler(type)), 798 'es3fUniformApiTests.generateRandomVarValue - sampler units do not match type', false, true 799 ); 800 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); 817 818 result.val = new es3fUniformApiTests.SamplerV(); 819 result.val.samplerV.unit = samplerUnit; 820 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; 826 default: 827 throw new Error('es3fUniformApiTests.generateRandomVarValue - Invalid scalar type'); 828 } 829 } 830 } else 831 throw new Error('es3fUniformApiTests.generateRandomVarValue - Invalid type'); 832 833 return result; 834 }; 835 836 /** 837 * @param {gluShaderUtil.DataType} type 838 * @return {es3fUniformApiTests.VarValue} 839 */ 840 es3fUniformApiTests.generateZeroVarValue = function(type) { 841 /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(type); 842 /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue(); 843 result.type = type; 844 845 if (gluShaderUtil.isDataTypeFloatOrVec(type) || gluShaderUtil.isDataTypeMatrix(type)) { 846 for (var i = 0; i < numElems; i++) 847 result.val[i] = 0.0; 848 } else if (gluShaderUtil.isDataTypeIntOrIVec(type)) { 849 for (var i = 0; i < numElems; i++) 850 result.val[i] = 0; 851 } else if (gluShaderUtil.isDataTypeUintOrUVec(type)) { 852 for (var i = 0; i < numElems; i++) 853 result.val[i] = 0; 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); 861 862 result.val = new es3fUniformApiTests.SamplerV(); 863 result.val.samplerV.unit = 0; 864 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; 870 default: 871 throw new Error('es3fUniformApiTests.generateZeroVarValue - Invalid scalar type'); 872 } 873 } 874 } else 875 throw new Error('es3fUniformApiTests.generateZeroVarValue - Invalid type'); 876 877 return result; 878 }; 879 880 /** 881 * @param {es3fUniformApiTests.VarValue} a 882 * @param {es3fUniformApiTests.VarValue} b 883 * @return {boolean} 884 */ 885 es3fUniformApiTests.apiVarValueEquals = function(a, b) { 886 /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(a.type); 887 /** @type {number} */ var floatThreshold = 0.05; 888 889 assertMsgOptions(a.type == b.type, 'es3fUniformApiTests.apiVarValueEquals - types are different', false, true); 890 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) 894 return false; 895 } else if (gluShaderUtil.isDataTypeIntOrIVec(a.type)) { 896 for (var i = 0; i < size; i++) 897 if (a.val[i] != b.val[i]) 898 return false; 899 } else if (gluShaderUtil.isDataTypeUintOrUVec(a.type)) { 900 for (var i = 0; i < size; i++) 901 if (a.val[i] != b.val[i]) 902 return false; 903 } else if (gluShaderUtil.isDataTypeBoolOrBVec(a.type)) { 904 for (var i = 0; i < size; i++) 905 if (a.val[i] != b.val[i]) 906 return false; 907 } else if (gluShaderUtil.isDataTypeSampler(a.type)) { 908 if (a.val.samplerV.unit != b.val.samplerV.unit) 909 return false; 910 } else 911 throw new Error('es3fUniformApiTests.apiVarValueEquals - Invalid type'); 912 913 return true; 914 }; 915 916 /** 917 * @param {es3fUniformApiTests.VarValue} boolValue 918 * @param {gluShaderUtil.DataType} targetScalarType 919 * @param {deRandom.Random} rnd 920 * @return {es3fUniformApiTests.VarValue} 921 */ 922 es3fUniformApiTests.getRandomBoolRepresentation = function(boolValue, targetScalarType, rnd) { 923 assertMsgOptions( 924 gluShaderUtil.isDataTypeBoolOrBVec(boolValue.type), 925 'es3fUniformApiTests.getRandomBoolRepresentation - Data type not boolean or boolean vector', 926 false, 927 true 928 ); 929 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; 934 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) 941 result.val[i] = 1; 942 } else 943 result.val[i] = 0; 944 } 945 break; 946 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); 951 else 952 result.val[i] = 0; 953 } 954 break; 955 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) 961 result.val[i] = 1.0; 962 } else 963 result.val[i] = 0; 964 } 965 break; 966 967 default: 968 throw new Error('es3fUniformApiTests.getRandomBoolRepresentation - Invalid type'); 969 } 970 971 return result; 972 }; 973 974 /** 975 * @param {es3fUniformApiTests.CaseShaderType} type 976 * @return {?string} 977 */ 978 es3fUniformApiTests.getCaseShaderTypeName = function(type) { 979 switch (type) { 980 case es3fUniformApiTests.CaseShaderType.VERTEX: return 'vertex'; 981 case es3fUniformApiTests.CaseShaderType.FRAGMENT: return 'fragment'; 982 case es3fUniformApiTests.CaseShaderType.BOTH: return 'both'; 983 default: 984 throw new Error('es3fUniformApiTests.getCaseShaderTypeName - Invalid shader type'); 985 } 986 }; 987 988 /** 989 * @param {number} seed 990 * @return {number} 991 */ 992 es3fUniformApiTests.randomCaseShaderType = function(seed) { 993 return (new deRandom.Random(seed)).getInt(0, Object.keys(es3fUniformApiTests.CaseShaderType).length - 1); 994 }; 995 996 //es3fUniformApiTests.UniformCase definitions 997 998 /** 999 * es3fUniformApiTests.Feature - Implemented as a function to create an object without unwanted properties. 1000 * @constructor 1001 */ 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; 1005 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; 1008 1009 // MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major. 1010 this.MATRIXMODE_ROWMAJOR = false; 1011 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*(). 1015 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; 1018 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; 1022 1023 // UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values. 1024 this.UNIFORMVALUE_ZERO = false; 1025 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; 1028 }; 1029 1030 // A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d). 1031 /** 1032 * @constructor 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_ 1040 */ 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. 1046 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. 1050 }; 1051 1052 /** 1053 * @param {Array<es3fUniformApiTests.BasicUniform>} vec 1054 * @param {string} name 1055 * @return {es3fUniformApiTests.BasicUniform} 1056 */ 1057 es3fUniformApiTests.BasicUniform.findWithName = function(vec, name) { 1058 for (var i = 0; i < vec.length; i++) { 1059 if (vec[i].name == name) 1060 return vec[i]; 1061 } 1062 return null; 1063 }; 1064 1065 // Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniforms(). 1066 /** 1067 * @constructor 1068 * @param {string} name_ 1069 * @param {gluShaderUtil.DataType} type_ 1070 * @param {boolean} used 1071 */ 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; 1079 }; 1080 1081 /** 1082 * To be used after constructor 1083 * @param {number} minS 1084 * @param {number} maxS 1085 * @return {es3fUniformApiTests.BasicUniformReportRef} 1086 */ 1087 es3fUniformApiTests.BasicUniformReportRef.prototype.constructor_A = function(minS, maxS) { 1088 this.minSize = minS; 1089 this.maxSize = maxS; 1090 1091 assertMsgOptions( 1092 this.minSize <= this.maxSize, 1093 'es3fUniformApiTests.BasicUniformReportRef.prototype.constructor_A - min size not smaller or equal than max size', 1094 false, 1095 true 1096 ); 1097 1098 return this; 1099 }; 1100 1101 // Info that is actually reported by glGetActiveUniform() or glGetActiveUniforms(). 1102 /** 1103 * @constructor 1104 * @param {string} name_ 1105 * @param {number} nameLength_ 1106 * @param {number} size_ 1107 * @param {gluShaderUtil.DataType} type_ 1108 * @param {number} index_ 1109 */ 1110 es3fUniformApiTests.BasicUniformReportGL = function(name_, nameLength_, size_, type_, index_) { 1111 this.name = name_; 1112 this.nameLength = nameLength_; 1113 this.size = size_; 1114 this.type = type_; 1115 this.index = index_; 1116 }; 1117 1118 /** 1119 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} vec 1120 * @param {string} name 1121 * @return {es3fUniformApiTests.BasicUniformReportGL} 1122 */ 1123 es3fUniformApiTests.BasicUniformReportGL.findWithName = function(vec, name) { 1124 for (var i = 0; i < vec.length; i++) { 1125 if (vec[i].name == name) 1126 return vec[i]; 1127 } 1128 return null; 1129 }; 1130 1131 /** 1132 * es3fUniformApiTests.UniformCase class, inherits from TestCase class 1133 * @constructor 1134 * @param {string} name 1135 * @param {string} description 1136 * @extends {tcuTestCase.DeqpTest} 1137 */ 1138 es3fUniformApiTests.UniformCase = function(name, description) { // \note Randomizes caseType, uniformCollection and features. 1139 tcuTestCase.DeqpTest.call(this, name, description); 1140 1141 /** @type {es3fUniformApiTests.Feature} */ this.m_features; 1142 /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ this.m_uniformCollection; 1143 1144 /** @type {number} */ this.m_caseShaderType = 0; 1145 1146 /** @type {Array<gluTexture.Texture2D>} */ this.m_textures2d = []; 1147 /** @type {Array<gluTexture.TextureCube>} */ this.m_texturesCube = []; 1148 /** @type {Array<number>} */ this.m_filledTextureUnits = []; 1149 }; 1150 1151 es3fUniformApiTests.UniformCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 1152 /** es3fUniformApiTests.UniformCase prototype restore */ 1153 es3fUniformApiTests.UniformCase.prototype.constructor = es3fUniformApiTests.UniformCase; 1154 1155 /** 1156 * es3fUniformApiTests.UniformCase newC. Creates a es3fUniformApiTests.UniformCase. Use after constructor. 1157 * @param {number} seed 1158 * @return {es3fUniformApiTests.UniformCase} 1159 */ 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); 1164 1165 return this; 1166 }; 1167 1168 /** 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} 1174 */ 1175 es3fUniformApiTests.UniformCase.new_C = function(name, description, seed) { 1176 var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newC(seed); 1177 1178 return uniformCase; 1179 }; 1180 1181 /** 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} 1187 */ 1188 es3fUniformApiTests.UniformCase.prototype.newB = function(caseShaderType, uniformCollection, features) { 1189 this.m_caseShaderType = caseShaderType; 1190 this.m_uniformCollection = uniformCollection; 1191 this.m_features = features; 1192 1193 return this; 1194 }; 1195 1196 /** 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} 1204 */ 1205 es3fUniformApiTests.UniformCase.new_B = function(name, description, caseShaderType, uniformCollection, features) { 1206 var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newB(caseShaderType, uniformCollection, features); 1207 1208 return uniformCase; 1209 }; 1210 1211 /** 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} 1216 */ 1217 es3fUniformApiTests.UniformCase.prototype.newA = function(caseShaderType, uniformCollection) { 1218 this.m_caseShaderType = caseShaderType; 1219 this.m_uniformCollection = uniformCollection; 1220 this.m_features = null; 1221 1222 return this; 1223 }; 1224 1225 /** 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} 1232 */ 1233 es3fUniformApiTests.UniformCase.new_A = function(name, description, caseShaderType, uniformCollection) { 1234 var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newA(caseShaderType, uniformCollection); 1235 1236 return uniformCase; 1237 }; 1238 1239 /** 1240 * @param {number} seed 1241 * @return {es3fUniformApiTests.Feature} 1242 */ 1243 es3fUniformApiTests.UniformCase.prototype.randomFeatures = function(seed) { 1244 /** @type {es3fUniformApiTests.Feature} */ var result = new es3fUniformApiTests.Feature(); 1245 1246 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(seed); 1247 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(); 1257 1258 return result; 1259 }; 1260 1261 /** 1262 * Initialize the es3fUniformApiTests.UniformCase 1263 */ 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)); 1272 1273 assertMsgOptions( 1274 numSamplerUniforms <= es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS, 1275 'es3fUniformApiTests.UniformCase.prototype.init - sampler uniforms exceed MAX_NUM_SAMPLER_UNIFORMS', 1276 false, 1277 true 1278 ); 1279 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); 1286 }; 1287 1288 /** 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 1297 */ 1298 es3fUniformApiTests.UniformCase.prototype.generateBasicUniforms = function(basicUniformsDst, basicUniformReportsDst, varType, varName, isParentActive, samplerUnitCounter, rnd) { 1299 /** @type {es3fUniformApiTests.VarValue} */ var value; 1300 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); 1307 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 = []; 1314 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); 1320 1321 isElemActive.push(isCurElemActive); 1322 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); 1329 1330 basicUniformsDst.push(new es3fUniformApiTests.BasicUniform(indexedName, elemBasicType, isCurElemActive, value, arrayRootName, elemNdx, size)); 1331 } else 1332 samplerUnitCounter = this.generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName, isCurElemActive, samplerUnitCounter, rnd); 1333 } 1334 1335 if (varType.getElementType().isBasicType()) { 1336 /** @type {number} */ var minSize; 1337 for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize - 1]; minSize--) {} 1338 1339 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportRef(arrayRootName, varType.getElementType().getBasicType(), isParentActive && minSize > 0).constructor_A(minSize, size)); 1340 } 1341 } else { 1342 assertMsgOptions( 1343 varType.isStructType(), 1344 'es3fUniformApiTests.UniformCase.prototype.generateBasicUniforms - not a struct type', 1345 false, 1346 true 1347 ); 1348 1349 /** @type {gluVarType.StructType} */ var structType = varType.getStruct(); 1350 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(); 1354 1355 samplerUnitCounter = this.generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName, isParentActive, samplerUnitCounter, rnd); 1356 } 1357 } 1358 1359 return samplerUnitCounter; 1360 }; 1361 1362 /** 1363 * @param {string} dst 1364 * @return {string} 1365 */ 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'; 1369 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'; 1372 1373 dst += '\n'; 1374 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; }' 1378 },{ 1379 requiringTypes: [ 1380 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC2, t);}, 1381 function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(2, t);} 1382 ], 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); }' 1384 },{ 1385 requiringTypes: [ 1386 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC3, t);}, 1387 function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(3, t);} 1388 ], 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); }' 1390 },{ 1391 requiringTypes: [ 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); }' 1395 },{ 1396 requiringTypes: [ 1397 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2, t);}, 1398 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1399 ], 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]); }' 1401 },{ 1402 requiringTypes: [ 1403 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2X3, t);}, 1404 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1405 ], 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]); }' 1407 },{ 1408 requiringTypes: [ 1409 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2X4, t);}, 1410 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1411 ], 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]); }' 1413 },{ 1414 requiringTypes: [ 1415 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3X2, t);}, 1416 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1417 ], 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]); }' 1419 },{ 1420 requiringTypes: [ 1421 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3, t);}, 1422 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1423 ], 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]); }' 1425 },{ 1426 requiringTypes: [ 1427 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3X4, t);}, 1428 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1429 ], 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]); }' 1431 },{ 1432 requiringTypes: [ 1433 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4X2, t);}, 1434 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1435 ], 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]); }' 1437 },{ 1438 requiringTypes: [ 1439 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4X3, t);}, 1440 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1441 ], 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]); }' 1443 },{ 1444 requiringTypes: [ 1445 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4, t);}, 1446 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1447 ], 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]); }' 1449 },{ 1450 requiringTypes: [ 1451 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT, t);}, 1452 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1453 ], 1454 definition: 'mediump float compare_int (mediump int a, mediump int b) { return a == b ? 1.0 : 0.0; }' 1455 },{ 1456 requiringTypes: [ 1457 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC2, t);}, 1458 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1459 ], 1460 definition: 'mediump float compare_ivec2 (mediump ivec2 a, mediump ivec2 b) { return a == b ? 1.0 : 0.0; }' 1461 },{ 1462 requiringTypes: [ 1463 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC3, t);}, 1464 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1465 ], 1466 definition: 'mediump float compare_ivec3 (mediump ivec3 a, mediump ivec3 b) { return a == b ? 1.0 : 0.0; }' 1467 },{ 1468 requiringTypes: [ 1469 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC4, t);}, 1470 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1471 ], 1472 definition: 'mediump float compare_ivec4 (mediump ivec4 a, mediump ivec4 b) { return a == b ? 1.0 : 0.0; }' 1473 },{ 1474 requiringTypes: [ 1475 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT, t);}, 1476 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1477 ], 1478 definition: 'mediump float compare_uint (mediump uint a, mediump uint b) { return a == b ? 1.0 : 0.0; }' 1479 },{ 1480 requiringTypes: [ 1481 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC2, t);}, 1482 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1483 ], 1484 definition: 'mediump float compare_uvec2 (mediump uvec2 a, mediump uvec2 b) { return a == b ? 1.0 : 0.0; }' 1485 },{ 1486 requiringTypes: [ 1487 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC3, t);}, 1488 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1489 ], 1490 definition: 'mediump float compare_uvec3 (mediump uvec3 a, mediump uvec3 b) { return a == b ? 1.0 : 0.0; }' 1491 },{ 1492 requiringTypes: [ 1493 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC4, t);}, 1494 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1495 ], 1496 definition: 'mediump float compare_uvec4 (mediump uvec4 a, mediump uvec4 b) { return a == b ? 1.0 : 0.0; }' 1497 },{ 1498 requiringTypes: [ 1499 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL, t);}, 1500 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1501 ], 1502 definition: 'mediump float compare_bool (bool a, bool b) { return a == b ? 1.0 : 0.0; }' 1503 },{ 1504 requiringTypes: [ 1505 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC2, t);}, 1506 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1507 ], 1508 definition: 'mediump float compare_bvec2 (bvec2 a, bvec2 b) { return a == b ? 1.0 : 0.0; }' 1509 },{ 1510 requiringTypes: [ 1511 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC3, t);}, 1512 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1513 ], 1514 definition: 'mediump float compare_bvec3 (bvec3 a, bvec3 b) { return a == b ? 1.0 : 0.0; }' 1515 },{ 1516 requiringTypes: [ 1517 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC4, t);}, 1518 function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);} 1519 ], 1520 definition: 'mediump float compare_bvec4 (bvec4 a, bvec4 b) { return a == b ? 1.0 : 0.0; }' 1521 } 1522 ]; 1523 1524 /** @type {Array<gluShaderUtil.DataType>} */ var samplerTypes = this.m_uniformCollection.getSamplerTypes(); 1525 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; 1529 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; 1535 break; 1536 } 1537 } 1538 } 1539 1540 if (containsTypeSampler || this.m_uniformCollection.containsMatchingBasicType(typeReq[0]) || this.m_uniformCollection.containsMatchingBasicType(typeReq[1])) 1541 dst += compareFuncs[compFuncNdx].definition + '\n'; 1542 } 1543 1544 return dst; 1545 }; 1546 1547 /** 1548 * @param {string} dst 1549 * @param {es3fUniformApiTests.BasicUniform} uniform 1550 * @return {string} Used to write the string in the output parameter 1551 */ 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 1555 else 1556 dst += 'compare_' + gluShaderUtil.getDataTypeName(uniform.type) + '(' + uniform.name; 1557 1558 dst += ', ' + es3fUniformApiTests.shaderVarValueStr(uniform.finalValue) + ')'; 1559 1560 return dst; 1561 }; 1562 1563 /** 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 1568 */ 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]; 1572 1573 if (unif.isUsedInShader) { 1574 dst += '\t' + variableName + ' *= '; 1575 dst = this.writeUniformCompareExpr(dst, basicUniforms[i]); 1576 dst += ';\n'; 1577 } else 1578 dst += '\t// UNUSED: ' + basicUniforms[i].name + '\n'; 1579 } 1580 1581 return dst; 1582 }; 1583 1584 /** 1585 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 1586 * @return {string} 1587 */ 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 = ''; 1591 1592 result += '#version 300 es\n' + 1593 'in highp vec4 a_position;\n' + 1594 'out mediump float v_vtxOut;\n' + 1595 '\n'; 1596 1597 if (isVertexCase) 1598 result = this.writeUniformDefinitions(result); 1599 1600 result += '\n' + 1601 'void main (void)\n' + 1602 ' {\n' + 1603 ' gl_Position = a_position;\n' + 1604 ' v_vtxOut = 1.0;\n'; 1605 1606 if (isVertexCase) 1607 result = this.writeUniformComparisons(result, basicUniforms, 'v_vtxOut'); 1608 1609 result += '}\n'; 1610 1611 return result; 1612 }; 1613 1614 /** 1615 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 1616 * @return {string} 1617 */ 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 = ''; 1621 1622 result += '#version 300 es\n' + 1623 'in mediump float v_vtxOut;\n' + 1624 '\n'; 1625 1626 if (isFragmentCase) 1627 result = this.writeUniformDefinitions(result); 1628 1629 result += '\n' + 1630 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' + 1631 '\n' + 1632 'void main (void)\n' + 1633 ' {\n' + 1634 ' mediump float result = v_vtxOut;\n'; 1635 1636 if (isFragmentCase) 1637 result = this.writeUniformComparisons(result, basicUniforms, 'result'); 1638 1639 result += ' dEQP_FragColor = vec4(result, result, result, 1.0);\n' + 1640 '}\n'; 1641 1642 return result; 1643 }; 1644 1645 /** 1646 * @param {es3fUniformApiTests.VarValue} value 1647 */ 1648 es3fUniformApiTests.UniformCase.prototype.setupTexture = function(value) { 1649 // \note No handling for samplers other than 2D or cube. 1650 1651 assertMsgOptions( 1652 es3fUniformApiTests.getSamplerLookupReturnType(value.type) == gluShaderUtil.DataType.FLOAT_VEC4, 1653 'es3fUniformApiTests.UniformCase.prototype.setupTexture - sampler return type should be vec4f', false, true 1654 ); 1655 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; 1661 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); 1666 1667 refTexture.allocLevel(0); 1668 es3fUniformApiTests.fillWithColor(refTexture.getLevel(0), color); 1669 1670 gl.activeTexture(gl.TEXTURE0 + value.val.samplerV.unit); 1671 this.m_filledTextureUnits.push(value.val.samplerV.unit); 1672 texture.upload(); 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); 1679 1680 texture = gluTexture.cubeFromFormat(gl, gl.RGBA, gl.UNSIGNED_BYTE, width); 1681 refTexture = texture.getRefTexture(); 1682 this.m_texturesCube.push(texture); 1683 1684 for (var face in tcuTexture.CubeFace) { 1685 refTexture.allocLevel(tcuTexture.CubeFace[face], 0); 1686 es3fUniformApiTests.fillWithColor(refTexture.getLevelFace(0, tcuTexture.CubeFace[face]), color); 1687 } 1688 1689 gl.activeTexture(gl.TEXTURE0 + value.val.samplerV.unit); 1690 this.m_filledTextureUnits.push(value.val.samplerV.unit); 1691 texture.upload(); 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); 1696 } else 1697 throw new Error('es3fUniformApiTests.UniformCase.prototype.setupTexture - Invalid sampler type'); 1698 }; 1699 1700 /** 1701 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} basicUniformReportsDst 1702 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef 1703 * @param {WebGLProgram} programGL 1704 * @return {boolean} 1705 */ 1706 es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne = function(basicUniformReportsDst, basicUniformReportsRef, programGL) { 1707 /** @type {WebGLProgram} */ var numActiveUniforms; 1708 /** @type {boolean} */ var success = true; 1709 1710 numActiveUniforms = /** @type {WebGLProgram} */ (gl.getProgramParameter(programGL, gl.ACTIVE_UNIFORMS)); 1711 bufferedLogToConsole('// Number of active uniforms reported: ' + numActiveUniforms); 1712 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; 1719 1720 activeInfo = gl.getActiveUniform(programGL, unifNdx); 1721 1722 reportedNameStr = activeInfo.name; 1723 reportedTypeGL = activeInfo.type; 1724 reportedSize = activeInfo.size; 1725 1726 reportedType = gluShaderUtil.getDataTypeFromGLType(reportedTypeGL); 1727 1728 checkMessage(reportedType !== undefined, 'Invalid uniform type'); 1729 1730 bufferedLogToConsole('// Got name = ' + reportedNameStr + ', size = ' + reportedSize + ', type = ' + gluShaderUtil.getDataTypeName(reportedType)); 1731 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) 1737 break; 1738 } 1739 1740 if (referenceNdx >= basicUniformReportsRef.length) { 1741 bufferedLogToConsole('// FAILURE: invalid non-built-in uniform name reported'); 1742 success = false; 1743 } else { 1744 /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var reference = basicUniformReportsRef[referenceNdx]; 1745 1746 assertMsgOptions( 1747 reference.type !== undefined, 1748 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - type is undefined', 1749 false, 1750 true 1751 ); 1752 assertMsgOptions( 1753 reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader), 1754 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - uniform min size does not match usage in shader', 1755 false, 1756 true 1757 ); 1758 assertMsgOptions( 1759 reference.minSize <= reference.maxSize, 1760 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - uniform min size bigger than max size', 1761 false, 1762 true 1763 ); 1764 1765 if (es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, reportedNameStr) !== null) { 1766 bufferedLogToConsole('// FAILURE: same uniform name reported twice'); 1767 success = false; 1768 } 1769 1770 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportGL(reportedNameStr, reportedNameStr.length, reportedSize, reportedType, unifNdx)); 1771 1772 if (reportedType != reference.type) { 1773 bufferedLogToConsole('// FAILURE: wrong type reported, should be ' + gluShaderUtil.getDataTypeName(reference.type)); 1774 success = false; 1775 } 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 + ']')); 1779 1780 success = false; 1781 } 1782 } 1783 } 1784 } 1785 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'); 1790 success = false; 1791 } 1792 } 1793 1794 return success; 1795 }; 1796 1797 /** 1798 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} basicUniformReportsDst 1799 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef 1800 * @param {WebGLProgram} programGL 1801 * @return {boolean} 1802 */ 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; 1809 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]; 1814 } 1815 1816 uniformIndices = gl.getUniformIndices(programGL, queryNamesC); 1817 1818 for (var i = 0; i < uniformIndices.length; i++) { 1819 if (uniformIndices[i] != gl.INVALID_INDEX) 1820 validUniformIndices.push(uniformIndices[i]); 1821 else { 1822 if (basicUniformReportsRef[i].isUsedInShader) { 1823 bufferedLogToConsole('// FAILURE: uniform with name ' + basicUniformReportsRef[i].name + ' received gl.INVALID_INDEX'); 1824 success = false; 1825 } 1826 } 1827 } 1828 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); 1833 1834 uniformSizeBuf = gl.getActiveUniforms(programGL, validUniformIndices, gl.UNIFORM_SIZE); 1835 uniformTypeBuf = gl.getActiveUniforms(programGL, validUniformIndices, gl.UNIFORM_TYPE); 1836 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) 1840 continue; 1841 1842 validNdx++; 1843 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; 1850 1851 bufferedLogToConsole('// Got name size = ' + reportedSize + 1852 ', type = ' + gluShaderUtil.getDataTypeName(reportedType) + 1853 ' for the uniform at index ' + reportedIndex + ' (' + reference.name + ')'); 1854 1855 assertMsgOptions( 1856 reference.type !== undefined, 1857 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - type is undefined', 1858 false, 1859 true 1860 ); 1861 assertMsgOptions( 1862 reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader), 1863 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - uniform min size does not match usage in shader', 1864 false, 1865 true 1866 ); 1867 assertMsgOptions( 1868 reference.minSize <= reference.maxSize, 1869 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - uniform min size bigger than max size', 1870 false, 1871 true 1872 ); 1873 1874 if (es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, reportedNameStr) !== null) { 1875 bufferedLogToConsole('// FAILURE: same uniform name reported twice'); 1876 success = false; 1877 } 1878 basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportGL(reference.name, reportedNameLength, reportedSize, reportedType, reportedIndex)); 1879 1880 if (reportedType != reference.type) { 1881 bufferedLogToConsole('// FAILURE: wrong type reported, should be ' + gluShaderUtil.getDataTypeName(reference.type)); 1882 success = false; 1883 } 1884 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 + ']')); 1888 1889 success = false; 1890 } 1891 } 1892 } 1893 1894 return success; 1895 }; 1896 1897 /** 1898 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} uniformResults 1899 * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} uniformsResults 1900 * @return {boolean} 1901 */ 1902 es3fUniformApiTests.UniformCase.prototype.uniformVsUniformsComparison = function(uniformResults, uniformsResults) { 1903 /** @type {boolean} */ var success = true; 1904 /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformsResult; 1905 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); 1910 1911 if (uniformsResult !== null) { 1912 bufferedLogToConsole('// Checking uniform ' + uniformName); 1913 1914 if (uniformResult.index != uniformsResult.index) { 1915 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetUniformIndices() gave different indices for uniform ' + uniformName); 1916 success = false; 1917 } 1918 if (uniformResult.nameLength != uniformsResult.nameLength) { 1919 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave incompatible name lengths for uniform ' + uniformName); 1920 success = false; 1921 } 1922 if (uniformResult.size != uniformsResult.size) { 1923 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave different sizes for uniform ' + uniformName); 1924 success = false; 1925 } 1926 if (uniformResult.type != uniformsResult.type) { 1927 bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave different types for uniform ' + uniformName); 1928 success = false; 1929 } 1930 } else { 1931 bufferedLogToConsole('// FAILURE: uniform ' + uniformName + ' was reported active by glGetActiveUniform() but not by glGetUniformIndices()'); 1932 success = false; 1933 } 1934 } 1935 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); 1940 1941 if (uniformsResultIt === null) { 1942 bufferedLogToConsole('// FAILURE: uniform ' + uniformsName + ' was reported active by glGetUniformIndices() but not by glGetActiveUniform()'); 1943 success = false; 1944 } 1945 } 1946 1947 return success; 1948 }; 1949 1950 /** 1951 * @param {Array<es3fUniformApiTests.VarValue>} valuesDst 1952 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 1953 * @param {WebGLProgram} programGL 1954 * @return {boolean} 1955 */ 1956 es3fUniformApiTests.UniformCase.prototype.getUniforms = function(valuesDst, basicUniforms, programGL) { 1957 /** @type {boolean} */ var success = true; 1958 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(); 1965 1966 if (!location) { 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'); 1971 success = false; 1972 } 1973 continue; 1974 } 1975 1976 value.type = uniform.type; 1977 1978 var result = /** @type {number} */ (gl.getUniform(programGL, location)); 1979 1980 if (gluShaderUtil.isDataTypeSampler(uniform.type)) { 1981 value.val = new es3fUniformApiTests.SamplerV(); 1982 value.val.samplerV.unit = result; 1983 } else 1984 value.val = /** @type {Array<number>} */ (result.length === undefined ? [result] : result); 1985 1986 valuesDst.push(value); 1987 1988 bufferedLogToConsole('// Got ' + uniform.name + ' value ' + es3fUniformApiTests.apiVarValueStr(value)); 1989 } 1990 1991 return success; 1992 }; 1993 1994 /** 1995 * @param {Array<es3fUniformApiTests.VarValue>} values 1996 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 1997 * @return {boolean} 1998 */ 1999 es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues = function(values, basicUniforms) { 2000 /** @type {boolean} */ var success = true; 2001 2002 assertMsgOptions( 2003 values.length == basicUniforms.length, 2004 'es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues - lengths do not match', 2005 false, 2006 true 2007 ); 2008 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); 2013 2014 bufferedLogToConsole('// Checking uniform ' + uniform.name); 2015 2016 if (unifValue.type == gluShaderUtil.DataType.INVALID) // This happens when glGetUniformLocation() returned -1. 2017 continue; 2018 2019 var CHECK_UNIFORM = function(ZERO) { 2020 do { 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'); 2024 success = false; 2025 } 2026 } 2027 } while (false); 2028 }; 2029 2030 if (gluShaderUtil.isDataTypeFloatOrVec(uniform.type) || gluShaderUtil.isDataTypeMatrix(uniform.type)) 2031 CHECK_UNIFORM(0.0); 2032 else if (gluShaderUtil.isDataTypeIntOrIVec(uniform.type)) 2033 CHECK_UNIFORM(0); 2034 else if (gluShaderUtil.isDataTypeUintOrUVec(uniform.type)) 2035 CHECK_UNIFORM(0); 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'); 2041 success = false; 2042 } 2043 } else 2044 throw new Error('es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues - invalid uniform type'); 2045 } 2046 2047 return success; 2048 }; 2049 2050 /** 2051 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 2052 * @param {WebGLProgram} programGL 2053 * @param {deRandom.Random} rnd 2054 */ 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; 2061 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; 2070 2071 assertMsgOptions( 2072 numValuesToAssign >= 0, 2073 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - number of values to assign not a positive integer', 2074 false, 2075 true 2076 ); 2077 assertMsgOptions( 2078 numValuesToAssign == 1 || isArrayMember, 2079 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - not an array member and number of values to assign not 1', 2080 false, 2081 true 2082 ); 2083 2084 if (numValuesToAssign == 0) { 2085 bufferedLogToConsole('// es3fUniformApiTests.Uniform ' + uniform.name + ' is covered by another glUniform*v() call to the same array'); 2086 continue; 2087 } 2088 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; 2094 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(); 2098 2099 if (isArrayMember) { 2100 /** @type {es3fUniformApiTests.BasicUniform} */ var elemUnif = es3fUniformApiTests.BasicUniform.findWithName(basicUniforms, curName); 2101 if (elemUnif === null) 2102 continue; 2103 unifValue = elemUnif.finalValue; 2104 } else 2105 unifValue = uniform.finalValue; 2106 2107 /** @type {es3fUniformApiTests.VarValue} */ var apiValue = gluShaderUtil.isDataTypeBoolOrBVec(unifValue.type) ? es3fUniformApiTests.getRandomBoolRepresentation(unifValue, boolApiType, rnd) : 2108 gluShaderUtil.isDataTypeSampler(unifValue.type) ? es3fUniformApiTests.getSamplerUnitValue(unifValue) : 2109 unifValue; 2110 2111 valuesToAssign.push(gluShaderUtil.isDataTypeMatrix(apiValue.type) && transpose ? es3fUniformApiTests.getTransposeMatrix(apiValue) : apiValue); 2112 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))); 2117 } 2118 2119 assertMsgOptions( 2120 valuesToAssign.length > 0, 2121 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - values quantity less than one', 2122 false, 2123 true 2124 ); 2125 2126 if (gluShaderUtil.isDataTypeFloatOrVec(valuesToAssign[0].type)) { 2127 if (assignByValue) { 2128 switch (typeSize) { 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; 2133 default: 2134 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size'); 2135 } 2136 } else { 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]; 2140 2141 switch (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; 2146 default: 2147 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size'); 2148 } 2149 } 2150 } else if (gluShaderUtil.isDataTypeMatrix(valuesToAssign[0].type)) { 2151 assertMsgOptions( 2152 !assignByValue, 2153 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - assigning by value in matrix type', 2154 false, true 2155 ); 2156 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]; 2160 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; 2171 default: 2172 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid uniform type'); 2173 } 2174 } else if (gluShaderUtil.isDataTypeIntOrIVec(valuesToAssign[0].type)) { 2175 if (assignByValue) { 2176 switch (typeSize) { 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; 2181 default: 2182 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size'); 2183 } 2184 } else { 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]; 2188 2189 switch (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; 2194 default: 2195 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size'); 2196 } 2197 } 2198 } else if (gluShaderUtil.isDataTypeUintOrUVec(valuesToAssign[0].type)) { 2199 if (assignByValue) { 2200 switch (typeSize) { 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; 2205 default: 2206 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size'); 2207 } 2208 } else { 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]; 2212 2213 switch (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; 2218 default: 2219 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size'); 2220 } 2221 } 2222 } else if (gluShaderUtil.isDataTypeSampler(valuesToAssign[0].type)) { 2223 if (assignByValue) 2224 gl.uniform1i(location, uniform.finalValue.val.samplerV.unit); 2225 else { 2226 var unit = /** @type {Array<number>} */ (uniform.finalValue.val); 2227 gl.uniform1iv(location, unit); 2228 } 2229 } else 2230 throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid uniform type'); 2231 } 2232 }; 2233 2234 /** 2235 * @param {Array<es3fUniformApiTests.VarValue>} values 2236 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 2237 * @return {boolean} 2238 */ 2239 es3fUniformApiTests.UniformCase.prototype.compareUniformValues = function(values, basicUniforms) { 2240 /** @type {boolean} */ var success = true; 2241 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]; 2245 2246 bufferedLogToConsole('// Checking uniform ' + uniform.name); 2247 2248 if (unifValue.type == gluShaderUtil.DataType.INVALID) // This happens when glGetUniformLocation() returned -1. 2249 continue; 2250 2251 if (!es3fUniformApiTests.apiVarValueEquals(unifValue, uniform.finalValue)) { 2252 bufferedLogToConsole('// FAILURE: value obtained with glGetUniform*() for uniform ' + uniform.name + ' differs from value set with glUniform*()'); 2253 success = false; 2254 } 2255 } 2256 2257 return success; 2258 }; 2259 2260 /** @const @type {number} */ es3fUniformApiTests.VIEWPORT_WIDTH = 128; 2261 /** @const @type {number} */ es3fUniformApiTests.VIEWPORT_HEIGHT = 128; 2262 2263 /** 2264 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 2265 * @param {gluShaderProgram.ShaderProgram} program 2266 * @param {deRandom.Random} rnd 2267 * @return {boolean} 2268 */ 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); 2276 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) 2282 assertMsgOptions( 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', 2285 false, true 2286 ); 2287 } 2288 } 2289 } 2290 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); 2295 } 2296 } 2297 2298 gl.viewport(viewportX, viewportY, viewportW, viewportH); 2299 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, 2304 1.0, 1.0, 0.0, 1.0 2305 ]); 2306 2307 /** @type {Uint16Array} */ 2308 var indices = new Uint16Array([0, 1, 2, 2, 1, 3]); 2309 2310 /** @type {number} */ var posLoc = gl.getAttribLocation(program.getProgram(), 'a_position'); 2311 gl.enableVertexAttribArray(posLoc); 2312 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); 2317 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); 2321 2322 gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); 2323 2324 renderedImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]); 2325 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; 2333 } 2334 } 2335 2336 if (numFailedPixels > 0) { 2337 //TODO: log << TestLog::Image("RenderedImage", "Rendered image", renderedImg); 2338 bufferedLogToConsole('FAILURE: image comparison failed, got ' + numFailedPixels + ' non-white pixels'); 2339 return false; 2340 } else { 2341 bufferedLogToConsole('Success: got all-white pixels (all uniforms have correct values)'); 2342 return true; 2343 } 2344 }; 2345 2346 /** 2347 * @return {tcuTestCase.IterateResult} 2348 */ 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 = []; 2353 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); 2357 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)); 2361 2362 bufferedLogToConsole(program.getProgramInfo().infoLog); 2363 2364 if (!program.isOk()) { 2365 testFailedOptions('Compile failed', false); 2366 return tcuTestCase.IterateResult.STOP; 2367 } 2368 2369 gl.useProgram(program.getProgram()); 2370 2371 /** @type {boolean} */ var success = this.test(basicUniforms, basicUniformReportsRef, program, rnd); 2372 assertMsgOptions(success, '', true, false); 2373 2374 return tcuTestCase.IterateResult.STOP; 2375 }; 2376 2377 /** 2378 * @enum {number} 2379 */ 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. 2384 }; 2385 2386 /** 2387 * es3fUniformApiTests.UniformInfoQueryCase class 2388 * @constructor 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} 2396 */ 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; 2401 }; 2402 2403 es3fUniformApiTests.UniformInfoQueryCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype); 2404 /** Constructor restore */ 2405 es3fUniformApiTests.UniformInfoQueryCase.prototype.constructor = es3fUniformApiTests.UniformInfoQueryCase; 2406 2407 /** 2408 * @param {es3fUniformApiTests.CaseType} caseType 2409 * @return {?string} 2410 */ 2411 es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeName = function(caseType) { 2412 switch (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'; 2416 default: 2417 throw new Error('Invalid type'); 2418 } 2419 }; 2420 2421 /** 2422 * @param {es3fUniformApiTests.CaseType} caseType 2423 * @return {?string} 2424 */ 2425 es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeDescription = function(caseType) { 2426 switch (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()'; 2430 default: 2431 throw new Error('Invalid type'); 2432 } 2433 }; 2434 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. 2436 /** 2437 * @constructor 2438 * @param {?string} name 2439 * @param {es3fUniformApiTests.UniformCollection} uniformCollection_ 2440 */ 2441 es3fUniformApiTests.UniformCollectionCase = function(name, uniformCollection_) { 2442 /** @type {string} */ this.namePrefix = name ? name + '_' : ''; 2443 /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ this.uniformCollection = uniformCollection_; 2444 }; 2445 2446 /** 2447 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 2448 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef 2449 * @param {gluShaderProgram.ShaderProgram} program 2450 * @param {deRandom.Random} rnd 2451 * @return {boolean} 2452 */ 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; 2458 2459 if (this.m_caseType == es3fUniformApiTests.CaseType.UNIFORM || this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) { 2460 success = false; 2461 2462 //TODO:: const ScopedLogSection section(log, "InfoGetActiveUniform", "es3fUniformApiTests.Uniform information queries with glGetActiveUniform()"); 2463 success = this.getActiveUniformsOneByOne(basicUniformReportsUniform, basicUniformReportsRef, programGL); 2464 2465 if (!success) { 2466 if (this.m_caseType == es3fUniformApiTests.CaseType.UNIFORM) 2467 return false; 2468 else { 2469 assertMsgOptions( 2470 this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY, 2471 'es3fUniformApiTests.UniformInfoQueryCase.prototype.test - case type is not consistency', 2472 false, 2473 true 2474 ); 2475 bufferedLogToConsole('// Note: this is a consistency case, so ignoring above failure(s)'); 2476 } 2477 } 2478 } 2479 2480 if (this.m_caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV || this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) { 2481 success = false; 2482 2483 //TODO: const ScopedLogSection section(log, "InfoGetActiveUniforms", "es3fUniformApiTests.Uniform information queries with glGetUniformIndices() and glGetActiveUniforms()"); 2484 success = this.getActiveUniforms(basicUniformReportsUniforms, basicUniformReportsRef, programGL); 2485 2486 if (!success) { 2487 if (this.m_caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV) 2488 return false; 2489 else { 2490 assertMsgOptions( 2491 this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY, 2492 'es3fUniformApiTests.UniformInfoQueryCase.prototype.test - case type is not consistency', 2493 false, 2494 true 2495 ); 2496 bufferedLogToConsole('// Note: this is a consistency case, so ignoring above failure(s)'); 2497 } 2498 } 2499 } 2500 2501 if (this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) { 2502 success = false; 2503 2504 //TODO: const ScopedLogSection section(log, "CompareUniformVsUniforms", "Comparison of results from glGetActiveUniform() and glGetActiveUniforms()"); 2505 success = this.uniformVsUniformsComparison(basicUniformReportsUniform, basicUniformReportsUniforms); 2506 2507 if (!success) 2508 return false; 2509 } 2510 2511 return true; 2512 }; 2513 2514 /** 2515 * @enum {number} 2516 */ 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. 2520 }; 2521 2522 /** 2523 * @enum {number} 2524 */ 2525 es3fUniformApiTests.CheckMethod = { 2526 GET_UNIFORM: 0, //!< Check values with glGetUniform*(). 2527 RENDER: 1 //!< Check values by rendering with the value-checking shader. 2528 }; 2529 2530 /** 2531 * @enum {number} 2532 */ 2533 es3fUniformApiTests.AssignMethod = { 2534 POINTER: 0, 2535 VALUE: 1 2536 }; 2537 2538 /** 2539 * es3fUniformApiTests.UniformValueCase test class 2540 * @constructor 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} 2550 */ 2551 es3fUniformApiTests.UniformValueCase = function(name, description, shaderType, uniformCollection, valueToCheck, checkMethod, assignMethod, additionalFeatures) { 2552 es3fUniformApiTests.UniformCase.call(this, name, description); 2553 2554 additionalFeatures.UNIFORMVALUE_ZERO |= valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL; 2555 additionalFeatures.UNIFORMFUNC_VALUE |= assignMethod == es3fUniformApiTests.AssignMethod.VALUE; 2556 this.newB(shaderType, uniformCollection, additionalFeatures); 2557 2558 this.m_valueToCheck = valueToCheck; 2559 this.m_checkMethod = checkMethod; 2560 2561 assertMsgOptions( 2562 !(assignMethod === undefined && valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED), 2563 'es3fUniformApiTests.UniformValueCase - assign method is undefined when value to check requires it', 2564 false, 2565 true 2566 ); 2567 }; 2568 2569 es3fUniformApiTests.UniformValueCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype); 2570 /** Constructor restore */ 2571 es3fUniformApiTests.UniformValueCase.prototype.constructor = es3fUniformApiTests.UniformValueCase; 2572 2573 /** 2574 * @param {es3fUniformApiTests.ValueToCheck} valueToCheck 2575 * @return {?string} 2576 */ 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'); 2582 } 2583 }; 2584 2585 /** 2586 * @param {es3fUniformApiTests.ValueToCheck} valueToCheck 2587 * @return {?string} 2588 */ 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'); 2594 } 2595 }; 2596 2597 /** 2598 * @param {es3fUniformApiTests.CheckMethod} checkMethod 2599 * @return {?string} 2600 */ 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'); 2606 } 2607 }; 2608 2609 /** 2610 * @param {es3fUniformApiTests.CheckMethod} checkMethod 2611 * @return {?string} 2612 */ 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'); 2618 } 2619 }; 2620 2621 /** 2622 * @param {es3fUniformApiTests.AssignMethod} assignMethod 2623 * @return {?string} 2624 */ 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'); 2630 } 2631 }; 2632 2633 /** 2634 * @param {es3fUniformApiTests.AssignMethod} assignMethod 2635 * @return {?string} 2636 */ 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'); 2642 } 2643 }; 2644 2645 /** 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 2651 * @return {boolean} 2652 */ 2653 es3fUniformApiTests.UniformValueCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) { 2654 /** @type {WebGLProgram} */ var programGL = program.getProgram(); 2655 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); 2659 } else 2660 assertMsgOptions( 2661 this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL, 2662 'es3fUniformApiTests.UniformValueCase.prototype.test - value to check not initial', 2663 false, true 2664 ); 2665 2666 /** @type {boolean}*/ var success; 2667 2668 if (this.m_checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM) { 2669 /** @type {Array<es3fUniformApiTests.VarValue>} */ var values = []; 2670 2671 //TODO: const ScopedLogSection section(log, "GetUniforms", "es3fUniformApiTests.Uniform value query"); 2672 success = this.getUniforms(values, basicUniforms, program.getProgram()); 2673 2674 if (!success) 2675 return false; 2676 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); 2680 2681 if (!success) 2682 return false; 2683 } else { 2684 assertMsgOptions( 2685 this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL, 2686 'es3fUniformApiTests.UniformValueCase.prototype.test - value to check not initial', 2687 false, true 2688 ); 2689 2690 //TODO: const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)"); 2691 success = this.checkUniformDefaultValues(values, basicUniforms); 2692 2693 if (!success) 2694 return false; 2695 } 2696 } else { 2697 assertMsgOptions( 2698 this.m_checkMethod == es3fUniformApiTests.CheckMethod.RENDER, 2699 'es3fUniformApiTests.UniformValueCase.prototype.test - check method different than RENDER', 2700 false, true 2701 ); 2702 2703 //TODO: const ScopedLogSection section(log, "RenderTest", "Render test"); 2704 success = this.renderTest(basicUniforms, program, rnd); 2705 2706 if (!success) 2707 return false; 2708 } 2709 2710 return true; 2711 }; 2712 2713 /** 2714 * es3fUniformApiTests.RandomUniformCase test class 2715 * @constructor 2716 * @param {string} name 2717 * @param {string} description 2718 * @param {number} seed 2719 * @extends {es3fUniformApiTests.UniformCase} 2720 */ 2721 es3fUniformApiTests.RandomUniformCase = function(name, description, seed) { 2722 es3fUniformApiTests.UniformCase.call(this, name, description); 2723 this.newC(seed ^ deRandom.getBaseSeed()); 2724 }; 2725 2726 es3fUniformApiTests.RandomUniformCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype); 2727 /** Constructor restore */ 2728 es3fUniformApiTests.RandomUniformCase.prototype.constructor = es3fUniformApiTests.RandomUniformCase; 2729 2730 /** 2731 * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms 2732 * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef 2733 * @param {gluShaderProgram.ShaderProgram} program 2734 * @param {deRandom.Random} rnd 2735 * @return {boolean} 2736 */ 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(); 2740 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(); 2750 2751 if (!(performGetActiveUniforms || performGetActiveUniformsiv || performUniformVsUniformsivComparison || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest)) 2752 performGetActiveUniforms = true; // Do something at least. 2753 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(); 2757 if (!success) 2758 return false; 2759 }; 2760 2761 /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var reportsUniform = []; 2762 /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var reportsUniformsiv = []; 2763 2764 var current = this; //To use "this" in anonymous function. 2765 2766 if (performGetActiveUniforms) 2767 PERFORM_AND_CHECK(function() {current.getActiveUniformsOneByOne(reportsUniform, basicUniformReportsRef, programGL);}, 'InfoGetActiveUniform', 'es3fUniformApiTests.Uniform information queries with glGetActiveUniform()'); 2768 2769 if (performGetActiveUniformsiv) 2770 PERFORM_AND_CHECK(function() {current.getActiveUniforms(reportsUniformsiv, basicUniformReportsRef, programGL);}, 'InfoGetActiveUniformsiv', 'es3fUniformApiTests.Uniform information queries with glGetIndices() and glGetActiveUniformsiv()'); 2771 2772 if (performUniformVsUniformsivComparison) 2773 PERFORM_AND_CHECK(function() {current.uniformVsUniformsComparison(reportsUniform, reportsUniformsiv);}, 'CompareUniformVsUniformsiv', 'Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()'); 2774 2775 /** @type {Array<es3fUniformApiTests.VarValue>} */ var uniformDefaultValues = []; 2776 2777 if (performGetUniforms) 2778 PERFORM_AND_CHECK(function() {current.getUniforms(uniformDefaultValues, basicUniforms, programGL);}, 'GetUniformDefaults', 'es3fUniformApiTests.Uniform default value query'); 2779 2780 if (performCheckUniformDefaultValues) 2781 PERFORM_AND_CHECK(function() {current.checkUniformDefaultValues(uniformDefaultValues, basicUniforms);}, 'DefaultValueCheck', 'Verify that the uniforms have correct initial values (zeros)'); 2782 2783 /** @type {Array<es3fUniformApiTests.VarValue>} */ var uniformValues = []; 2784 2785 if (performAssignUniforms) { 2786 //TODO: const ScopedLogSection section(log, "UniformAssign", "es3fUniformApiTests.Uniform value assignments"); 2787 this.assignUniforms(basicUniforms, programGL, rnd); 2788 } 2789 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'); 2793 } 2794 2795 if (performRenderTest) 2796 PERFORM_AND_CHECK(function() {current.renderTest(basicUniforms, program, rnd);}, 'RenderTest', 'Render test'); 2797 2798 return true; 2799 }; 2800 2801 /** 2802 * Initializes the tests to be performed. 2803 */ 2804 es3fUniformApiTests.init = function() { 2805 var state = tcuTestCase.runner; 2806 var testGroup = state.testCases; 2807 2808 // Generate sets of UniformCollections that are used by several cases. 2809 /** 2810 * @enum 2811 */ 2812 var UniformCollections = { 2813 BASIC: 0, 2814 BASIC_ARRAY: 1, 2815 BASIC_STRUCT: 2, 2816 STRUCT_IN_ARRAY: 3, 2817 ARRAY_IN_STRUCT: 4, 2818 NESTED_STRUCTS_ARRAYS: 5, 2819 MULTIPLE_BASIC: 6, 2820 MULTIPLE_BASIC_ARRAY: 7, 2821 MULTIPLE_NESTED_STRUCTS_ARRAYS: 8 2822 }; 2823 2824 /** 2825 * @constructor 2826 */ 2827 var UniformCollectionGroup = function() { 2828 /** @type {string} */ this.name = ''; 2829 /** @type {Array<es3fUniformApiTests.UniformCollectionCase>} */ this.cases = []; 2830 }; 2831 2832 /** @type {Array<UniformCollectionGroup>} */ var defaultUniformCollections = new Array(Object.keys(UniformCollections).length); 2833 2834 /** @type {string} */ var name; 2835 2836 //Initialize 2837 for (var i = 0; i < defaultUniformCollections.length; i++) defaultUniformCollections[i] = new UniformCollectionGroup(); 2838 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'; 2848 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); 2852 2853 defaultUniformCollections[UniformCollections.BASIC].cases.push(new es3fUniformApiTests.UniformCollectionCase(typeName, es3fUniformApiTests.UniformCollection.basic(dataType))); 2854 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))); 2860 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; 2871 2872 assertMsgOptions( 2873 secondDataType !== undefined, 2874 'es3fUniformApiTests.init - second data type undefined', 2875 false, true 2876 ); 2877 2878 /** @type {string} */ var secondTypeName = gluShaderUtil.getDataTypeName(secondDataType); 2879 name = typeName + '_' + secondTypeName; 2880 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))); 2885 } 2886 } 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())); 2890 2891 // Info-query cases (check info returned by e.g. glGetActiveUniforms()). 2892 2893 // info_query 2894 /** @type {tcuTestCase.DeqpTest} */ 2895 var infoQueryGroup = tcuTestCase.newTest('info_query', 'Test uniform info querying functions'); 2896 testGroup.addChild(infoQueryGroup); 2897 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; 2913 2914 /** @type {Array<string>} */ var shaderTypes = Object.keys(es3fUniformApiTests.CaseShaderType); 2915 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); 2921 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; 2924 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); 2930 2931 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) { 2932 collectionCase = collectionGroup.cases[collectionNdx]; 2933 2934 for (var i = 0; i < shaderTypes.length; i++) { 2935 name = collectionCase.namePrefix + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]); 2936 uniformCollection = collectionCase.uniformCollection; 2937 2938 features = new es3fUniformApiTests.Feature(); 2939 features.ARRAY_FIRST_ELEM_NAME_NO_INDEX = referToFirstArrayElemWithoutIndexI != 0; 2940 2941 collectionTestGroup.addChild(new es3fUniformApiTests.UniformInfoQueryCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, caseType, features)); 2942 } 2943 } 2944 } 2945 } 2946 2947 // Info-querying cases when unused uniforms are present. 2948 2949 unusedUniformsGroup = tcuTestCase.newTest('unused_uniforms', 'Test with unused uniforms'); 2950 caseTypeGroup.addChild(unusedUniformsGroup); 2951 2952 collectionGroup = defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT]; 2953 2954 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) { 2955 collectionCase = collectionGroup.cases[collectionNdx]; 2956 collName = collectionCase.namePrefix; 2957 uniformCollection = collectionCase.uniformCollection; 2958 2959 for (var i = 0; i < shaderTypes.length; i++) { 2960 name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]); 2961 2962 features = new es3fUniformApiTests.Feature(); 2963 features.UNIFORMUSAGE_EVERY_OTHER = true; 2964 features.ARRAYUSAGE_ONLY_MIDDLE_INDEX = true; 2965 2966 unusedUniformsGroup.addChild(new es3fUniformApiTests.UniformInfoQueryCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, caseType, features)); 2967 } 2968 } 2969 } 2970 2971 // Cases testing uniform values. 2972 2973 // Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering. 2974 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); 2979 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); 2984 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); 2989 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; 2998 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. 3001 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; 3006 3007 booleanTypeName = booleanTypeI == 1 ? 'int' : 3008 booleanTypeI == 2 ? 'uint' : 3009 'float'; 3010 /** @type {string} */ var nameWithApiType = varyBoolApiType ? collName + 'api_' + booleanTypeName + '_' : collName; 3011 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)); 3016 } 3017 } 3018 } 3019 } 3020 } 3021 3022 // Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering. 3023 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); 3028 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); 3033 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); 3038 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; 3041 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); 3047 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; 3060 3061 if (containsMatrices && assignMethod != es3fUniformApiTests.AssignMethod.POINTER) 3062 continue; 3063 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; 3068 3069 booleanTypeName = booleanTypeI == 1 ? 'int' : 3070 booleanTypeI == 2 ? 'uint' : 3071 'float'; 3072 /** @type {string} */ var nameWithBoolType = varyBoolApiType ? collName + 'api_' + booleanTypeName + '_' : collName; 3073 3074 for (var matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++) { 3075 /** @type {string} */ var nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? 'row_major_' : ''); 3076 3077 for (var i = 0; i < shaderTypes.length; i++) { 3078 name = nameWithMatrixType + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]); 3079 3080 booleanTypeFeat.ARRAY_FIRST_ELEM_NAME_NO_INDEX = referToFirstArrayElemWithoutIndexI != 0; 3081 booleanTypeFeat.MATRIXMODE_ROWMAJOR = matrixTypeI == 1; 3082 3083 collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, 3084 es3fUniformApiTests.ValueToCheck.ASSIGNED, checkMethod, assignMethod, booleanTypeFeat)); 3085 } 3086 } 3087 } 3088 } 3089 } 3090 } 3091 } 3092 } 3093 3094 // Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1). 3095 3096 /** @type {es3fUniformApiTests.Feature} */ var arrayAssignFullMode = new es3fUniformApiTests.Feature(); 3097 arrayAssignFullMode.ARRAYASSIGN_FULL = true; 3098 3099 /** @type {es3fUniformApiTests.Feature} */ var arrayAssignBlocksOfTwo = new es3fUniformApiTests.Feature(); 3100 arrayAssignFullMode.ARRAYASSIGN_BLOCKS_OF_TWO = true; 3101 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'} 3104 ]; 3105 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; 3110 3111 /** @type {tcuTestCase.DeqpTest} */ var curArrayAssignGroup = tcuTestCase.newTest(groupName, groupDesc); 3112 assignedValuesGroup.addChild(curArrayAssignGroup); 3113 3114 /** @type {Array<number>} */ var basicArrayCollectionGroups = [UniformCollections.BASIC_ARRAY, UniformCollections.ARRAY_IN_STRUCT, UniformCollections.MULTIPLE_BASIC_ARRAY]; 3115 3116 for (var collectionGroupNdx = 0; collectionGroupNdx < basicArrayCollectionGroups.length; collectionGroupNdx++) { 3117 collectionGroup = defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]]; 3118 collectionTestGroup = tcuTestCase.newTest(collectionGroup.name, ''); 3119 curArrayAssignGroup.addChild(collectionTestGroup); 3120 3121 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) { 3122 collectionCase = collectionGroup.cases[collectionNdx]; 3123 collName = collectionCase.namePrefix; 3124 uniformCollection = collectionCase.uniformCollection; 3125 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, 3130 arrayAssignMode)); 3131 } 3132 } 3133 } 3134 } 3135 3136 // Value checking cases when unused uniforms are present. 3137 3138 unusedUniformsGroup = tcuTestCase.newTest('unused_uniforms', 'Test with unused uniforms'); 3139 assignedValuesGroup.addChild(unusedUniformsGroup); 3140 3141 collectionGroup = defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT]; 3142 3143 for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) { 3144 collectionCase = collectionGroup.cases[collectionNdx]; 3145 collName = collectionCase.namePrefix; 3146 uniformCollection = collectionCase.uniformCollection; 3147 3148 for (var i = 0; i < shaderTypes.length; i++) { 3149 name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]); 3150 3151 features = new es3fUniformApiTests.Feature(); 3152 features.ARRAYUSAGE_ONLY_MIDDLE_INDEX = true; 3153 features.UNIFORMUSAGE_EVERY_OTHER = true; 3154 3155 unusedUniformsGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, 3156 es3fUniformApiTests.ValueToCheck.ASSIGNED, es3fUniformApiTests.CheckMethod.GET_UNIFORM, es3fUniformApiTests.AssignMethod.POINTER, 3157 features)); 3158 } 3159 } 3160 3161 // Random cases. 3162 3163 /** @type {number} */ var numRandomCases = 100; 3164 /** @type {tcuTestCase.DeqpTest} */ var randomGroup = tcuTestCase.newTest('random', 'Random cases'); 3165 testGroup.addChild(randomGroup); 3166 3167 for (var ndx = 0; ndx < numRandomCases; ndx++) 3168 randomGroup.addChild(new es3fUniformApiTests.RandomUniformCase('' + ndx, '', ndx)); 3169 }; 3170 3171 /** 3172 * Create and execute the test cases 3173 * @param {WebGL2RenderingContext} context 3174 */ 3175 es3fUniformApiTests.run = function(context, range) { 3176 gl = context; 3177 //Set up Test Root parameters 3178 var testName = 'uniform_api'; 3179 var testDescription = 'es3fUniformApiTests.Uniform API Tests'; 3180 var state = tcuTestCase.runner; 3181 3182 state.testName = testName; 3183 state.testCases = tcuTestCase.newTest(testName, testDescription, null); 3184 3185 //Set up name and description of this test series. 3186 setCurrentTestName(testName); 3187 description(testDescription); 3188 3189 try { 3190 //Create test cases 3191 es3fUniformApiTests.init(); 3192 if (range) 3193 state.setRange(range); 3194 //Run test cases 3195 tcuTestCase.runTestCases(); 3196 } 3197 catch (err) { 3198 testFailedOptions('Failed to es3fUniformApiTests.run tests', false); 3199 tcuTestCase.runner.terminate(); 3200 } 3201 }; 3202 3203 });