glsTextureTestUtil.js (122947B)
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('modules.shared.glsTextureTestUtil'); 23 goog.require('framework.common.tcuImageCompare'); 24 goog.require('framework.common.tcuPixelFormat'); 25 goog.require('framework.common.tcuRGBA'); 26 goog.require('framework.common.tcuStringTemplate'); 27 goog.require('framework.common.tcuSurface'); 28 goog.require('framework.common.tcuTexLookupVerifier'); 29 goog.require('framework.common.tcuTexCompareVerifier'); 30 goog.require('framework.common.tcuTexture'); 31 goog.require('framework.delibs.debase.deMath'); 32 goog.require('framework.opengl.gluDrawUtil'); 33 goog.require('framework.opengl.gluShaderUtil'); 34 goog.require('framework.opengl.gluShaderProgram'); 35 goog.require('framework.delibs.debase.deRandom'); 36 37 goog.scope(function() { 38 var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier; 39 var tcuTexCompareVerifier = framework.common.tcuTexCompareVerifier; 40 var glsTextureTestUtil = modules.shared.glsTextureTestUtil; 41 var gluDrawUtil = framework.opengl.gluDrawUtil; 42 var gluShaderProgram = framework.opengl.gluShaderProgram; 43 var tcuTexture = framework.common.tcuTexture; 44 var tcuSurface = framework.common.tcuSurface; 45 var gluShaderUtil = framework.opengl.gluShaderUtil; 46 var tcuStringTemplate = framework.common.tcuStringTemplate; 47 var deMath = framework.delibs.debase.deMath; 48 var tcuImageCompare = framework.common.tcuImageCompare; 49 var tcuPixelFormat = framework.common.tcuPixelFormat; 50 var tcuRGBA = framework.common.tcuRGBA; 51 var deRandom = framework.delibs.debase.deRandom; 52 53 var DE_ASSERT = function(x) { 54 if (!x) 55 throw new Error('Assert failed'); 56 }; 57 58 var MIN_SUBPIXEL_BITS = 4; 59 60 /** 61 * @enum 62 */ 63 glsTextureTestUtil.textureType = { 64 TEXTURETYPE_2D: 0, 65 TEXTURETYPE_CUBE: 1, 66 TEXTURETYPE_2D_ARRAY: 2, 67 TEXTURETYPE_3D: 3, 68 TEXTURETYPE_CUBE_ARRAY: 4, 69 TEXTURETYPE_1D: 5, 70 TEXTURETYPE_1D_ARRAY: 6, 71 TEXTURETYPE_BUFFER: 7 72 }; 73 74 /** 75 * @enum 76 */ 77 glsTextureTestUtil.samplerType = { 78 SAMPLERTYPE_FLOAT: 0, 79 SAMPLERTYPE_INT: 1, 80 SAMPLERTYPE_UINT: 2, 81 SAMPLERTYPE_SHADOW: 3, 82 83 SAMPLERTYPE_FETCH_FLOAT: 4, 84 SAMPLERTYPE_FETCH_INT: 5, 85 SAMPLERTYPE_FETCH_UINT: 6 86 }; 87 88 /** 89 * @param {tcuTexture.TextureFormat} format 90 * @return {glsTextureTestUtil.samplerType} 91 */ 92 glsTextureTestUtil.getSamplerType = function(format) { 93 if (format == null) 94 throw new Error('Missing format information'); 95 96 switch (format.type) { 97 case tcuTexture.ChannelType.SIGNED_INT8: 98 case tcuTexture.ChannelType.SIGNED_INT16: 99 case tcuTexture.ChannelType.SIGNED_INT32: 100 return glsTextureTestUtil.samplerType.SAMPLERTYPE_INT; 101 102 case tcuTexture.ChannelType.UNSIGNED_INT8: 103 case tcuTexture.ChannelType.UNSIGNED_INT32: 104 case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV: 105 return glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT; 106 107 // Texture formats used in depth/stencil textures. 108 case tcuTexture.ChannelType.UNSIGNED_INT16: 109 case tcuTexture.ChannelType.UNSIGNED_INT_24_8: 110 return (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS) ? glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT : glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT; 111 112 default: 113 return glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT; 114 } 115 }; 116 117 /** 118 * @constructor 119 * @param {HTMLElement} canvas 120 * @param {number} preferredWidth 121 * @param {number} preferredHeight 122 * @param {number=} seed 123 */ 124 glsTextureTestUtil.RandomViewport = function(canvas, preferredWidth, preferredHeight, seed) { 125 this.width = Math.min(canvas.width, preferredWidth); 126 this.height = Math.min(canvas.height, preferredHeight); 127 128 if (typeof seed === 'undefined') 129 seed = preferredWidth + preferredHeight; 130 131 var rnd = new deRandom.Random(seed); 132 this.x = rnd.getInt(0, canvas.width - this.width); 133 this.y = rnd.getInt(0, canvas.height - this.height); 134 }; 135 136 /** 137 * @constructor 138 * @param {glsTextureTestUtil.textureType} texType 139 */ 140 glsTextureTestUtil.RenderParams = function(texType) { 141 this.flags = { 142 projected: false, 143 use_bias: false, 144 log_programs: false, 145 log_uniforms: false 146 }; 147 this.texType = texType; 148 this.w = [1, 1, 1, 1]; 149 this.bias = 0; 150 this.ref = 0; 151 this.colorScale = [1, 1, 1, 1]; 152 this.colorBias = [0, 0, 0, 0]; 153 this.samplerType = glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT; 154 }; 155 156 /** 157 * @enum 158 */ 159 glsTextureTestUtil.lodMode = { 160 EXACT: 0, //!< Ideal lod computation. 161 MIN_BOUND: 1, //!< Use estimation range minimum bound. 162 MAX_BOUND: 2 //!< Use estimation range maximum bound. 163 164 }; 165 166 /** 167 * @constructor 168 * @extends {glsTextureTestUtil.RenderParams} 169 * @param {glsTextureTestUtil.textureType} texType 170 * @param {tcuTexture.Sampler=} sampler 171 * @param {glsTextureTestUtil.lodMode=} lodMode_ 172 */ 173 glsTextureTestUtil.ReferenceParams = function(texType, sampler, lodMode_) { 174 glsTextureTestUtil.RenderParams.call(this, texType); 175 if (sampler) 176 this.sampler = sampler; 177 if (lodMode_) 178 this.lodMode = lodMode_; 179 else 180 this.lodMode = glsTextureTestUtil.lodMode.EXACT; 181 this.minLod = -1000; 182 this.maxLod = 1000; 183 this.baseLevel = 0; 184 this.maxLevel = 1000; 185 }; 186 187 glsTextureTestUtil.ReferenceParams.prototype = Object.create(glsTextureTestUtil.RenderParams.prototype); 188 189 /** Copy constructor */ 190 glsTextureTestUtil.ReferenceParams.prototype.constructor = glsTextureTestUtil.ReferenceParams; 191 192 /** 193 * @param {Array<number>} bottomLeft 194 * @param {Array<number>} topRight 195 * @return {Array<number>} 196 */ 197 glsTextureTestUtil.computeQuadTexCoord2D = function(bottomLeft, topRight) { 198 var dst = []; 199 dst.length = 4 * 2; 200 201 dst[0] = bottomLeft[0]; dst[1] = bottomLeft[1]; 202 dst[2] = bottomLeft[0]; dst[3] = topRight[1]; 203 dst[4] = topRight[0]; dst[5] = bottomLeft[1]; 204 dst[6] = topRight[0]; dst[7] = topRight[1]; 205 206 return dst; 207 }; 208 209 /** 210 * @param {tcuTexture.CubeFace} face 211 * @return {Array<number>} 212 */ 213 glsTextureTestUtil.computeQuadTexCoordCube = function(face) { 214 var texCoordNegX = [ 215 -1, 1, -1, 216 -1, -1, -1, 217 -1, 1, 1, 218 -1, -1, 1 219 ]; 220 var texCoordPosX = [ 221 +1, 1, 1, 222 +1, -1, 1, 223 +1, 1, -1, 224 +1, -1, -1 225 ]; 226 var texCoordNegY = [ 227 -1, -1, 1, 228 -1, -1, -1, 229 1, -1, 1, 230 1, -1, -1 231 ]; 232 var texCoordPosY = [ 233 -1, +1, -1, 234 -1, +1, 1, 235 1, +1, -1, 236 1, +1, 1 237 ]; 238 var texCoordNegZ = [ 239 1, 1, -1, 240 1, -1, -1, 241 -1, 1, -1, 242 -1, -1, -1 243 ]; 244 var texCoordPosZ = [ 245 -1, 1, +1, 246 -1, -1, +1, 247 1, 1, +1, 248 1, -1, +1 249 ]; 250 251 switch (face) { 252 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: return texCoordNegX; 253 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: return texCoordPosX; 254 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: return texCoordNegY; 255 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: return texCoordPosY; 256 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: return texCoordNegZ; 257 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: return texCoordPosZ; 258 } 259 throw new Error('Unrecognized face ' + face); 260 }; 261 262 /** 263 * @param {tcuTexture.CubeFace} face 264 * @param {Array<number>} bottomLeft 265 * @param {Array<number>} topRight 266 * @return {Array<number>} 267 */ 268 glsTextureTestUtil.computeQuadTexCoordCubeFace = function(face, bottomLeft, topRight) { 269 var dst = []; 270 /** @type {number} */ var sRow = 0; 271 /** @type {number} */ var tRow = 0; 272 /** @type {number} */ var mRow = 0; 273 /** @type {number} */ var sSign = 1.0; 274 /** @type {number} */ var tSign = 1.0; 275 /** @type {number} */ var mSign = 1.0; 276 277 switch (face) { 278 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: mRow = 0; sRow = 2; tRow = 1; mSign = -1.0; tSign = -1.0; break; 279 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: mRow = 0; sRow = 2; tRow = 1; sSign = -1.0; tSign = -1.0; break; 280 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: mRow = 1; sRow = 0; tRow = 2; mSign = -1.0; tSign = -1.0; break; 281 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: mRow = 1; sRow = 0; tRow = 2; break; 282 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: mRow = 2; sRow = 0; tRow = 1; mSign = -1.0; sSign = -1.0; tSign = -1.0; break; 283 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: mRow = 2; sRow = 0; tRow = 1; tSign = -1.0; break; 284 default: 285 throw new Error('Invalid cube face specified.'); 286 } 287 288 dst[0 + mRow] = mSign; 289 dst[3 + mRow] = mSign; 290 dst[6 + mRow] = mSign; 291 dst[9 + mRow] = mSign; 292 293 dst[0 + sRow] = sSign * bottomLeft[0]; 294 dst[3 + sRow] = sSign * bottomLeft[0]; 295 dst[6 + sRow] = sSign * topRight[0]; 296 dst[9 + sRow] = sSign * topRight[0]; 297 298 dst[0 + tRow] = tSign * bottomLeft[1]; 299 dst[3 + tRow] = tSign * topRight[1]; 300 dst[6 + tRow] = tSign * bottomLeft[1]; 301 dst[9 + tRow] = tSign * topRight[1]; 302 303 return dst; 304 }; 305 306 /** 307 * @param {number} layerNdx 308 * @param {Array<number>} bottomLeft 309 * @param {Array<number>} topRight 310 * @return {Array<number>} 311 */ 312 glsTextureTestUtil.computeQuadTexCoord2DArray = function(layerNdx, bottomLeft, topRight) { 313 var dst = []; 314 dst.length = 4 * 3; 315 316 dst[0] = bottomLeft[0]; dst[1] = bottomLeft[1]; dst[2] = layerNdx; 317 dst[3] = bottomLeft[0]; dst[4] = topRight[1]; dst[5] = layerNdx; 318 dst[6] = topRight[0]; dst[7] = bottomLeft[1]; dst[8] = layerNdx; 319 dst[9] = topRight[0]; dst[10] = topRight[1]; dst[11] = layerNdx; 320 321 return dst; 322 }; 323 324 /** 325 * @param {Array<number>} a 326 * @param {Array<number>} b 327 * @param {Array<number>} c 328 * @return {Array<number>} a + (b - a) * c 329 */ 330 glsTextureTestUtil.selectCoords = function(a, b, c) { 331 var x1 = deMath.subtract(b, a); 332 var x2 = deMath.multiply(x1, c); 333 var x3 = deMath.add(a, x2); 334 return x3; 335 }; 336 337 /** 338 * @param {Array<number>} p0 339 * @param {Array<number>} p1 340 * @param {Array<number>} dirSwz 341 * @return {Array<number>} 342 */ 343 glsTextureTestUtil.computeQuadTexCoord3D = function(p0, p1, dirSwz) { 344 var dst = []; 345 dst.length = 4 * 3; 346 347 var f0 = deMath.swizzle(([0, 0, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]); 348 var f1 = deMath.swizzle(([0, 1, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]); 349 var f2 = deMath.swizzle(([1, 0, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]); 350 var f3 = deMath.swizzle(([1, 1, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]); 351 352 var v0 = glsTextureTestUtil.selectCoords(p0, p1, f0); 353 var v1 = glsTextureTestUtil.selectCoords(p0, p1, f1); 354 var v2 = glsTextureTestUtil.selectCoords(p0, p1, f2); 355 var v3 = glsTextureTestUtil.selectCoords(p0, p1, f3); 356 357 dst[0] = v0[0]; dst[1] = v0[1]; dst[2] = v0[2]; 358 dst[3] = v1[0]; dst[4] = v1[1]; dst[5] = v1[2]; 359 dst[6] = v2[0]; dst[7] = v2[1]; dst[8] = v2[2]; 360 dst[9] = v3[0]; dst[10] = v3[1]; dst[11] = v3[2]; 361 362 return dst; 363 }; 364 365 /** 366 * @enum 367 */ 368 glsTextureTestUtil.programType = { 369 PROGRAM_2D_FLOAT: 0, 370 PROGRAM_2D_INT: 1, 371 PROGRAM_2D_UINT: 2, 372 PROGRAM_2D_SHADOW: 3, 373 374 PROGRAM_2D_FLOAT_BIAS: 4, 375 PROGRAM_2D_INT_BIAS: 5, 376 PROGRAM_2D_UINT_BIAS: 6, 377 PROGRAM_2D_SHADOW_BIAS: 7, 378 379 PROGRAM_1D_FLOAT: 8, 380 PROGRAM_1D_INT: 9, 381 PROGRAM_1D_UINT: 10, 382 PROGRAM_1D_SHADOW: 11, 383 384 PROGRAM_1D_FLOAT_BIAS: 12, 385 PROGRAM_1D_INT_BIAS: 13, 386 PROGRAM_1D_UINT_BIAS: 14, 387 PROGRAM_1D_SHADOW_BIAS: 15, 388 389 PROGRAM_CUBE_FLOAT: 16, 390 PROGRAM_CUBE_INT: 17, 391 PROGRAM_CUBE_UINT: 18, 392 PROGRAM_CUBE_SHADOW: 19, 393 394 PROGRAM_CUBE_FLOAT_BIAS: 20, 395 PROGRAM_CUBE_INT_BIAS: 21, 396 PROGRAM_CUBE_UINT_BIAS: 22, 397 PROGRAM_CUBE_SHADOW_BIAS: 23, 398 399 PROGRAM_1D_ARRAY_FLOAT: 24, 400 PROGRAM_1D_ARRAY_INT: 25, 401 PROGRAM_1D_ARRAY_UINT: 26, 402 PROGRAM_1D_ARRAY_SHADOW: 27, 403 404 PROGRAM_2D_ARRAY_FLOAT: 28, 405 PROGRAM_2D_ARRAY_INT: 29, 406 PROGRAM_2D_ARRAY_UINT: 30, 407 PROGRAM_2D_ARRAY_SHADOW: 31, 408 409 PROGRAM_3D_FLOAT: 32, 410 PROGRAM_3D_INT: 33, 411 PROGRAM_3D_UINT: 34, 412 413 PROGRAM_3D_FLOAT_BIAS: 35, 414 PROGRAM_3D_INT_BIAS: 36, 415 PROGRAM_3D_UINT_BIAS: 37, 416 417 PROGRAM_CUBE_ARRAY_FLOAT: 38, 418 PROGRAM_CUBE_ARRAY_INT: 39, 419 PROGRAM_CUBE_ARRAY_UINT: 40, 420 PROGRAM_CUBE_ARRAY_SHADOW: 41, 421 422 PROGRAM_BUFFER_FLOAT: 42, 423 PROGRAM_BUFFER_INT: 43, 424 PROGRAM_BUFFER_UINT: 44 425 }; 426 427 /** 428 * @constructor 429 * @param {string} version GL version 430 * @param {gluShaderUtil.precision} precision 431 */ 432 glsTextureTestUtil.ProgramLibrary = function(version, precision) { 433 this.m_glslVersion = version; 434 this.m_texCoordPrecision = precision; 435 }; 436 437 /** 438 * @param {glsTextureTestUtil.programType} program 439 * @return {gluShaderProgram.ShaderProgram} 440 */ 441 glsTextureTestUtil.ProgramLibrary.prototype.getProgram = function(program) { 442 /* TODO: Implement */ 443 // if (m_programs.find(program) != m_programs.end()) 444 // return m_programs[program]; // Return from cache. 445 446 var vertShaderTemplate = 447 '${VTX_HEADER}' + 448 '${VTX_IN} highp vec4 a_position;\n' + 449 '${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n' + 450 '${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n' + 451 '\n' + 452 'void main (void)\n' + 453 ' {\n' + 454 ' gl_Position = a_position;\n' + 455 ' v_texCoord = a_texCoord;\n' + 456 '}\n'; 457 var fragShaderTemplate = 458 '${FRAG_HEADER}' + 459 '${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n' + 460 'uniform ${PRECISION} float u_bias;\n' + 461 'uniform ${PRECISION} float u_ref;\n' + 462 'uniform ${PRECISION} vec4 u_colorScale;\n' + 463 'uniform ${PRECISION} vec4 u_colorBias;\n' + 464 'uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n' + 465 '\n' + 466 'void main (void)\n' + 467 ' {\n' + 468 ' ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n' + 469 '}\n'; 470 471 var params = []; 472 473 var isCube = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT, glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW_BIAS); 474 var isArray = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW) || 475 deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW); 476 477 var is1D = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_1D_FLOAT, glsTextureTestUtil.programType.PROGRAM_1D_UINT_BIAS) || 478 deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW) || 479 deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT, glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT); 480 481 var is2D = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_2D_FLOAT, glsTextureTestUtil.programType.PROGRAM_2D_UINT_BIAS) || 482 deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW); 483 484 var is3D = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_3D_FLOAT, glsTextureTestUtil.programType.PROGRAM_3D_UINT_BIAS); 485 var isCubeArray = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_SHADOW); 486 var isBuffer = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT, glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT); 487 488 if (this.m_glslVersion === '100 es') { 489 params['FRAG_HEADER'] = ''; 490 params['VTX_HEADER'] = ''; 491 params['VTX_IN'] = 'attribute'; 492 params['VTX_OUT'] = 'varying'; 493 params['FRAG_IN'] = 'varying'; 494 params['FRAG_COLOR'] = 'gl_FragColor'; 495 } else if (this.m_glslVersion === '300 es' || this.m_glslVersion === '310 es' || this.m_glslVersion === '330 es') { 496 var ext = null; 497 498 // if (isCubeArray && glu::glslVersionIsES(m_glslVersion)) 499 // ext = "gl.EXT_texture_cube_map_array"; 500 // else if (isBuffer && glu::glslVersionIsES(m_glslVersion)) 501 // ext = "gl.EXT_texture_buffer"; 502 503 var extension = ''; 504 if (ext) 505 extension = '\n#extension ' + ext + ' : require'; 506 507 params['FRAG_HEADER'] = '#version ' + this.m_glslVersion + extension + '\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n'; 508 params['VTX_HEADER'] = '#version ' + this.m_glslVersion + '\n'; 509 params['VTX_IN'] = 'in'; 510 params['VTX_OUT'] = 'out'; 511 params['FRAG_IN'] = 'in'; 512 params['FRAG_COLOR'] = 'dEQP_FragColor'; 513 } else 514 throw new Error('Unsupported version: ' + this.m_glslVersion); 515 516 params['PRECISION'] = gluShaderUtil.getPrecisionName(this.m_texCoordPrecision); 517 518 if (isCubeArray) 519 params['TEXCOORD_TYPE'] = 'vec4'; 520 else if (isCube || (is2D && isArray) || is3D) 521 params['TEXCOORD_TYPE'] = 'vec3'; 522 else if ((is1D && isArray) || is2D) 523 params['TEXCOORD_TYPE'] = 'vec2'; 524 else if (is1D) 525 params['TEXCOORD_TYPE'] = 'float'; 526 else 527 DE_ASSERT(false); 528 529 var sampler = null; 530 var lookup = null; 531 532 if (this.m_glslVersion === '300 es' || this.m_glslVersion === '310 es' || this.m_glslVersion === '330 es') { 533 switch (program) { 534 case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT: sampler = 'sampler2D'; lookup = 'texture(u_sampler, v_texCoord)'; break; 535 case glsTextureTestUtil.programType.PROGRAM_2D_INT: sampler = 'isampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 536 case glsTextureTestUtil.programType.PROGRAM_2D_UINT: sampler = 'usampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 537 case glsTextureTestUtil.programType.PROGRAM_2D_SHADOW: sampler = 'sampler2DShadow'; lookup = 'vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)'; break; 538 case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT_BIAS: sampler = 'sampler2D'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break; 539 case glsTextureTestUtil.programType.PROGRAM_2D_INT_BIAS: sampler = 'isampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 540 case glsTextureTestUtil.programType.PROGRAM_2D_UINT_BIAS: sampler = 'usampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 541 case glsTextureTestUtil.programType.PROGRAM_2D_SHADOW_BIAS: sampler = 'sampler2DShadow'; lookup = 'vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)'; break; 542 case glsTextureTestUtil.programType.PROGRAM_1D_FLOAT: sampler = 'sampler1D'; lookup = 'texture(u_sampler, v_texCoord)'; break; 543 case glsTextureTestUtil.programType.PROGRAM_1D_INT: sampler = 'isampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 544 case glsTextureTestUtil.programType.PROGRAM_1D_UINT: sampler = 'usampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 545 case glsTextureTestUtil.programType.PROGRAM_1D_SHADOW: sampler = 'sampler1DShadow'; lookup = 'vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)'; break; 546 case glsTextureTestUtil.programType.PROGRAM_1D_FLOAT_BIAS: sampler = 'sampler1D'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break; 547 case glsTextureTestUtil.programType.PROGRAM_1D_INT_BIAS: sampler = 'isampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 548 case glsTextureTestUtil.programType.PROGRAM_1D_UINT_BIAS: sampler = 'usampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 549 case glsTextureTestUtil.programType.PROGRAM_1D_SHADOW_BIAS: sampler = 'sampler1DShadow'; lookup = 'vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)'; break; 550 case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT: sampler = 'samplerCube'; lookup = 'texture(u_sampler, v_texCoord)'; break; 551 case glsTextureTestUtil.programType.PROGRAM_CUBE_INT: sampler = 'isamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 552 case glsTextureTestUtil.programType.PROGRAM_CUBE_UINT: sampler = 'usamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 553 case glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW: sampler = 'samplerCubeShadow'; lookup = 'vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)'; break; 554 case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT_BIAS: sampler = 'samplerCube'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break; 555 case glsTextureTestUtil.programType.PROGRAM_CUBE_INT_BIAS: sampler = 'isamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 556 case glsTextureTestUtil.programType.PROGRAM_CUBE_UINT_BIAS: sampler = 'usamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 557 case glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW_BIAS: sampler = 'samplerCubeShadow'; lookup = 'vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)'; break; 558 case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT: sampler = 'sampler2DArray'; lookup = 'texture(u_sampler, v_texCoord)'; break; 559 case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_INT: sampler = 'isampler2DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 560 case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_UINT: sampler = 'usampler2DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 561 case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW: sampler = 'sampler2DArrayShadow'; lookup = 'vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)'; break; 562 case glsTextureTestUtil.programType.PROGRAM_3D_FLOAT: sampler = 'sampler3D'; lookup = 'texture(u_sampler, v_texCoord)'; break; 563 case glsTextureTestUtil.programType.PROGRAM_3D_INT: sampler = 'isampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 564 case glsTextureTestUtil.programType.PROGRAM_3D_UINT: sampler = ' usampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 565 case glsTextureTestUtil.programType.PROGRAM_3D_FLOAT_BIAS: sampler = 'sampler3D'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break; 566 case glsTextureTestUtil.programType.PROGRAM_3D_INT_BIAS: sampler = 'isampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 567 case glsTextureTestUtil.programType.PROGRAM_3D_UINT_BIAS: sampler = ' usampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break; 568 case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_FLOAT: sampler = 'samplerCubeArray'; lookup = 'texture(u_sampler, v_texCoord)'; break; 569 case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_INT: sampler = 'isamplerCubeArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 570 case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_UINT: sampler = 'usamplerCubeArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 571 case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_SHADOW: sampler = 'samplerCubeArrayShadow'; lookup = 'vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)'; break; 572 case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT: sampler = 'sampler1DArray'; lookup = 'texture(u_sampler, v_texCoord)'; break; 573 case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_INT: sampler = 'isampler1DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 574 case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_UINT: sampler = 'usampler1DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break; 575 case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW: sampler = 'sampler1DArrayShadow'; lookup = 'vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)'; break; 576 case glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT: sampler = 'samplerBuffer'; lookup = 'texelFetch(u_sampler, int(v_texCoord))'; break; 577 case glsTextureTestUtil.programType.PROGRAM_BUFFER_INT: sampler = 'isamplerBuffer'; lookup = 'vec4(texelFetch(u_sampler, int(v_texCoord)))'; break; 578 case glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT: sampler = 'usamplerBuffer'; lookup = 'vec4(texelFetch(u_sampler, int(v_texCoord)))'; break; 579 default: 580 DE_ASSERT(false); 581 } 582 } else if (this.m_glslVersion === '100 es') { 583 sampler = isCube ? 'samplerCube' : 'sampler2D'; 584 585 switch (program) { 586 case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT: lookup = 'texture2D(u_sampler, v_texCoord)'; break; 587 case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT_BIAS: lookup = 'texture2D(u_sampler, v_texCoord, u_bias)'; break; 588 case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT: lookup = 'textureCube(u_sampler, v_texCoord)'; break; 589 case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT_BIAS: lookup = 'textureCube(u_sampler, v_texCoord, u_bias)'; break; 590 default: 591 DE_ASSERT(false); 592 } 593 } else 594 DE_ASSERT(!'Unsupported version'); 595 596 params['SAMPLER_TYPE'] = sampler; 597 params['LOOKUP'] = lookup; 598 599 var vertSrc = tcuStringTemplate.specialize(vertShaderTemplate, params); 600 var fragSrc = tcuStringTemplate.specialize(fragShaderTemplate, params); 601 var progObj = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertSrc, fragSrc)); 602 // if (!progObj.isOk()) { 603 // // log << *progObj; 604 // testFailedOptions("Failed to create shader", true); 605 // } 606 607 // try 608 // { 609 // m_programs[program] = progObj; 610 // } 611 // catch (...) 612 // { 613 // delete progObj; 614 // throw; 615 // } 616 617 return progObj; 618 }; 619 620 // public: 621 // glsTextureTestUtil.ProgramLibrary (const glu::RenderContext& context, tcu::TestContext& testCtx, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision); 622 // ~glsTextureTestUtil.ProgramLibrary (void); 623 624 // glu::ShaderProgram* getProgram (Program program); 625 // void clear (void); 626 627 // private: 628 // glsTextureTestUtil.ProgramLibrary (const glsTextureTestUtil.ProgramLibrary& other); 629 // glsTextureTestUtil.ProgramLibrary& operator= (const glsTextureTestUtil.ProgramLibrary& other); 630 631 // const glu::RenderContext& m_context; 632 // tcu::TestContext& m_testCtx; 633 // glu::GLSLVersion m_glslVersion; 634 // glu::Precision m_texCoordPrecision; 635 // std::map<Program, glu::ShaderProgram*> m_programs; 636 // }; 637 638 /** 639 * @constructor 640 * @param {string} version GL version 641 * @param {gluShaderUtil.precision} precision 642 */ 643 glsTextureTestUtil.TextureRenderer = function(version, precision) { 644 this.m_programLibrary = new glsTextureTestUtil.ProgramLibrary(version, precision); 645 }; 646 647 /** 648 * @param {tcuPixelFormat.PixelFormat} format 649 * @return {Array<boolean>} 650 */ 651 glsTextureTestUtil.getCompareMask = function(format) { 652 return [ 653 format.redBits > 0, 654 format.greenBits > 0, 655 format.blueBits > 0, 656 format.alphaBits > 0 657 ]; 658 }; 659 660 /** 661 * @param {tcuPixelFormat.PixelFormat} format 662 * @return {Array<number>} 663 */ 664 glsTextureTestUtil.getBitsVec = function(format) { 665 return [ 666 format.redBits, 667 format.greenBits, 668 format.blueBits, 669 format.alphaBits 670 ]; 671 }; 672 673 /** 674 * @param {number} texUnit 675 * @param {Array<number>} texCoord 676 * @param {glsTextureTestUtil.RenderParams} params 677 */ 678 glsTextureTestUtil.TextureRenderer.prototype.renderQuad = function(texUnit, texCoord, params) { 679 var wCoord = params.flags.projected ? params.w : [1, 1, 1, 1]; 680 var useBias = params.flags.use_bias; 681 var logUniforms = params.flags.log_uniforms; 682 683 // Render quad with texture. 684 var position = [ 685 -1 * wCoord[0], -1 * wCoord[0], 0, wCoord[0], 686 -1 * wCoord[1], +1 * wCoord[1], 0, wCoord[1], 687 +1 * wCoord[2], -1 * wCoord[2], 0, wCoord[2], 688 +1 * wCoord[3], +1 * wCoord[3], 0, wCoord[3] 689 ]; 690 /** @const */ var indices = [0, 1, 2, 2, 1, 3]; 691 692 /** @type {?glsTextureTestUtil.programType} */ var progSpec = null; 693 var numComps = 0; 694 if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_2D) { 695 numComps = 2; 696 697 switch (params.samplerType) { 698 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_FLOAT; break; 699 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_INT; break; 700 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_UINT; break; 701 case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_SHADOW_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_SHADOW; break; 702 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 703 } 704 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_1D) { 705 numComps = 1; 706 707 switch (params.samplerType) { 708 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_FLOAT; break; 709 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_INT; break; 710 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_UINT; break; 711 case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_SHADOW_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_SHADOW; break; 712 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 713 } 714 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_CUBE) { 715 numComps = 3; 716 717 switch (params.samplerType) { 718 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT; break; 719 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_INT; break; 720 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_UINT; break; 721 case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW; break; 722 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 723 } 724 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_3D) { 725 numComps = 3; 726 727 switch (params.samplerType) { 728 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_3D_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_3D_FLOAT; break; 729 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_3D_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_3D_INT; break; 730 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_3D_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_3D_UINT; break; 731 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 732 } 733 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY) { 734 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias. 735 736 numComps = 3; 737 738 switch (params.samplerType) { 739 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT; break; 740 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_INT; break; 741 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_UINT; break; 742 case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW; break; 743 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 744 } 745 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_CUBE_ARRAY) { 746 DE_ASSERT(!useBias); 747 748 numComps = 4; 749 750 switch (params.samplerType) { 751 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_FLOAT; break; 752 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_INT; break; 753 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_UINT; break; 754 case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_SHADOW; break; 755 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 756 } 757 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_1D_ARRAY) { 758 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias. 759 760 numComps = 2; 761 762 switch (params.samplerType) { 763 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT; break; 764 case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_INT; break; 765 case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_UINT; break; 766 case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW; break; 767 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 768 } 769 } else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_BUFFER) { 770 numComps = 1; 771 772 switch (params.samplerType) { 773 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FETCH_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT; break; 774 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FETCH_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_BUFFER_INT; break; 775 case glsTextureTestUtil.samplerType.SAMPLERTYPE_FETCH_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT; break; 776 default: throw new Error('Unrecognized sampler type:' + params.samplerType); 777 } 778 } else 779 throw new Error('Unrecognized texture type:' + params.texType); 780 781 if (progSpec === null) 782 throw new Error('Could not find program specification'); 783 784 var program = this.m_programLibrary.getProgram(progSpec); 785 786 // \todo [2012-09-26 pyry] Move to glsTextureTestUtil.ProgramLibrary and log unique programs only(?) 787 /* TODO: Port logging 788 if (params.flags.log_programs) 789 log << *program; 790 */ 791 792 // Program and uniforms. 793 var prog = program.getProgram(); 794 gl.useProgram(prog); 795 796 var loc = gl.getUniformLocation(prog, 'u_sampler'); 797 gl.uniform1i(loc, texUnit); 798 // if (logUniforms) 799 // log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage; 800 801 if (useBias) { 802 gl.uniform1f(gl.getUniformLocation(prog, 'u_bias'), params.bias); 803 // if (logUniforms) 804 // log << TestLog::Message << "u_bias = " << params.bias << TestLog::EndMessage; 805 } 806 807 if (params.samplerType == glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW) { 808 gl.uniform1f(gl.getUniformLocation(prog, 'u_ref'), params.ref); 809 // if (logUniforms) 810 // log << TestLog::Message << "u_ref = " << params.ref << TestLog::EndMessage; 811 } 812 813 gl.uniform4fv(gl.getUniformLocation(prog, 'u_colorScale'), params.colorScale); 814 gl.uniform4fv(gl.getUniformLocation(prog, 'u_colorBias'), params.colorBias); 815 816 // if (logUniforms) 817 // { 818 // log << TestLog::Message << "u_colorScale = " << params.colorScale << TestLog::EndMessage; 819 // log << TestLog::Message << "u_colorBias = " << params.colorBias << TestLog::EndMessage; 820 // } 821 var vertexArrays = []; 822 823 var posLoc = gl.getAttribLocation(prog, 'a_position'); 824 if (posLoc === -1) { 825 testFailedOptions("no location found for attribute 'a_position'", true); 826 } 827 var texLoc = gl.getAttribLocation(prog, 'a_texCoord'); 828 if (texLoc === -1) { 829 testFailedOptions("no location found for attribute 'a_texCoord'", true); 830 } 831 832 vertexArrays.push(new gluDrawUtil.VertexArrayBinding(gl.FLOAT, posLoc, 4, 4, position)); 833 vertexArrays.push(new gluDrawUtil.VertexArrayBinding(gl.FLOAT, texLoc, numComps, 4, texCoord)); 834 gluDrawUtil.draw(gl, prog, vertexArrays, gluDrawUtil.triangles(indices)); 835 }; 836 837 // public: 838 // glsTextureTestUtil.TextureRenderer (const glu::RenderContext& context, tcu::TestContext& testCtx, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision); 839 // ~glsTextureTestUtil.TextureRenderer (void); 840 841 // void clear (void); //!< Frees allocated resources. Destructor will call clear() as well. 842 843 // void renderQuad (int texUnit, const float* texCoord, TextureType texType); 844 // void renderQuad (int texUnit, const float* texCoord, const glsTextureTestUtil.RenderParams& params); 845 846 // private: 847 // glsTextureTestUtil.TextureRenderer (const glsTextureTestUtil.TextureRenderer& other); 848 // glsTextureTestUtil.TextureRenderer& operator= (const glsTextureTestUtil.TextureRenderer& other); 849 850 // const glu::RenderContext& m_renderCtx; 851 // tcu::TestContext& m_testCtx; 852 // glsTextureTestUtil.ProgramLibrary m_programLibrary; 853 // }; 854 855 /** 856 * @constructor 857 * @param {tcuSurface.Surface} surface 858 * @param {tcuPixelFormat.PixelFormat=} colorFmt 859 * @param {number=} x 860 * @param {number=} y 861 * @param {number=} width 862 * @param {number=} height 863 */ 864 glsTextureTestUtil.SurfaceAccess = function(surface, colorFmt, x, y, width, height) { 865 this.m_surface = surface; 866 this.colorMask = undefined; /*TODO*/ 867 this.m_x = x || 0; 868 this.m_y = y || 0; 869 this.m_width = width || surface.getWidth(); 870 this.m_height = height || surface.getHeight(); 871 }; 872 873 /** @return {number} */ 874 glsTextureTestUtil.SurfaceAccess.prototype.getWidth = function() { return this.m_width; }; 875 /** @return {number} */ 876 glsTextureTestUtil.SurfaceAccess.prototype.getHeight = function() { return this.m_height; }; 877 878 /** 879 * @param {Array<number>} color 880 * @param {number} x 881 * @param {number} y 882 */ 883 glsTextureTestUtil.SurfaceAccess.prototype.setPixel = function(color, x, y) { 884 /* TODO: Apply color mask */ 885 var c = color; 886 for (var i = 0; i < c.length; i++) 887 c[i] = deMath.clamp(Math.round(color[i] * 255), 0, 255); 888 this.m_surface.setPixel(x, y, c); 889 }; 890 891 /** 892 * @param {glsTextureTestUtil.lodMode} mode 893 * @param {number} dudx 894 * @param {number} dvdx 895 * @param {number} dwdx 896 * @param {number} dudy 897 * @param {number} dvdy 898 * @param {number} dwdy 899 * @return {number} 900 */ 901 glsTextureTestUtil.computeLodFromDerivates3D = function(mode, dudx, dvdx, dwdx, dudy, dvdy, dwdy) { 902 var p = 0; 903 switch (mode) { 904 case glsTextureTestUtil.lodMode.EXACT: 905 p = Math.max(Math.sqrt(dudx * dudx + dvdx * dvdx + dwdx * dwdx), Math.sqrt(dudy * dudy + dvdy * dvdy + dwdy * dwdy)); 906 break; 907 908 case glsTextureTestUtil.lodMode.MIN_BOUND: 909 case glsTextureTestUtil.lodMode.MAX_BOUND: { 910 var mu = Math.max(Math.abs(dudx), Math.abs(dudy)); 911 var mv = Math.max(Math.abs(dvdx), Math.abs(dvdy)); 912 var mw = Math.max(Math.abs(dwdx), Math.abs(dwdy)); 913 914 p = (mode == glsTextureTestUtil.lodMode.MIN_BOUND) ? Math.max(mu, mv, mw) : mu + mv + mw; 915 break; 916 } 917 918 default: 919 DE_ASSERT(false); 920 } 921 922 // Native dEQP uses 32-bit numbers. So here 64-bit floating numbers should be transformed into 32-bit ones to ensure the correctness of the result. 923 return deMath.toFloat32(Math.log(p)) * deMath.INV_LOG_2_FLOAT32; 924 }; 925 926 /** 927 * @param {glsTextureTestUtil.lodMode} mode 928 * @param {Array<number>} dstSize 929 * @param {Array<number>} srcSize 930 * @param {Array<number>} sq 931 * @param {Array<number>} tq 932 * @param {Array<number>=} rq 933 * @return {number} 934 */ 935 glsTextureTestUtil.computeNonProjectedTriLod = function(mode, dstSize, srcSize, sq, tq, rq) { 936 var dux = (sq[2] - sq[0]) * srcSize[0]; 937 var duy = (sq[1] - sq[0]) * srcSize[0]; 938 var dvx = (tq[2] - tq[0]) * srcSize[1]; 939 var dvy = (tq[1] - tq[0]) * srcSize[1]; 940 var dwx = 0; 941 var dwy = 0; 942 if (rq) { 943 dwx = (rq[2] - rq[0]) * srcSize[2]; 944 dwy = (rq[1] - rq[0]) * srcSize[2]; 945 } 946 var dx = dstSize[0]; 947 var dy = dstSize[1]; 948 949 return glsTextureTestUtil.computeLodFromDerivates3D(mode, dux / dx, dvx / dx, dwx / dx, duy / dy, dvy / dy, dwy / dy); 950 }; 951 952 /** 953 * @param {Array<number>} v 954 * @param {number} x 955 * @param {number} y 956 * @return {number} 957 */ 958 glsTextureTestUtil.triangleInterpolate = function(v, x, y) { 959 return v[0] + (v[2] - v[0]) * x + (v[1] - v[0]) * y; 960 }; 961 962 /** 963 * @param {Array<number>} s 964 * @param {Array<number>} w 965 * @param {number} wx 966 * @param {number} width 967 * @param {number} ny 968 * @return {number} 969 */ 970 glsTextureTestUtil.triDerivateX = function(s, w, wx, width, ny) { 971 var d = w[1] * w[2] * (width * (ny - 1) + wx) - w[0] * (w[2] * width * ny + w[1] * wx); 972 return (w[0] * w[1] * w[2] * width * (w[1] * (s[0] - s[2]) * (ny - 1) + ny * (w[2] * (s[1] - s[0]) + w[0] * (s[2] - s[1])))) / (d * d); 973 }; 974 975 /** 976 * @param {Array<number>} s 977 * @param {Array<number>} w 978 * @param {number} wy 979 * @param {number} height 980 * @param {number} nx 981 * @return {number} 982 */ 983 glsTextureTestUtil.triDerivateY = function(s, w, wy, height, nx) { 984 var d = w[1] * w[2] * (height * (nx - 1) + wy) - w[0] * (w[1] * height * nx + w[2] * wy); 985 return (w[0] * w[1] * w[2] * height * (w[2] * (s[0] - s[1]) * (nx - 1) + nx * (w[0] * (s[1] - s[2]) + w[1] * (s[2] - s[0])))) / (d * d); 986 }; 987 988 /** 989 * @param {(tcuTexture.Texture2DView|tcuTexture.Texture2DArrayView|tcuTexture.TextureCubeView)} src 990 * @param {glsTextureTestUtil.ReferenceParams} params 991 * @param {Array<number>} texCoord Texture coordinates 992 * @param {number} lod 993 * @return {Array<number>} sample 994 */ 995 glsTextureTestUtil.execSample = function(src, params, texCoord, lod) { 996 if (params.samplerType == glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW) 997 return [src.sampleCompare(params.sampler, params.ref, texCoord, lod), 0, 0, 1]; 998 else 999 return src.sample(params.sampler, texCoord, lod); 1000 }; 1001 1002 /** 1003 * @param {Array<number>} pixel 1004 * @param {Array<number>} scale 1005 * @param {Array<number>} bias 1006 */ 1007 glsTextureTestUtil.applyScaleAndBias = function(pixel, scale, bias) { 1008 pixel[0] = pixel[0] * scale[0] + bias[0]; 1009 pixel[1] = pixel[1] * scale[1] + bias[1]; 1010 pixel[2] = pixel[2] * scale[2] + bias[2]; 1011 pixel[3] = pixel[3] * scale[3] + bias[3]; 1012 }; 1013 1014 /** 1015 * @param {Array<number>} pixel 1016 * @param {Array<number>} scale 1017 * @param {Array<number>} bias 1018 */ 1019 glsTextureTestUtil.deapplyScaleAndBias = function(pixel, scale, bias) { 1020 pixel[0] = (pixel[0] - bias[0]) / scale[0]; 1021 pixel[1] = (pixel[1] - bias[1]) / scale[1]; 1022 pixel[2] = (pixel[2] - bias[2]) / scale[2]; 1023 pixel[3] = (pixel[3] - bias[3]) / scale[3]; 1024 }; 1025 1026 /** 1027 * @param {glsTextureTestUtil.SurfaceAccess} dst 1028 * @param {tcuTexture.Texture2DView} src 1029 * @param {Array<number>} sq 1030 * @param {Array<number>} tq 1031 * @param {glsTextureTestUtil.ReferenceParams} params 1032 */ 1033 glsTextureTestUtil.sampleTextureProjected2D = function(dst, src, sq, tq, params) { 1034 /** @type {number} */ var lodBias = params.flags.use_bias ? params.bias : 0.0; 1035 /** @type {number} */ var dstW = dst.getWidth(); 1036 /** @type {number} */ var dstH = dst.getHeight(); 1037 1038 /** @type {Array<number>} */ var uq = deMath.scale(sq, src.getWidth()); 1039 /** @type {Array<number>} */ var vq = deMath.scale(tq, src.getHeight()); 1040 1041 /** @type {Array<Array<number>>} */ var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1042 /** @type {Array<Array<number>>} */ var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1043 /** @type {Array<Array<number>>} */ var triU = [deMath.swizzle(uq, [0, 1, 2]), deMath.swizzle(uq, [3, 2, 1])]; 1044 /** @type {Array<Array<number>>} */ var triV = [deMath.swizzle(vq, [0, 1, 2]), deMath.swizzle(vq, [3, 2, 1])]; 1045 /** @type {Array<Array<number>>} */ var triW = [deMath.swizzle(params.w, [0, 1, 2]), deMath.swizzle(params.w, [3, 2, 1])]; 1046 1047 for (var py = 0; py < dst.getHeight(); py++) { 1048 for (var px = 0; px < dst.getWidth(); px++) { 1049 /** @type {number} */ var wx = px + 0.5; 1050 /** @type {number} */ var wy = py + 0.5; 1051 /** @type {number} */ var nx = wx / dstW; 1052 /** @type {number} */ var ny = wy / dstH; 1053 1054 /** @type {number} */ var triNdx = nx + ny >= 1.0 ? 1 : 0; 1055 /** @type {number} */ var triWx = triNdx ? dstW - wx : wx; 1056 /** @type {number} */ var triWy = triNdx ? dstH - wy : wy; 1057 /** @type {number} */ var triNx = triNdx ? 1.0 - nx : nx; 1058 /** @type {number} */ var triNy = triNdx ? 1.0 - ny : ny; 1059 1060 /** @type {number} */ var s = glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy); 1061 /** @type {number} */ var t = glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy); 1062 /** @type {number} */ var lod = glsTextureTestUtil.computeProjectedTriLod2D(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triWx, triWy, dst.getWidth(), dst.getHeight()) + lodBias; 1063 1064 var pixel = glsTextureTestUtil.execSample(src, params, [s, t], lod); 1065 glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias); 1066 dst.setPixel(pixel, px, py); 1067 } 1068 } 1069 }; 1070 1071 /** 1072 * @param {glsTextureTestUtil.lodMode} mode 1073 * @param {Array<number>} u 1074 * @param {Array<number>} v 1075 * @param {Array<number>} projection 1076 * @param {number} wx 1077 * @param {number} wy 1078 * @param {number} width 1079 * @param {number} height 1080 * @return {number} 1081 */ 1082 glsTextureTestUtil.computeProjectedTriLod2D = function(mode, u, v, projection, wx, wy, width, height) { 1083 // Exact derivatives. 1084 /** @type {number} */ var dudx = glsTextureTestUtil.triDerivateX(u, projection, wx, width, wy / height); 1085 /** @type {number} */ var dvdx = glsTextureTestUtil.triDerivateX(v, projection, wx, width, wy / height); 1086 /** @type {number} */ var dudy = glsTextureTestUtil.triDerivateY(u, projection, wy, height, wx / width); 1087 /** @type {number} */ var dvdy = glsTextureTestUtil.triDerivateY(v, projection, wy, height, wx / width); 1088 1089 return glsTextureTestUtil.computeLodFromDerivates2D(mode, dudx, dvdx, dudy, dvdy); 1090 }; 1091 1092 /** 1093 * @param {glsTextureTestUtil.SurfaceAccess} dst 1094 * @param {tcuTexture.Texture2DView} src 1095 * @param {Array<number>} sq 1096 * @param {Array<number>} tq 1097 * @param {glsTextureTestUtil.ReferenceParams} params 1098 */ 1099 glsTextureTestUtil.sampleTextureNonProjected2D = function(dst, src, sq, tq, params) { 1100 var lodBias = params.flags.use_bias ? params.bias : 0; 1101 1102 var dstSize = [dst.getWidth(), dst.getHeight()]; 1103 var srcSize = [src.getWidth(), src.getHeight()]; 1104 1105 // Coordinates and lod per triangle. 1106 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1107 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1108 var triLod = [deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias), params.minLod, params.maxLod), 1109 deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias), params.minLod, params.maxLod)]; 1110 1111 1112 for (var y = 0; y < dst.getHeight(); y++) { 1113 for (var x = 0; x < dst.getWidth(); x++) { 1114 var yf = (y + 0.5) / dst.getHeight(); 1115 var xf = (x + 0.5) / dst.getWidth(); 1116 1117 var triNdx = xf + yf >= 1 ? 1 : 0; // Top left fill rule. 1118 var triX = triNdx ? 1 - xf : xf; 1119 var triY = triNdx ? 1 - yf : yf; 1120 1121 var s = glsTextureTestUtil.triangleInterpolate(triS[triNdx], triX, triY); 1122 var t = glsTextureTestUtil.triangleInterpolate(triT[triNdx], triX, triY); 1123 var lod = triLod[triNdx]; 1124 1125 var pixel = glsTextureTestUtil.execSample(src, params, [s, t], lod); 1126 glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias); 1127 dst.setPixel(pixel, x, y); 1128 } 1129 } 1130 }; 1131 1132 /** 1133 * @param {glsTextureTestUtil.SurfaceAccess} dst 1134 * @param {tcuTexture.Texture2DArrayView} src 1135 * @param {Array<number>} sq 1136 * @param {Array<number>} tq 1137 * @param {Array<number>} rq 1138 * @param {glsTextureTestUtil.ReferenceParams} params 1139 */ 1140 glsTextureTestUtil.sampleTextureNonProjected2DArray = function(dst, src, sq, tq, rq, params) { 1141 var lodBias = (params.flags.use_bias) ? params.bias : 0; 1142 1143 var dstSize = [dst.getWidth(), dst.getHeight()]; 1144 var srcSize = [src.getWidth(), src.getHeight()]; 1145 1146 // Coordinates and lod per triangle. 1147 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1148 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1149 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 1150 var triLod = [glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias, 1151 glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias]; 1152 1153 for (var y = 0; y < dst.getHeight(); y++) { 1154 for (var x = 0; x < dst.getWidth(); x++) { 1155 var yf = (y + 0.5) / dst.getHeight(); 1156 var xf = (x + 0.5) / dst.getWidth(); 1157 1158 var triNdx = xf + yf >= 1 ? 1 : 0; // Top left fill rule. 1159 var triX = triNdx ? 1 - xf : xf; 1160 var triY = triNdx ? 1 - yf : yf; 1161 1162 var s = glsTextureTestUtil.triangleInterpolate(triS[triNdx], triX, triY); 1163 var t = glsTextureTestUtil.triangleInterpolate(triT[triNdx], triX, triY); 1164 var r = glsTextureTestUtil.triangleInterpolate(triR[triNdx], triX, triY); 1165 var lod = triLod[triNdx]; 1166 1167 var pixel = glsTextureTestUtil.execSample(src, params, [s, t, r], lod); 1168 glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias); 1169 dst.setPixel(pixel, x, y); 1170 } 1171 } 1172 }; 1173 1174 /** 1175 * @param {glsTextureTestUtil.SurfaceAccess} dst 1176 * @param {tcuTexture.Texture2DView} src 1177 * @param {Array<number>} texCoord 1178 * @param {glsTextureTestUtil.ReferenceParams} params 1179 */ 1180 glsTextureTestUtil.sampleTexture2D = function(dst, src, texCoord, params) { 1181 var view = src.getSubView(params.baseLevel, params.maxLevel); 1182 var sq = [texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]]; 1183 var tq = [texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]]; 1184 1185 if (params.flags.projected) 1186 glsTextureTestUtil.sampleTextureProjected2D(dst, view, sq, tq, params); 1187 else 1188 glsTextureTestUtil.sampleTextureNonProjected2D(dst, view, sq, tq, params); 1189 }; 1190 1191 /** 1192 * @param {glsTextureTestUtil.lodMode} mode 1193 * @param {number} dudx 1194 * @param {number} dvdx 1195 * @param {number} dudy 1196 * @param {number} dvdy 1197 * @return {number} 1198 */ 1199 glsTextureTestUtil.computeLodFromDerivates2D = function(mode, dudx, dvdx, dudy, dvdy) { 1200 var p = 0; 1201 switch (mode) { 1202 case glsTextureTestUtil.lodMode.EXACT: 1203 p = Math.max(Math.sqrt(dudx * dudx + dvdx * dvdx), Math.sqrt(dudy * dudy + dvdy * dvdy)); 1204 break; 1205 1206 case glsTextureTestUtil.lodMode.MIN_BOUND: 1207 case glsTextureTestUtil.lodMode.MAX_BOUND: { 1208 var mu = Math.max(Math.abs(dudx), Math.abs(dudy)); 1209 var mv = Math.max(Math.abs(dvdx), Math.abs(dvdy)); 1210 1211 p = (mode == glsTextureTestUtil.lodMode.MIN_BOUND) ? Math.max(mu, mv) : mu + mv; 1212 break; 1213 } 1214 1215 default: 1216 throw new Error('Unrecognized mode:' + mode); 1217 } 1218 1219 // Native dEQP uses 32-bit numbers. So here 64-bit floating numbers should be transformed into 32-bit ones to ensure the correctness of the result. 1220 return deMath.toFloat32(Math.log(p)) * deMath.INV_LOG_2_FLOAT32; 1221 }; 1222 1223 /** 1224 * @param {glsTextureTestUtil.lodMode} lodModeParm 1225 * @param {Array<number>} coord 1226 * @param {Array<number>} coordDx 1227 * @param {Array<number>} coordDy 1228 * @param {number} faceSize 1229 * @return {number} 1230 */ 1231 glsTextureTestUtil.computeCubeLodFromDerivates = function(lodModeParm, coord, coordDx, coordDy, faceSize) { 1232 var face = tcuTexture.selectCubeFace(coord); 1233 var maNdx = 0; 1234 var sNdx = 0; 1235 var tNdx = 0; 1236 1237 // \note Derivate signs don't matter when computing lod 1238 switch (face) { 1239 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: 1240 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: maNdx = 0; sNdx = 2; tNdx = 1; break; 1241 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: 1242 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: maNdx = 1; sNdx = 0; tNdx = 2; break; 1243 case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: 1244 case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: maNdx = 2; sNdx = 0; tNdx = 1; break; 1245 default: 1246 throw new Error('Unrecognized face ' + face); 1247 } { 1248 var sc = coord[sNdx]; 1249 var tc = coord[tNdx]; 1250 var ma = Math.abs(coord[maNdx]); 1251 var scdx = coordDx[sNdx]; 1252 var tcdx = coordDx[tNdx]; 1253 var madx = Math.abs(coordDx[maNdx]); 1254 var scdy = coordDy[sNdx]; 1255 var tcdy = coordDy[tNdx]; 1256 var mady = Math.abs(coordDy[maNdx]); 1257 var dudx = faceSize * 0.5 * (scdx * ma - sc * madx) / (ma * ma); 1258 var dvdx = faceSize * 0.5 * (tcdx * ma - tc * madx) / (ma * ma); 1259 var dudy = faceSize * 0.5 * (scdy * ma - sc * mady) / (ma * ma); 1260 var dvdy = faceSize * 0.5 * (tcdy * ma - tc * mady) / (ma * ma); 1261 return glsTextureTestUtil.computeLodFromDerivates2D(lodModeParm, dudx, dvdx, dudy, dvdy); 1262 } 1263 }; 1264 1265 /** 1266 * @param {glsTextureTestUtil.SurfaceAccess} dst 1267 * @param {tcuTexture.TextureCubeView} src 1268 * @param {Array<number>} sq 1269 * @param {Array<number>} tq 1270 * @param {Array<number>} rq 1271 * @param {glsTextureTestUtil.ReferenceParams} params 1272 */ 1273 glsTextureTestUtil.sampleTextureCube_str = function(dst, src, sq, tq, rq, params) { 1274 var dstSize = [dst.getWidth(), dst.getHeight()]; 1275 var dstW = dstSize[0]; 1276 var dstH = dstSize[1]; 1277 var srcSize = src.getSize(); 1278 1279 // Coordinates per triangle. 1280 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1281 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1282 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 1283 var triW = [deMath.swizzle(params.w, [0, 1, 2]), deMath.swizzle(params.w, [3, 2, 1])]; 1284 1285 var lodBias = (params.flags.use_bias ? params.bias : 0); 1286 1287 for (var py = 0; py < dst.getHeight(); py++) { 1288 for (var px = 0; px < dst.getWidth(); px++) { 1289 var wx = px + 0.5; 1290 var wy = py + 0.5; 1291 var nx = wx / dstW; 1292 var ny = wy / dstH; 1293 var triNdx = nx + ny >= 1 ? 1 : 0; 1294 var triNx = triNdx ? 1 - nx : nx; 1295 var triNy = triNdx ? 1 - ny : ny; 1296 1297 var coord = [glsTextureTestUtil.triangleInterpolate(triS[triNdx], triNx, triNy), 1298 glsTextureTestUtil.triangleInterpolate(triT[triNdx], triNx, triNy), 1299 glsTextureTestUtil.triangleInterpolate(triR[triNdx], triNx, triNy)]; 1300 var coordDx = [glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1301 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 1302 glsTextureTestUtil.triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)]; 1303 var coordDy = [glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1304 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 1305 glsTextureTestUtil.triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)]; 1306 1307 var lod = deMath.clamp((glsTextureTestUtil.computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, srcSize) + lodBias), params.minLod, params.maxLod); 1308 1309 var pixel = glsTextureTestUtil.execSample(src, params, coord, lod); 1310 glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias); 1311 dst.setPixel(pixel, px, py); 1312 } 1313 } 1314 }; 1315 1316 /** 1317 * @param {glsTextureTestUtil.SurfaceAccess} dst 1318 * @param {tcuTexture.TextureCubeView} src 1319 * @param {Array<number>} texCoord 1320 * @param {glsTextureTestUtil.ReferenceParams} params 1321 */ 1322 glsTextureTestUtil.sampleTextureCube = function(dst, src, texCoord, params) { 1323 /*const tcu::TextureCubeView*/ var view = src.getSubView(params.baseLevel, params.maxLevel); 1324 var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 1325 var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 1326 var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 1327 1328 glsTextureTestUtil.sampleTextureCube_str(dst, view, sq, tq, rq, params); 1329 }; 1330 1331 /** 1332 * @param {glsTextureTestUtil.SurfaceAccess} dst 1333 * @param {tcuTexture.Texture2DArrayView} src 1334 * @param {Array<number>} texCoord 1335 * @param {glsTextureTestUtil.ReferenceParams} params 1336 */ 1337 glsTextureTestUtil.sampleTexture2DArray = function(dst, src, texCoord, params) { 1338 var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 1339 var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 1340 var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 1341 1342 DE_ASSERT(!(params.flags.projected)); // \todo [2012-02-17 pyry] Support projected lookups. 1343 glsTextureTestUtil.sampleTextureNonProjected2DArray(dst, src, sq, tq, rq, params); 1344 }; 1345 1346 /** 1347 * @param {glsTextureTestUtil.SurfaceAccess} dst 1348 * @param {tcuTexture.Texture3DView} src 1349 * @param {Array<number>} sq 1350 * @param {Array<number>} tq 1351 * @param {Array<number>} rq 1352 * @param {glsTextureTestUtil.ReferenceParams} params 1353 */ 1354 glsTextureTestUtil.sampleTextureNonProjected3D = function(dst, src, sq, tq, rq, params) { 1355 var lodBias = params.flags.use_bias ? params.bias : 0; 1356 1357 var dstSize = [dst.getWidth(), dst.getHeight()]; 1358 var srcSize = [src.getWidth(), src.getHeight(), src.getDepth()]; 1359 1360 // Coordinates and lod per triangle. 1361 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1362 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1363 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 1364 var triLod = [deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0], triR[0]) + lodBias), params.minLod, params.maxLod), 1365 deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1], triR[1]) + lodBias), params.minLod, params.maxLod)]; 1366 1367 for (var y = 0; y < dst.getHeight(); y++) { 1368 for (var x = 0; x < dst.getWidth(); x++) { 1369 var yf = (y + 0.5) / dst.getHeight(); 1370 var xf = (x + 0.5) / dst.getWidth(); 1371 1372 var triNdx = xf + yf >= 1 ? 1 : 0; // Top left fill rule. 1373 var triX = triNdx ? 1 - xf : xf; 1374 var triY = triNdx ? 1 - yf : yf; 1375 1376 var s = glsTextureTestUtil.triangleInterpolate(triS[triNdx], triX, triY); 1377 var t = glsTextureTestUtil.triangleInterpolate(triT[triNdx], triX, triY); 1378 var r = glsTextureTestUtil.triangleInterpolate(triR[triNdx], triX, triY); 1379 var lod = triLod[triNdx]; 1380 1381 var pixel = src.sample(params.sampler, [s, t, r], lod); 1382 glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias); 1383 dst.setPixel(pixel, x, y); 1384 } 1385 } 1386 }; 1387 1388 /** 1389 * @param {glsTextureTestUtil.SurfaceAccess} dst 1390 * @param {tcuTexture.Texture3DView} src 1391 * @param {Array<number>} texCoord 1392 * @param {glsTextureTestUtil.ReferenceParams} params 1393 */ 1394 glsTextureTestUtil.sampleTexture3D = function(dst, src, texCoord, params) { 1395 /*const tcu::TextureCubeView*/ var view = src.getSubView(params.baseLevel, params.maxLevel); 1396 var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 1397 var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 1398 var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 1399 1400 glsTextureTestUtil.sampleTextureNonProjected3D(dst, view, sq, tq, rq, params); 1401 }; 1402 1403 /** 1404 * @param {tcuSurface.Surface} reference 1405 * @param {tcuSurface.Surface} rendered 1406 * @param {Array<number>} threshold 1407 * @param {Array< Array<number> >} skipPixels 1408 * 1409 * @return {boolean} 1410 */ 1411 glsTextureTestUtil.compareImages = function(reference, rendered, threshold, skipPixels) { 1412 return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, rendered, threshold, undefined /*tcu::COMPARE_LOG_RESULT*/, skipPixels); 1413 }; 1414 1415 /** 1416 * @param {tcuTexture.ConstPixelBufferAccess} result 1417 * @param {tcuTexture.Texture2DView} src 1418 * @param {Array<number>} texCoord 1419 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 1420 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 1421 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 1422 * @param {tcuPixelFormat.PixelFormat} pixelFormat 1423 * @return {boolean} 1424 */ 1425 glsTextureTestUtil.verifyTexture2DResult = function(result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat) { 1426 DE_ASSERT(deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask)); 1427 /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight()); 1428 /** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight()); 1429 /** @type {number} */ var numFailedPixels; 1430 1431 /** @type {glsTextureTestUtil.SurfaceAccess} */ var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat); 1432 1433 glsTextureTestUtil.sampleTexture2D(surface, src, texCoord, sampleParams); 1434 numFailedPixels = glsTextureTestUtil.computeTextureLookupDiff2D(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec/*, testCtx.getWatchDog()*/); 1435 1436 if (numFailedPixels > 0) 1437 tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess()); 1438 1439 return numFailedPixels == 0; 1440 }; 1441 1442 /** 1443 * @param {tcuTexture.ConstPixelBufferAccess} result 1444 * @param {tcuTexture.ConstPixelBufferAccess} reference 1445 * @param {tcuTexture.PixelBufferAccess} errorMask 1446 * @param {tcuTexture.Texture2DView} src 1447 * @param {Array<number>} texCoord 1448 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 1449 * @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec 1450 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 1451 * @param {Array<number>} nonShadowThreshold 1452 * @return {number} 1453 */ 1454 glsTextureTestUtil.computeTextureCompareDiff2D = function(result, reference, errorMask, src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold) { 1455 DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1456 DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1457 1458 var sq = [texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]]; 1459 var tq = [texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]]; 1460 1461 var dstSize = [result.getWidth(), result.getHeight()]; 1462 var dstW = dstSize[0]; 1463 var dstH = dstSize[1]; 1464 var srcSize = [src.getWidth(), src.getHeight()]; 1465 1466 // Coordinates and lod per triangle. 1467 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1468 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1469 var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])]; 1470 1471 var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0, 0]; 1472 var numFailed = 0; 1473 1474 var lodOffsets = [ 1475 [-1, 0], 1476 [1, 0], 1477 [0, -1], 1478 [0, 1] 1479 ]; 1480 1481 /** @type {Array<number>} */ var green = [0, 255, 0, 255]; 1482 errorMask.clear(green); 1483 1484 /** @type {Array<number>} */ var red = []; 1485 for (var py = 0; py < result.getHeight(); py++) { 1486 for (var px = 0; px < result.getWidth(); px++) { 1487 /** @type {Array<number>} */ 1488 var resPix = result.getPixel(px, py); 1489 /** @type {Array<number>} */ 1490 var refPix = reference.getPixel(px, py); 1491 1492 if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(deMath.swizzle(refPix, [1, 2, 3]), deMath.swizzle(resPix, [1, 2, 3])), nonShadowThreshold))) { 1493 red = [255, 0, 0, 255]; 1494 errorMask.setPixel(red, px, py); 1495 numFailed += 1; 1496 continue; 1497 } 1498 1499 if (resPix[0] != refPix[0]) { 1500 var wx = px + 0.5; 1501 var wy = py + 0.5; 1502 var nx = wx / dstW; 1503 var ny = wy / dstH; 1504 1505 var triNdx = nx + ny >= 1.0 ? 1 : 0; 1506 var triWx = triNdx ? dstW - wx : wx; 1507 var triWy = triNdx ? dstH - wy : wy; 1508 var triNx = triNdx ? 1.0 - nx : nx; 1509 var triNy = triNdx ? 1.0 - ny : ny; 1510 1511 var coord = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1512 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)]; 1513 var coordDx = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1514 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize); 1515 var coordDy = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1516 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize); 1517 1518 var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec); 1519 1520 // Compute lod bounds across lodOffsets range. 1521 for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) { 1522 var wxo = triWx + lodOffsets[lodOffsNdx][0]; 1523 var wyo = triWy + lodOffsets[lodOffsNdx][1]; 1524 var nxo = wxo / dstW; 1525 var nyo = wyo / dstH; 1526 1527 var coordO = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 1528 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo)]; 1529 var coordDxo = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1530 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize); 1531 var coordDyo = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1532 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize); 1533 var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec); 1534 1535 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 1536 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 1537 } 1538 1539 var clampedLod = tcuTexLookupVerifier.clampLodBounds(deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec); 1540 var isOk = tcuTexCompareVerifier.isTexCompareResultValid2D(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix[0]); 1541 1542 if (!isOk) { 1543 red = [255, 0, 0, 255]; 1544 errorMask.setPixel(red, px, py); 1545 numFailed += 1; 1546 } 1547 } 1548 } 1549 } 1550 1551 return numFailed; 1552 }; 1553 1554 /** 1555 * @param {tcuTexture.ConstPixelBufferAccess} result 1556 * @param {tcuTexture.Texture3DView} src 1557 * @param {Array<number>} texCoord 1558 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 1559 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 1560 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 1561 * @param {tcuPixelFormat.PixelFormat} pixelFormat 1562 * @return {boolean} 1563 */ 1564 glsTextureTestUtil.verifyTexture3DResult = function( 1565 result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat 1566 ) { 1567 /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight()); 1568 /** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight()); 1569 var numFailedPixels = 0; 1570 1571 assertMsgOptions( 1572 deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask), 1573 'Compare color masks do not match', false, true 1574 ); 1575 1576 /** @type {glsTextureTestUtil.SurfaceAccess} */ var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat); 1577 glsTextureTestUtil.sampleTexture3D(surface, src, texCoord, sampleParams); 1578 numFailedPixels = glsTextureTestUtil.computeTextureLookupDiff3D(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec); 1579 1580 if (numFailedPixels > 0) 1581 tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess()); 1582 1583 return numFailedPixels == 0; 1584 }; 1585 1586 /** 1587 * @param {tcuTexture.ConstPixelBufferAccess} result 1588 * @param {tcuTexture.ConstPixelBufferAccess} reference 1589 * @param {tcuTexture.PixelBufferAccess} errorMask 1590 * @param {tcuTexture.Texture3DView} baseView 1591 * @param {Array<number>} texCoord 1592 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 1593 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 1594 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 1595 * @return {number} 1596 */ 1597 glsTextureTestUtil.computeTextureLookupDiff3D = function( 1598 result, reference, errorMask, baseView, texCoord, 1599 sampleParams, lookupPrec, lodPrec 1600 ) { 1601 assertMsgOptions( 1602 result.getWidth() == reference.getWidth() && 1603 result.getHeight() == reference.getHeight(), 1604 'Result and reference images are not the same size', false, true 1605 ); 1606 assertMsgOptions( 1607 result.getWidth() == errorMask.getWidth() && 1608 result.getHeight() == errorMask.getHeight(), 1609 'Result and error mask images are not the same size', false, true 1610 ); 1611 1612 /** @type {tcuTexture.Texture3DView} */ 1613 var src = baseView.getSubView( 1614 sampleParams.baseLevel, sampleParams.maxLevel 1615 ); 1616 1617 var sq = 1618 [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 1619 var tq = 1620 [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 1621 var rq = 1622 [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 1623 1624 var dstSize = [result.getWidth(), result.getHeight()]; 1625 var dstW = dstSize[0]; 1626 var dstH = dstSize[1]; 1627 var srcSize = [src.getWidth(), src.getHeight(), src.getDepth()]; 1628 1629 // Coordinates and lod per triangle. 1630 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1631 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1632 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 1633 var triW = [ 1634 deMath.swizzle(sampleParams.w, [0, 1, 2]), 1635 deMath.swizzle(sampleParams.w, [3, 2, 1]) 1636 ]; 1637 1638 var lodBias = sampleParams.flags.useBias ? sampleParams.bias : 0.0; 1639 1640 var posEps = 1.0 / ((1 << MIN_SUBPIXEL_BITS) + 1); 1641 1642 var numFailed = 0; 1643 1644 var lodOffsets = [ 1645 [-1, 0], 1646 [+1, 0], 1647 [0, -1], 1648 [0, +1] 1649 ]; 1650 1651 var green = [0, 255, 0, 255]; 1652 errorMask.clear(new tcuRGBA.RGBA(green).toVec()); 1653 1654 for (var py = 0; py < result.getHeight(); py++) { 1655 // Ugly hack, validation can take way too long at the moment. 1656 /*TODO: if (watchDog) 1657 qpWatchDog_touch(watchDog);*/ 1658 1659 for (var px = 0; px < result.getWidth(); px++) { 1660 /** @type {Array<number>} */ 1661 var resPix = result.getPixel(px, py); 1662 glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias); 1663 /** @type {Array<number>} */ 1664 var refPix = reference.getPixel(px, py); 1665 glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias); 1666 1667 // Try comparison to ideal reference first, 1668 // and if that fails use slower verificator. 1669 if (!deMath.boolAll(deMath.lessThanEqual( 1670 deMath.absDiff(resPix, refPix), 1671 lookupPrec.colorThreshold)) 1672 ) { 1673 /** @type {number} */ var wx = px + 0.5; 1674 /** @type {number} */ var wy = py + 0.5; 1675 /** @type {number} */ var nx = wx / dstW; 1676 /** @type {number} */ var ny = wy / dstH; 1677 1678 /** @type {boolean} */ var tri0 = nx + ny - posEps <= 1.0; 1679 /** @type {boolean} */ var tri1 = nx + ny + posEps >= 1.0; 1680 1681 var isOk = false; 1682 1683 assertMsgOptions( 1684 tri0 || tri1, 1685 'Pixel should belong at least to one triangle', 1686 false, true 1687 ); 1688 1689 // Pixel can belong to either of the triangles 1690 // if it lies close enough to the edge. 1691 for (var triNdx = (tri0 ? 0 : 1); 1692 triNdx <= (tri1 ? 1 : 0); 1693 triNdx++) { 1694 var triWx = triNdx ? dstW - wx : wx; 1695 var triWy = triNdx ? dstH - wy : wy; 1696 var triNx = triNdx ? 1.0 - nx : nx; 1697 var triNy = triNdx ? 1.0 - ny : ny; 1698 1699 var coord = [ 1700 glsTextureTestUtil.projectedTriInterpolate( 1701 triS[triNdx], triW[triNdx], triNx, triNy 1702 ), 1703 glsTextureTestUtil.projectedTriInterpolate( 1704 triT[triNdx], triW[triNdx], triNx, triNy 1705 ), 1706 glsTextureTestUtil.projectedTriInterpolate( 1707 triR[triNdx], triW[triNdx], triNx, triNy 1708 ) 1709 ]; 1710 var coordDx = deMath.multiply([ 1711 glsTextureTestUtil.triDerivateX( 1712 triS[triNdx], triW[triNdx], wx, dstW, triNy 1713 ), 1714 glsTextureTestUtil.triDerivateX( 1715 triT[triNdx], triW[triNdx], wx, dstW, triNy 1716 ), 1717 glsTextureTestUtil.triDerivateX( 1718 triR[triNdx], triW[triNdx], wx, dstW, triNy 1719 ) 1720 ], srcSize); 1721 var coordDy = deMath.multiply([ 1722 glsTextureTestUtil.triDerivateY( 1723 triS[triNdx], triW[triNdx], wy, dstH, triNx 1724 ), 1725 glsTextureTestUtil.triDerivateY( 1726 triT[triNdx], triW[triNdx], wy, dstH, triNx 1727 ), 1728 glsTextureTestUtil.triDerivateY( 1729 triR[triNdx], triW[triNdx], wy, dstH, triNx 1730 ) 1731 ], srcSize); 1732 1733 var lodBounds = 1734 tcuTexLookupVerifier.computeLodBoundsFromDerivates( 1735 coordDx[0], coordDx[1], coordDx[2], 1736 coordDy[0], coordDy[1], coordDy[2], lodPrec 1737 ); 1738 1739 // Compute lod bounds across lodOffsets range. 1740 for (var lodOffsNdx = 0; 1741 lodOffsNdx < lodOffsets.length; 1742 lodOffsNdx++) { 1743 var wxo = triWx + lodOffsets[lodOffsNdx][0]; 1744 var wyo = triWy + lodOffsets[lodOffsNdx][1]; 1745 var nxo = wxo / dstW; 1746 var nyo = wyo / dstH; 1747 1748 var coordO = [ 1749 glsTextureTestUtil.projectedTriInterpolate( 1750 triS[triNdx], triW[triNdx], nxo, nyo 1751 ), 1752 glsTextureTestUtil.projectedTriInterpolate( 1753 triT[triNdx], triW[triNdx], nxo, nyo 1754 ), 1755 glsTextureTestUtil.projectedTriInterpolate( 1756 triR[triNdx], triW[triNdx], nxo, nyo 1757 ) 1758 ]; 1759 var coordDxo = deMath.multiply([ 1760 glsTextureTestUtil.triDerivateX( 1761 triS[triNdx], triW[triNdx], wxo, dstW, nyo 1762 ), 1763 glsTextureTestUtil.triDerivateX( 1764 triT[triNdx], triW[triNdx], wxo, dstW, nyo 1765 ), 1766 glsTextureTestUtil.triDerivateX( 1767 triR[triNdx], triW[triNdx], wxo, dstW, nyo 1768 ) 1769 ], srcSize); 1770 var coordDyo = deMath.multiply([ 1771 glsTextureTestUtil.triDerivateY( 1772 triS[triNdx], triW[triNdx], wyo, dstH, nxo 1773 ), 1774 glsTextureTestUtil.triDerivateY( 1775 triT[triNdx], triW[triNdx], wyo, dstH, nxo 1776 ), 1777 glsTextureTestUtil.triDerivateY( 1778 triR[triNdx], triW[triNdx], wyo, dstH, nxo 1779 ) 1780 ], srcSize); 1781 var lodO = 1782 tcuTexLookupVerifier.computeLodBoundsFromDerivates( 1783 coordDxo[0], coordDxo[1], coordDxo[2], 1784 coordDyo[0], coordDyo[1], coordDyo[2], lodPrec 1785 ); 1786 1787 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 1788 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 1789 } 1790 1791 var clampedLod = tcuTexLookupVerifier.clampLodBounds( 1792 deMath.addScalar(lodBounds, lodBias), 1793 [sampleParams.minLod, sampleParams.maxLod], 1794 lodPrec 1795 ); 1796 1797 if ( 1798 tcuTexLookupVerifier.isLookupResultValid( 1799 src, sampleParams.sampler, lookupPrec, 1800 coord, clampedLod, resPix 1801 ) 1802 ) { 1803 isOk = true; 1804 break; 1805 } 1806 } 1807 1808 if (!isOk) { 1809 var red = [255, 0, 0, 255]; 1810 errorMask.setPixel(new tcuRGBA.RGBA(red).toVec(), px, py); 1811 numFailed += 1; 1812 } 1813 } 1814 } 1815 } 1816 1817 return numFailed; 1818 }; 1819 1820 /** 1821 * @param {tcuTexture.ConstPixelBufferAccess} result 1822 * @param {tcuTexture.TextureCubeView} src 1823 * @param {Array<number>} texCoord 1824 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 1825 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 1826 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 1827 * @param {tcuPixelFormat.PixelFormat} pixelFormat 1828 * @return {boolean} 1829 */ 1830 glsTextureTestUtil.verifyTextureCubeResult = function( 1831 result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat 1832 ) { 1833 /** @type {tcuSurface.Surface} */ 1834 var reference = new tcuSurface.Surface( 1835 result.getWidth(), result.getHeight() 1836 ); 1837 /** @type {tcuSurface.Surface} */ 1838 var errorMask = new tcuSurface.Surface( 1839 result.getWidth(), result.getHeight() 1840 ); 1841 /** @type {number} */ var numFailedPixels = 0; 1842 1843 assertMsgOptions( 1844 deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask), 1845 'Compare color masks do not match', false, true 1846 ); 1847 1848 /** @type {glsTextureTestUtil.SurfaceAccess} */ 1849 var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat); 1850 1851 glsTextureTestUtil.sampleTextureCube( 1852 surface, src, texCoord, sampleParams 1853 ); 1854 1855 numFailedPixels = glsTextureTestUtil.computeTextureLookupDiffCube( 1856 result, reference.getAccess(), errorMask.getAccess(), 1857 src, texCoord, sampleParams, lookupPrec, lodPrec 1858 /*, testCtx.getWatchDog()*/ 1859 ); 1860 1861 if (numFailedPixels > 0) 1862 tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess()); 1863 1864 return numFailedPixels == 0; 1865 }; 1866 1867 /** 1868 * @param {tcuTexture.ConstPixelBufferAccess} result 1869 * @param {tcuTexture.ConstPixelBufferAccess} reference 1870 * @param {tcuTexture.PixelBufferAccess} errorMask 1871 * @param {tcuTexture.TextureCubeView} baseView 1872 * @param {Array<number>} texCoord 1873 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 1874 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 1875 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 1876 * @return {number} 1877 */ 1878 glsTextureTestUtil.computeTextureLookupDiffCube = function( 1879 result, reference, errorMask, baseView, texCoord, 1880 sampleParams, lookupPrec, lodPrec 1881 ) { 1882 assertMsgOptions( 1883 result.getWidth() == reference.getWidth() && 1884 result.getHeight() == reference.getHeight(), 1885 'Result and reference images are not the same size', false, true 1886 ); 1887 assertMsgOptions( 1888 result.getWidth() == errorMask.getWidth() && 1889 result.getHeight() == errorMask.getHeight(), 1890 'Result and error mask images are not the same size', false, true 1891 ); 1892 1893 /** @type {tcuTexture.TextureCubeView} */ 1894 var src = baseView.getSubView( 1895 sampleParams.baseLevel, sampleParams.maxLevel 1896 ); 1897 1898 var sq = 1899 [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 1900 var tq = 1901 [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 1902 var rq = 1903 [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 1904 1905 var dstSize = [result.getWidth(), result.getHeight()]; 1906 var dstW = dstSize[0]; 1907 var dstH = dstSize[1]; 1908 var srcSize = [src.getSize(), src.getSize()]; 1909 1910 // Coordinates and lod per triangle. 1911 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 1912 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 1913 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 1914 var triW = [ 1915 deMath.swizzle(sampleParams.w, [0, 1, 2]), 1916 deMath.swizzle(sampleParams.w, [3, 2, 1]) 1917 ]; 1918 1919 var lodBias = sampleParams.flags.useBias ? sampleParams.bias : 0.0; 1920 1921 var posEps = 1.0 / ((1 << MIN_SUBPIXEL_BITS) + 1); 1922 1923 var numFailed = 0; 1924 1925 var lodOffsets = [ 1926 [-1, 0], 1927 [+1, 0], 1928 [0, -1], 1929 [0, +1], 1930 1931 // \note Not strictly allowed by spec, 1932 // but implementations do this in practice. 1933 [-1, -1], 1934 [-1, 1], 1935 [1, -1], 1936 [1, 1] 1937 ]; 1938 1939 var green = [0, 255, 0, 255]; 1940 errorMask.clear(new tcuRGBA.RGBA(green).toVec()); 1941 1942 for (var py = 0; py < result.getHeight(); py++) { 1943 // Ugly hack, validation can take way too long at the moment. 1944 /*TODO: if (watchDog) 1945 qpWatchDog_touch(watchDog);*/ 1946 1947 for (var px = 0; px < result.getWidth(); px++) { 1948 /** @type {Array<number>} */ 1949 var resPix = result.getPixel(px, py); 1950 glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias); 1951 /** @type {Array<number>} */ 1952 var refPix = reference.getPixel(px, py); 1953 glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias); 1954 1955 // Try comparison to ideal reference first, 1956 // and if that fails use slower verificator. 1957 if (!deMath.boolAll(deMath.lessThanEqual( 1958 deMath.absDiff(resPix, refPix), 1959 lookupPrec.colorThreshold)) 1960 ) { 1961 /** @type {number} */ var wx = px + 0.5; 1962 /** @type {number} */ var wy = py + 0.5; 1963 /** @type {number} */ var nx = wx / dstW; 1964 /** @type {number} */ var ny = wy / dstH; 1965 1966 /** @type {boolean} */ var tri0 = nx + ny - posEps <= 1.0; 1967 /** @type {boolean} */ var tri1 = nx + ny + posEps >= 1.0; 1968 1969 var isOk = false; 1970 1971 assertMsgOptions( 1972 tri0 || tri1, 1973 'Pixel should belong at least to one triangle', 1974 false, true 1975 ); 1976 1977 // Pixel can belong to either of the triangles 1978 // if it lies close enough to the edge. 1979 for (var triNdx = (tri0 ? 0 : 1); 1980 triNdx <= (tri1 ? 1 : 0); 1981 triNdx++) { 1982 var triWx = triNdx ? dstW - wx : wx; 1983 var triWy = triNdx ? dstH - wy : wy; 1984 var triNx = triNdx ? 1.0 - nx : nx; 1985 var triNy = triNdx ? 1.0 - ny : ny; 1986 1987 var coord = [ 1988 glsTextureTestUtil.projectedTriInterpolate( 1989 triS[triNdx], triW[triNdx], triNx, triNy 1990 ), 1991 glsTextureTestUtil.projectedTriInterpolate( 1992 triT[triNdx], triW[triNdx], triNx, triNy 1993 ), 1994 glsTextureTestUtil.projectedTriInterpolate( 1995 triR[triNdx], triW[triNdx], triNx, triNy 1996 ) 1997 ]; 1998 var coordDx = [ 1999 glsTextureTestUtil.triDerivateX( 2000 triS[triNdx], triW[triNdx], wx, dstW, triNy 2001 ), 2002 glsTextureTestUtil.triDerivateX( 2003 triT[triNdx], triW[triNdx], wx, dstW, triNy 2004 ), 2005 glsTextureTestUtil.triDerivateX( 2006 triR[triNdx], triW[triNdx], wx, dstW, triNy 2007 ) 2008 ]; 2009 var coordDy = [ 2010 glsTextureTestUtil.triDerivateY( 2011 triS[triNdx], triW[triNdx], wy, dstH, triNx 2012 ), 2013 glsTextureTestUtil.triDerivateY( 2014 triT[triNdx], triW[triNdx], wy, dstH, triNx 2015 ), 2016 glsTextureTestUtil.triDerivateY( 2017 triR[triNdx], triW[triNdx], wy, dstH, triNx 2018 ) 2019 ]; 2020 2021 var lodBounds = 2022 tcuTexLookupVerifier.computeCubeLodBoundsFromDerivates( 2023 coord, coordDx, coordDy, src.getSize(), lodPrec 2024 ); 2025 2026 // Compute lod bounds across lodOffsets range. 2027 for (var lodOffsNdx = 0; 2028 lodOffsNdx < lodOffsets.length; 2029 lodOffsNdx++) { 2030 var wxo = triWx + lodOffsets[lodOffsNdx][0]; 2031 var wyo = triWy + lodOffsets[lodOffsNdx][1]; 2032 var nxo = wxo / dstW; 2033 var nyo = wyo / dstH; 2034 2035 var coordO = [ 2036 glsTextureTestUtil.projectedTriInterpolate( 2037 triS[triNdx], triW[triNdx], nxo, nyo 2038 ), 2039 glsTextureTestUtil.projectedTriInterpolate( 2040 triT[triNdx], triW[triNdx], nxo, nyo 2041 ), 2042 glsTextureTestUtil.projectedTriInterpolate( 2043 triR[triNdx], triW[triNdx], nxo, nyo 2044 ) 2045 ]; 2046 var coordDxo = [ 2047 glsTextureTestUtil.triDerivateX( 2048 triS[triNdx], triW[triNdx], wxo, dstW, nyo 2049 ), 2050 glsTextureTestUtil.triDerivateX( 2051 triT[triNdx], triW[triNdx], wxo, dstW, nyo 2052 ), 2053 glsTextureTestUtil.triDerivateX( 2054 triR[triNdx], triW[triNdx], wxo, dstW, nyo 2055 ) 2056 ]; 2057 var coordDyo = [ 2058 glsTextureTestUtil.triDerivateY( 2059 triS[triNdx], triW[triNdx], wyo, dstH, nxo 2060 ), 2061 glsTextureTestUtil.triDerivateY( 2062 triT[triNdx], triW[triNdx], wyo, dstH, nxo 2063 ), 2064 glsTextureTestUtil.triDerivateY( 2065 triR[triNdx], triW[triNdx], wyo, dstH, nxo 2066 ) 2067 ]; 2068 var lodO = 2069 tcuTexLookupVerifier. 2070 computeCubeLodBoundsFromDerivates( 2071 coordO, coordDxo, coordDyo, 2072 src.getSize(), lodPrec 2073 ); 2074 2075 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 2076 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 2077 } 2078 2079 var clampedLod = tcuTexLookupVerifier.clampLodBounds( 2080 deMath.addScalar(lodBounds, lodBias), 2081 [sampleParams.minLod, sampleParams.maxLod], 2082 lodPrec 2083 ); 2084 2085 if (tcuTexLookupVerifier. 2086 isLookupResultValid_TextureCubeView( 2087 src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix 2088 ) 2089 ) { 2090 isOk = true; 2091 break; 2092 } 2093 } 2094 2095 if (!isOk) { 2096 var red = [255, 0, 0, 255]; 2097 errorMask.setPixel(new tcuRGBA.RGBA(red).toVec(), px, py); 2098 numFailed += 1; 2099 } 2100 } 2101 } 2102 } 2103 2104 return numFailed; 2105 }; 2106 2107 /** 2108 * @param {tcuTexture.ConstPixelBufferAccess} result 2109 * @param {tcuTexture.Texture2DArrayView} src 2110 * @param {Array<number>} texCoord 2111 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 2112 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 2113 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 2114 * @param {tcuPixelFormat.PixelFormat} pixelFormat 2115 * @return {boolean} 2116 */ 2117 glsTextureTestUtil.verifyTexture2DArrayResult = function(result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat) { 2118 DE_ASSERT(deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask)); 2119 /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight()); 2120 /** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight()); 2121 /** @type {number} */ var numFailedPixels; 2122 2123 /** @type {glsTextureTestUtil.SurfaceAccess} */ var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat); 2124 2125 glsTextureTestUtil.sampleTexture2DArray(surface, src, texCoord, sampleParams); 2126 numFailedPixels = glsTextureTestUtil.computeTextureLookupDiff2DArray(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec/*, testCtx.getWatchDog()*/); 2127 2128 if (numFailedPixels > 0) 2129 tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess()); 2130 2131 return numFailedPixels == 0; 2132 }; 2133 2134 /** 2135 * @param {tcuTexture.ConstPixelBufferAccess} result 2136 * @param {tcuTexture.ConstPixelBufferAccess} reference 2137 * @param {tcuTexture.PixelBufferAccess} errorMask 2138 * @param {tcuTexture.Texture2DArrayView} src 2139 * @param {Array<number>} texCoord 2140 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 2141 * @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec 2142 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 2143 * @param {Array<number>} nonShadowThreshold 2144 * @return {number} 2145 */ 2146 glsTextureTestUtil.computeTextureCompareDiff2DArray = function(result, reference, errorMask, src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold) { 2147 DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2148 DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2149 2150 var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 2151 var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 2152 var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 2153 2154 var dstSize = [result.getWidth(), result.getHeight()]; 2155 var dstW = dstSize[0]; 2156 var dstH = dstSize[1]; 2157 var srcSize = [src.getWidth(), src.getHeight()]; 2158 2159 // Coordinates and lod per triangle. 2160 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 2161 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 2162 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 2163 var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])]; 2164 2165 var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0, 0]; 2166 var numFailed = 0; 2167 2168 var lodOffsets = [ 2169 [-1, 0], 2170 [1, 0], 2171 [0, -1], 2172 [0, 1] 2173 ]; 2174 2175 /** @type {Array<number>} */ var green = [0, 255, 0, 255]; 2176 errorMask.clear(green); 2177 2178 /** @type {Array<number>} */ var red = []; 2179 for (var py = 0; py < result.getHeight(); py++) { 2180 for (var px = 0; px < result.getWidth(); px++) { 2181 /** @type {Array<number>} */ 2182 var resPix = result.getPixel(px, py); 2183 /** @type {Array<number>} */ 2184 var refPix = reference.getPixel(px, py); 2185 2186 if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(deMath.swizzle(refPix, [1, 2, 3]), deMath.swizzle(resPix, [1, 2, 3])), nonShadowThreshold))) { 2187 red = [255, 0, 0, 255]; 2188 errorMask.setPixel(red, px, py); 2189 numFailed += 1; 2190 continue; 2191 } 2192 2193 if (resPix[0] != refPix[0]) { 2194 var wx = px + 0.5; 2195 var wy = py + 0.5; 2196 var nx = wx / dstW; 2197 var ny = wy / dstH; 2198 2199 var triNdx = nx + ny >= 1.0 ? 1 : 0; 2200 var triWx = triNdx ? dstW - wx : wx; 2201 var triWy = triNdx ? dstH - wy : wy; 2202 var triNx = triNdx ? 1.0 - nx : nx; 2203 var triNy = triNdx ? 1.0 - ny : ny; 2204 2205 var coord = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2206 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2207 glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)]; 2208 var coordDx = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2209 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize); 2210 var coordDy = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2211 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize); 2212 2213 var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec); 2214 2215 // Compute lod bounds across lodOffsets range. 2216 for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) { 2217 var wxo = triWx + lodOffsets[lodOffsNdx][0]; 2218 var wyo = triWy + lodOffsets[lodOffsNdx][1]; 2219 var nxo = wxo / dstW; 2220 var nyo = wyo / dstH; 2221 2222 var coordO = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2223 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo)]; 2224 var coordDxo = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2225 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize); 2226 var coordDyo = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2227 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize); 2228 var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec); 2229 2230 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 2231 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 2232 } 2233 2234 var clampedLod = tcuTexLookupVerifier.clampLodBounds(deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec); 2235 var isOk = tcuTexCompareVerifier.isTexCompareResultValid2DArray(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix[0]); 2236 2237 if (!isOk) { 2238 red = [255, 0, 0, 255]; 2239 errorMask.setPixel(red, px, py); 2240 numFailed += 1; 2241 } 2242 } 2243 } 2244 } 2245 2246 return numFailed; 2247 }; 2248 2249 /** 2250 * @param {tcuTexture.ConstPixelBufferAccess} result 2251 * @param {tcuTexture.ConstPixelBufferAccess} reference 2252 * @param {tcuTexture.PixelBufferAccess} errorMask 2253 * @param {tcuTexture.TextureCubeView} src 2254 * @param {Array<number>} texCoord 2255 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 2256 * @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec 2257 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 2258 * @param {Array<number>} nonShadowThreshold 2259 * @return {number} 2260 */ 2261 glsTextureTestUtil.computeTextureCompareDiffCube = function(result, reference, errorMask, src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold) { 2262 DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2263 DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2264 2265 var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 2266 var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 2267 var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 2268 2269 var dstSize = [result.getWidth(), result.getHeight()]; 2270 var dstW = dstSize[0]; 2271 var dstH = dstSize[1]; 2272 var srcSize = src.getSize(); 2273 2274 // Coordinates per triangle. 2275 var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 2276 var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 2277 var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 2278 var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])]; 2279 2280 var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0, 0]; 2281 var numFailed = 0; 2282 2283 var lodOffsets = [ 2284 [-1, 0], 2285 [1, 0], 2286 [0, -1], 2287 [0, 1] 2288 ]; 2289 2290 /** @type {Array<number>} */ var green = [0, 255, 0, 255]; 2291 errorMask.clear(new tcuRGBA.RGBA(green).toVec()); 2292 2293 /** @type {Array<number>} */ var red = []; 2294 for (var py = 0; py < result.getHeight(); py++) { 2295 for (var px = 0; px < result.getWidth(); px++) { 2296 /** @type {Array<number>} */ 2297 var resPix = result.getPixel(px, py); 2298 /** @type {Array<number>} */ 2299 var refPix = reference.getPixel(px, py); 2300 2301 if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(deMath.swizzle(resPix, [1, 2, 3]), deMath.swizzle(refPix, [1, 2, 3])), nonShadowThreshold))) { 2302 red = [255, 0, 0, 255]; 2303 errorMask.setPixel(red, px, py); 2304 numFailed += 1; 2305 continue; 2306 } 2307 2308 if (resPix[0] != refPix[0]) { 2309 var wx = px + 0.5; 2310 var wy = py + 0.5; 2311 var nx = wx / dstW; 2312 var ny = wy / dstH; 2313 2314 var triNdx = nx + ny >= 1.0 ? 1 : 0; 2315 var triWx = triNdx ? dstW - wx : wx; 2316 var triWy = triNdx ? dstH - wy : wy; 2317 var triNx = triNdx ? 1.0 - nx : nx; 2318 var triNy = triNdx ? 1.0 - ny : ny; 2319 2320 var coord = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2321 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2322 glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)]; 2323 var coordDx = [glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2324 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 2325 glsTextureTestUtil.triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)]; 2326 var coordDy = [glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2327 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 2328 glsTextureTestUtil.triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)]; 2329 2330 var lodBounds = tcuTexLookupVerifier.computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec); 2331 2332 // Compute lod bounds across lodOffsets range. 2333 for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) { 2334 var wxo = triWx + lodOffsets[lodOffsNdx][0]; 2335 var wyo = triWy + lodOffsets[lodOffsNdx][1]; 2336 var nxo = wxo / dstW; 2337 var nyo = wyo / dstH; 2338 2339 var coordO = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2340 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 2341 glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)]; 2342 var coordDxo = [glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2343 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 2344 glsTextureTestUtil.triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)]; 2345 var coordDyo = [glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2346 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 2347 glsTextureTestUtil.triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)]; 2348 var lodO = tcuTexLookupVerifier.computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 2349 2350 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 2351 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 2352 } 2353 2354 var clampedLod = tcuTexLookupVerifier.clampLodBounds(deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec); 2355 var isOk = tcuTexCompareVerifier.isTexCompareResultValidCube(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix[0]); 2356 2357 if (!isOk) { 2358 red = [255, 0, 0, 255]; 2359 errorMask.setPixel(red, px, py); 2360 numFailed += 1; 2361 } 2362 } 2363 } 2364 } 2365 2366 return numFailed; 2367 }; 2368 2369 /** 2370 * @param {Array<number>} s 2371 * @param {Array<number>} w 2372 * @param {number} nx 2373 * @param {number} ny 2374 * @return {number} 2375 */ 2376 glsTextureTestUtil.projectedTriInterpolate = function(s, w, nx, ny) { 2377 return (s[0] * (1.0 - nx - ny) / w[0] + s[1] * ny / w[1] + s[2] * nx / w[2]) / ((1.0 - nx - ny) / w[0] + ny / w[1] + nx / w[2]); 2378 }; 2379 2380 /** 2381 * @param {tcuTexture.ConstPixelBufferAccess} result 2382 * @param {tcuTexture.ConstPixelBufferAccess} reference 2383 * @param {tcuTexture.PixelBufferAccess} errorMask 2384 * @param {tcuTexture.Texture2DView} baseView 2385 * @param {Array<number>} texCoord 2386 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 2387 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 2388 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 2389 * @param {*=} watchDog - TODO: ?? 2390 * @return {number} 2391 */ 2392 glsTextureTestUtil.computeTextureLookupDiff2D = function(result, reference, errorMask, baseView, texCoord, sampleParams, lookupPrec, lodPrec, watchDog) { 2393 DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2394 DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2395 2396 /** @type {tcuTexture.Texture2DView} */ var src = baseView.getSubView(sampleParams.baseLevel, sampleParams.maxLevel); 2397 2398 /** @type {Array<number>} */ var sq = [texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]]; 2399 /** @type {Array<number>} */ var tq = [texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]]; 2400 2401 /** @type {Array<number>} */ var dstSize = [result.getWidth(), result.getHeight()]; 2402 /** @type {number} */ var dstW = dstSize[0]; 2403 /** @type {number} */ var dstH = dstSize[1]; 2404 /** @type {Array<number>} */ var srcSize = [src.getWidth(), src.getHeight()]; 2405 2406 // Coordinates and lod per triangle. 2407 /** @type {Array<Array<number>>} */ var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 2408 /** @type {Array<Array<number>>} */ var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 2409 /** @type {Array<Array<number>>} */ var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])]; 2410 2411 /** @type {Array<number>} */ var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0.0, 0.0]; 2412 2413 /** @type {number} */ var numFailed = 0; 2414 2415 /** @type {Array<Array<number>>} */ var lodOffsets = [ 2416 [-1, 0], 2417 [1, 0], 2418 [0, -1], 2419 [0, 1] 2420 ]; 2421 2422 /** @type {Array<number>} */ var green = [0, 255, 0, 255]; 2423 errorMask.clear(new tcuRGBA.RGBA(green).toVec()); 2424 2425 for (var py = 0; py < result.getHeight(); py++) { 2426 // Ugly hack, validation can take way too long at the moment. 2427 2428 // TODO:are we implementing qpWatchDog? skipping in the meantime 2429 // if (watchDog) 2430 // qpWatchDog_touch(watchDog); 2431 2432 for (var px = 0; px < result.getWidth(); px++) { 2433 /** @type {Array<number>} */ 2434 var resPix = result.getPixel(px, py); 2435 glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias); 2436 /** @type {Array<number>} */ 2437 var refPix = reference.getPixel(px, py); 2438 glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias); 2439 2440 // Try comparison to ideal reference first, and if that fails use slower verificator. 2441 if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(resPix, refPix), lookupPrec.colorThreshold))) { 2442 /** @type {number} */ var wx = px + 0.5; 2443 /** @type {number} */ var wy = py + 0.5; 2444 /** @type {number} */ var nx = wx / dstW; 2445 /** @type {number} */ var ny = wy / dstH; 2446 2447 /** @type {number} */ var triNdx = nx + ny >= 1.0 ? 1 : 0; 2448 /** @type {number} */ var triWx = triNdx ? dstW - wx : wx; 2449 /** @type {number} */ var triWy = triNdx ? dstH - wy : wy; 2450 /** @type {number} */ var triNx = triNdx ? 1.0 - nx : nx; 2451 /** @type {number} */ var triNy = triNdx ? 1.0 - ny : ny; 2452 2453 /** @type {Array<number>} */ var coord = [ 2454 glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2455 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy) 2456 ]; 2457 /** @type {Array<number>} */ var coordDx = deMath.multiply([ 2458 glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2459 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize); 2460 /** @type {Array<number>} */ var coordDy = deMath.multiply([ 2461 glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2462 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize); 2463 2464 /** @type {Array<number>} */ 2465 var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec); 2466 2467 // Compute lod bounds across lodOffsets range. 2468 for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) { 2469 /** @type {number} */ var wxo = triWx + lodOffsets[lodOffsNdx][0]; 2470 /** @type {number} */ var wyo = triWy + lodOffsets[lodOffsNdx][1]; 2471 /** @type {number} */ var nxo = wxo / dstW; 2472 /** @type {number} */ var nyo = wyo / dstH; 2473 2474 /** @type {Array<number>} */ var coordO = [ 2475 glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2476 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo)]; 2477 /** @type {Array<number>} */ var coordDxo = deMath.multiply([ 2478 glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2479 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize); 2480 /** @type {Array<number>} */ var coordDyo = deMath.multiply([ 2481 glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2482 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize); 2483 /** @type {Array<number>} */ 2484 var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec); 2485 2486 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 2487 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 2488 } 2489 2490 /** @type {Array<number>} */ var clampedLod = tcuTexLookupVerifier.clampLodBounds( 2491 deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec); 2492 /** @type {boolean} */ 2493 var isOk = tcuTexLookupVerifier.isLookupResultValid_Texture2DView(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 2494 2495 if (!isOk) { 2496 /** @type {tcuRGBA.RGBA} */ var red = tcuRGBA.newRGBAComponents(255, 0, 0, 255); 2497 errorMask.setPixel(red.toVec(), px, py); 2498 numFailed += 1; 2499 } 2500 } 2501 } 2502 } 2503 2504 return numFailed; 2505 }; 2506 2507 // Verifies texture lookup results and returns number of failed pixels. 2508 2509 /** 2510 * @param {tcuTexture.ConstPixelBufferAccess} result 2511 * @param {tcuTexture.ConstPixelBufferAccess} reference 2512 * @param {tcuTexture.PixelBufferAccess} errorMask 2513 * @param {tcuTexture.Texture2DArrayView} src 2514 * @param {Array<number>} texCoord 2515 * @param {glsTextureTestUtil.ReferenceParams} sampleParams 2516 * @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec 2517 * @param {tcuTexLookupVerifier.LodPrecision} lodPrec 2518 * @param {*=} watchDog - TODO: ?? 2519 * @return {number} 2520 */ 2521 glsTextureTestUtil.computeTextureLookupDiff2DArray = function(result, reference, errorMask, src, texCoord, sampleParams, lookupPrec, lodPrec, watchDog) { 2522 DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2523 DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2524 2525 /** @type {Array<number>} */ var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]]; 2526 /** @type {Array<number>} */ var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]]; 2527 /** @type {Array<number>} */ var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]]; 2528 2529 /** @type {Array<number>} */ var dstSize = [result.getWidth(), result.getHeight()]; 2530 /** @type {number} */ var dstW = dstSize[0]; 2531 /** @type {number} */ var dstH = dstSize[1]; 2532 /** @type {Array<number>} */ var srcSize = [src.getWidth(), src.getHeight()]; 2533 2534 // Coordinates and lod per triangle. 2535 /** @type {Array<Array<number>>} */ var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])]; 2536 /** @type {Array<Array<number>>} */ var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])]; 2537 /** @type {Array<Array<number>>} */ var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])]; 2538 /** @type {Array<Array<number>>} */ var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])]; 2539 2540 /** @type {Array<number>} */ var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0.0, 0.0]; 2541 2542 /** @type {number} */ var numFailed = 0; 2543 2544 /** @type {Array<Array<number>>} */ var lodOffsets = [ 2545 [-1, 0], 2546 [1, 0], 2547 [0, -1], 2548 [0, 1] 2549 ]; 2550 2551 /** @type {Array<number>} */ var green = [0, 255, 0, 255]; 2552 errorMask.clear(new tcuRGBA.RGBA(green).toVec()); 2553 2554 for (var py = 0; py < result.getHeight(); py++) { 2555 // Ugly hack, validation can take way too long at the moment. 2556 2557 // TODO:are we implementing qpWatchDog? skipping in the meantime 2558 // if (watchDog) 2559 // qpWatchDog_touch(watchDog); 2560 2561 for (var px = 0; px < result.getWidth(); px++) { 2562 /** @type {Array<number>} */ 2563 var resPix = result.getPixel(px, py); 2564 glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias); 2565 /** @type {Array<number>} */ 2566 var refPix = reference.getPixel(px, py); 2567 glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias); 2568 2569 2570 // Try comparison to ideal reference first, and if that fails use slower verificator. 2571 if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(resPix, refPix), lookupPrec.colorThreshold))) { 2572 /** @type {number} */ var wx = px + 0.5; 2573 /** @type {number} */ var wy = py + 0.5; 2574 /** @type {number} */ var nx = wx / dstW; 2575 /** @type {number} */ var ny = wy / dstH; 2576 2577 /** @type {number} */ var triNdx = nx + ny >= 1.0 ? 1 : 0; 2578 /** @type {number} */ var triWx = triNdx ? dstW - wx : wx; 2579 /** @type {number} */ var triWy = triNdx ? dstH - wy : wy; 2580 /** @type {number} */ var triNx = triNdx ? 1.0 - nx : nx; 2581 /** @type {number} */ var triNy = triNdx ? 1.0 - ny : ny; 2582 2583 /** @type {Array<number>} */ var coord = [ 2584 glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2585 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2586 glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy) 2587 ]; 2588 /** @type {Array<number>} */ var coordDx = deMath.multiply([ 2589 glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2590 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize); 2591 /** @type {Array<number>} */ var coordDy = deMath.multiply([ 2592 glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2593 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize); 2594 2595 /** @type {Array<number>} */ 2596 var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec); 2597 2598 // Compute lod bounds across lodOffsets range. 2599 for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) { 2600 /** @type {number} */ var wxo = triWx + lodOffsets[lodOffsNdx][0]; 2601 /** @type {number} */ var wyo = triWy + lodOffsets[lodOffsNdx][1]; 2602 /** @type {number} */ var nxo = wxo / dstW; 2603 /** @type {number} */ var nyo = wyo / dstH; 2604 2605 /** @type {Array<number>} */ var coordO = [ 2606 glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2607 glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 2608 glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo) 2609 ]; 2610 /** @type {Array<number>} */ var coordDxo = deMath.multiply([ 2611 glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2612 glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize 2613 ); 2614 /** @type {Array<number>} */ var coordDyo = deMath.multiply([ 2615 glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2616 glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize 2617 ); 2618 /** @type {Array<number>} */ 2619 var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec); 2620 2621 lodBounds[0] = Math.min(lodBounds[0], lodO[0]); 2622 lodBounds[1] = Math.max(lodBounds[1], lodO[1]); 2623 } 2624 2625 /** @type {Array<number>} */ var clampedLod = tcuTexLookupVerifier.clampLodBounds( 2626 deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec); 2627 /** @type {boolean} */ 2628 var isOk = tcuTexLookupVerifier.isLookupResultValid_Texture2DArrayView(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 2629 2630 if (!isOk) { 2631 /** @type {tcuRGBA.RGBA} */ var red = tcuRGBA.newRGBAComponents(255, 0, 0, 255); 2632 errorMask.setPixel(red.toVec(), px, py); 2633 numFailed += 1; 2634 } 2635 } 2636 } 2637 } 2638 2639 return numFailed; 2640 }; 2641 2642 });