blob: f35d9422615e04c82e28fe54b0dc1ac98739c9f3 [file] [log] [blame]
/*-------------------------------------------------------------------------
* drawElements Quality Program OpenGL ES Utilities
* ------------------------------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
'use strict';
goog.provide('modules.shared.glsTextureTestUtil');
goog.require('framework.common.tcuImageCompare');
goog.require('framework.common.tcuPixelFormat');
goog.require('framework.common.tcuRGBA');
goog.require('framework.common.tcuStringTemplate');
goog.require('framework.common.tcuSurface');
goog.require('framework.common.tcuTexLookupVerifier');
goog.require('framework.common.tcuTexCompareVerifier');
goog.require('framework.common.tcuTexture');
goog.require('framework.delibs.debase.deMath');
goog.require('framework.opengl.gluDrawUtil');
goog.require('framework.opengl.gluShaderUtil');
goog.require('framework.opengl.gluShaderProgram');
goog.require('framework.delibs.debase.deRandom');
goog.scope(function() {
var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier;
var tcuTexCompareVerifier = framework.common.tcuTexCompareVerifier;
var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
var gluDrawUtil = framework.opengl.gluDrawUtil;
var gluShaderProgram = framework.opengl.gluShaderProgram;
var tcuTexture = framework.common.tcuTexture;
var tcuSurface = framework.common.tcuSurface;
var gluShaderUtil = framework.opengl.gluShaderUtil;
var tcuStringTemplate = framework.common.tcuStringTemplate;
var deMath = framework.delibs.debase.deMath;
var tcuImageCompare = framework.common.tcuImageCompare;
var tcuPixelFormat = framework.common.tcuPixelFormat;
var tcuRGBA = framework.common.tcuRGBA;
var deRandom = framework.delibs.debase.deRandom;
var DE_ASSERT = function(x) {
if (!x)
throw new Error('Assert failed');
};
var MIN_SUBPIXEL_BITS = 4;
/**
* @enum
*/
glsTextureTestUtil.textureType = {
TEXTURETYPE_2D: 0,
TEXTURETYPE_CUBE: 1,
TEXTURETYPE_2D_ARRAY: 2,
TEXTURETYPE_3D: 3,
TEXTURETYPE_CUBE_ARRAY: 4,
TEXTURETYPE_1D: 5,
TEXTURETYPE_1D_ARRAY: 6,
TEXTURETYPE_BUFFER: 7
};
/**
* @enum
*/
glsTextureTestUtil.samplerType = {
SAMPLERTYPE_FLOAT: 0,
SAMPLERTYPE_INT: 1,
SAMPLERTYPE_UINT: 2,
SAMPLERTYPE_SHADOW: 3,
SAMPLERTYPE_FETCH_FLOAT: 4,
SAMPLERTYPE_FETCH_INT: 5,
SAMPLERTYPE_FETCH_UINT: 6
};
/**
* @param {tcuTexture.TextureFormat} format
* @return {glsTextureTestUtil.samplerType}
*/
glsTextureTestUtil.getSamplerType = function(format) {
if (format == null)
throw new Error('Missing format information');
switch (format.type) {
case tcuTexture.ChannelType.SIGNED_INT8:
case tcuTexture.ChannelType.SIGNED_INT16:
case tcuTexture.ChannelType.SIGNED_INT32:
return glsTextureTestUtil.samplerType.SAMPLERTYPE_INT;
case tcuTexture.ChannelType.UNSIGNED_INT8:
case tcuTexture.ChannelType.UNSIGNED_INT32:
case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV:
return glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT;
// Texture formats used in depth/stencil textures.
case tcuTexture.ChannelType.UNSIGNED_INT16:
case tcuTexture.ChannelType.UNSIGNED_INT_24_8:
return (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS) ? glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT : glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT;
default:
return glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT;
}
};
/**
* @constructor
* @param {HTMLElement} canvas
* @param {number} preferredWidth
* @param {number} preferredHeight
* @param {number=} seed
*/
glsTextureTestUtil.RandomViewport = function(canvas, preferredWidth, preferredHeight, seed) {
this.width = Math.min(canvas.width, preferredWidth);
this.height = Math.min(canvas.height, preferredHeight);
if (typeof seed === 'undefined')
seed = preferredWidth + preferredHeight;
var rnd = new deRandom.Random(seed);
this.x = rnd.getInt(0, canvas.width - this.width);
this.y = rnd.getInt(0, canvas.height - this.height);
};
/**
* @constructor
* @param {glsTextureTestUtil.textureType} texType
*/
glsTextureTestUtil.RenderParams = function(texType) {
this.flags = {
projected: false,
use_bias: false,
log_programs: false,
log_uniforms: false
};
this.texType = texType;
this.w = [1, 1, 1, 1];
this.bias = 0;
this.ref = 0;
this.colorScale = [1, 1, 1, 1];
this.colorBias = [0, 0, 0, 0];
this.samplerType = glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT;
};
/**
* @enum
*/
glsTextureTestUtil.lodMode = {
EXACT: 0, //!< Ideal lod computation.
MIN_BOUND: 1, //!< Use estimation range minimum bound.
MAX_BOUND: 2 //!< Use estimation range maximum bound.
};
/**
* @constructor
* @extends {glsTextureTestUtil.RenderParams}
* @param {glsTextureTestUtil.textureType} texType
* @param {tcuTexture.Sampler=} sampler
* @param {glsTextureTestUtil.lodMode=} lodMode_
*/
glsTextureTestUtil.ReferenceParams = function(texType, sampler, lodMode_) {
glsTextureTestUtil.RenderParams.call(this, texType);
if (sampler)
this.sampler = sampler;
if (lodMode_)
this.lodMode = lodMode_;
else
this.lodMode = glsTextureTestUtil.lodMode.EXACT;
this.minLod = -1000;
this.maxLod = 1000;
this.baseLevel = 0;
this.maxLevel = 1000;
};
glsTextureTestUtil.ReferenceParams.prototype = Object.create(glsTextureTestUtil.RenderParams.prototype);
/** Copy constructor */
glsTextureTestUtil.ReferenceParams.prototype.constructor = glsTextureTestUtil.ReferenceParams;
/**
* @param {Array<number>} bottomLeft
* @param {Array<number>} topRight
* @return {Array<number>}
*/
glsTextureTestUtil.computeQuadTexCoord2D = function(bottomLeft, topRight) {
var dst = [];
dst.length = 4 * 2;
dst[0] = bottomLeft[0]; dst[1] = bottomLeft[1];
dst[2] = bottomLeft[0]; dst[3] = topRight[1];
dst[4] = topRight[0]; dst[5] = bottomLeft[1];
dst[6] = topRight[0]; dst[7] = topRight[1];
return dst;
};
/**
* @param {tcuTexture.CubeFace} face
* @return {Array<number>}
*/
glsTextureTestUtil.computeQuadTexCoordCube = function(face) {
var texCoordNegX = [
-1, 1, -1,
-1, -1, -1,
-1, 1, 1,
-1, -1, 1
];
var texCoordPosX = [
+1, 1, 1,
+1, -1, 1,
+1, 1, -1,
+1, -1, -1
];
var texCoordNegY = [
-1, -1, 1,
-1, -1, -1,
1, -1, 1,
1, -1, -1
];
var texCoordPosY = [
-1, +1, -1,
-1, +1, 1,
1, +1, -1,
1, +1, 1
];
var texCoordNegZ = [
1, 1, -1,
1, -1, -1,
-1, 1, -1,
-1, -1, -1
];
var texCoordPosZ = [
-1, 1, +1,
-1, -1, +1,
1, 1, +1,
1, -1, +1
];
switch (face) {
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: return texCoordNegX;
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: return texCoordPosX;
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: return texCoordNegY;
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: return texCoordPosY;
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: return texCoordNegZ;
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: return texCoordPosZ;
}
throw new Error('Unrecognized face ' + face);
};
/**
* @param {tcuTexture.CubeFace} face
* @param {Array<number>} bottomLeft
* @param {Array<number>} topRight
* @return {Array<number>}
*/
glsTextureTestUtil.computeQuadTexCoordCubeFace = function(face, bottomLeft, topRight) {
var dst = [];
/** @type {number} */ var sRow = 0;
/** @type {number} */ var tRow = 0;
/** @type {number} */ var mRow = 0;
/** @type {number} */ var sSign = 1.0;
/** @type {number} */ var tSign = 1.0;
/** @type {number} */ var mSign = 1.0;
switch (face) {
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: mRow = 0; sRow = 2; tRow = 1; mSign = -1.0; tSign = -1.0; break;
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: mRow = 0; sRow = 2; tRow = 1; sSign = -1.0; tSign = -1.0; break;
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: mRow = 1; sRow = 0; tRow = 2; mSign = -1.0; tSign = -1.0; break;
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: mRow = 1; sRow = 0; tRow = 2; break;
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: mRow = 2; sRow = 0; tRow = 1; mSign = -1.0; sSign = -1.0; tSign = -1.0; break;
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: mRow = 2; sRow = 0; tRow = 1; tSign = -1.0; break;
default:
throw new Error('Invalid cube face specified.');
}
dst[0 + mRow] = mSign;
dst[3 + mRow] = mSign;
dst[6 + mRow] = mSign;
dst[9 + mRow] = mSign;
dst[0 + sRow] = sSign * bottomLeft[0];
dst[3 + sRow] = sSign * bottomLeft[0];
dst[6 + sRow] = sSign * topRight[0];
dst[9 + sRow] = sSign * topRight[0];
dst[0 + tRow] = tSign * bottomLeft[1];
dst[3 + tRow] = tSign * topRight[1];
dst[6 + tRow] = tSign * bottomLeft[1];
dst[9 + tRow] = tSign * topRight[1];
return dst;
};
/**
* @param {number} layerNdx
* @param {Array<number>} bottomLeft
* @param {Array<number>} topRight
* @return {Array<number>}
*/
glsTextureTestUtil.computeQuadTexCoord2DArray = function(layerNdx, bottomLeft, topRight) {
var dst = [];
dst.length = 4 * 3;
dst[0] = bottomLeft[0]; dst[1] = bottomLeft[1]; dst[2] = layerNdx;
dst[3] = bottomLeft[0]; dst[4] = topRight[1]; dst[5] = layerNdx;
dst[6] = topRight[0]; dst[7] = bottomLeft[1]; dst[8] = layerNdx;
dst[9] = topRight[0]; dst[10] = topRight[1]; dst[11] = layerNdx;
return dst;
};
/**
* @param {Array<number>} a
* @param {Array<number>} b
* @param {Array<number>} c
* @return {Array<number>} a + (b - a) * c
*/
glsTextureTestUtil.selectCoords = function(a, b, c) {
var x1 = deMath.subtract(b, a);
var x2 = deMath.multiply(x1, c);
var x3 = deMath.add(a, x2);
return x3;
};
/**
* @param {Array<number>} p0
* @param {Array<number>} p1
* @param {Array<number>} dirSwz
* @return {Array<number>}
*/
glsTextureTestUtil.computeQuadTexCoord3D = function(p0, p1, dirSwz) {
var dst = [];
dst.length = 4 * 3;
var f0 = deMath.swizzle(([0, 0, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]);
var f1 = deMath.swizzle(([0, 1, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]);
var f2 = deMath.swizzle(([1, 0, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]);
var f3 = deMath.swizzle(([1, 1, 0]), [dirSwz[0], dirSwz[1], dirSwz[2]]);
var v0 = glsTextureTestUtil.selectCoords(p0, p1, f0);
var v1 = glsTextureTestUtil.selectCoords(p0, p1, f1);
var v2 = glsTextureTestUtil.selectCoords(p0, p1, f2);
var v3 = glsTextureTestUtil.selectCoords(p0, p1, f3);
dst[0] = v0[0]; dst[1] = v0[1]; dst[2] = v0[2];
dst[3] = v1[0]; dst[4] = v1[1]; dst[5] = v1[2];
dst[6] = v2[0]; dst[7] = v2[1]; dst[8] = v2[2];
dst[9] = v3[0]; dst[10] = v3[1]; dst[11] = v3[2];
return dst;
};
/**
* @enum
*/
glsTextureTestUtil.programType = {
PROGRAM_2D_FLOAT: 0,
PROGRAM_2D_INT: 1,
PROGRAM_2D_UINT: 2,
PROGRAM_2D_SHADOW: 3,
PROGRAM_2D_FLOAT_BIAS: 4,
PROGRAM_2D_INT_BIAS: 5,
PROGRAM_2D_UINT_BIAS: 6,
PROGRAM_2D_SHADOW_BIAS: 7,
PROGRAM_1D_FLOAT: 8,
PROGRAM_1D_INT: 9,
PROGRAM_1D_UINT: 10,
PROGRAM_1D_SHADOW: 11,
PROGRAM_1D_FLOAT_BIAS: 12,
PROGRAM_1D_INT_BIAS: 13,
PROGRAM_1D_UINT_BIAS: 14,
PROGRAM_1D_SHADOW_BIAS: 15,
PROGRAM_CUBE_FLOAT: 16,
PROGRAM_CUBE_INT: 17,
PROGRAM_CUBE_UINT: 18,
PROGRAM_CUBE_SHADOW: 19,
PROGRAM_CUBE_FLOAT_BIAS: 20,
PROGRAM_CUBE_INT_BIAS: 21,
PROGRAM_CUBE_UINT_BIAS: 22,
PROGRAM_CUBE_SHADOW_BIAS: 23,
PROGRAM_1D_ARRAY_FLOAT: 24,
PROGRAM_1D_ARRAY_INT: 25,
PROGRAM_1D_ARRAY_UINT: 26,
PROGRAM_1D_ARRAY_SHADOW: 27,
PROGRAM_2D_ARRAY_FLOAT: 28,
PROGRAM_2D_ARRAY_INT: 29,
PROGRAM_2D_ARRAY_UINT: 30,
PROGRAM_2D_ARRAY_SHADOW: 31,
PROGRAM_3D_FLOAT: 32,
PROGRAM_3D_INT: 33,
PROGRAM_3D_UINT: 34,
PROGRAM_3D_FLOAT_BIAS: 35,
PROGRAM_3D_INT_BIAS: 36,
PROGRAM_3D_UINT_BIAS: 37,
PROGRAM_CUBE_ARRAY_FLOAT: 38,
PROGRAM_CUBE_ARRAY_INT: 39,
PROGRAM_CUBE_ARRAY_UINT: 40,
PROGRAM_CUBE_ARRAY_SHADOW: 41,
PROGRAM_BUFFER_FLOAT: 42,
PROGRAM_BUFFER_INT: 43,
PROGRAM_BUFFER_UINT: 44
};
/**
* @constructor
* @param {string} version GL version
* @param {gluShaderUtil.precision} precision
*/
glsTextureTestUtil.ProgramLibrary = function(version, precision) {
this.m_glslVersion = version;
this.m_texCoordPrecision = precision;
};
/**
* @param {glsTextureTestUtil.programType} program
* @return {gluShaderProgram.ShaderProgram}
*/
glsTextureTestUtil.ProgramLibrary.prototype.getProgram = function(program) {
/* TODO: Implement */
// if (m_programs.find(program) != m_programs.end())
// return m_programs[program]; // Return from cache.
var vertShaderTemplate =
'${VTX_HEADER}' +
'${VTX_IN} highp vec4 a_position;\n' +
'${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n' +
'${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n' +
'\n' +
'void main (void)\n' +
' {\n' +
' gl_Position = a_position;\n' +
' v_texCoord = a_texCoord;\n' +
'}\n';
var fragShaderTemplate =
'${FRAG_HEADER}' +
'${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n' +
'uniform ${PRECISION} float u_bias;\n' +
'uniform ${PRECISION} float u_ref;\n' +
'uniform ${PRECISION} vec4 u_colorScale;\n' +
'uniform ${PRECISION} vec4 u_colorBias;\n' +
'uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n' +
'\n' +
'void main (void)\n' +
' {\n' +
' ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n' +
'}\n';
var params = [];
var isCube = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT, glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW_BIAS);
var isArray = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW) ||
deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW);
var is1D = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_1D_FLOAT, glsTextureTestUtil.programType.PROGRAM_1D_UINT_BIAS) ||
deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW) ||
deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT, glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT);
var is2D = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_2D_FLOAT, glsTextureTestUtil.programType.PROGRAM_2D_UINT_BIAS) ||
deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW);
var is3D = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_3D_FLOAT, glsTextureTestUtil.programType.PROGRAM_3D_UINT_BIAS);
var isCubeArray = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_FLOAT, glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_SHADOW);
var isBuffer = deMath.deInRange32(program, glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT, glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT);
if (this.m_glslVersion === '100 es') {
params['FRAG_HEADER'] = '';
params['VTX_HEADER'] = '';
params['VTX_IN'] = 'attribute';
params['VTX_OUT'] = 'varying';
params['FRAG_IN'] = 'varying';
params['FRAG_COLOR'] = 'gl_FragColor';
} else if (this.m_glslVersion === '300 es' || this.m_glslVersion === '310 es' || this.m_glslVersion === '330 es') {
var ext = null;
// if (isCubeArray && glu::glslVersionIsES(m_glslVersion))
// ext = "gl.EXT_texture_cube_map_array";
// else if (isBuffer && glu::glslVersionIsES(m_glslVersion))
// ext = "gl.EXT_texture_buffer";
var extension = '';
if (ext)
extension = '\n#extension ' + ext + ' : require';
params['FRAG_HEADER'] = '#version ' + this.m_glslVersion + extension + '\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n';
params['VTX_HEADER'] = '#version ' + this.m_glslVersion + '\n';
params['VTX_IN'] = 'in';
params['VTX_OUT'] = 'out';
params['FRAG_IN'] = 'in';
params['FRAG_COLOR'] = 'dEQP_FragColor';
} else
throw new Error('Unsupported version: ' + this.m_glslVersion);
params['PRECISION'] = gluShaderUtil.getPrecisionName(this.m_texCoordPrecision);
if (isCubeArray)
params['TEXCOORD_TYPE'] = 'vec4';
else if (isCube || (is2D && isArray) || is3D)
params['TEXCOORD_TYPE'] = 'vec3';
else if ((is1D && isArray) || is2D)
params['TEXCOORD_TYPE'] = 'vec2';
else if (is1D)
params['TEXCOORD_TYPE'] = 'float';
else
DE_ASSERT(false);
var sampler = null;
var lookup = null;
if (this.m_glslVersion === '300 es' || this.m_glslVersion === '310 es' || this.m_glslVersion === '330 es') {
switch (program) {
case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT: sampler = 'sampler2D'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_INT: sampler = 'isampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_UINT: sampler = 'usampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT_BIAS: sampler = 'sampler2D'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_INT_BIAS: sampler = 'isampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_UINT_BIAS: sampler = 'usampler2D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_1D_FLOAT: sampler = 'sampler1D'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_1D_INT: sampler = 'isampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_1D_UINT: sampler = 'usampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_1D_FLOAT_BIAS: sampler = 'sampler1D'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break;
case glsTextureTestUtil.programType.PROGRAM_1D_INT_BIAS: sampler = 'isampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
case glsTextureTestUtil.programType.PROGRAM_1D_UINT_BIAS: sampler = 'usampler1D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT: sampler = 'samplerCube'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_INT: sampler = 'isamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_UINT: sampler = 'usamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT_BIAS: sampler = 'samplerCube'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_INT_BIAS: sampler = 'isamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_UINT_BIAS: sampler = 'usamplerCube'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT: sampler = 'sampler2DArray'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_INT: sampler = 'isampler2DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_UINT: sampler = 'usampler2DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_3D_FLOAT: sampler = 'sampler3D'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_3D_INT: sampler = 'isampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_3D_UINT: sampler = ' usampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_3D_FLOAT_BIAS: sampler = 'sampler3D'; lookup = 'texture(u_sampler, v_texCoord, u_bias)'; break;
case glsTextureTestUtil.programType.PROGRAM_3D_INT_BIAS: sampler = 'isampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
case glsTextureTestUtil.programType.PROGRAM_3D_UINT_BIAS: sampler = ' usampler3D'; lookup = 'vec4(texture(u_sampler, v_texCoord, u_bias))'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_FLOAT: sampler = 'samplerCubeArray'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_INT: sampler = 'isamplerCubeArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_UINT: sampler = 'usamplerCubeArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT: sampler = 'sampler1DArray'; lookup = 'texture(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_INT: sampler = 'isampler1DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_UINT: sampler = 'usampler1DArray'; lookup = 'vec4(texture(u_sampler, v_texCoord))'; break;
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;
case glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT: sampler = 'samplerBuffer'; lookup = 'texelFetch(u_sampler, int(v_texCoord))'; break;
case glsTextureTestUtil.programType.PROGRAM_BUFFER_INT: sampler = 'isamplerBuffer'; lookup = 'vec4(texelFetch(u_sampler, int(v_texCoord)))'; break;
case glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT: sampler = 'usamplerBuffer'; lookup = 'vec4(texelFetch(u_sampler, int(v_texCoord)))'; break;
default:
DE_ASSERT(false);
}
} else if (this.m_glslVersion === '100 es') {
sampler = isCube ? 'samplerCube' : 'sampler2D';
switch (program) {
case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT: lookup = 'texture2D(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_2D_FLOAT_BIAS: lookup = 'texture2D(u_sampler, v_texCoord, u_bias)'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT: lookup = 'textureCube(u_sampler, v_texCoord)'; break;
case glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT_BIAS: lookup = 'textureCube(u_sampler, v_texCoord, u_bias)'; break;
default:
DE_ASSERT(false);
}
} else
DE_ASSERT(!'Unsupported version');
params['SAMPLER_TYPE'] = sampler;
params['LOOKUP'] = lookup;
var vertSrc = tcuStringTemplate.specialize(vertShaderTemplate, params);
var fragSrc = tcuStringTemplate.specialize(fragShaderTemplate, params);
var progObj = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertSrc, fragSrc));
// if (!progObj.isOk()) {
// // log << *progObj;
// testFailedOptions("Failed to create shader", true);
// }
// try
// {
// m_programs[program] = progObj;
// }
// catch (...)
// {
// delete progObj;
// throw;
// }
return progObj;
};
// public:
// glsTextureTestUtil.ProgramLibrary (const glu::RenderContext& context, tcu::TestContext& testCtx, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision);
// ~glsTextureTestUtil.ProgramLibrary (void);
// glu::ShaderProgram* getProgram (Program program);
// void clear (void);
// private:
// glsTextureTestUtil.ProgramLibrary (const glsTextureTestUtil.ProgramLibrary& other);
// glsTextureTestUtil.ProgramLibrary& operator= (const glsTextureTestUtil.ProgramLibrary& other);
// const glu::RenderContext& m_context;
// tcu::TestContext& m_testCtx;
// glu::GLSLVersion m_glslVersion;
// glu::Precision m_texCoordPrecision;
// std::map<Program, glu::ShaderProgram*> m_programs;
// };
/**
* @constructor
* @param {string} version GL version
* @param {gluShaderUtil.precision} precision
*/
glsTextureTestUtil.TextureRenderer = function(version, precision) {
this.m_programLibrary = new glsTextureTestUtil.ProgramLibrary(version, precision);
};
/**
* @param {tcuPixelFormat.PixelFormat} format
* @return {Array<boolean>}
*/
glsTextureTestUtil.getCompareMask = function(format) {
return [
format.redBits > 0,
format.greenBits > 0,
format.blueBits > 0,
format.alphaBits > 0
];
};
/**
* @param {tcuPixelFormat.PixelFormat} format
* @return {Array<number>}
*/
glsTextureTestUtil.getBitsVec = function(format) {
return [
format.redBits,
format.greenBits,
format.blueBits,
format.alphaBits
];
};
/**
* @param {number} texUnit
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.RenderParams} params
*/
glsTextureTestUtil.TextureRenderer.prototype.renderQuad = function(texUnit, texCoord, params) {
var wCoord = params.flags.projected ? params.w : [1, 1, 1, 1];
var useBias = params.flags.use_bias;
var logUniforms = params.flags.log_uniforms;
// Render quad with texture.
var position = [
-1 * wCoord[0], -1 * wCoord[0], 0, wCoord[0],
-1 * wCoord[1], +1 * wCoord[1], 0, wCoord[1],
+1 * wCoord[2], -1 * wCoord[2], 0, wCoord[2],
+1 * wCoord[3], +1 * wCoord[3], 0, wCoord[3]
];
/** @const */ var indices = [0, 1, 2, 2, 1, 3];
/** @type {?glsTextureTestUtil.programType} */ var progSpec = null;
var numComps = 0;
if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_2D) {
numComps = 2;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_UINT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_2D_SHADOW_BIAS : glsTextureTestUtil.programType.PROGRAM_2D_SHADOW; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_1D) {
numComps = 1;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_UINT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_1D_SHADOW_BIAS : glsTextureTestUtil.programType.PROGRAM_1D_SHADOW; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_CUBE) {
numComps = 3;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_UINT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW_BIAS : glsTextureTestUtil.programType.PROGRAM_CUBE_SHADOW; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_3D) {
numComps = 3;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_3D_FLOAT_BIAS : glsTextureTestUtil.programType.PROGRAM_3D_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_3D_INT_BIAS : glsTextureTestUtil.programType.PROGRAM_3D_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = useBias ? glsTextureTestUtil.programType.PROGRAM_3D_UINT_BIAS : glsTextureTestUtil.programType.PROGRAM_3D_UINT; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY) {
DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
numComps = 3;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_UINT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = glsTextureTestUtil.programType.PROGRAM_2D_ARRAY_SHADOW; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_CUBE_ARRAY) {
DE_ASSERT(!useBias);
numComps = 4;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_UINT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = glsTextureTestUtil.programType.PROGRAM_CUBE_ARRAY_SHADOW; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_1D_ARRAY) {
DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
numComps = 2;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_UINT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW: progSpec = glsTextureTestUtil.programType.PROGRAM_1D_ARRAY_SHADOW; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else if (params.texType == glsTextureTestUtil.textureType.TEXTURETYPE_BUFFER) {
numComps = 1;
switch (params.samplerType) {
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FETCH_FLOAT: progSpec = glsTextureTestUtil.programType.PROGRAM_BUFFER_FLOAT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FETCH_INT: progSpec = glsTextureTestUtil.programType.PROGRAM_BUFFER_INT; break;
case glsTextureTestUtil.samplerType.SAMPLERTYPE_FETCH_UINT: progSpec = glsTextureTestUtil.programType.PROGRAM_BUFFER_UINT; break;
default: throw new Error('Unrecognized sampler type:' + params.samplerType);
}
} else
throw new Error('Unrecognized texture type:' + params.texType);
if (progSpec === null)
throw new Error('Could not find program specification');
var program = this.m_programLibrary.getProgram(progSpec);
// \todo [2012-09-26 pyry] Move to glsTextureTestUtil.ProgramLibrary and log unique programs only(?)
/* TODO: Port logging
if (params.flags.log_programs)
log << *program;
*/
// Program and uniforms.
var prog = program.getProgram();
gl.useProgram(prog);
var loc = gl.getUniformLocation(prog, 'u_sampler');
gl.uniform1i(loc, texUnit);
// if (logUniforms)
// log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
if (useBias) {
gl.uniform1f(gl.getUniformLocation(prog, 'u_bias'), params.bias);
// if (logUniforms)
// log << TestLog::Message << "u_bias = " << params.bias << TestLog::EndMessage;
}
if (params.samplerType == glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW) {
gl.uniform1f(gl.getUniformLocation(prog, 'u_ref'), params.ref);
// if (logUniforms)
// log << TestLog::Message << "u_ref = " << params.ref << TestLog::EndMessage;
}
gl.uniform4fv(gl.getUniformLocation(prog, 'u_colorScale'), params.colorScale);
gl.uniform4fv(gl.getUniformLocation(prog, 'u_colorBias'), params.colorBias);
// if (logUniforms)
// {
// log << TestLog::Message << "u_colorScale = " << params.colorScale << TestLog::EndMessage;
// log << TestLog::Message << "u_colorBias = " << params.colorBias << TestLog::EndMessage;
// }
var vertexArrays = [];
var posLoc = gl.getAttribLocation(prog, 'a_position');
if (posLoc === -1) {
testFailedOptions("no location found for attribute 'a_position'", true);
}
var texLoc = gl.getAttribLocation(prog, 'a_texCoord');
if (texLoc === -1) {
testFailedOptions("no location found for attribute 'a_texCoord'", true);
}
vertexArrays.push(new gluDrawUtil.VertexArrayBinding(gl.FLOAT, posLoc, 4, 4, position));
vertexArrays.push(new gluDrawUtil.VertexArrayBinding(gl.FLOAT, texLoc, numComps, 4, texCoord));
gluDrawUtil.draw(gl, prog, vertexArrays, gluDrawUtil.triangles(indices));
};
// public:
// glsTextureTestUtil.TextureRenderer (const glu::RenderContext& context, tcu::TestContext& testCtx, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision);
// ~glsTextureTestUtil.TextureRenderer (void);
// void clear (void); //!< Frees allocated resources. Destructor will call clear() as well.
// void renderQuad (int texUnit, const float* texCoord, TextureType texType);
// void renderQuad (int texUnit, const float* texCoord, const glsTextureTestUtil.RenderParams& params);
// private:
// glsTextureTestUtil.TextureRenderer (const glsTextureTestUtil.TextureRenderer& other);
// glsTextureTestUtil.TextureRenderer& operator= (const glsTextureTestUtil.TextureRenderer& other);
// const glu::RenderContext& m_renderCtx;
// tcu::TestContext& m_testCtx;
// glsTextureTestUtil.ProgramLibrary m_programLibrary;
// };
/**
* @constructor
* @param {tcuSurface.Surface} surface
* @param {tcuPixelFormat.PixelFormat=} colorFmt
* @param {number=} x
* @param {number=} y
* @param {number=} width
* @param {number=} height
*/
glsTextureTestUtil.SurfaceAccess = function(surface, colorFmt, x, y, width, height) {
this.m_surface = surface;
this.colorMask = undefined; /*TODO*/
this.m_x = x || 0;
this.m_y = y || 0;
this.m_width = width || surface.getWidth();
this.m_height = height || surface.getHeight();
};
/** @return {number} */
glsTextureTestUtil.SurfaceAccess.prototype.getWidth = function() { return this.m_width; };
/** @return {number} */
glsTextureTestUtil.SurfaceAccess.prototype.getHeight = function() { return this.m_height; };
/**
* @param {Array<number>} color
* @param {number} x
* @param {number} y
*/
glsTextureTestUtil.SurfaceAccess.prototype.setPixel = function(color, x, y) {
/* TODO: Apply color mask */
var c = color;
for (var i = 0; i < c.length; i++)
c[i] = deMath.clamp(Math.round(color[i] * 255), 0, 255);
this.m_surface.setPixel(x, y, c);
};
/**
* @param {glsTextureTestUtil.lodMode} mode
* @param {number} dudx
* @param {number} dvdx
* @param {number} dwdx
* @param {number} dudy
* @param {number} dvdy
* @param {number} dwdy
* @return {number}
*/
glsTextureTestUtil.computeLodFromDerivates3D = function(mode, dudx, dvdx, dwdx, dudy, dvdy, dwdy) {
var p = 0;
switch (mode) {
case glsTextureTestUtil.lodMode.EXACT:
p = Math.max(Math.sqrt(dudx * dudx + dvdx * dvdx + dwdx * dwdx), Math.sqrt(dudy * dudy + dvdy * dvdy + dwdy * dwdy));
break;
case glsTextureTestUtil.lodMode.MIN_BOUND:
case glsTextureTestUtil.lodMode.MAX_BOUND: {
var mu = Math.max(Math.abs(dudx), Math.abs(dudy));
var mv = Math.max(Math.abs(dvdx), Math.abs(dvdy));
var mw = Math.max(Math.abs(dwdx), Math.abs(dwdy));
p = (mode == glsTextureTestUtil.lodMode.MIN_BOUND) ? Math.max(mu, mv, mw) : mu + mv + mw;
break;
}
default:
DE_ASSERT(false);
}
// 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.
return deMath.toFloat32(Math.log(p)) * deMath.INV_LOG_2_FLOAT32;
};
/**
* @param {glsTextureTestUtil.lodMode} mode
* @param {Array<number>} dstSize
* @param {Array<number>} srcSize
* @param {Array<number>} sq
* @param {Array<number>} tq
* @param {Array<number>=} rq
* @return {number}
*/
glsTextureTestUtil.computeNonProjectedTriLod = function(mode, dstSize, srcSize, sq, tq, rq) {
var dux = (sq[2] - sq[0]) * srcSize[0];
var duy = (sq[1] - sq[0]) * srcSize[0];
var dvx = (tq[2] - tq[0]) * srcSize[1];
var dvy = (tq[1] - tq[0]) * srcSize[1];
var dwx = 0;
var dwy = 0;
if (rq) {
dwx = (rq[2] - rq[0]) * srcSize[2];
dwy = (rq[1] - rq[0]) * srcSize[2];
}
var dx = dstSize[0];
var dy = dstSize[1];
return glsTextureTestUtil.computeLodFromDerivates3D(mode, dux / dx, dvx / dx, dwx / dx, duy / dy, dvy / dy, dwy / dy);
};
/**
* @param {Array<number>} v
* @param {number} x
* @param {number} y
* @return {number}
*/
glsTextureTestUtil.triangleInterpolate = function(v, x, y) {
return v[0] + (v[2] - v[0]) * x + (v[1] - v[0]) * y;
};
/**
* @param {Array<number>} s
* @param {Array<number>} w
* @param {number} wx
* @param {number} width
* @param {number} ny
* @return {number}
*/
glsTextureTestUtil.triDerivateX = function(s, w, wx, width, ny) {
var d = w[1] * w[2] * (width * (ny - 1) + wx) - w[0] * (w[2] * width * ny + w[1] * wx);
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);
};
/**
* @param {Array<number>} s
* @param {Array<number>} w
* @param {number} wy
* @param {number} height
* @param {number} nx
* @return {number}
*/
glsTextureTestUtil.triDerivateY = function(s, w, wy, height, nx) {
var d = w[1] * w[2] * (height * (nx - 1) + wy) - w[0] * (w[1] * height * nx + w[2] * wy);
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);
};
/**
* @param {(tcuTexture.Texture2DView|tcuTexture.Texture2DArrayView|tcuTexture.TextureCubeView)} src
* @param {glsTextureTestUtil.ReferenceParams} params
* @param {Array<number>} texCoord Texture coordinates
* @param {number} lod
* @return {Array<number>} sample
*/
glsTextureTestUtil.execSample = function(src, params, texCoord, lod) {
if (params.samplerType == glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW)
return [src.sampleCompare(params.sampler, params.ref, texCoord, lod), 0, 0, 1];
else
return src.sample(params.sampler, texCoord, lod);
};
/**
* @param {Array<number>} pixel
* @param {Array<number>} scale
* @param {Array<number>} bias
*/
glsTextureTestUtil.applyScaleAndBias = function(pixel, scale, bias) {
pixel[0] = pixel[0] * scale[0] + bias[0];
pixel[1] = pixel[1] * scale[1] + bias[1];
pixel[2] = pixel[2] * scale[2] + bias[2];
pixel[3] = pixel[3] * scale[3] + bias[3];
};
/**
* @param {Array<number>} pixel
* @param {Array<number>} scale
* @param {Array<number>} bias
*/
glsTextureTestUtil.deapplyScaleAndBias = function(pixel, scale, bias) {
pixel[0] = (pixel[0] - bias[0]) / scale[0];
pixel[1] = (pixel[1] - bias[1]) / scale[1];
pixel[2] = (pixel[2] - bias[2]) / scale[2];
pixel[3] = (pixel[3] - bias[3]) / scale[3];
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture2DView} src
* @param {Array<number>} sq
* @param {Array<number>} tq
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTextureProjected2D = function(dst, src, sq, tq, params) {
/** @type {number} */ var lodBias = params.flags.use_bias ? params.bias : 0.0;
/** @type {number} */ var dstW = dst.getWidth();
/** @type {number} */ var dstH = dst.getHeight();
/** @type {Array<number>} */ var uq = deMath.scale(sq, src.getWidth());
/** @type {Array<number>} */ var vq = deMath.scale(tq, src.getHeight());
/** @type {Array<Array<number>>} */ var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triU = [deMath.swizzle(uq, [0, 1, 2]), deMath.swizzle(uq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triV = [deMath.swizzle(vq, [0, 1, 2]), deMath.swizzle(vq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triW = [deMath.swizzle(params.w, [0, 1, 2]), deMath.swizzle(params.w, [3, 2, 1])];
for (var py = 0; py < dst.getHeight(); py++) {
for (var px = 0; px < dst.getWidth(); px++) {
/** @type {number} */ var wx = px + 0.5;
/** @type {number} */ var wy = py + 0.5;
/** @type {number} */ var nx = wx / dstW;
/** @type {number} */ var ny = wy / dstH;
/** @type {number} */ var triNdx = nx + ny >= 1.0 ? 1 : 0;
/** @type {number} */ var triWx = triNdx ? dstW - wx : wx;
/** @type {number} */ var triWy = triNdx ? dstH - wy : wy;
/** @type {number} */ var triNx = triNdx ? 1.0 - nx : nx;
/** @type {number} */ var triNy = triNdx ? 1.0 - ny : ny;
/** @type {number} */ var s = glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
/** @type {number} */ var t = glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy);
/** @type {number} */ var lod = glsTextureTestUtil.computeProjectedTriLod2D(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triWx, triWy, dst.getWidth(), dst.getHeight()) + lodBias;
var pixel = glsTextureTestUtil.execSample(src, params, [s, t], lod);
glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias);
dst.setPixel(pixel, px, py);
}
}
};
/**
* @param {glsTextureTestUtil.lodMode} mode
* @param {Array<number>} u
* @param {Array<number>} v
* @param {Array<number>} projection
* @param {number} wx
* @param {number} wy
* @param {number} width
* @param {number} height
* @return {number}
*/
glsTextureTestUtil.computeProjectedTriLod2D = function(mode, u, v, projection, wx, wy, width, height) {
// Exact derivatives.
/** @type {number} */ var dudx = glsTextureTestUtil.triDerivateX(u, projection, wx, width, wy / height);
/** @type {number} */ var dvdx = glsTextureTestUtil.triDerivateX(v, projection, wx, width, wy / height);
/** @type {number} */ var dudy = glsTextureTestUtil.triDerivateY(u, projection, wy, height, wx / width);
/** @type {number} */ var dvdy = glsTextureTestUtil.triDerivateY(v, projection, wy, height, wx / width);
return glsTextureTestUtil.computeLodFromDerivates2D(mode, dudx, dvdx, dudy, dvdy);
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture2DView} src
* @param {Array<number>} sq
* @param {Array<number>} tq
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTextureNonProjected2D = function(dst, src, sq, tq, params) {
var lodBias = params.flags.use_bias ? params.bias : 0;
var dstSize = [dst.getWidth(), dst.getHeight()];
var srcSize = [src.getWidth(), src.getHeight()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triLod = [deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias), params.minLod, params.maxLod),
deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias), params.minLod, params.maxLod)];
for (var y = 0; y < dst.getHeight(); y++) {
for (var x = 0; x < dst.getWidth(); x++) {
var yf = (y + 0.5) / dst.getHeight();
var xf = (x + 0.5) / dst.getWidth();
var triNdx = xf + yf >= 1 ? 1 : 0; // Top left fill rule.
var triX = triNdx ? 1 - xf : xf;
var triY = triNdx ? 1 - yf : yf;
var s = glsTextureTestUtil.triangleInterpolate(triS[triNdx], triX, triY);
var t = glsTextureTestUtil.triangleInterpolate(triT[triNdx], triX, triY);
var lod = triLod[triNdx];
var pixel = glsTextureTestUtil.execSample(src, params, [s, t], lod);
glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias);
dst.setPixel(pixel, x, y);
}
}
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture2DArrayView} src
* @param {Array<number>} sq
* @param {Array<number>} tq
* @param {Array<number>} rq
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTextureNonProjected2DArray = function(dst, src, sq, tq, rq, params) {
var lodBias = (params.flags.use_bias) ? params.bias : 0;
var dstSize = [dst.getWidth(), dst.getHeight()];
var srcSize = [src.getWidth(), src.getHeight()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triLod = [glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias,
glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias];
for (var y = 0; y < dst.getHeight(); y++) {
for (var x = 0; x < dst.getWidth(); x++) {
var yf = (y + 0.5) / dst.getHeight();
var xf = (x + 0.5) / dst.getWidth();
var triNdx = xf + yf >= 1 ? 1 : 0; // Top left fill rule.
var triX = triNdx ? 1 - xf : xf;
var triY = triNdx ? 1 - yf : yf;
var s = glsTextureTestUtil.triangleInterpolate(triS[triNdx], triX, triY);
var t = glsTextureTestUtil.triangleInterpolate(triT[triNdx], triX, triY);
var r = glsTextureTestUtil.triangleInterpolate(triR[triNdx], triX, triY);
var lod = triLod[triNdx];
var pixel = glsTextureTestUtil.execSample(src, params, [s, t, r], lod);
glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias);
dst.setPixel(pixel, x, y);
}
}
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture2DView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTexture2D = function(dst, src, texCoord, params) {
var view = src.getSubView(params.baseLevel, params.maxLevel);
var sq = [texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]];
var tq = [texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]];
if (params.flags.projected)
glsTextureTestUtil.sampleTextureProjected2D(dst, view, sq, tq, params);
else
glsTextureTestUtil.sampleTextureNonProjected2D(dst, view, sq, tq, params);
};
/**
* @param {glsTextureTestUtil.lodMode} mode
* @param {number} dudx
* @param {number} dvdx
* @param {number} dudy
* @param {number} dvdy
* @return {number}
*/
glsTextureTestUtil.computeLodFromDerivates2D = function(mode, dudx, dvdx, dudy, dvdy) {
var p = 0;
switch (mode) {
case glsTextureTestUtil.lodMode.EXACT:
p = Math.max(Math.sqrt(dudx * dudx + dvdx * dvdx), Math.sqrt(dudy * dudy + dvdy * dvdy));
break;
case glsTextureTestUtil.lodMode.MIN_BOUND:
case glsTextureTestUtil.lodMode.MAX_BOUND: {
var mu = Math.max(Math.abs(dudx), Math.abs(dudy));
var mv = Math.max(Math.abs(dvdx), Math.abs(dvdy));
p = (mode == glsTextureTestUtil.lodMode.MIN_BOUND) ? Math.max(mu, mv) : mu + mv;
break;
}
default:
throw new Error('Unrecognized mode:' + mode);
}
// 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.
return deMath.toFloat32(Math.log(p)) * deMath.INV_LOG_2_FLOAT32;
};
/**
* @param {glsTextureTestUtil.lodMode} lodModeParm
* @param {Array<number>} coord
* @param {Array<number>} coordDx
* @param {Array<number>} coordDy
* @param {number} faceSize
* @return {number}
*/
glsTextureTestUtil.computeCubeLodFromDerivates = function(lodModeParm, coord, coordDx, coordDy, faceSize) {
var face = tcuTexture.selectCubeFace(coord);
var maNdx = 0;
var sNdx = 0;
var tNdx = 0;
// \note Derivate signs don't matter when computing lod
switch (face) {
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X:
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: maNdx = 0; sNdx = 2; tNdx = 1; break;
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y:
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: maNdx = 1; sNdx = 0; tNdx = 2; break;
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z:
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: maNdx = 2; sNdx = 0; tNdx = 1; break;
default:
throw new Error('Unrecognized face ' + face);
} {
var sc = coord[sNdx];
var tc = coord[tNdx];
var ma = Math.abs(coord[maNdx]);
var scdx = coordDx[sNdx];
var tcdx = coordDx[tNdx];
var madx = Math.abs(coordDx[maNdx]);
var scdy = coordDy[sNdx];
var tcdy = coordDy[tNdx];
var mady = Math.abs(coordDy[maNdx]);
var dudx = faceSize * 0.5 * (scdx * ma - sc * madx) / (ma * ma);
var dvdx = faceSize * 0.5 * (tcdx * ma - tc * madx) / (ma * ma);
var dudy = faceSize * 0.5 * (scdy * ma - sc * mady) / (ma * ma);
var dvdy = faceSize * 0.5 * (tcdy * ma - tc * mady) / (ma * ma);
return glsTextureTestUtil.computeLodFromDerivates2D(lodModeParm, dudx, dvdx, dudy, dvdy);
}
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.TextureCubeView} src
* @param {Array<number>} sq
* @param {Array<number>} tq
* @param {Array<number>} rq
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTextureCube_str = function(dst, src, sq, tq, rq, params) {
var dstSize = [dst.getWidth(), dst.getHeight()];
var dstW = dstSize[0];
var dstH = dstSize[1];
var srcSize = src.getSize();
// Coordinates per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triW = [deMath.swizzle(params.w, [0, 1, 2]), deMath.swizzle(params.w, [3, 2, 1])];
var lodBias = (params.flags.use_bias ? params.bias : 0);
for (var py = 0; py < dst.getHeight(); py++) {
for (var px = 0; px < dst.getWidth(); px++) {
var wx = px + 0.5;
var wy = py + 0.5;
var nx = wx / dstW;
var ny = wy / dstH;
var triNdx = nx + ny >= 1 ? 1 : 0;
var triNx = triNdx ? 1 - nx : nx;
var triNy = triNdx ? 1 - ny : ny;
var coord = [glsTextureTestUtil.triangleInterpolate(triS[triNdx], triNx, triNy),
glsTextureTestUtil.triangleInterpolate(triT[triNdx], triNx, triNy),
glsTextureTestUtil.triangleInterpolate(triR[triNdx], triNx, triNy)];
var coordDx = [glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)];
var coordDy = [glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)];
var lod = deMath.clamp((glsTextureTestUtil.computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, srcSize) + lodBias), params.minLod, params.maxLod);
var pixel = glsTextureTestUtil.execSample(src, params, coord, lod);
glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias);
dst.setPixel(pixel, px, py);
}
}
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.TextureCubeView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTextureCube = function(dst, src, texCoord, params) {
/*const tcu::TextureCubeView*/ var view = src.getSubView(params.baseLevel, params.maxLevel);
var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
glsTextureTestUtil.sampleTextureCube_str(dst, view, sq, tq, rq, params);
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture2DArrayView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTexture2DArray = function(dst, src, texCoord, params) {
var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
DE_ASSERT(!(params.flags.projected)); // \todo [2012-02-17 pyry] Support projected lookups.
glsTextureTestUtil.sampleTextureNonProjected2DArray(dst, src, sq, tq, rq, params);
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture3DView} src
* @param {Array<number>} sq
* @param {Array<number>} tq
* @param {Array<number>} rq
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTextureNonProjected3D = function(dst, src, sq, tq, rq, params) {
var lodBias = params.flags.use_bias ? params.bias : 0;
var dstSize = [dst.getWidth(), dst.getHeight()];
var srcSize = [src.getWidth(), src.getHeight(), src.getDepth()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triLod = [deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0], triR[0]) + lodBias), params.minLod, params.maxLod),
deMath.clamp((glsTextureTestUtil.computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1], triR[1]) + lodBias), params.minLod, params.maxLod)];
for (var y = 0; y < dst.getHeight(); y++) {
for (var x = 0; x < dst.getWidth(); x++) {
var yf = (y + 0.5) / dst.getHeight();
var xf = (x + 0.5) / dst.getWidth();
var triNdx = xf + yf >= 1 ? 1 : 0; // Top left fill rule.
var triX = triNdx ? 1 - xf : xf;
var triY = triNdx ? 1 - yf : yf;
var s = glsTextureTestUtil.triangleInterpolate(triS[triNdx], triX, triY);
var t = glsTextureTestUtil.triangleInterpolate(triT[triNdx], triX, triY);
var r = glsTextureTestUtil.triangleInterpolate(triR[triNdx], triX, triY);
var lod = triLod[triNdx];
var pixel = src.sample(params.sampler, [s, t, r], lod);
glsTextureTestUtil.applyScaleAndBias(pixel, params.colorScale, params.colorBias);
dst.setPixel(pixel, x, y);
}
}
};
/**
* @param {glsTextureTestUtil.SurfaceAccess} dst
* @param {tcuTexture.Texture3DView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} params
*/
glsTextureTestUtil.sampleTexture3D = function(dst, src, texCoord, params) {
/*const tcu::TextureCubeView*/ var view = src.getSubView(params.baseLevel, params.maxLevel);
var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
glsTextureTestUtil.sampleTextureNonProjected3D(dst, view, sq, tq, rq, params);
};
/**
* @param {tcuSurface.Surface} reference
* @param {tcuSurface.Surface} rendered
* @param {Array<number>} threshold
* @param {Array< Array<number> >} skipPixels
*
* @return {boolean}
*/
glsTextureTestUtil.compareImages = function(reference, rendered, threshold, skipPixels) {
return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, rendered, threshold, undefined /*tcu::COMPARE_LOG_RESULT*/, skipPixels);
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.Texture2DView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {tcuPixelFormat.PixelFormat} pixelFormat
* @return {boolean}
*/
glsTextureTestUtil.verifyTexture2DResult = function(result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat) {
DE_ASSERT(deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask));
/** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight());
/** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
/** @type {number} */ var numFailedPixels;
/** @type {glsTextureTestUtil.SurfaceAccess} */ var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat);
glsTextureTestUtil.sampleTexture2D(surface, src, texCoord, sampleParams);
numFailedPixels = glsTextureTestUtil.computeTextureLookupDiff2D(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec/*, testCtx.getWatchDog()*/);
if (numFailedPixels > 0)
tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess());
return numFailedPixels == 0;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.Texture2DView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {Array<number>} nonShadowThreshold
* @return {number}
*/
glsTextureTestUtil.computeTextureCompareDiff2D = function(result, reference, errorMask, src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold) {
DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
var sq = [texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]];
var tq = [texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]];
var dstSize = [result.getWidth(), result.getHeight()];
var dstW = dstSize[0];
var dstH = dstSize[1];
var srcSize = [src.getWidth(), src.getHeight()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])];
var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0, 0];
var numFailed = 0;
var lodOffsets = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
/** @type {Array<number>} */ var green = [0, 255, 0, 255];
errorMask.clear(green);
/** @type {Array<number>} */ var red = [];
for (var py = 0; py < result.getHeight(); py++) {
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(deMath.swizzle(refPix, [1, 2, 3]), deMath.swizzle(resPix, [1, 2, 3])), nonShadowThreshold))) {
red = [255, 0, 0, 255];
errorMask.setPixel(red, px, py);
numFailed += 1;
continue;
}
if (resPix[0] != refPix[0]) {
var wx = px + 0.5;
var wy = py + 0.5;
var nx = wx / dstW;
var ny = wy / dstH;
var triNdx = nx + ny >= 1.0 ? 1 : 0;
var triWx = triNdx ? dstW - wx : wx;
var triWy = triNdx ? dstH - wy : wy;
var triNx = triNdx ? 1.0 - nx : nx;
var triNy = triNdx ? 1.0 - ny : ny;
var coord = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)];
var coordDx = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize);
var coordDy = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize);
var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) {
var wxo = triWx + lodOffsets[lodOffsNdx][0];
var wyo = triWy + lodOffsets[lodOffsNdx][1];
var nxo = wxo / dstW;
var nyo = wyo / dstH;
var coordO = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo)];
var coordDxo = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize);
var coordDyo = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize);
var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
var clampedLod = tcuTexLookupVerifier.clampLodBounds(deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec);
var isOk = tcuTexCompareVerifier.isTexCompareResultValid2D(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix[0]);
if (!isOk) {
red = [255, 0, 0, 255];
errorMask.setPixel(red, px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.Texture3DView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {tcuPixelFormat.PixelFormat} pixelFormat
* @return {boolean}
*/
glsTextureTestUtil.verifyTexture3DResult = function(
result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat
) {
/** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight());
/** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
var numFailedPixels = 0;
assertMsgOptions(
deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask),
'Compare color masks do not match', false, true
);
/** @type {glsTextureTestUtil.SurfaceAccess} */ var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat);
glsTextureTestUtil.sampleTexture3D(surface, src, texCoord, sampleParams);
numFailedPixels = glsTextureTestUtil.computeTextureLookupDiff3D(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec);
if (numFailedPixels > 0)
tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess());
return numFailedPixels == 0;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.Texture3DView} baseView
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @return {number}
*/
glsTextureTestUtil.computeTextureLookupDiff3D = function(
result, reference, errorMask, baseView, texCoord,
sampleParams, lookupPrec, lodPrec
) {
assertMsgOptions(
result.getWidth() == reference.getWidth() &&
result.getHeight() == reference.getHeight(),
'Result and reference images are not the same size', false, true
);
assertMsgOptions(
result.getWidth() == errorMask.getWidth() &&
result.getHeight() == errorMask.getHeight(),
'Result and error mask images are not the same size', false, true
);
/** @type {tcuTexture.Texture3DView} */
var src = baseView.getSubView(
sampleParams.baseLevel, sampleParams.maxLevel
);
var sq =
[texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq =
[texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq =
[texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
var dstSize = [result.getWidth(), result.getHeight()];
var dstW = dstSize[0];
var dstH = dstSize[1];
var srcSize = [src.getWidth(), src.getHeight(), src.getDepth()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triW = [
deMath.swizzle(sampleParams.w, [0, 1, 2]),
deMath.swizzle(sampleParams.w, [3, 2, 1])
];
var lodBias = sampleParams.flags.useBias ? sampleParams.bias : 0.0;
var posEps = 1.0 / ((1 << MIN_SUBPIXEL_BITS) + 1);
var numFailed = 0;
var lodOffsets = [
[-1, 0],
[+1, 0],
[0, -1],
[0, +1]
];
var green = [0, 255, 0, 255];
errorMask.clear(new tcuRGBA.RGBA(green).toVec());
for (var py = 0; py < result.getHeight(); py++) {
// Ugly hack, validation can take way too long at the moment.
/*TODO: if (watchDog)
qpWatchDog_touch(watchDog);*/
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias);
// Try comparison to ideal reference first,
// and if that fails use slower verificator.
if (!deMath.boolAll(deMath.lessThanEqual(
deMath.absDiff(resPix, refPix),
lookupPrec.colorThreshold))
) {
/** @type {number} */ var wx = px + 0.5;
/** @type {number} */ var wy = py + 0.5;
/** @type {number} */ var nx = wx / dstW;
/** @type {number} */ var ny = wy / dstH;
/** @type {boolean} */ var tri0 = nx + ny - posEps <= 1.0;
/** @type {boolean} */ var tri1 = nx + ny + posEps >= 1.0;
var isOk = false;
assertMsgOptions(
tri0 || tri1,
'Pixel should belong at least to one triangle',
false, true
);
// Pixel can belong to either of the triangles
// if it lies close enough to the edge.
for (var triNdx = (tri0 ? 0 : 1);
triNdx <= (tri1 ? 1 : 0);
triNdx++) {
var triWx = triNdx ? dstW - wx : wx;
var triWy = triNdx ? dstH - wy : wy;
var triNx = triNdx ? 1.0 - nx : nx;
var triNy = triNdx ? 1.0 - ny : ny;
var coord = [
glsTextureTestUtil.projectedTriInterpolate(
triS[triNdx], triW[triNdx], triNx, triNy
),
glsTextureTestUtil.projectedTriInterpolate(
triT[triNdx], triW[triNdx], triNx, triNy
),
glsTextureTestUtil.projectedTriInterpolate(
triR[triNdx], triW[triNdx], triNx, triNy
)
];
var coordDx = deMath.multiply([
glsTextureTestUtil.triDerivateX(
triS[triNdx], triW[triNdx], wx, dstW, triNy
),
glsTextureTestUtil.triDerivateX(
triT[triNdx], triW[triNdx], wx, dstW, triNy
),
glsTextureTestUtil.triDerivateX(
triR[triNdx], triW[triNdx], wx, dstW, triNy
)
], srcSize);
var coordDy = deMath.multiply([
glsTextureTestUtil.triDerivateY(
triS[triNdx], triW[triNdx], wy, dstH, triNx
),
glsTextureTestUtil.triDerivateY(
triT[triNdx], triW[triNdx], wy, dstH, triNx
),
glsTextureTestUtil.triDerivateY(
triR[triNdx], triW[triNdx], wy, dstH, triNx
)
], srcSize);
var lodBounds =
tcuTexLookupVerifier.computeLodBoundsFromDerivates(
coordDx[0], coordDx[1], coordDx[2],
coordDy[0], coordDy[1], coordDy[2], lodPrec
);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0;
lodOffsNdx < lodOffsets.length;
lodOffsNdx++) {
var wxo = triWx + lodOffsets[lodOffsNdx][0];
var wyo = triWy + lodOffsets[lodOffsNdx][1];
var nxo = wxo / dstW;
var nyo = wyo / dstH;
var coordO = [
glsTextureTestUtil.projectedTriInterpolate(
triS[triNdx], triW[triNdx], nxo, nyo
),
glsTextureTestUtil.projectedTriInterpolate(
triT[triNdx], triW[triNdx], nxo, nyo
),
glsTextureTestUtil.projectedTriInterpolate(
triR[triNdx], triW[triNdx], nxo, nyo
)
];
var coordDxo = deMath.multiply([
glsTextureTestUtil.triDerivateX(
triS[triNdx], triW[triNdx], wxo, dstW, nyo
),
glsTextureTestUtil.triDerivateX(
triT[triNdx], triW[triNdx], wxo, dstW, nyo
),
glsTextureTestUtil.triDerivateX(
triR[triNdx], triW[triNdx], wxo, dstW, nyo
)
], srcSize);
var coordDyo = deMath.multiply([
glsTextureTestUtil.triDerivateY(
triS[triNdx], triW[triNdx], wyo, dstH, nxo
),
glsTextureTestUtil.triDerivateY(
triT[triNdx], triW[triNdx], wyo, dstH, nxo
),
glsTextureTestUtil.triDerivateY(
triR[triNdx], triW[triNdx], wyo, dstH, nxo
)
], srcSize);
var lodO =
tcuTexLookupVerifier.computeLodBoundsFromDerivates(
coordDxo[0], coordDxo[1], coordDxo[2],
coordDyo[0], coordDyo[1], coordDyo[2], lodPrec
);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
var clampedLod = tcuTexLookupVerifier.clampLodBounds(
deMath.addScalar(lodBounds, lodBias),
[sampleParams.minLod, sampleParams.maxLod],
lodPrec
);
if (
tcuTexLookupVerifier.isLookupResultValid(
src, sampleParams.sampler, lookupPrec,
coord, clampedLod, resPix
)
) {
isOk = true;
break;
}
}
if (!isOk) {
var red = [255, 0, 0, 255];
errorMask.setPixel(new tcuRGBA.RGBA(red).toVec(), px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.TextureCubeView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {tcuPixelFormat.PixelFormat} pixelFormat
* @return {boolean}
*/
glsTextureTestUtil.verifyTextureCubeResult = function(
result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat
) {
/** @type {tcuSurface.Surface} */
var reference = new tcuSurface.Surface(
result.getWidth(), result.getHeight()
);
/** @type {tcuSurface.Surface} */
var errorMask = new tcuSurface.Surface(
result.getWidth(), result.getHeight()
);
/** @type {number} */ var numFailedPixels = 0;
assertMsgOptions(
deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask),
'Compare color masks do not match', false, true
);
/** @type {glsTextureTestUtil.SurfaceAccess} */
var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat);
glsTextureTestUtil.sampleTextureCube(
surface, src, texCoord, sampleParams
);
numFailedPixels = glsTextureTestUtil.computeTextureLookupDiffCube(
result, reference.getAccess(), errorMask.getAccess(),
src, texCoord, sampleParams, lookupPrec, lodPrec
/*, testCtx.getWatchDog()*/
);
if (numFailedPixels > 0)
tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess());
return numFailedPixels == 0;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.TextureCubeView} baseView
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @return {number}
*/
glsTextureTestUtil.computeTextureLookupDiffCube = function(
result, reference, errorMask, baseView, texCoord,
sampleParams, lookupPrec, lodPrec
) {
assertMsgOptions(
result.getWidth() == reference.getWidth() &&
result.getHeight() == reference.getHeight(),
'Result and reference images are not the same size', false, true
);
assertMsgOptions(
result.getWidth() == errorMask.getWidth() &&
result.getHeight() == errorMask.getHeight(),
'Result and error mask images are not the same size', false, true
);
/** @type {tcuTexture.TextureCubeView} */
var src = baseView.getSubView(
sampleParams.baseLevel, sampleParams.maxLevel
);
var sq =
[texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq =
[texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq =
[texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
var dstSize = [result.getWidth(), result.getHeight()];
var dstW = dstSize[0];
var dstH = dstSize[1];
var srcSize = [src.getSize(), src.getSize()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triW = [
deMath.swizzle(sampleParams.w, [0, 1, 2]),
deMath.swizzle(sampleParams.w, [3, 2, 1])
];
var lodBias = sampleParams.flags.useBias ? sampleParams.bias : 0.0;
var posEps = 1.0 / ((1 << MIN_SUBPIXEL_BITS) + 1);
var numFailed = 0;
var lodOffsets = [
[-1, 0],
[+1, 0],
[0, -1],
[0, +1],
// \note Not strictly allowed by spec,
// but implementations do this in practice.
[-1, -1],
[-1, 1],
[1, -1],
[1, 1]
];
var green = [0, 255, 0, 255];
errorMask.clear(new tcuRGBA.RGBA(green).toVec());
for (var py = 0; py < result.getHeight(); py++) {
// Ugly hack, validation can take way too long at the moment.
/*TODO: if (watchDog)
qpWatchDog_touch(watchDog);*/
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias);
// Try comparison to ideal reference first,
// and if that fails use slower verificator.
if (!deMath.boolAll(deMath.lessThanEqual(
deMath.absDiff(resPix, refPix),
lookupPrec.colorThreshold))
) {
/** @type {number} */ var wx = px + 0.5;
/** @type {number} */ var wy = py + 0.5;
/** @type {number} */ var nx = wx / dstW;
/** @type {number} */ var ny = wy / dstH;
/** @type {boolean} */ var tri0 = nx + ny - posEps <= 1.0;
/** @type {boolean} */ var tri1 = nx + ny + posEps >= 1.0;
var isOk = false;
assertMsgOptions(
tri0 || tri1,
'Pixel should belong at least to one triangle',
false, true
);
// Pixel can belong to either of the triangles
// if it lies close enough to the edge.
for (var triNdx = (tri0 ? 0 : 1);
triNdx <= (tri1 ? 1 : 0);
triNdx++) {
var triWx = triNdx ? dstW - wx : wx;
var triWy = triNdx ? dstH - wy : wy;
var triNx = triNdx ? 1.0 - nx : nx;
var triNy = triNdx ? 1.0 - ny : ny;
var coord = [
glsTextureTestUtil.projectedTriInterpolate(
triS[triNdx], triW[triNdx], triNx, triNy
),
glsTextureTestUtil.projectedTriInterpolate(
triT[triNdx], triW[triNdx], triNx, triNy
),
glsTextureTestUtil.projectedTriInterpolate(
triR[triNdx], triW[triNdx], triNx, triNy
)
];
var coordDx = [
glsTextureTestUtil.triDerivateX(
triS[triNdx], triW[triNdx], wx, dstW, triNy
),
glsTextureTestUtil.triDerivateX(
triT[triNdx], triW[triNdx], wx, dstW, triNy
),
glsTextureTestUtil.triDerivateX(
triR[triNdx], triW[triNdx], wx, dstW, triNy
)
];
var coordDy = [
glsTextureTestUtil.triDerivateY(
triS[triNdx], triW[triNdx], wy, dstH, triNx
),
glsTextureTestUtil.triDerivateY(
triT[triNdx], triW[triNdx], wy, dstH, triNx
),
glsTextureTestUtil.triDerivateY(
triR[triNdx], triW[triNdx], wy, dstH, triNx
)
];
var lodBounds =
tcuTexLookupVerifier.computeCubeLodBoundsFromDerivates(
coord, coordDx, coordDy, src.getSize(), lodPrec
);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0;
lodOffsNdx < lodOffsets.length;
lodOffsNdx++) {
var wxo = triWx + lodOffsets[lodOffsNdx][0];
var wyo = triWy + lodOffsets[lodOffsNdx][1];
var nxo = wxo / dstW;
var nyo = wyo / dstH;
var coordO = [
glsTextureTestUtil.projectedTriInterpolate(
triS[triNdx], triW[triNdx], nxo, nyo
),
glsTextureTestUtil.projectedTriInterpolate(
triT[triNdx], triW[triNdx], nxo, nyo
),
glsTextureTestUtil.projectedTriInterpolate(
triR[triNdx], triW[triNdx], nxo, nyo
)
];
var coordDxo = [
glsTextureTestUtil.triDerivateX(
triS[triNdx], triW[triNdx], wxo, dstW, nyo
),
glsTextureTestUtil.triDerivateX(
triT[triNdx], triW[triNdx], wxo, dstW, nyo
),
glsTextureTestUtil.triDerivateX(
triR[triNdx], triW[triNdx], wxo, dstW, nyo
)
];
var coordDyo = [
glsTextureTestUtil.triDerivateY(
triS[triNdx], triW[triNdx], wyo, dstH, nxo
),
glsTextureTestUtil.triDerivateY(
triT[triNdx], triW[triNdx], wyo, dstH, nxo
),
glsTextureTestUtil.triDerivateY(
triR[triNdx], triW[triNdx], wyo, dstH, nxo
)
];
var lodO =
tcuTexLookupVerifier.
computeCubeLodBoundsFromDerivates(
coordO, coordDxo, coordDyo,
src.getSize(), lodPrec
);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
var clampedLod = tcuTexLookupVerifier.clampLodBounds(
deMath.addScalar(lodBounds, lodBias),
[sampleParams.minLod, sampleParams.maxLod],
lodPrec
);
if (tcuTexLookupVerifier.
isLookupResultValid_TextureCubeView(
src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix
)
) {
isOk = true;
break;
}
}
if (!isOk) {
var red = [255, 0, 0, 255];
errorMask.setPixel(new tcuRGBA.RGBA(red).toVec(), px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.Texture2DArrayView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {tcuPixelFormat.PixelFormat} pixelFormat
* @return {boolean}
*/
glsTextureTestUtil.verifyTexture2DArrayResult = function(result, src, texCoord, sampleParams, lookupPrec, lodPrec, pixelFormat) {
DE_ASSERT(deMath.equal(glsTextureTestUtil.getCompareMask(pixelFormat), lookupPrec.colorMask));
/** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight());
/** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
/** @type {number} */ var numFailedPixels;
/** @type {glsTextureTestUtil.SurfaceAccess} */ var surface = new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat);
glsTextureTestUtil.sampleTexture2DArray(surface, src, texCoord, sampleParams);
numFailedPixels = glsTextureTestUtil.computeTextureLookupDiff2DArray(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec/*, testCtx.getWatchDog()*/);
if (numFailedPixels > 0)
tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess());
return numFailedPixels == 0;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.Texture2DArrayView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {Array<number>} nonShadowThreshold
* @return {number}
*/
glsTextureTestUtil.computeTextureCompareDiff2DArray = function(result, reference, errorMask, src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold) {
DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
var dstSize = [result.getWidth(), result.getHeight()];
var dstW = dstSize[0];
var dstH = dstSize[1];
var srcSize = [src.getWidth(), src.getHeight()];
// Coordinates and lod per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])];
var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0, 0];
var numFailed = 0;
var lodOffsets = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
/** @type {Array<number>} */ var green = [0, 255, 0, 255];
errorMask.clear(green);
/** @type {Array<number>} */ var red = [];
for (var py = 0; py < result.getHeight(); py++) {
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(deMath.swizzle(refPix, [1, 2, 3]), deMath.swizzle(resPix, [1, 2, 3])), nonShadowThreshold))) {
red = [255, 0, 0, 255];
errorMask.setPixel(red, px, py);
numFailed += 1;
continue;
}
if (resPix[0] != refPix[0]) {
var wx = px + 0.5;
var wy = py + 0.5;
var nx = wx / dstW;
var ny = wy / dstH;
var triNdx = nx + ny >= 1.0 ? 1 : 0;
var triWx = triNdx ? dstW - wx : wx;
var triWy = triNdx ? dstH - wy : wy;
var triNx = triNdx ? 1.0 - nx : nx;
var triNy = triNdx ? 1.0 - ny : ny;
var coord = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)];
var coordDx = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize);
var coordDy = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize);
var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) {
var wxo = triWx + lodOffsets[lodOffsNdx][0];
var wyo = triWy + lodOffsets[lodOffsNdx][1];
var nxo = wxo / dstW;
var nyo = wyo / dstH;
var coordO = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo)];
var coordDxo = deMath.multiply([glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize);
var coordDyo = deMath.multiply([glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize);
var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
var clampedLod = tcuTexLookupVerifier.clampLodBounds(deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec);
var isOk = tcuTexCompareVerifier.isTexCompareResultValid2DArray(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix[0]);
if (!isOk) {
red = [255, 0, 0, 255];
errorMask.setPixel(red, px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.TextureCubeView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {Array<number>} nonShadowThreshold
* @return {number}
*/
glsTextureTestUtil.computeTextureCompareDiffCube = function(result, reference, errorMask, src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold) {
DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
var dstSize = [result.getWidth(), result.getHeight()];
var dstW = dstSize[0];
var dstH = dstSize[1];
var srcSize = src.getSize();
// Coordinates per triangle.
var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])];
var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0, 0];
var numFailed = 0;
var lodOffsets = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
/** @type {Array<number>} */ var green = [0, 255, 0, 255];
errorMask.clear(new tcuRGBA.RGBA(green).toVec());
/** @type {Array<number>} */ var red = [];
for (var py = 0; py < result.getHeight(); py++) {
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(deMath.swizzle(resPix, [1, 2, 3]), deMath.swizzle(refPix, [1, 2, 3])), nonShadowThreshold))) {
red = [255, 0, 0, 255];
errorMask.setPixel(red, px, py);
numFailed += 1;
continue;
}
if (resPix[0] != refPix[0]) {
var wx = px + 0.5;
var wy = py + 0.5;
var nx = wx / dstW;
var ny = wy / dstH;
var triNdx = nx + ny >= 1.0 ? 1 : 0;
var triWx = triNdx ? dstW - wx : wx;
var triWy = triNdx ? dstH - wy : wy;
var triNx = triNdx ? 1.0 - nx : nx;
var triNy = triNdx ? 1.0 - ny : ny;
var coord = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)];
var coordDx = [glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)];
var coordDy = [glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)];
var lodBounds = tcuTexLookupVerifier.computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) {
var wxo = triWx + lodOffsets[lodOffsNdx][0];
var wyo = triWy + lodOffsets[lodOffsNdx][1];
var nxo = wxo / dstW;
var nyo = wyo / dstH;
var coordO = [glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)];
var coordDxo = [glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
glsTextureTestUtil.triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)];
var coordDyo = [glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
glsTextureTestUtil.triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)];
var lodO = tcuTexLookupVerifier.computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
var clampedLod = tcuTexLookupVerifier.clampLodBounds(deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec);
var isOk = tcuTexCompareVerifier.isTexCompareResultValidCube(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix[0]);
if (!isOk) {
red = [255, 0, 0, 255];
errorMask.setPixel(red, px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
/**
* @param {Array<number>} s
* @param {Array<number>} w
* @param {number} nx
* @param {number} ny
* @return {number}
*/
glsTextureTestUtil.projectedTriInterpolate = function(s, w, nx, ny) {
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]);
};
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.Texture2DView} baseView
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {*=} watchDog - TODO: ??
* @return {number}
*/
glsTextureTestUtil.computeTextureLookupDiff2D = function(result, reference, errorMask, baseView, texCoord, sampleParams, lookupPrec, lodPrec, watchDog) {
DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
/** @type {tcuTexture.Texture2DView} */ var src = baseView.getSubView(sampleParams.baseLevel, sampleParams.maxLevel);
/** @type {Array<number>} */ var sq = [texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]];
/** @type {Array<number>} */ var tq = [texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]];
/** @type {Array<number>} */ var dstSize = [result.getWidth(), result.getHeight()];
/** @type {number} */ var dstW = dstSize[0];
/** @type {number} */ var dstH = dstSize[1];
/** @type {Array<number>} */ var srcSize = [src.getWidth(), src.getHeight()];
// Coordinates and lod per triangle.
/** @type {Array<Array<number>>} */ var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])];
/** @type {Array<number>} */ var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0.0, 0.0];
/** @type {number} */ var numFailed = 0;
/** @type {Array<Array<number>>} */ var lodOffsets = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
/** @type {Array<number>} */ var green = [0, 255, 0, 255];
errorMask.clear(new tcuRGBA.RGBA(green).toVec());
for (var py = 0; py < result.getHeight(); py++) {
// Ugly hack, validation can take way too long at the moment.
// TODO:are we implementing qpWatchDog? skipping in the meantime
// if (watchDog)
// qpWatchDog_touch(watchDog);
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias);
// Try comparison to ideal reference first, and if that fails use slower verificator.
if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(resPix, refPix), lookupPrec.colorThreshold))) {
/** @type {number} */ var wx = px + 0.5;
/** @type {number} */ var wy = py + 0.5;
/** @type {number} */ var nx = wx / dstW;
/** @type {number} */ var ny = wy / dstH;
/** @type {number} */ var triNdx = nx + ny >= 1.0 ? 1 : 0;
/** @type {number} */ var triWx = triNdx ? dstW - wx : wx;
/** @type {number} */ var triWy = triNdx ? dstH - wy : wy;
/** @type {number} */ var triNx = triNdx ? 1.0 - nx : nx;
/** @type {number} */ var triNy = triNdx ? 1.0 - ny : ny;
/** @type {Array<number>} */ var coord = [
glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)
];
/** @type {Array<number>} */ var coordDx = deMath.multiply([
glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize);
/** @type {Array<number>} */ var coordDy = deMath.multiply([
glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize);
/** @type {Array<number>} */
var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) {
/** @type {number} */ var wxo = triWx + lodOffsets[lodOffsNdx][0];
/** @type {number} */ var wyo = triWy + lodOffsets[lodOffsNdx][1];
/** @type {number} */ var nxo = wxo / dstW;
/** @type {number} */ var nyo = wyo / dstH;
/** @type {Array<number>} */ var coordO = [
glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo)];
/** @type {Array<number>} */ var coordDxo = deMath.multiply([
glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize);
/** @type {Array<number>} */ var coordDyo = deMath.multiply([
glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize);
/** @type {Array<number>} */
var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
/** @type {Array<number>} */ var clampedLod = tcuTexLookupVerifier.clampLodBounds(
deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec);
/** @type {boolean} */
var isOk = tcuTexLookupVerifier.isLookupResultValid_Texture2DView(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);
if (!isOk) {
/** @type {tcuRGBA.RGBA} */ var red = tcuRGBA.newRGBAComponents(255, 0, 0, 255);
errorMask.setPixel(red.toVec(), px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
// Verifies texture lookup results and returns number of failed pixels.
/**
* @param {tcuTexture.ConstPixelBufferAccess} result
* @param {tcuTexture.ConstPixelBufferAccess} reference
* @param {tcuTexture.PixelBufferAccess} errorMask
* @param {tcuTexture.Texture2DArrayView} src
* @param {Array<number>} texCoord
* @param {glsTextureTestUtil.ReferenceParams} sampleParams
* @param {tcuTexLookupVerifier.LookupPrecision} lookupPrec
* @param {tcuTexLookupVerifier.LodPrecision} lodPrec
* @param {*=} watchDog - TODO: ??
* @return {number}
*/
glsTextureTestUtil.computeTextureLookupDiff2DArray = function(result, reference, errorMask, src, texCoord, sampleParams, lookupPrec, lodPrec, watchDog) {
DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
/** @type {Array<number>} */ var sq = [texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]];
/** @type {Array<number>} */ var tq = [texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]];
/** @type {Array<number>} */ var rq = [texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]];
/** @type {Array<number>} */ var dstSize = [result.getWidth(), result.getHeight()];
/** @type {number} */ var dstW = dstSize[0];
/** @type {number} */ var dstH = dstSize[1];
/** @type {Array<number>} */ var srcSize = [src.getWidth(), src.getHeight()];
// Coordinates and lod per triangle.
/** @type {Array<Array<number>>} */ var triS = [deMath.swizzle(sq, [0, 1, 2]), deMath.swizzle(sq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triT = [deMath.swizzle(tq, [0, 1, 2]), deMath.swizzle(tq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triR = [deMath.swizzle(rq, [0, 1, 2]), deMath.swizzle(rq, [3, 2, 1])];
/** @type {Array<Array<number>>} */ var triW = [deMath.swizzle(sampleParams.w, [0, 1, 2]), deMath.swizzle(sampleParams.w, [3, 2, 1])];
/** @type {Array<number>} */ var lodBias = sampleParams.flags.use_bias ? [sampleParams.bias, sampleParams.bias] : [0.0, 0.0];
/** @type {number} */ var numFailed = 0;
/** @type {Array<Array<number>>} */ var lodOffsets = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
/** @type {Array<number>} */ var green = [0, 255, 0, 255];
errorMask.clear(new tcuRGBA.RGBA(green).toVec());
for (var py = 0; py < result.getHeight(); py++) {
// Ugly hack, validation can take way too long at the moment.
// TODO:are we implementing qpWatchDog? skipping in the meantime
// if (watchDog)
// qpWatchDog_touch(watchDog);
for (var px = 0; px < result.getWidth(); px++) {
/** @type {Array<number>} */
var resPix = result.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(resPix, sampleParams.colorScale, sampleParams.colorBias);
/** @type {Array<number>} */
var refPix = reference.getPixel(px, py);
glsTextureTestUtil.deapplyScaleAndBias(refPix, sampleParams.colorScale, sampleParams.colorBias);
// Try comparison to ideal reference first, and if that fails use slower verificator.
if (!deMath.boolAll(deMath.lessThanEqual(deMath.absDiff(resPix, refPix), lookupPrec.colorThreshold))) {
/** @type {number} */ var wx = px + 0.5;
/** @type {number} */ var wy = py + 0.5;
/** @type {number} */ var nx = wx / dstW;
/** @type {number} */ var ny = wy / dstH;
/** @type {number} */ var triNdx = nx + ny >= 1.0 ? 1 : 0;
/** @type {number} */ var triWx = triNdx ? dstW - wx : wx;
/** @type {number} */ var triWy = triNdx ? dstH - wy : wy;
/** @type {number} */ var triNx = triNdx ? 1.0 - nx : nx;
/** @type {number} */ var triNy = triNdx ? 1.0 - ny : ny;
/** @type {Array<number>} */ var coord = [
glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)
];
/** @type {Array<number>} */ var coordDx = deMath.multiply([
glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)], srcSize);
/** @type {Array<number>} */ var coordDy = deMath.multiply([
glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)], srcSize);
/** @type {Array<number>} */
var lodBounds = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDx[0], coordDx[1], coordDy[0], coordDy[1], lodPrec);
// Compute lod bounds across lodOffsets range.
for (var lodOffsNdx = 0; lodOffsNdx < lodOffsets.length; lodOffsNdx++) {
/** @type {number} */ var wxo = triWx + lodOffsets[lodOffsNdx][0];
/** @type {number} */ var wyo = triWy + lodOffsets[lodOffsNdx][1];
/** @type {number} */ var nxo = wxo / dstW;
/** @type {number} */ var nyo = wyo / dstH;
/** @type {Array<number>} */ var coordO = [
glsTextureTestUtil.projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
glsTextureTestUtil.projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)
];
/** @type {Array<number>} */ var coordDxo = deMath.multiply([
glsTextureTestUtil.triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
glsTextureTestUtil.triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)], srcSize
);
/** @type {Array<number>} */ var coordDyo = deMath.multiply([
glsTextureTestUtil.triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
glsTextureTestUtil.triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)], srcSize
);
/** @type {Array<number>} */
var lodO = tcuTexLookupVerifier.computeLodBoundsFromDerivatesUV(coordDxo[0], coordDxo[1], coordDyo[0], coordDyo[1], lodPrec);
lodBounds[0] = Math.min(lodBounds[0], lodO[0]);
lodBounds[1] = Math.max(lodBounds[1], lodO[1]);
}
/** @type {Array<number>} */ var clampedLod = tcuTexLookupVerifier.clampLodBounds(
deMath.add(lodBounds, lodBias), [sampleParams.minLod, sampleParams.maxLod], lodPrec);
/** @type {boolean} */
var isOk = tcuTexLookupVerifier.isLookupResultValid_Texture2DArrayView(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);
if (!isOk) {
/** @type {tcuRGBA.RGBA} */ var red = tcuRGBA.newRGBAComponents(255, 0, 0, 255);
errorMask.setPixel(red.toVec(), px, py);
numFailed += 1;
}
}
}
}
return numFailed;
};
});