es3fShaderCommonFunctionTests.js (95022B)
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.es3fShaderCommonFunctionTests'); 23 goog.require('framework.common.tcuFloat'); 24 goog.require('framework.common.tcuTestCase'); 25 goog.require('framework.delibs.debase.deMath'); 26 goog.require('framework.delibs.debase.deRandom'); 27 goog.require('framework.delibs.debase.deString'); 28 goog.require('framework.opengl.gluShaderProgram'); 29 goog.require('framework.opengl.gluShaderUtil'); 30 goog.require('framework.opengl.gluVarType'); 31 goog.require('modules.shared.glsShaderExecUtil'); 32 goog.scope(function() { 33 var es3fShaderCommonFunctionTests = functional.gles3.es3fShaderCommonFunctionTests; 34 var tcuFloat = framework.common.tcuFloat; 35 var tcuTestCase = framework.common.tcuTestCase; 36 var gluShaderProgram = framework.opengl.gluShaderProgram; 37 var gluShaderUtil = framework.opengl.gluShaderUtil; 38 var gluVarType = framework.opengl.gluVarType; 39 var deRandom = framework.delibs.debase.deRandom; 40 var deMath = framework.delibs.debase.deMath; 41 var deString = framework.delibs.debase.deString; 42 var glsShaderExecUtil = modules.shared.glsShaderExecUtil; 43 44 /** @typedef {function(new: es3fShaderCommonFunctionTests.CommonFunctionCase, gluShaderUtil.DataType, gluShaderUtil.precision, gluShaderProgram.shaderType)} */ es3fShaderCommonFunctionTests.TestClass; 45 46 /** 47 * @enum 48 */ 49 es3fShaderCommonFunctionTests.Types = { 50 FLOAT: 0, 51 INT: 1, 52 UINT: 2 53 }; 54 55 /** 56 * @param {Array<number>} values 57 */ 58 es3fShaderCommonFunctionTests.vecToFloat16 = function(values) { 59 for (var ndx = 0; ndx < values.length; ndx++) 60 values[ndx] = tcuFloat.newFloat16(values[ndx]).getValue(); 61 }; 62 63 /** 64 * @param {es3fShaderCommonFunctionTests.Types} type 65 * @param {deRandom.Random} rnd 66 * @param {number} minValue 67 * @param {number} maxValue 68 * @return {number} 69 */ 70 es3fShaderCommonFunctionTests.randomScalar = function(type, rnd, minValue, maxValue) { 71 switch (type) { 72 case es3fShaderCommonFunctionTests.Types.FLOAT: return rnd.getFloat(minValue, maxValue); 73 case es3fShaderCommonFunctionTests.Types.INT: return rnd.getInt(minValue, maxValue); 74 case es3fShaderCommonFunctionTests.Types.UINT: return Math.abs(rnd.getInt(minValue, maxValue)); 75 default: throw new Error('Only FLOAT, INT, and UINT are supported.'); 76 } 77 }; 78 79 /** 80 * @param {es3fShaderCommonFunctionTests.Types} type 81 * @param {Array<number>} size 82 * @param {deRandom.Random} rnd 83 * @param {Array<number>} minValue 84 * @param {Array<number>} maxValue 85 * @return {Array<number>} 86 */ 87 es3fShaderCommonFunctionTests.randomVector = function(type, size, rnd, minValue, maxValue) { 88 /** @type {Array<number>} */ var res = []; 89 for (var ndx = 0; ndx < size; ndx++) 90 res.push(es3fShaderCommonFunctionTests.randomScalar(type, rnd, minValue[ndx], maxValue[ndx])); 91 return res; 92 }; 93 94 /** 95 * @param {es3fShaderCommonFunctionTests.Types} type 96 * @param {Array<number>} size 97 * @param {deRandom.Random} rnd 98 * @param {Array<number>} minValue 99 * @param {Array<number>} maxValue 100 * @param {number} numValues 101 * @param {number=} offset 102 * @return {Array<Array<number>>} 103 */ 104 es3fShaderCommonFunctionTests.fillRandomVectors = function(type, size, rnd, minValue, maxValue, numValues, offset) { 105 offset = offset === undefined ? 0 : offset; 106 /** @type {Array<Array<number>>} */ var access; 107 for (var ndx = 0; ndx < numValues; ndx++) 108 access[offset + ndx] = es3fShaderCommonFunctionTests.randomVector(type, size, rnd, minValue, maxValue); 109 return access; 110 }; 111 112 /** 113 * @param {es3fShaderCommonFunctionTests.Types} type 114 * @param {deRandom.Random} rnd 115 * @param {number} minValue 116 * @param {number} maxValue 117 * @param {number} numValues 118 * @param {number=} offset 119 * @return {Array<number>} 120 */ 121 es3fShaderCommonFunctionTests.fillRandomScalars = function(type, rnd, minValue, maxValue, numValues, offset) { 122 offset = offset === undefined ? 0 : offset; 123 /** @type {Array<number>} */ var access = []; 124 for (var ndx = 0; ndx < numValues; ndx++) 125 access[offset + ndx] = es3fShaderCommonFunctionTests.randomScalar(type, rnd, minValue, maxValue); 126 return access; 127 }; 128 129 /** 130 * @param {number} input 131 * @param {number} output 132 * @return {number} 133 */ 134 es3fShaderCommonFunctionTests.numBitsLostInOp = function(input, output) { 135 /** @type {number} */ var inExp = tcuFloat.newFloat32(input).exponent(); 136 /** @type {number} */ var outExp = tcuFloat.newFloat32(output).exponent(); 137 return Math.max(0, inExp - outExp); // Lost due to mantissa shift. 138 }; 139 140 /** 141 * @param {number} a 142 * @param {number} b 143 * @return {number} 144 */ 145 es3fShaderCommonFunctionTests.getUlpDiff = function(a, b) { 146 /** @type {number} */ var aBits = tcuFloat.newFloat32(a).bits(); 147 /** @type {number} */ var bBits = tcuFloat.newFloat32(b).bits(); 148 return aBits > bBits ? aBits - bBits : bBits - aBits; 149 }; 150 151 /** 152 * @param {number} a 153 * @param {number} b 154 * @return {number} 155 */ 156 es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign = function(a, b) { 157 if (tcuFloat.newFloat32(a).isZero()) 158 return es3fShaderCommonFunctionTests.getUlpDiff(new tcuFloat.deFloat().construct(tcuFloat.newFloat32(b).sign(), 0, 0).getValue(), b); 159 else if (tcuFloat.newFloat32(b).isZero()) 160 return es3fShaderCommonFunctionTests.getUlpDiff(a, new tcuFloat.deFloat().construct(tcuFloat.newFloat32(a).sign(), 0, 0).getValue()); 161 else 162 return es3fShaderCommonFunctionTests.getUlpDiff(a, b); 163 }; 164 165 /** 166 * @param {gluShaderUtil.precision} precision 167 * @return {boolean} 168 */ 169 es3fShaderCommonFunctionTests.supportsSignedZero = function(precision) { 170 // \note GLSL ES 3.0 doesn't really require support for -0, but we require it for highp 171 // as it is very widely supported. 172 return precision == gluShaderUtil.precision.PRECISION_HIGHP; 173 }; 174 175 /** 176 * @param {number} value 177 * @param {number} ulpDiff 178 * @return {number} 179 */ 180 es3fShaderCommonFunctionTests.getEpsFromMaxUlpDiff = function(value, ulpDiff) { 181 /** @type {number} */ var exp = tcuFloat.newFloat32(value).exponent(); 182 return new tcuFloat.deFloat().construct(+1, exp, (1 << 23) | ulpDiff).getValue() - new tcuFloat.deFloat().construct(+1, exp, 1 << 23).getValue(); 183 }; 184 185 /** 186 * @param {number} numAccurateBits 187 * @return {number} 188 */ 189 es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits = function(numAccurateBits) { 190 /** @type {number} */ var numGarbageBits = 23 - numAccurateBits; 191 /** @type {number} */ var mask = (1 << numGarbageBits) - 1; 192 193 return mask; 194 }; 195 196 /** 197 * @param {number} value 198 * @param {number} numAccurateBits 199 * @return {number} 200 */ 201 es3fShaderCommonFunctionTests.getEpsFromBits = function(value, numAccurateBits) { 202 return es3fShaderCommonFunctionTests.getEpsFromMaxUlpDiff(value, es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(numAccurateBits)); 203 }; 204 205 /** 206 * @param {gluShaderUtil.precision} precision 207 * @return {number} 208 */ 209 es3fShaderCommonFunctionTests.getMinMantissaBits = function(precision) { 210 /** @type {Array<number>} */ var bits = [ 211 7, // lowp 212 10, // mediump 213 23 // highp 214 ]; 215 216 assertMsgOptions(deMath.deInBounds32(precision, 0, bits.length), 'Unexpected precision option.', false, true); 217 return bits[precision]; 218 }; 219 220 /** 221 * @constructor 222 * @extends {tcuTestCase.DeqpTest} 223 * @param {string} name 224 * @param {string} description 225 * @param {gluShaderProgram.shaderType} shaderType 226 */ 227 es3fShaderCommonFunctionTests.CommonFunctionCase = function(name, description, shaderType) { 228 tcuTestCase.DeqpTest.call(this, name, description); 229 /** @type {gluShaderProgram.shaderType} */ this.m_shaderType = shaderType; 230 /** @type {number} */ this.m_numValues = 100; 231 /** @type {glsShaderExecUtil.ShaderExecutor} */ this.m_executor = null; 232 /** @type {glsShaderExecUtil.ShaderSpec} */ this.m_spec = new glsShaderExecUtil.ShaderSpec(); 233 this.m_spec.version = gluShaderUtil.GLSLVersion.V300_ES; 234 /** @type {string} */ this.m_failMsg; //!< Comparison failure help message. 235 }; 236 237 es3fShaderCommonFunctionTests.CommonFunctionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 238 es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.constructor = es3fShaderCommonFunctionTests.CommonFunctionCase; 239 240 es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.init = function() { 241 assertMsgOptions(!this.m_executor, 'Shader executor should be null at this point', false, true); 242 this.m_executor = glsShaderExecUtil.createExecutor(this.m_shaderType, this.m_spec); 243 if (!this.m_executor.isOk()) 244 throw new Error('Compile failed'); 245 }; 246 247 es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.deinit = function() { 248 this.m_executor = null; 249 }; 250 251 /** 252 * @param {Array<glsShaderExecUtil.Symbol>} symbols 253 * @return {Array<number>} 254 */ 255 es3fShaderCommonFunctionTests.getScalarSizes = function(symbols) { 256 /** @type {Array<number>} */ var sizes = []; 257 for (var ndx = 0; ndx < symbols.length; ++ndx) 258 sizes.push(symbols[ndx].varType.getScalarSize()); 259 return sizes; 260 }; 261 262 /** 263 * @param {Array<glsShaderExecUtil.Symbol>} symbols 264 * @return {number} 265 */ 266 es3fShaderCommonFunctionTests.computeTotalScalarSize = function(symbols) { 267 /** @type {number} */ var totalSize = 0; 268 for (var sym in symbols) 269 totalSize += symbols[sym].varType.getScalarSize(); 270 return totalSize; 271 }; 272 273 /** 274 * @param {boolean} value 275 * @return {string} 276 */ 277 es3fShaderCommonFunctionTests.ToBoolString = function(value) { 278 return value ? "true" : "false"; 279 }; 280 281 /** 282 * @param {gluVarType.VarType} varType 283 * @param {Array<*>} values 284 * @return {string} 285 */ 286 es3fShaderCommonFunctionTests.VarValue = function(varType, values) { 287 /** @type {gluShaderUtil.DataType} */ var basicType = varType.getBasicType(); 288 /** @type {gluShaderUtil.DataType} */ var scalarType = gluShaderUtil.getDataTypeScalarTypeAsDataType(basicType); 289 /** @type {number} */ var numComponents = gluShaderUtil.getDataTypeScalarSize(basicType); 290 /** @type {string} */ var outputStr = ""; 291 292 if (numComponents > 1) { 293 outputStr += gluShaderUtil.getDataTypeName(basicType) + "("; 294 } 295 296 for (var compNdx = 0; compNdx < numComponents; ++compNdx) { 297 if (compNdx != 0) { 298 outputStr += ", "; 299 } 300 301 // tcu::toHex() is all commented out in this project. 302 // e.g. Line 199 of es3fShaderPackingFunctionTests.js 303 switch (scalarType) { 304 case gluShaderUtil.DataType.FLOAT: 305 case gluShaderUtil.DataType.INT: 306 case gluShaderUtil.DataType.UINT: 307 outputStr += values[compNdx]; 308 break; 309 case gluShaderUtil.DataType.BOOL: 310 outputStr += es3fShaderCommonFunctionTests.ToBoolString(values[compNdx]); 311 break; 312 313 default: 314 throw Error('Unrecognized dataType ' + scalarType); 315 } 316 } 317 318 if (numComponents > 1) { 319 outputStr += ")"; 320 } 321 322 return outputStr; 323 } 324 325 /** 326 * @return {tcuTestCase.IterateResult} 327 */ 328 es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.iterate = function() { 329 /** @type {number} */ var numInputScalars = es3fShaderCommonFunctionTests.computeTotalScalarSize(this.m_spec.inputs); 330 /** @type {number} */ var numOutputScalars = es3fShaderCommonFunctionTests.computeTotalScalarSize(this.m_spec.outputs); 331 /** @type {Array<goog.TypedArray>} */ var inputData = []; 332 /** @type {Array<goog.TypedArray>} */ var outputData = []; 333 /** @type {gluShaderUtil.DataType} */ var inputType = this.m_spec.inputs[0].varType.getBasicType(); 334 /** @type {gluShaderUtil.DataType} */ var outputType = this.m_spec.outputs[0].varType.getBasicType(); 335 /** @type {Array<Array<number>>} */ var inputValues; 336 /** @type {ArrayBuffer} */ var outputValues; 337 inputValues = this.getInputValues(this.m_numValues); 338 339 for (var inNdx = 0; inNdx < inputValues.length; inNdx++) { 340 var data = inputType >= gluShaderUtil.DataType.FLOAT && inputType <= gluShaderUtil.DataType.FLOAT_VEC4 ? new Float32Array(inputValues[inNdx]) : 341 inputType >= gluShaderUtil.DataType.INT && inputType <= gluShaderUtil.DataType.INT_VEC4 ? new Int32Array(inputValues[inNdx]) : 342 inputType >= gluShaderUtil.DataType.UINT && inputType <= gluShaderUtil.DataType.UINT_VEC4 ? new Uint32Array(inputValues[inNdx]) : 343 null; 344 inputData.push(data); 345 } 346 347 // Execute shader. 348 this.m_executor.useProgram(); 349 outputValues = this.m_executor.execute(this.m_numValues, inputData); 350 for (var outNdx = 0; outNdx < outputValues.length; outNdx++) { 351 var data = outputType >= gluShaderUtil.DataType.FLOAT && outputType <= gluShaderUtil.DataType.FLOAT_VEC4 ? new Float32Array(outputValues[outNdx].buffer) : 352 outputType >= gluShaderUtil.DataType.INT && outputType <= gluShaderUtil.DataType.INT_VEC4 ? new Int32Array(outputValues[outNdx].buffer) : 353 outputType >= gluShaderUtil.DataType.UINT && outputType <= gluShaderUtil.DataType.UINT_VEC4 ? new Uint32Array(outputValues[outNdx].buffer) : 354 outputType >= gluShaderUtil.DataType.BOOL && outputType <= gluShaderUtil.DataType.BOOL_VEC4 ? new Int32Array(outputValues[outNdx].buffer) : 355 null; 356 outputData.push(data); 357 } 358 359 // TODO: verify proper TypedArray for BOOL types; defaulting to Int32Array in the mean time (outputValues returns 400 bytes, we need 100 elements) 360 // Compare results. 361 /** @type {Array<number>} */ var inScalarSizes = es3fShaderCommonFunctionTests.getScalarSizes(this.m_spec.inputs); 362 /** @type {Array<number>} */ var outScalarSizes = es3fShaderCommonFunctionTests.getScalarSizes(this.m_spec.outputs); 363 /** @type {Array<*>} */ var curInputPtr = []; 364 /** @type {Array<*>} */ var curOutputPtr = []; 365 /** @type {number} */ var numFailed = 0; 366 367 for (var inNdx = 0; inNdx < inputData.length; inNdx++) { 368 curInputPtr[inNdx] = []; 369 for (var valNdx = 0; valNdx < inputData[inNdx].length; valNdx += inScalarSizes[inNdx]) 370 curInputPtr[inNdx].push(inputData[inNdx].slice(valNdx, valNdx + inScalarSizes[inNdx])); 371 } 372 373 for (var outNdx = 0; outNdx < outputData.length; outNdx++) { 374 curOutputPtr[outNdx] = []; 375 for (var valNdx = 0; valNdx < outputData[outNdx].length; valNdx += outScalarSizes[outNdx]) 376 curOutputPtr[outNdx].push(outputData[outNdx].slice(valNdx, valNdx + outScalarSizes[outNdx])); 377 } 378 379 this.m_failMsg = ''; 380 for (var valNdx = 0; valNdx < this.m_numValues; valNdx++) { 381 var curInputValues = []; 382 var curOutputValues = []; 383 for (var inNdx = 0; inNdx < inputData.length; inNdx++) { 384 curInputValues.push(curInputPtr[inNdx][valNdx]); 385 } 386 for (var outNdx = 0; outNdx < outputData.length; outNdx++) { 387 curOutputValues.push(curOutputPtr[outNdx][valNdx]); 388 } 389 if (!this.compare(curInputValues, curOutputValues)) { 390 // \todo [2013-08-08 pyry] We probably want to log reference value as well? 391 392 bufferedLogToConsole('ERROR: comparison failed for value ' + valNdx + ':\n ' + this.m_failMsg); 393 bufferedLogToConsole(' inputs:'); 394 for (var inNdx = 0; inNdx < inputData.length; ++inNdx) { 395 var varValue = es3fShaderCommonFunctionTests.VarValue(this.m_spec.inputs[0].varType, curInputValues[inNdx]); 396 bufferedLogToConsole(' ' + this.m_spec.inputs[inNdx].name + ' = ' + varValue); 397 } 398 399 bufferedLogToConsole(' outputs:'); 400 for (var outNdx = 0; outNdx < outputData.length; ++outNdx) { 401 var varValue = es3fShaderCommonFunctionTests.VarValue(this.m_spec.inputs[0].varType, curOutputValues[outNdx]); 402 bufferedLogToConsole(' ' + this.m_spec.outputs[outNdx].name + ' = ' + varValue); 403 } 404 405 this.m_failMsg = ''; 406 numFailed += 1; 407 } 408 } 409 410 bufferedLogToConsole((this.m_numValues - numFailed) + ' / ' + this.m_numValues + ' values passed'); 411 412 /** @type {boolean} */ var isOk = numFailed === 0; 413 414 if (!isOk) 415 testFailedOptions('Result comparison failed', false); 416 else 417 testPassedOptions('Pass', true); 418 419 return tcuTestCase.IterateResult.STOP; 420 }; 421 422 /** 423 * @param {gluShaderUtil.precision} precision 424 * @return {string} 425 */ 426 es3fShaderCommonFunctionTests.getPrecisionPostfix = function(precision) { 427 /** @type {Array<string>} */ var s_postfix = [ 428 '_lowp', 429 '_mediump', 430 '_highp' 431 ]; 432 assertMsgOptions(0 <= precision && precision < s_postfix.length, 'Error: Out of range', false, true); 433 return s_postfix[precision]; 434 }; 435 436 /** 437 * @param {gluShaderProgram.shaderType} shaderType 438 * @return {string} 439 */ 440 es3fShaderCommonFunctionTests.getShaderTypePostfix = function(shaderType) { 441 /** @type {Array<string>} */ var s_postfix = [ 442 '_vertex', 443 '_fragment' 444 ]; 445 assertMsgOptions(0 <= shaderType && shaderType < s_postfix.length, 'Error Out of range', false, true); 446 return s_postfix[shaderType]; 447 }; 448 449 /** 450 * @param {gluShaderUtil.DataType} baseType 451 * @param {gluShaderUtil.precision} precision 452 * @param {gluShaderProgram.shaderType} shaderType 453 * @return {string} 454 */ 455 es3fShaderCommonFunctionTests.getCommonFuncCaseName = function(baseType, precision, shaderType) { 456 return gluShaderUtil.getDataTypeName(baseType) + 457 es3fShaderCommonFunctionTests.getPrecisionPostfix(precision) + 458 es3fShaderCommonFunctionTests.getShaderTypePostfix(shaderType); 459 }; 460 461 /** 462 * @constructor 463 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 464 * @param {gluShaderUtil.DataType} baseType 465 * @param {gluShaderUtil.precision} precision 466 * @param {gluShaderProgram.shaderType} shaderType 467 */ 468 es3fShaderCommonFunctionTests.AbsCase = function(baseType, precision, shaderType) { 469 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 470 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 471 'abs', shaderType); 472 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 473 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 474 this.m_spec.source = 'out0 = abs(in0);'; 475 }; 476 477 es3fShaderCommonFunctionTests.AbsCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 478 es3fShaderCommonFunctionTests.AbsCase.prototype.constructor = es3fShaderCommonFunctionTests.AbsCase; 479 480 /** 481 * @param {number} numValues 482 * @return {*} 483 */ 484 es3fShaderCommonFunctionTests.AbsCase.prototype.getInputValues = function(numValues) { 485 /** @type {Array<Array<number>>} */ var floatRanges = [ 486 [-2.0, 2.0], // lowp 487 [-1e3, 1e3], // mediump 488 [-1e7, 1e7] // highp 489 ]; 490 491 /** @type {Array<Array<number>>} */ var intRanges = [ 492 [-(1 << 7) + 1, (1 << 7) - 1], 493 [-(1 << 15) + 1, (1 << 15) - 1], 494 [-0x80000000 + 1, 0x7fffffff] 495 ]; 496 497 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x235fac); 498 499 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 500 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 501 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 502 /** @type {Array<Array<number>>} */ var values = []; 503 values[0] = []; 504 505 if (gluShaderUtil.isDataTypeFloatOrVec(type)) 506 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, floatRanges[precision][0], floatRanges[precision][1], numValues * scalarSize); 507 else 508 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.INT, rnd, intRanges[precision][0], intRanges[precision][1], numValues * scalarSize); 509 510 return values; 511 }; 512 513 /** 514 * @param {*} inputs 515 * @param {*} outputs 516 * @return {boolean} 517 */ 518 es3fShaderCommonFunctionTests.AbsCase.prototype.compare = function(inputs, outputs) { 519 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 520 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 521 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 522 523 /** @type {number} */ var in0; 524 /** @type {number} */ var out0; 525 /** @type {number} */ var ref0; 526 527 if (gluShaderUtil.isDataTypeFloatOrVec(type)) { 528 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 529 /** @type {number} */ var maxUlpDiff = (1 << (23 - mantissaBits)) - 1; 530 531 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 532 in0 = inputs[0][compNdx]; 533 out0 = outputs[0][compNdx]; 534 ref0 = Math.abs(in0); 535 /** @type {number} */ var ulpDiff0 = es3fShaderCommonFunctionTests.getUlpDiff(out0, ref0); 536 537 if (ulpDiff0 > maxUlpDiff) { 538 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0 /*HexFloat(ref0)*/ + ' with ULP threshold ' + maxUlpDiff + ', got ULP diff ' + ulpDiff0; 539 return false; 540 } 541 } 542 } else 543 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 544 in0 = inputs[0][compNdx]; 545 out0 = outputs[0][compNdx]; 546 ref0 = Math.abs(in0); 547 548 if (out0 != ref0) { 549 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0; 550 return false; 551 } 552 } 553 554 return true; 555 }; 556 557 /** 558 * @constructor 559 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 560 * @param {gluShaderUtil.DataType} baseType 561 * @param {gluShaderUtil.precision} precision 562 * @param {gluShaderProgram.shaderType} shaderType 563 */ 564 es3fShaderCommonFunctionTests.SignCase = function(baseType, precision, shaderType) { 565 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 566 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 567 'sign', shaderType); 568 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 569 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 570 this.m_spec.source = 'out0 = sign(in0);'; 571 }; 572 573 es3fShaderCommonFunctionTests.SignCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 574 es3fShaderCommonFunctionTests.SignCase.prototype.constructor = es3fShaderCommonFunctionTests.SignCase; 575 576 /** 577 * @param {number} numValues 578 * @return {*} 579 */ 580 es3fShaderCommonFunctionTests.SignCase.prototype.getInputValues = function(numValues) { 581 /** @type {Array<Array<number>>} */ var floatRanges = [ 582 [-2.0, 2.0], // lowp 583 [-1e4, 1e4], // mediump 584 [-1e8, 1e8] // highp 585 ]; 586 587 /** @type {Array<Array<number>>} */ var intRanges = [ 588 [-(1 << 7), (1 << 7) - 1], 589 [-(1 << 15), (1 << 15) - 1], 590 [0x80000000, 0x7fffffff] 591 ]; 592 593 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x324); 594 595 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 596 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 597 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 598 /** @type {Array<Array<number>>} */ var values = []; 599 values[0] = []; 600 601 if (gluShaderUtil.isDataTypeFloatOrVec(type)) { 602 // Special cases. 603 // [dag] The special cases are 1, -1, and 0 604 var specialCases = [1.0, -1.0, 0.0]; 605 for (var caseNdx = 0; caseNdx < specialCases.length; caseNdx++) 606 for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) { 607 values[0].push(specialCases[caseNdx]); 608 } 609 values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, floatRanges[precision][0], floatRanges[precision][1], (numValues - 3) * scalarSize)); 610 } else { 611 var specialCases = [1, -1, 0]; 612 for (var caseNdx = 0; caseNdx < specialCases.length; caseNdx++) 613 for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) { 614 values[0].push(specialCases[caseNdx]); 615 } 616 values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.INT, rnd, intRanges[precision][0], intRanges[precision][1], (numValues - 3) * scalarSize)); 617 } 618 619 return values; 620 }; 621 622 /** 623 * @param {*} inputs 624 * @param {*} outputs 625 * @return {boolean} 626 */ 627 es3fShaderCommonFunctionTests.SignCase.prototype.compare = function(inputs, outputs) { 628 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 629 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 630 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 631 632 /** @type {number} */ var in0; 633 /** @type {number} */ var out0; 634 /** @type {number} */ var ref0; 635 636 if (gluShaderUtil.isDataTypeFloatOrVec(type)) { 637 // Both highp and mediump should be able to represent -1, 0, and +1 exactly 638 /** @type {number} */ var maxUlpDiff = precision === gluShaderUtil.precision.PRECISION_LOWP ? 639 es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(es3fShaderCommonFunctionTests.getMinMantissaBits(precision)) : 640 0; 641 642 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 643 in0 = inputs[0][compNdx]; 644 out0 = outputs[0][compNdx]; 645 ref0 = in0 < 0.0 ? -1.0 : 646 in0 > 0.0 ? 1.0 : 0.0; 647 /** @type {number} */ var ulpDiff0 = es3fShaderCommonFunctionTests.getUlpDiff(out0, ref0); 648 649 if (ulpDiff0 > maxUlpDiff) { 650 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0 /*HexFloat(ref0)*/ + ' with ULP threshold ' + maxUlpDiff + ', got ULP diff ' + ulpDiff0; 651 return false; 652 } 653 } 654 } else { 655 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 656 in0 = inputs[0][compNdx]; 657 out0 = outputs[0][compNdx]; 658 ref0 = in0 < 0 ? -1 : 659 in0 > 0 ? 1 : 0; 660 661 if (out0 != ref0) { 662 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0; 663 return false; 664 } 665 } 666 } 667 668 return true; 669 }; 670 671 /** 672 * @param {number} v 673 * @return {number} 674 */ 675 es3fShaderCommonFunctionTests.roundEven = function(v) { 676 /** @type {number} */ var q = deMath.deFloatFrac(v); 677 /** @type {number} */ var truncated = Math.trunc(v - q); 678 /** @type {number} */ var rounded = (q > 0.5) ? (truncated + 1) : // Rounded up 679 (q == 0.5 && (truncated % 2 != 0)) ? (truncated + 1) : // Round to nearest even at 0.5 680 truncated; // Rounded down 681 return rounded; 682 }; 683 684 /** 685 * @constructor 686 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 687 * @param {gluShaderUtil.DataType} baseType 688 * @param {gluShaderUtil.precision} precision 689 * @param {gluShaderProgram.shaderType} shaderType 690 */ 691 es3fShaderCommonFunctionTests.RoundEvenCase = function(baseType, precision, shaderType) { 692 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 693 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 694 'roundEven', shaderType); 695 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 696 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 697 this.m_spec.source = 'out0 = roundEven(in0);'; 698 }; 699 700 es3fShaderCommonFunctionTests.RoundEvenCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 701 es3fShaderCommonFunctionTests.RoundEvenCase.prototype.constructor = es3fShaderCommonFunctionTests.RoundEvenCase; 702 703 /** 704 * @param {number} numValues 705 * @return {*} 706 */ 707 es3fShaderCommonFunctionTests.RoundEvenCase.prototype.getInputValues = function(numValues) { 708 /** @type {Array<Array<number>>} */ var ranges = [ 709 [-2.0, 2.0], // lowp 710 [-1e3, 1e3], // mediump 711 [-1e7, 1e7] // highp 712 ]; 713 714 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 715 716 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 717 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 718 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 719 /** @type {number} */ var numSpecialCases = 0; 720 /** @type {Array<Array<number>>} */ var values = []; 721 values[0] = []; 722 // Special cases. 723 if (precision !== gluShaderUtil.precision.PRECISION_LOWP) { 724 assertMsgOptions(numValues >= 20, 'numValues should be greater or equal than 20', false, true); 725 for (var ndx = 0; ndx < 20; ndx++) { 726 /** @type {number} */ var v = deMath.clamp(ndx - 10.5, ranges[precision][0], ranges[precision][1]); 727 for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) { 728 values[0].push(v); 729 } 730 numSpecialCases += 1; 731 } 732 } 733 734 // Random cases. 735 values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - numSpecialCases) * scalarSize)); 736 737 // If precision is mediump, make sure values can be represented in fp16 exactly 738 if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP) 739 es3fShaderCommonFunctionTests.vecToFloat16(values[0]); 740 741 return values; 742 }; 743 744 /** 745 * @param {*} inputs 746 * @param {*} outputs 747 * @return {boolean} 748 */ 749 es3fShaderCommonFunctionTests.RoundEvenCase.prototype.compare = function(inputs, outputs) { 750 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 751 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 752 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 753 /** @type {number} */ var in0; 754 /** @type {number} */ var out0; 755 756 if (precision == gluShaderUtil.precision.PRECISION_HIGHP || precision == gluShaderUtil.precision.PRECISION_MEDIUMP) { 757 // Require exact rounding result. 758 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 759 in0 = inputs[0][compNdx]; 760 out0 = outputs[0][compNdx]; 761 /** @type {number} */ var ref = es3fShaderCommonFunctionTests.roundEven(in0); 762 763 /** @type {number} */ var ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref); 764 765 if (ulpDiff > 0) { 766 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff; 767 return false; 768 } 769 } 770 } else { 771 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 772 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 773 /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds 774 775 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 776 in0 = inputs[0][compNdx]; 777 out0 = outputs[0][compNdx]; 778 /** @type {number} */ var minRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 - eps)); 779 /** @type {number} */ var maxRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 + eps)); 780 /** @type {boolean} */ var anyOk = false; 781 782 for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) { 783 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal); 784 785 if (ulpDiff <= maxUlpDiff) { 786 anyOk = true; 787 break; 788 } 789 } 790 791 if (!anyOk) { 792 this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff; 793 return false; 794 } 795 } 796 } 797 798 return true; 799 }; 800 801 /** 802 * @constructor 803 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 804 * @param {gluShaderUtil.DataType} baseType 805 * @param {gluShaderUtil.precision} precision 806 * @param {gluShaderProgram.shaderType} shaderType 807 */ 808 es3fShaderCommonFunctionTests.ModfCase = function(baseType, precision, shaderType) { 809 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 810 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 811 'modf', shaderType); 812 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 813 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 814 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out1', gluVarType.newTypeBasic(baseType, precision))); 815 this.m_spec.source = 'out0 = modf(in0, out1);'; 816 }; 817 818 es3fShaderCommonFunctionTests.ModfCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 819 es3fShaderCommonFunctionTests.ModfCase.prototype.constructor = es3fShaderCommonFunctionTests.ModfCase; 820 821 /** 822 * @param {number} numValues 823 * @return {*} 824 */ 825 es3fShaderCommonFunctionTests.ModfCase.prototype.getInputValues = function(numValues) { 826 /** @type {Array<Array<number>>} */ var ranges = [ 827 [-2.0, 2.0], // lowp 828 [-1e3, 1e3], // mediump 829 [-1e7, 1e7] // highp 830 ]; 831 832 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 833 834 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 835 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 836 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 837 /** @type {Array<Array<number>>} */ var values = []; 838 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize); 839 840 return values; 841 }; 842 843 /** 844 * @param {*} inputs 845 * @param {*} outputs 846 * @return {boolean} 847 */ 848 es3fShaderCommonFunctionTests.ModfCase.prototype.compare = function(inputs, outputs) { 849 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 850 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 851 /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision); 852 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 853 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 854 /** @type {number} */ var in0; 855 /** @type {number} */ var out0; 856 /** @type {number} */ var out1; 857 858 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 859 in0 = inputs[0][compNdx]; 860 out0 = outputs[0][compNdx]; 861 out1 = outputs[1][compNdx]; 862 863 /** @type {number} */ var refOut1 = Math.floor(in0); 864 /** @type {number} */ var refOut0 = in0 - refOut1; 865 866 /** @type {number} */ var bitsLost = precision != gluShaderUtil.precision.PRECISION_HIGHP ? es3fShaderCommonFunctionTests.numBitsLostInOp(in0, refOut0) : 0; 867 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(Math.max(mantissaBits - bitsLost, 0)); 868 869 /** @type {number} */ var resSum = out0 + out1; 870 871 /** @type {number} */ var ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(resSum, in0) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(resSum, in0); 872 873 if (ulpDiff > maxUlpDiff) { 874 this.m_failMsg += 'Expected [' + compNdx + '] = (' + refOut0 + ') + (' + refOut1 + ') = ' + in0 + ' with ULP threshold ' + 875 maxUlpDiff + ', got ULP diff ' + ulpDiff; 876 return false; 877 } 878 } 879 880 return true; 881 }; 882 883 /** 884 * @constructor 885 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 886 * @param {gluShaderUtil.DataType} baseType 887 * @param {gluShaderUtil.precision} precision 888 * @param {gluShaderProgram.shaderType} shaderType 889 */ 890 es3fShaderCommonFunctionTests.IsnanCase = function(baseType, precision, shaderType) { 891 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 892 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 893 'isnan', shaderType); 894 assertMsgOptions(gluShaderUtil.isDataTypeFloatOrVec(baseType), 'Assert error.', false, true); 895 896 /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType); 897 /** @type {gluShaderUtil.DataType} */ var boolType = vecSize > 1 ? 898 gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.BOOL, vecSize) : 899 gluShaderUtil.DataType.BOOL; 900 901 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 902 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(boolType))); 903 this.m_spec.source = 'out0 = isnan(in0);'; 904 }; 905 906 es3fShaderCommonFunctionTests.IsnanCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 907 es3fShaderCommonFunctionTests.IsnanCase.prototype.constructor = es3fShaderCommonFunctionTests.IsnanCase; 908 909 /** 910 * @param {number} numValues 911 * @return {*} 912 */ 913 es3fShaderCommonFunctionTests.IsnanCase.prototype.getInputValues = function(numValues) { 914 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xc2a39f); 915 916 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 917 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 918 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 919 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 920 /** @type {number} */ var mantissaMask = (~es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits)) & ((1 << 23) - 1); 921 /** @type {Array<Array<number>>} */ var values = []; 922 values[0] = []; 923 924 for (var valNdx = 0; valNdx < numValues * scalarSize; valNdx++) { 925 /** @type {boolean} */ var isNan = rnd.getFloat() > 0.3; 926 /** @type {boolean} */ var isInf = !isNan && rnd.getFloat() > 0.4; 927 /** @type {number} */ var mantissa = !isInf ? ((1 << 22) | (Math.abs(rnd.getInt()) & mantissaMask)) : 0; 928 /** @type {number} */ var exp = !isNan && !isInf ? (Math.abs(rnd.getInt()) & 0x7f) : 0xff; 929 /** @type {number} */ var sign = Math.abs(rnd.getInt()) & 0x1; 930 /** @type {number} */ var value = (sign << 31) | (exp << 23) | mantissa; 931 932 // Convert int to float. 933 var view = new DataView(new ArrayBuffer(4)); 934 view.setInt32(0, value, true); 935 value = view.getFloat32(0, true); 936 937 assertMsgOptions(tcuFloat.newFloat32(value).isInf() === isInf && tcuFloat.newFloat32(value).isNaN() === isNan, 'Assert error.', false, true); 938 939 values[0].push(value); 940 } 941 942 return values; 943 }; 944 945 /** 946 * @param {*} inputs 947 * @param {*} outputs 948 * @return {boolean} 949 */ 950 es3fShaderCommonFunctionTests.IsnanCase.prototype.compare = function(inputs, outputs) { 951 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 952 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 953 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 954 955 /** @type {number} */ var in0; 956 /** @type {number} */ var out0; 957 /** @type {number} */ var ref; 958 959 if (precision === gluShaderUtil.precision.PRECISION_HIGHP) { 960 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 961 in0 = inputs[0][compNdx]; 962 out0 = outputs[0][compNdx]; 963 ref = tcuFloat.newFloat32(in0).isNaN() ? 1 : 0; 964 965 if (out0 !== ref) { 966 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref; 967 return false; 968 } 969 } 970 } else { 971 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 972 out0 = outputs[0][compNdx]; 973 974 if (out0 !== 0 && out0 !== 1) { 975 this.m_failMsg += 'Expected [' + compNdx + '] = 0 / 1'; 976 return false; 977 } 978 } 979 } 980 return true; 981 }; 982 983 /** 984 * @constructor 985 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 986 * @param {gluShaderUtil.DataType} baseType 987 * @param {gluShaderUtil.precision} precision 988 * @param {gluShaderProgram.shaderType} shaderType 989 */ 990 es3fShaderCommonFunctionTests.IsinfCase = function(baseType, precision, shaderType) { 991 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 992 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 993 'isinf', shaderType); 994 assertMsgOptions(gluShaderUtil.isDataTypeFloatOrVec(baseType), 'Assert error.', false, true); 995 996 /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType); 997 /** @type {gluShaderUtil.DataType} */ var boolType = vecSize > 1 ? 998 gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.BOOL, vecSize) : 999 gluShaderUtil.DataType.BOOL; 1000 1001 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1002 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(boolType))); 1003 this.m_spec.source = 'out0 = isinf(in0);'; 1004 }; 1005 1006 es3fShaderCommonFunctionTests.IsinfCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1007 es3fShaderCommonFunctionTests.IsinfCase.prototype.constructor = es3fShaderCommonFunctionTests.IsinfCase; 1008 1009 /** 1010 * @param {number} numValues 1011 * @return {*} 1012 */ 1013 es3fShaderCommonFunctionTests.IsinfCase.prototype.getInputValues = function(numValues) { 1014 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xc2a39f); 1015 1016 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1017 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1018 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1019 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1020 /** @type {number} */ var mantissaMask = (~es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits)) & ((1 << 23) - 1); 1021 /** @type {Array<Array<number>>} */ var values = []; 1022 values[0] = []; 1023 1024 for (var valNdx = 0; valNdx < numValues * scalarSize; valNdx++) { 1025 /** @type {boolean} */ var isInf = rnd.getFloat() > 0.3; 1026 /** @type {boolean} */ var isNan = !isInf && rnd.getFloat() > 0.4; 1027 /** @type {number} */ var mantissa = !isInf ? ((1 << 22) | (Math.abs(rnd.getInt()) & mantissaMask)) : 0; 1028 /** @type {number} */ var exp = !isNan && !isInf ? (Math.abs(rnd.getInt()) & 0x7f) : 0xff; 1029 /** @type {number} */ var sign = Math.abs(rnd.getInt()) & 0x1; 1030 /** @type {number} */ var value = (sign << 31) | (exp << 23) | mantissa; 1031 1032 // Convert int to float. 1033 var view = new DataView(new ArrayBuffer(4)); 1034 view.setInt32(0, value, true); 1035 value = view.getFloat32(0, true); 1036 1037 assertMsgOptions(tcuFloat.newFloat32(value).isInf() === isInf && tcuFloat.newFloat32(value).isNaN() === isNan, 'Assert error.', false, true); 1038 1039 values[0].push(value); 1040 } 1041 1042 return values; 1043 }; 1044 1045 /** 1046 * @param {*} inputs 1047 * @param {*} outputs 1048 * @return {boolean} 1049 */ 1050 es3fShaderCommonFunctionTests.IsinfCase.prototype.compare = function(inputs, outputs) { 1051 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1052 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1053 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1054 1055 /** @type {number} */ var in0; 1056 /** @type {number} */ var out0; 1057 /** @type {number} */ var ref; 1058 1059 if (precision === gluShaderUtil.precision.PRECISION_HIGHP) { 1060 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1061 in0 = inputs[0][compNdx]; 1062 out0 = outputs[0][compNdx]; 1063 ref = tcuFloat.newFloat32(in0).isInf() ? 1 : 0; 1064 1065 if (out0 !== ref) { 1066 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref; 1067 return false; 1068 } 1069 } 1070 } else { 1071 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1072 out0 = outputs[0][compNdx]; 1073 1074 if (out0 !== 0 && out0 !== 1) { 1075 this.m_failMsg += 'Expected [' + compNdx + '] = 0 / 1'; 1076 return false; 1077 } 1078 } 1079 } 1080 return true; 1081 }; 1082 1083 /** 1084 * @constructor 1085 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1086 * @param {gluShaderUtil.DataType} baseType 1087 * @param {gluShaderUtil.precision} precision 1088 * @param {gluShaderProgram.shaderType} shaderType 1089 * @param {boolean} outIsSigned 1090 */ 1091 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase = function(baseType, precision, shaderType, outIsSigned) { 1092 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1093 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 1094 outIsSigned ? 'floatBitsToInt' : 'floatBitsToUint', shaderType); 1095 1096 /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType); 1097 /** @type {gluShaderUtil.DataType} */ var intType = outIsSigned ? 1098 (vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : gluShaderUtil.DataType.INT) : 1099 (vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.UINT, vecSize) : gluShaderUtil.DataType.UINT); 1100 1101 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1102 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(intType, gluShaderUtil.precision.PRECISION_HIGHP))); 1103 this.m_spec.source = outIsSigned ? 'out0 = floatBitsToInt(in0);' : 'out0 = floatBitsToUint(in0);'; 1104 }; 1105 1106 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1107 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype.constructor = es3fShaderCommonFunctionTests.FloatBitsToUintIntCase; 1108 1109 /** 1110 * @param {number} numValues 1111 * @return {*} 1112 */ 1113 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype.getInputValues = function(numValues) { 1114 1115 /** @type {Array<number>} */ var ranges = [ 1116 [-2.0, 2.0], // lowp 1117 [-1e3, 1e3], // mediump 1118 [-1e7, 1e7] // highp 1119 ]; 1120 1121 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x2790a); 1122 1123 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1124 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1125 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1126 /** @type {Array<Array<number>>} */ var values = []; 1127 1128 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize); 1129 return values; 1130 }; 1131 1132 /** 1133 * @param {*} inputs 1134 * @param {*} outputs 1135 * @return {boolean} 1136 */ 1137 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype.compare = function(inputs, outputs) { 1138 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1139 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1140 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1141 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1142 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); 1143 1144 /** @type {number} */ var in0; 1145 /** @type {number} */ var out0; 1146 /** @type {number} */ var refOut0; 1147 /** @type {number} */ var ulpDiff; 1148 1149 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1150 in0 = inputs[0][compNdx]; 1151 out0 = outputs[0][compNdx]; 1152 1153 // Convert int to uint because ref out is in uint format. 1154 var view = new DataView(new ArrayBuffer(4)); 1155 view.setInt32(0, out0, true); 1156 out0 = view.getUint32(0, true); 1157 1158 refOut0 = tcuFloat.newFloat32(in0).bits(); 1159 ulpDiff = Math.abs(out0 - refOut0); 1160 if (ulpDiff > maxUlpDiff) { 1161 this.m_failMsg += 'Expected [' + compNdx + '] = ' + refOut0 + ' with threshold ' + 1162 maxUlpDiff + ', got diff ' + ulpDiff; 1163 return false; 1164 } 1165 } 1166 return true; 1167 }; 1168 1169 /** 1170 * @constructor 1171 * @extends {es3fShaderCommonFunctionTests.FloatBitsToUintIntCase} 1172 * @param {gluShaderUtil.DataType} baseType 1173 * @param {gluShaderUtil.precision} precision 1174 * @param {gluShaderProgram.shaderType} shaderType 1175 */ 1176 es3fShaderCommonFunctionTests.FloatBitsToIntCase = function(baseType, precision, shaderType) { 1177 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.call(this, baseType, precision, shaderType, true); 1178 }; 1179 1180 es3fShaderCommonFunctionTests.FloatBitsToIntCase.prototype = Object.create(es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype); 1181 es3fShaderCommonFunctionTests.FloatBitsToIntCase.prototype.constructor = es3fShaderCommonFunctionTests.FloatBitsToIntCase; 1182 1183 /** 1184 * @constructor 1185 * @extends {es3fShaderCommonFunctionTests.FloatBitsToUintIntCase} 1186 * @param {gluShaderUtil.DataType} baseType 1187 * @param {gluShaderUtil.precision} precision 1188 * @param {gluShaderProgram.shaderType} shaderType 1189 */ 1190 es3fShaderCommonFunctionTests.FloatBitsToUintCase = function(baseType, precision, shaderType) { 1191 es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.call(this, baseType, precision, shaderType, false); 1192 }; 1193 1194 es3fShaderCommonFunctionTests.FloatBitsToUintCase.prototype = Object.create(es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype); 1195 es3fShaderCommonFunctionTests.FloatBitsToUintCase.prototype.constructor = es3fShaderCommonFunctionTests.FloatBitsToUintCase; 1196 1197 /** 1198 * @constructor 1199 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1200 * @param {gluShaderUtil.DataType} baseType 1201 * @param {gluShaderProgram.shaderType} shaderType 1202 */ 1203 es3fShaderCommonFunctionTests.BitsToFloatCase = function(baseType, shaderType) { 1204 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1205 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, gluShaderUtil.precision.PRECISION_HIGHP, shaderType), 1206 gluShaderUtil.isDataTypeIntOrIVec(baseType) ? 'intBitsToFloat' : 'uintBitsToFloat', shaderType); 1207 /** @type {boolean} */ var inIsSigned = gluShaderUtil.isDataTypeIntOrIVec(baseType); 1208 /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType); 1209 /** @type {gluShaderUtil.DataType} */ var floatType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT; 1210 1211 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, gluShaderUtil.precision.PRECISION_HIGHP))); 1212 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(floatType, gluShaderUtil.precision.PRECISION_HIGHP))); 1213 this.m_spec.source = inIsSigned ? 'out0 = intBitsToFloat(in0);' : 'out0 = uintBitsToFloat(in0);'; 1214 }; 1215 1216 es3fShaderCommonFunctionTests.BitsToFloatCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1217 es3fShaderCommonFunctionTests.BitsToFloatCase.prototype.constructor = es3fShaderCommonFunctionTests.BitsToFloatCase; 1218 1219 /** 1220 * @param {number} numValues 1221 * @return {*} 1222 */ 1223 es3fShaderCommonFunctionTests.BitsToFloatCase.prototype.getInputValues = function(numValues) { 1224 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xbbb225); 1225 1226 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1227 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1228 /** @type {Array<number>} */ var range = [-1e8, 1e8]; 1229 /** @type {Array<Array<number>>} */ var values = []; 1230 1231 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, range[0], range[1], numValues * scalarSize); 1232 return values; 1233 }; 1234 1235 /** 1236 * @param {*} inputs 1237 * @param {*} outputs 1238 * @return {boolean} 1239 */ 1240 es3fShaderCommonFunctionTests.BitsToFloatCase.prototype.compare = function(inputs, outputs) { 1241 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1242 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1243 /** @type {number} */ var maxUlpDiff = 0; 1244 1245 /** @type {number} */ var in0; 1246 /** @type {number} */ var out0; 1247 /** @type {number} */ var ulpDiff; 1248 /** @type {number} */ var refOut0; 1249 1250 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1251 in0 = inputs[0][compNdx]; 1252 out0 = outputs[0][compNdx]; 1253 1254 // Convert int to float 1255 var view = new DataView(new ArrayBuffer(4)); 1256 view.setInt32(0, in0, true); 1257 in0 = view.getFloat32(0, true); 1258 1259 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiff(in0, out0); 1260 if (ulpDiff > maxUlpDiff) { 1261 this.m_failMsg += 'Expected [' + compNdx + '] = ' + in0 + ' with ULP threshold ' + 1262 maxUlpDiff + ', got ULP diff ' + ulpDiff; 1263 return false; 1264 } 1265 } 1266 return true; 1267 }; 1268 1269 /** 1270 * @constructor 1271 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1272 * @param {gluShaderUtil.DataType} baseType 1273 * @param {gluShaderUtil.precision} precision 1274 * @param {gluShaderProgram.shaderType} shaderType 1275 */ 1276 es3fShaderCommonFunctionTests.FloorCase = function(baseType, precision, shaderType) { 1277 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1278 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 1279 'floor', shaderType); 1280 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1281 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 1282 this.m_spec.source = 'out0 = floor(in0);'; 1283 }; 1284 1285 es3fShaderCommonFunctionTests.FloorCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1286 es3fShaderCommonFunctionTests.FloorCase.prototype.constructor = es3fShaderCommonFunctionTests.FloorCase; 1287 1288 /** 1289 * @param {number} numValues 1290 * @return {*} 1291 */ 1292 es3fShaderCommonFunctionTests.FloorCase.prototype.getInputValues = function(numValues) { 1293 /** @type {Array<Array<number>>} */ var ranges = [ 1294 [-2.0, 2.0], // lowp 1295 [-1e3, 1e3], // mediump 1296 [-1e7, 1e7] // highp 1297 ]; 1298 1299 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 1300 1301 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1302 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1303 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1304 /** @type {Array<Array<number>>} */ var values = []; 1305 // Random cases. 1306 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize); 1307 1308 // If precision is mediump, make sure values can be represented in fp16 exactly 1309 if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP) 1310 es3fShaderCommonFunctionTests.vecToFloat16(values[0]); 1311 1312 return values; 1313 }; 1314 1315 /** 1316 * @param {*} inputs 1317 * @param {*} outputs 1318 * @return {boolean} 1319 */ 1320 es3fShaderCommonFunctionTests.FloorCase.prototype.compare = function(inputs, outputs) { 1321 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1322 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1323 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1324 1325 /** @type {number} */ var in0; 1326 /** @type {number} */ var out0; 1327 /** @type {number} */ var ref; 1328 /** @type {number} */ var ulpDiff; 1329 1330 if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) { 1331 // Require exact result. 1332 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1333 in0 = inputs[0][compNdx]; 1334 out0 = outputs[0][compNdx]; 1335 ref = Math.floor(in0); 1336 1337 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiff(out0, ref); 1338 1339 if (ulpDiff > 0) { 1340 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff; 1341 return false; 1342 } 1343 } 1344 } else { 1345 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1346 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 1347 /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds 1348 1349 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1350 in0 = inputs[0][compNdx]; 1351 out0 = outputs[0][compNdx]; 1352 /** @type {number} */ var minRes = Math.floor(in0 - eps); 1353 /** @type {number} */ var maxRes = Math.floor(in0 + eps); 1354 /** @type {boolean} */ var anyOk = false; 1355 1356 for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) { 1357 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiff(out0, roundedVal); 1358 1359 if (ulpDiff <= maxUlpDiff) { 1360 anyOk = true; 1361 break; 1362 } 1363 } 1364 1365 if (!anyOk) { 1366 this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff; 1367 return false; 1368 } 1369 } 1370 } 1371 1372 return true; 1373 }; 1374 1375 /** 1376 * @constructor 1377 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1378 * @param {gluShaderUtil.DataType} baseType 1379 * @param {gluShaderUtil.precision} precision 1380 * @param {gluShaderProgram.shaderType} shaderType 1381 */ 1382 es3fShaderCommonFunctionTests.TruncCase = function(baseType, precision, shaderType) { 1383 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1384 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 1385 'trunc', shaderType); 1386 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1387 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 1388 this.m_spec.source = 'out0 = trunc(in0);'; 1389 }; 1390 1391 es3fShaderCommonFunctionTests.TruncCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1392 es3fShaderCommonFunctionTests.TruncCase.prototype.constructor = es3fShaderCommonFunctionTests.TruncCase; 1393 1394 /** 1395 * @param {number} numValues 1396 * @return {*} 1397 */ 1398 es3fShaderCommonFunctionTests.TruncCase.prototype.getInputValues = function(numValues) { 1399 /** @type {Array<Array<number>>} */ var ranges = [ 1400 [-2.0, 2.0], // lowp 1401 [-1e3, 1e3], // mediump 1402 [-1e7, 1e7] // highp 1403 ]; 1404 1405 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 1406 1407 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1408 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1409 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1410 1411 /** @type {Array<number>} */ var specialCases = [0.0, -0.0, -0.9, 0.9, 1.0, -1.0]; 1412 /** @type {Array<Array<number>>} */ var values = []; 1413 values[0] = []; 1414 1415 // Special cases 1416 for (var caseNdx = 0; caseNdx < specialCases.length; caseNdx++) 1417 for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 1418 values[0].push(specialCases[caseNdx]); 1419 1420 // Random cases. 1421 values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - specialCases.length) * scalarSize)); 1422 1423 // If precision is mediump, make sure values can be represented in fp16 exactly 1424 if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP) 1425 es3fShaderCommonFunctionTests.vecToFloat16(values[0]); 1426 1427 return values; 1428 }; 1429 1430 /** 1431 * @param {*} inputs 1432 * @param {*} outputs 1433 * @return {boolean} 1434 */ 1435 es3fShaderCommonFunctionTests.TruncCase.prototype.compare = function(inputs, outputs) { 1436 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1437 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1438 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1439 1440 /** @type {number} */ var in0; 1441 /** @type {number} */ var out0; 1442 /** @type {number} */ var ref; 1443 /** @type {number} */ var ulpDiff; 1444 1445 if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) { 1446 // Require exact result. 1447 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1448 in0 = inputs[0][compNdx]; 1449 out0 = outputs[0][compNdx]; 1450 /** @type {boolean} */ var isNeg = tcuFloat.newFloat32(in0).sign() < 0; 1451 ref = isNeg ? (-Math.floor(-in0)) : Math.floor(in0); 1452 1453 // \note: trunc() function definition is a bit broad on negative zeros. Ignore result sign if zero. 1454 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref); 1455 1456 if (ulpDiff > 0) { 1457 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff; 1458 return false; 1459 } 1460 } 1461 } else { 1462 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1463 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 1464 /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds 1465 1466 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1467 in0 = inputs[0][compNdx]; 1468 out0 = outputs[0][compNdx]; 1469 /** @type {number} */ var minRes = Math.trunc(in0 - eps); 1470 /** @type {number} */ var maxRes = Math.trunc(in0 + eps); 1471 /** @type {boolean} */ var anyOk = false; 1472 1473 for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) { 1474 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal); 1475 1476 if (ulpDiff <= maxUlpDiff) { 1477 anyOk = true; 1478 break; 1479 } 1480 } 1481 1482 if (!anyOk) { 1483 this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff; 1484 return false; 1485 } 1486 } 1487 } 1488 1489 return true; 1490 }; 1491 1492 /** 1493 * @constructor 1494 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1495 * @param {gluShaderUtil.DataType} baseType 1496 * @param {gluShaderUtil.precision} precision 1497 * @param {gluShaderProgram.shaderType} shaderType 1498 */ 1499 es3fShaderCommonFunctionTests.RoundCase = function(baseType, precision, shaderType) { 1500 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1501 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 1502 'round', shaderType); 1503 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1504 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 1505 this.m_spec.source = 'out0 = round(in0);'; 1506 }; 1507 1508 es3fShaderCommonFunctionTests.RoundCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1509 es3fShaderCommonFunctionTests.RoundCase.prototype.constructor = es3fShaderCommonFunctionTests.RoundCase; 1510 1511 /** 1512 * @param {number} numValues 1513 * @return {*} 1514 */ 1515 es3fShaderCommonFunctionTests.RoundCase.prototype.getInputValues = function(numValues) { 1516 /** @type {Array<Array<number>>} */ var ranges = [ 1517 [-2.0, 2.0], // lowp 1518 [-1e3, 1e3], // mediump 1519 [-1e7, 1e7] // highp 1520 ]; 1521 1522 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 1523 1524 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1525 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1526 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1527 /** @type {number} */ var numSpecialCases = 0; 1528 1529 /** @type {Array<Array<number>>} */ var values = []; 1530 values[0] = [] 1531 1532 // Special cases. 1533 if (precision === gluShaderUtil.precision.PRECISION_LOWP) { 1534 assertMsgOptions(numValues >= 10, 'Sample too small.', false, true); 1535 for (var ndx = 0; ndx < 10; ndx++) { 1536 /** @type {number} */ var v = deMath.clamp(ndx - 5.5, ranges[precision][0], ranges[precision][1]); 1537 for (var iter = 1; iter <= scalarSize; iter++) 1538 values[0].push(v); 1539 numSpecialCases += 1; 1540 } 1541 } 1542 1543 // Random cases. 1544 values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - numSpecialCases) * scalarSize)); 1545 1546 // If precision is mediump, make sure values can be represented in fp16 exactly 1547 if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP) 1548 es3fShaderCommonFunctionTests.vecToFloat16(values[0]); 1549 1550 return values; 1551 }; 1552 1553 /** 1554 * @param {*} inputs 1555 * @param {*} outputs 1556 * @return {boolean} 1557 */ 1558 es3fShaderCommonFunctionTests.RoundCase.prototype.compare = function(inputs, outputs) { 1559 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1560 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1561 /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision); 1562 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1563 1564 /** @type {number} */ var in0; 1565 /** @type {number} */ var out0; 1566 /** @type {number} */ var ulpDiff; 1567 1568 if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) { 1569 // Require exact result. 1570 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1571 in0 = inputs[0][compNdx]; 1572 out0 = outputs[0][compNdx]; 1573 1574 if ((in0 - Math.floor(in0)) === 0.5) { 1575 /** @type {number} */ var ref0 = Math.floor(in0); 1576 /** @type {number} */ var ref1 = Math.ceil(in0); 1577 /** @type {number} */ var ulpDiff0 = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref0) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref0); 1578 /** @type {number} */ var ulpDiff1 = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref1) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref1); 1579 if (ulpDiff0 > 0 && ulpDiff1 > 0) { 1580 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0 + ' or ' + ref1 + ', got ULP diff ' + Math.min(ulpDiff0, ulpDiff1); 1581 return false; 1582 } 1583 } else { 1584 // Require exact result 1585 /** @type {number} */ var ref = es3fShaderCommonFunctionTests.roundEven(in0); 1586 ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref); 1587 1588 if (ulpDiff > 0) { 1589 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff; 1590 return false; 1591 } 1592 } 1593 } 1594 } else { 1595 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1596 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 1597 /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds 1598 1599 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1600 in0 = inputs[0][compNdx]; 1601 out0 = outputs[0][compNdx]; 1602 /** @type {number} */ var minRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 - eps)); 1603 /** @type {number} */ var maxRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 + eps)); 1604 /** @type {boolean} */ var anyOk = false; 1605 1606 for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) { 1607 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal); 1608 1609 if (ulpDiff <= maxUlpDiff) { 1610 anyOk = true; 1611 break; 1612 } 1613 } 1614 1615 if (!anyOk) { 1616 this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff; 1617 return false; 1618 } 1619 } 1620 } 1621 1622 return true; 1623 }; 1624 1625 /** 1626 * @constructor 1627 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1628 * @param {gluShaderUtil.DataType} baseType 1629 * @param {gluShaderUtil.precision} precision 1630 * @param {gluShaderProgram.shaderType} shaderType 1631 */ 1632 es3fShaderCommonFunctionTests.CeilCase = function(baseType, precision, shaderType) { 1633 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1634 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 1635 'ceil', shaderType); 1636 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1637 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 1638 this.m_spec.source = 'out0 = ceil(in0);'; 1639 }; 1640 1641 es3fShaderCommonFunctionTests.CeilCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1642 es3fShaderCommonFunctionTests.CeilCase.prototype.constructor = es3fShaderCommonFunctionTests.CeilCase; 1643 1644 /** 1645 * @param {number} numValues 1646 * @return {*} 1647 */ 1648 es3fShaderCommonFunctionTests.CeilCase.prototype.getInputValues = function(numValues) { 1649 /** @type {Array<Array<number>>} */ var ranges = [ 1650 [-2.0, 2.0], // lowp 1651 [-1e3, 1e3], // mediump 1652 [-1e7, 1e7] // highp 1653 ]; 1654 1655 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 1656 1657 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1658 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1659 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1660 1661 /** @type {Array<Array<number>>} */ var values = []; 1662 1663 // Random cases. 1664 values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize); 1665 1666 // If precision is mediump, make sure values can be represented in fp16 exactly 1667 if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP) 1668 es3fShaderCommonFunctionTests.vecToFloat16(values[0]); 1669 1670 return values; 1671 }; 1672 1673 /** 1674 * @param {*} inputs 1675 * @param {*} outputs 1676 * @return {boolean} 1677 */ 1678 es3fShaderCommonFunctionTests.CeilCase.prototype.compare = function(inputs, outputs) { 1679 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1680 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1681 /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision); 1682 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1683 1684 /** @type {number} */ var in0; 1685 /** @type {number} */ var out0; 1686 /** @type {number} */ var ref; 1687 /** @type {number} */ var ulpDiff; 1688 1689 if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) { 1690 // Require exact result. 1691 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1692 in0 = inputs[0][compNdx]; 1693 out0 = outputs[0][compNdx]; 1694 ref = Math.ceil(in0); 1695 ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref); 1696 1697 if (ulpDiff > 0) { 1698 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff; 1699 return false; 1700 } 1701 } 1702 } else { 1703 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1704 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value. 1705 /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds 1706 1707 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1708 in0 = inputs[0][compNdx]; 1709 out0 = outputs[0][compNdx]; 1710 /** @type {number} */ var minRes = Math.ceil(in0 - eps); 1711 /** @type {number} */ var maxRes = Math.ceil(in0 + eps); 1712 /** @type {boolean} */ var anyOk = false; 1713 1714 for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) { 1715 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal); 1716 1717 if (ulpDiff <= maxUlpDiff) { 1718 anyOk = true; 1719 break; 1720 } 1721 } 1722 1723 if (!anyOk & deMath.deInRange32(0, minRes, maxRes)) { 1724 ulpDiff = Math.abs(Math.floor(tcuFloat.newFloat32(out0).bits()) - 0x80000000); 1725 anyOk = ulpDiff <= maxUlpDiff; 1726 } 1727 1728 if (!anyOk) { 1729 this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff; 1730 return false; 1731 } 1732 } 1733 } 1734 1735 return true; 1736 }; 1737 1738 /** 1739 * @constructor 1740 * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase} 1741 * @param {gluShaderUtil.DataType} baseType 1742 * @param {gluShaderUtil.precision} precision 1743 * @param {gluShaderProgram.shaderType} shaderType 1744 */ 1745 es3fShaderCommonFunctionTests.FractCase = function(baseType, precision, shaderType) { 1746 es3fShaderCommonFunctionTests.CommonFunctionCase.call(this, 1747 es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType), 1748 'fract', shaderType); 1749 this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision))); 1750 this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision))); 1751 this.m_spec.source = 'out0 = fract(in0);'; 1752 }; 1753 1754 es3fShaderCommonFunctionTests.FractCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype); 1755 es3fShaderCommonFunctionTests.FractCase.prototype.constructor = es3fShaderCommonFunctionTests.FractCase; 1756 1757 /** 1758 * @param {number} numValues 1759 * @return {*} 1760 */ 1761 es3fShaderCommonFunctionTests.FractCase.prototype.getInputValues = function(numValues) { 1762 /** @type {Array<Array<number>>} */ var ranges = [ 1763 [-2.0, 2.0], // lowp 1764 [-1e3, 1e3], // mediump 1765 [-1e7, 1e7] // highp 1766 ]; 1767 1768 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f); 1769 1770 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1771 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1772 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1773 /** @type {number} */ var numSpecialCases = 0; 1774 1775 /** @type {Array<Array<number>>} */ var values = []; 1776 values[0] = []; 1777 1778 // Special cases. 1779 if (precision !== gluShaderUtil.precision.PRECISION_LOWP) { 1780 assertMsgOptions(numValues >= 10, 'Sample too small.', false, true); 1781 for (var ndx = 0; ndx < 10; ndx++) { 1782 /** @type {number} */ var v = deMath.clamp(ndx - 5.5, ranges[precision][0], ranges[precision][1]); 1783 for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) { 1784 values[0].push(v); 1785 } 1786 numSpecialCases += 1; 1787 } 1788 } 1789 1790 // Random cases. 1791 values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - numSpecialCases) * scalarSize)); 1792 1793 // If precision is mediump, make sure values can be represented in fp16 exactly 1794 if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP) 1795 es3fShaderCommonFunctionTests.vecToFloat16(values[0]) 1796 1797 return values; 1798 }; 1799 1800 /** 1801 * @param {*} inputs 1802 * @param {*} outputs 1803 * @return {boolean} 1804 */ 1805 es3fShaderCommonFunctionTests.FractCase.prototype.compare = function(inputs, outputs) { 1806 /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType(); 1807 /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision(); 1808 /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision); 1809 /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type); 1810 1811 /** @type {number} */ var in0; 1812 /** @type {number} */ var out0; 1813 /** @type {number} */ var ref; 1814 /** @type {number} */ var ulpDiff; 1815 1816 if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) { 1817 // Require exact result. 1818 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1819 in0 = inputs[0][compNdx]; 1820 out0 = outputs[0][compNdx]; 1821 ref = in0 - Math.floor(in0); 1822 ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref); 1823 1824 if (ulpDiff > 0) { 1825 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff; 1826 return false; 1827 } 1828 } 1829 } else { 1830 /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision); 1831 /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds 1832 1833 for (var compNdx = 0; compNdx < scalarSize; compNdx++) { 1834 in0 = inputs[0][compNdx]; 1835 out0 = outputs[0][compNdx]; 1836 1837 if (Math.floor(in0 - eps) == Math.floor(in0 + eps)) { 1838 ref = in0 - Math.floor(in0); 1839 /** @type {number} */ var bitsLost = es3fShaderCommonFunctionTests.numBitsLostInOp(in0, ref); 1840 /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(Math.max(0, mantissaBits - bitsLost)); // ULP diff for rounded integer value. 1841 ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref); 1842 if (ulpDiff > maxUlpDiff) { 1843 this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ' with ULP threshold ' + maxUlpDiff + ', got diff ' + ulpDiff; 1844 return false; 1845 } 1846 } else { 1847 if (out0 >= 1.0) { 1848 this.m_failMsg += 'Expected [' + compNdx + '] < 1.0'; 1849 return false; 1850 } 1851 } 1852 } 1853 } 1854 1855 return true; 1856 }; 1857 1858 /** 1859 * @constructor 1860 * @extends {tcuTestCase.DeqpTest} 1861 */ 1862 es3fShaderCommonFunctionTests.ShaderCommonFunctionTests = function() { 1863 tcuTestCase.DeqpTest.call(this, 'common', 'Common function tests'); 1864 }; 1865 1866 es3fShaderCommonFunctionTests.ShaderCommonFunctionTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 1867 es3fShaderCommonFunctionTests.ShaderCommonFunctionTests.prototype.constructor = es3fShaderCommonFunctionTests.ShaderCommonFunctionTests; 1868 1869 /** 1870 * @param {tcuTestCase.DeqpTest} parent 1871 * @param {es3fShaderCommonFunctionTests.TestClass} testClass 1872 * @param {string} functionName 1873 * @param {boolean} floatTypes 1874 * @param {boolean} intTypes 1875 * @param {boolean} uintTypes 1876 */ 1877 es3fShaderCommonFunctionTests.addFunctionCases = function(parent, testClass, functionName, floatTypes, intTypes, uintTypes) { 1878 /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(functionName, functionName); 1879 parent.addChild(group); 1880 1881 /** @type {Array<gluShaderUtil.DataType>} */ var scalarTypes = [ 1882 gluShaderUtil.DataType.FLOAT, 1883 gluShaderUtil.DataType.INT, 1884 gluShaderUtil.DataType.UINT 1885 ]; 1886 1887 for (var scalarTypeNdx = 0; scalarTypeNdx < scalarTypes.length; scalarTypeNdx++) { 1888 /** @type {gluShaderUtil.DataType} */ var scalarType = scalarTypes[scalarTypeNdx]; 1889 1890 if ((!floatTypes && scalarType == gluShaderUtil.DataType.FLOAT) || 1891 (!intTypes && scalarType == gluShaderUtil.DataType.INT) || 1892 (!uintTypes && scalarType == gluShaderUtil.DataType.UINT)) 1893 continue; 1894 1895 for (var vecSize = 1; vecSize <= 4; vecSize++) 1896 for (var prec = gluShaderUtil.precision.PRECISION_LOWP; prec <= gluShaderUtil.precision.PRECISION_HIGHP; prec++) 1897 for (var shaderType = gluShaderProgram.shaderType.VERTEX; shaderType <= gluShaderProgram.shaderType.FRAGMENT; shaderType++) 1898 group.addChild(new testClass(/** @type {gluShaderUtil.DataType} */ (scalarType + vecSize - 1), prec, shaderType)); 1899 } 1900 }; 1901 1902 es3fShaderCommonFunctionTests.ShaderCommonFunctionTests.prototype.init = function() { 1903 var testGroup = tcuTestCase.runner.testCases; 1904 1905 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.AbsCase, 'abs', true, true, false); 1906 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.SignCase, 'sign', true, true, false); 1907 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FloorCase, 'floor', true, false, false); 1908 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.TruncCase, 'trunc', true, false, false); 1909 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.RoundCase, 'round', true, false, false); 1910 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.RoundEvenCase, 'roundeven', true, false, false); 1911 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.CeilCase, 'ceil', true, false, false); 1912 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FractCase, 'fract', true, false, false); 1913 // mod 1914 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.ModfCase, 'modf', true, false, false); 1915 // min, max, clamp, mix, step, smoothstep 1916 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.IsnanCase, 'isnan', true, false, false); 1917 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.IsinfCase, 'isinf', true, false, false); 1918 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FloatBitsToIntCase, 'floatbitstoint', true, false, false); 1919 es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FloatBitsToUintCase, 'floatbitstouint', true, false, false); 1920 1921 // (u)intBitsToFloat() 1922 /** @type {tcuTestCase.DeqpTest} */ var intGroup = tcuTestCase.newTest('intbitstofloat', 'intBitsToFloat() Tests'); 1923 /** @type {tcuTestCase.DeqpTest} */ var uintGroup = tcuTestCase.newTest('uintbitstofloat', 'uintBitsToFloat() Tests'); 1924 1925 testGroup.addChild(intGroup); 1926 testGroup.addChild(uintGroup); 1927 1928 /** @type {Array<gluShaderProgram.shaderType>} */ var shaderTypes = [ 1929 gluShaderProgram.shaderType.VERTEX, 1930 gluShaderProgram.shaderType.FRAGMENT 1931 ]; 1932 1933 for (var vecSize = 1; vecSize < 4; vecSize++) { 1934 /** @type {gluShaderUtil.DataType} */ var intType = vecSize > 1 ? 1935 gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : 1936 gluShaderUtil.DataType.INT; 1937 1938 /** @type {gluShaderUtil.DataType} */ var uintType = vecSize > 1 ? 1939 gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.UINT, vecSize) : 1940 gluShaderUtil.DataType.UINT; 1941 1942 for (var shaderType in shaderTypes) { 1943 intGroup.addChild(new es3fShaderCommonFunctionTests.BitsToFloatCase(intType, shaderTypes[shaderType])); 1944 uintGroup.addChild(new es3fShaderCommonFunctionTests.BitsToFloatCase(uintType, shaderTypes[shaderType])); 1945 } 1946 } 1947 }; 1948 1949 /** 1950 * Run test 1951 * @param {WebGL2RenderingContext} context 1952 */ 1953 es3fShaderCommonFunctionTests.run = function(context) { 1954 gl = context; 1955 //Set up Test Root parameters 1956 var state = tcuTestCase.runner; 1957 state.setRoot(new es3fShaderCommonFunctionTests.ShaderCommonFunctionTests()); 1958 1959 //Set up name and description of this test series. 1960 setCurrentTestName(state.testCases.fullName()); 1961 description(state.testCases.getDescription()); 1962 1963 try { 1964 //Run test cases 1965 tcuTestCase.runTestCases(); 1966 } 1967 catch (err) { 1968 testFailedOptions('Failed to es3fShaderCommonFunctionTests.run tests', false); 1969 tcuTestCase.runner.terminate(); 1970 } 1971 }; 1972 1973 });