blob: 45ff09a11c26793f4dbe523b4d4276fff86adcf2 [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('functional.gles3.es3fTextureFilteringTests');
goog.require('framework.common.tcuImageCompare');
goog.require('framework.common.tcuLogImage');
goog.require('framework.common.tcuPixelFormat');
goog.require('framework.common.tcuRGBA');
goog.require('framework.common.tcuSurface');
goog.require('framework.common.tcuTestCase');
goog.require('framework.common.tcuTexLookupVerifier');
goog.require('framework.common.tcuTexture');
goog.require('framework.common.tcuTextureUtil');
goog.require('framework.delibs.debase.deMath');
goog.require('framework.delibs.debase.deRandom');
goog.require('framework.delibs.debase.deString');
goog.require('framework.opengl.gluShaderUtil');
goog.require('framework.opengl.gluTexture');
goog.require('framework.opengl.gluTextureUtil');
goog.require('functional.gles3.es3fFboTestUtil');
goog.require('modules.shared.glsTextureTestUtil');
goog.scope(function() {
var es3fTextureFilteringTests = functional.gles3.es3fTextureFilteringTests;
var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
var gluShaderUtil = framework.opengl.gluShaderUtil;
var gluTextureUtil = framework.opengl.gluTextureUtil;
var tcuImageCompare = framework.common.tcuImageCompare;
var tcuLogImage = framework.common.tcuLogImage;
var tcuPixelFormat = framework.common.tcuPixelFormat;
var tcuRGBA = framework.common.tcuRGBA;
var tcuTestCase = framework.common.tcuTestCase;
var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier;
var tcuSurface = framework.common.tcuSurface;
var tcuTexture = framework.common.tcuTexture;
var tcuTextureUtil = framework.common.tcuTextureUtil;
var deMath = framework.delibs.debase.deMath;
var deString = framework.delibs.debase.deString;
var deRandom = framework.delibs.debase.deRandom;
var gluTexture = framework.opengl.gluTexture;
var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
/** @type {WebGL2RenderingContext} */ var gl;
es3fTextureFilteringTests.version =
gluShaderUtil.getGLSLVersionString(gluShaderUtil.GLSLVersion.V300_ES);
let canvasWH = 256;
let viewportWH = 64;
if (tcuTestCase.isQuickMode()) {
canvasWH = 64;
viewportWH = 32;
}
const TEX2D_VIEWPORT_WIDTH = viewportWH;
const TEX2D_VIEWPORT_HEIGHT = viewportWH;
const TEX2D_MIN_VIEWPORT_WIDTH = viewportWH;
const TEX2D_MIN_VIEWPORT_HEIGHT = viewportWH;
const TEX3D_VIEWPORT_WIDTH = viewportWH;
const TEX3D_VIEWPORT_HEIGHT = viewportWH;
const TEX3D_MIN_VIEWPORT_WIDTH = viewportWH;
const TEX3D_MIN_VIEWPORT_HEIGHT = viewportWH;
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
*/
es3fTextureFilteringTests.TextureFilteringTests = function() {
tcuTestCase.DeqpTest.call(this, 'filtering', 'Texture Filtering Tests');
};
es3fTextureFilteringTests.TextureFilteringTests.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fTextureFilteringTests.TextureFilteringTests.prototype.constructor =
es3fTextureFilteringTests.TextureFilteringTests;
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
* @param {string} name
* @param {string} desc
* @param {number} minFilter
* @param {number} magFilter
* @param {number} wrapS
* @param {number} wrapT
* @param {number} internalFormat
* @param {number} width
* @param {number} height
*/
es3fTextureFilteringTests.Texture2DFilteringCase = function(
name, desc, minFilter, magFilter, wrapS, wrapT,
internalFormat, width, height
) {
tcuTestCase.DeqpTest.call(this, name, desc);
this.m_minFilter = minFilter;
this.m_magFilter = magFilter;
this.m_wrapS = wrapS;
this.m_wrapT = wrapT;
this.m_internalFormat = internalFormat;
this.m_width = width;
this.m_height = height;
/** @type {glsTextureTestUtil.TextureRenderer} */
this.m_renderer = new glsTextureTestUtil.TextureRenderer(
es3fTextureFilteringTests.version,
gluShaderUtil.precision.PRECISION_HIGHP
);
this.m_caseNdx = 0;
/** @type {Array<gluTexture.Texture2D>} */ this.m_textures = [];
this.m_cases = [];
};
es3fTextureFilteringTests.Texture2DFilteringCase.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fTextureFilteringTests.Texture2DFilteringCase.prototype.constructor =
es3fTextureFilteringTests.Texture2DFilteringCase;
/**
* @constructor
* @param {gluTexture.Texture2D} tex_
* @param {Array<number>} minCoord_
* @param {Array<number>} maxCoord_
*/
es3fTextureFilteringTests.Texture2DFilteringCase.FilterCase = function(
tex_, minCoord_, maxCoord_
) {
this.texture = tex_;
this.minCoord = minCoord_;
this.maxCoord = maxCoord_;
};
/** @typedef {{texNdx: number, lodX: number,
* lodY: number, oX: number, oY: number}} */
es3fTextureFilteringTests.Cases;
/**
* init
*/
es3fTextureFilteringTests.Texture2DFilteringCase.prototype.init =
function() {
try {
// Create 2 textures.
for (var ndx = 0; ndx < 2; ndx++)
this.m_textures.push(
gluTexture.texture2DFromInternalFormat(
gl, this.m_internalFormat,
this.m_width, this.m_height
)
);
var mipmaps = true;
var numLevels = mipmaps ? deMath.logToFloor(
Math.max(this.m_width, this.m_height)
) + 1 : 1;
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(
this.m_textures[0].getRefTexture().getFormat()
);
/** @type {Array<number>} */ var cBias = fmtInfo.valueMin;
/** @type {Array<number>} */
var cScale = deMath.subtract(
fmtInfo.valueMax, fmtInfo.valueMin
);
// Fill first gradient texture.
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
/** @type {Array<number>} */ var gMin = deMath.add(
deMath.multiply([0.0, 0.0, 0.0, 1.0], cScale), cBias
);
/** @type {Array<number>} */ var gMax = deMath.add(
deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias
);
this.m_textures[0].getRefTexture().allocLevel(levelNdx);
tcuTextureUtil.fillWithComponentGradients(
this.m_textures[0].getRefTexture().getLevel(levelNdx),
gMin, gMax
);
}
// Fill second with grid texture.
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
/** @type {number} */ var step = 0x00ffffff / numLevels;
/** @type {number} */ var rgb = step * levelNdx;
/** @type {number} */ var colorA = deMath.binaryOp(
0xff000000, rgb, deMath.BinaryOp.OR
);
/** @type {number} */ var colorB = deMath.binaryOp(
0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
);
this.m_textures[1].getRefTexture().allocLevel(levelNdx);
tcuTextureUtil.fillWithGrid(
this.m_textures[1].getRefTexture().getLevel(levelNdx),
4,
deMath.add(deMath.multiply(
tcuRGBA.newRGBAFromValue(colorA).toVec(), cScale),
cBias
),
deMath.add(deMath.multiply(
tcuRGBA.newRGBAFromValue(colorB).toVec(), cScale),
cBias
)
);
}
// Upload.
for (var i = 0; i < this.m_textures.length; i++)
this.m_textures[i].upload();
// Compute cases.
/** @type {Array<es3fTextureFilteringTests.Cases>} */
var cases = [{
texNdx: 0, lodX: 1.6, lodY: 2.9, oX: -1.0, oY: -2.7
}, {
texNdx: 0, lodX: -2.0, lodY: -1.35, oX: -0.2, oY: 0.7
}, {
texNdx: 1, lodX: 0.14, lodY: 0.275, oX: -1.5, oY: -1.1
}, {
texNdx: 1, lodX: -0.92, lodY: -2.64, oX: 0.4, oY: -0.1
}
];
var viewportW = Math.min(
TEX2D_VIEWPORT_WIDTH, gl.canvas.width
);
var viewportH = Math.min(
TEX2D_VIEWPORT_HEIGHT, gl.canvas.height
);
for (var caseNdx = 0; caseNdx < cases.length; caseNdx++) {
/** @type {number} */ var texNdx = deMath.clamp(
cases[caseNdx].texNdx, 0, this.m_textures.length - 1
);
/** @type {number} */ var lodX = cases[caseNdx].lodX;
/** @type {number} */ var lodY = cases[caseNdx].lodY;
/** @type {number} */ var oX = cases[caseNdx].oX;
/** @type {number} */ var oY = cases[caseNdx].oY;
/** @type {number} */ var sX = Math.exp(lodX * Math.log(2)) * viewportW /
this.m_textures[texNdx].getRefTexture().getWidth();
/** @type {number} */ var sY = Math.exp(lodY * Math.log(2)) * viewportH /
this.m_textures[texNdx].getRefTexture().getHeight();
this.m_cases.push(
new
es3fTextureFilteringTests.Texture2DFilteringCase.FilterCase(
this.m_textures[texNdx], [oX, oY], [oX + sX, oY + sY]
)
);
}
this.m_caseNdx = 0;
}
catch (e) {
// Clean up to save memory.
this.deinit();
throw e;
}
};
/**
* deinit
*/
es3fTextureFilteringTests.Texture2DFilteringCase.prototype.deinit =
function() {
while (this.m_textures.length > 0) {
gl.deleteTexture(this.m_textures[0].getGLTexture());
this.m_textures.splice(0, 1);
}
};
/**
* @return {tcuTestCase.IterateResult}
*/
es3fTextureFilteringTests.Texture2DFilteringCase.prototype.iterate =
function() {
/** @type {glsTextureTestUtil.RandomViewport} */
var viewport = new glsTextureTestUtil.RandomViewport(
gl.canvas, TEX2D_VIEWPORT_WIDTH,
TEX2D_VIEWPORT_HEIGHT, deMath.binaryOp(
deString.deStringHash(this.fullName()),
deMath.deMathHash(this.m_caseNdx),
deMath.BinaryOp.XOR
)
);
/** @type {tcuTexture.TextureFormat} */
var texFmt = this.m_textures[0].getRefTexture().getFormat();
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
var curCase = this.m_cases[this.m_caseNdx];
bufferedLogToConsole('Test ' + this.m_caseNdx);
var refParams = new glsTextureTestUtil.ReferenceParams(
glsTextureTestUtil.textureType.TEXTURETYPE_2D
);
var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
var texCoord = [0, 0];
if (viewport.width < TEX2D_MIN_VIEWPORT_WIDTH ||
viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
throw new Error('Too small render target');
// Setup params for reference.
refParams.sampler = gluTextureUtil.mapGLSamplerWrapST(
this.m_wrapS, this.m_wrapT, this.m_minFilter, this.m_magFilter
);
refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
refParams.colorBias = fmtInfo.lookupBias;
refParams.colorScale = fmtInfo.lookupScale;
// Compute texture coordinates.
bufferedLogToConsole(
'Texture coordinates: ' + curCase.minCoord +
' -> ' + curCase.maxCoord
);
texCoord = glsTextureTestUtil.computeQuadTexCoord2D(
curCase.minCoord, curCase.maxCoord
);
gl.bindTexture(gl.TEXTURE_2D, curCase.texture.getGLTexture());
gl.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_minFilter
);
gl.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_magFilter
);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.m_wrapS);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.m_wrapT);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
this.m_renderer.renderQuad(0, texCoord, refParams);
rendered.readViewport(
gl, [viewport.x, viewport.y, viewport.width, viewport.height]
);
/** @type {boolean} */ var isNearestOnly =
this.m_minFilter == gl.NEAREST && this.m_magFilter == gl.NEAREST;
/** @type {tcuPixelFormat.PixelFormat} */
var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
//(iVec4)
var colorBits = deMath.max(
deMath.addScalar(
glsTextureTestUtil.getBitsVec(pixelFormat),
// 1 inaccurate bit if nearest only, 2 otherwise
-1 * (isNearestOnly ? 1 : 2)
),
[0, 0, 0, 0]
);
/** @type {tcuTexLookupVerifier.LodPrecision} */
var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
/** @type {tcuTexLookupVerifier.LookupPrecision} */
var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
lodPrecision.derivateBits = 18;
lodPrecision.lodBits = 6;
lookupPrecision.colorThreshold = deMath.divide(
tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
refParams.colorScale
);
lookupPrecision.coordBits = [20, 20, 0];
lookupPrecision.uvwBits = [7, 7, 0];
lookupPrecision.colorMask =
glsTextureTestUtil.getCompareMask(pixelFormat);
var isHighQuality = glsTextureTestUtil.verifyTexture2DResult(
rendered.getAccess(), curCase.texture.getRefTexture(),
texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
);
if (!isHighQuality) {
// Evaluate against lower precision requirements.
lodPrecision.lodBits = 4;
lookupPrecision.uvwBits = [4, 4, 0];
bufferedLogToConsole('Warning: Verification against high ' +
'precision requirements failed, trying with lower ' +
'requirements.'
);
var isOk = glsTextureTestUtil.verifyTexture2DResult(
rendered.getAccess(), curCase.texture.getRefTexture(),
texCoord, refParams, lookupPrecision, lodPrecision,
pixelFormat
);
if (!isOk) {
bufferedLogToConsole(
'ERROR: Verification against low ' +
'precision requirements failed, failing test case.'
);
testFailedOptions('Image verification failed', false);
//In JS version, one mistake and you're out
return tcuTestCase.IterateResult.STOP;
} else
checkMessage(
false,
'Low-quality filtering result in iteration no. ' +
this.m_caseNdx
);
}
this.m_caseNdx += 1;
if (this.m_caseNdx < this.m_cases.length)
return tcuTestCase.IterateResult.CONTINUE;
testPassed('Verified');
return tcuTestCase.IterateResult.STOP;
};
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
* @param {string} name
* @param {string} desc
* @param {number} minFilter
* @param {number} magFilter
* @param {number} wrapS
* @param {number} wrapT
* @param {boolean} onlySampleFaceInterior
* @param {number} internalFormat
* @param {number} width
* @param {number} height
*/
es3fTextureFilteringTests.TextureCubeFilteringCase = function(
name, desc, minFilter, magFilter, wrapS, wrapT, onlySampleFaceInterior,
internalFormat, width, height
) {
tcuTestCase.DeqpTest.call(this, name, desc);
this.m_minFilter = minFilter;
this.m_magFilter = magFilter;
this.m_wrapS = wrapS;
this.m_wrapT = wrapT;
/** @type {boolean}*/
this.m_onlySampleFaceInterior = onlySampleFaceInterior;
this.m_internalFormat = internalFormat;
this.m_width = width;
this.m_height = height;
/** @type {glsTextureTestUtil.TextureRenderer} */
this.m_renderer = new glsTextureTestUtil.TextureRenderer(
es3fTextureFilteringTests.version,
gluShaderUtil.precision.PRECISION_HIGHP
);
this.m_caseNdx = 0;
/** @type {Array<gluTexture.TextureCube>} */ this.m_textures = [];
/** @type {Array<es3fTextureFilteringTests.
* TextureCubeFilteringCase.FilterCase>}
*/
this.m_cases = [];
};
/**
* @constructor
* @param {gluTexture.TextureCube} tex_
* @param {Array<number>} bottomLeft_
* @param {Array<number>} topRight_
*/
es3fTextureFilteringTests.TextureCubeFilteringCase.FilterCase = function(
tex_, bottomLeft_, topRight_
) {
this.texture = tex_;
this.bottomLeft = bottomLeft_;
this.topRight = topRight_;
};
es3fTextureFilteringTests.TextureCubeFilteringCase.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.constructor =
es3fTextureFilteringTests.TextureCubeFilteringCase;
/**
* init
*/
es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.init =
function() {
try {
assertMsgOptions(
this.m_width == this.m_height, 'Texture has to be squared',
false, true
);
for (var ndx = 0; ndx < 2; ndx++)
this.m_textures.push(gluTexture.cubeFromInternalFormat(
gl, this.m_internalFormat, this.m_width
));
var numLevels = deMath.logToFloor(
Math.max(this.m_width, this.m_height)
) + 1;
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(
this.m_textures[0].getRefTexture().getFormat()
);
/** @type {Array<number>} */
var cBias = fmtInfo.valueMin;
/** @type {Array<number>} */
var cScale = deMath.subtract(
fmtInfo.valueMax, fmtInfo.valueMin
);
// Fill first with gradient texture.
/** @type {Array<Array<Array<number>>>}
* (array of 4 component vectors)
*/
var gradients = [
[ // negative x
[0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
], [ // positive x
[0.5, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
], [ // negative y
[0.0, 0.5, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
], [ // positive y
[0.0, 0.0, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]
], [ // negative z
[0.0, 0.0, 0.0, 0.5], [1.0, 1.0, 1.0, 1.0]
], [ // positive z
[0.5, 0.5, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]
]
];
for (var face = 0;
face < Object.keys(tcuTexture.CubeFace).length;
face++) {
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
this.m_textures[0].getRefTexture().allocLevel(
face, levelNdx
);
tcuTextureUtil.fillWithComponentGradients(
this.m_textures[0].getRefTexture().getLevelFace(
levelNdx, face
),
deMath.add(deMath.multiply(
gradients[face][0], cScale
), cBias),
deMath.add(deMath.multiply(
gradients[face][1], cScale
), cBias)
);
}
}
// Fill second with grid texture.
for (var face = 0;
face < Object.keys(tcuTexture.CubeFace).length;
face++) {
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
var step = 0x00ffffff / (
numLevels * Object.keys(tcuTexture.CubeFace).length
);
var rgb = step * levelNdx * face;
/** @type {number} */ var colorA = deMath.binaryOp(
0xff000000, rgb, deMath.BinaryOp.OR
);
/** @type {number} */ var colorB = deMath.binaryOp(
0xff000000, deMath.binaryNot(rgb),
deMath.BinaryOp.OR
);
this.m_textures[1].getRefTexture().allocLevel(
face, levelNdx
);
tcuTextureUtil.fillWithGrid(
this.m_textures[1].getRefTexture().getLevelFace(
levelNdx, face
), 4, deMath.add(
deMath.multiply(
tcuRGBA.newRGBAFromValue(colorA).toVec(),
cScale
), cBias
), deMath.add(
deMath.multiply(
tcuRGBA.newRGBAFromValue(colorB).toVec(),
cScale
), cBias
)
);
}
}
// Upload.
for (var i = 0; i < this.m_textures.length; i++)
this.m_textures[i].upload();
// Compute cases
/** @type {gluTexture.TextureCube} */
var tex0 = this.m_textures[0];
/** @type {gluTexture.TextureCube} */
var tex1 = this.m_textures.length > 1 ? this.m_textures[1] : tex0;
if (this.m_onlySampleFaceInterior) {
// minification
this.m_cases.push(new es3fTextureFilteringTests.
TextureCubeFilteringCase.FilterCase(
tex0, [-0.8, -0.8], [0.8, 0.8]
));
// magnification
this.m_cases.push(new es3fTextureFilteringTests.
TextureCubeFilteringCase.FilterCase(
tex0, [0.5, 0.65], [0.8, 0.8]
));
// minification
this.m_cases.push(new es3fTextureFilteringTests.
TextureCubeFilteringCase.FilterCase(
tex1, [-0.8, -0.8], [0.8, 0.8]
));
// magnification
this.m_cases.push(new es3fTextureFilteringTests.
TextureCubeFilteringCase.FilterCase(
tex1, [0.2, 0.2], [0.6, 0.5]
));
} else {
// minification
if (gl.getParameter(gl.SAMPLES) == 0)
this.m_cases.push(
new es3fTextureFilteringTests.TextureCubeFilteringCase.
FilterCase(
tex0, [-1.25, -1.2], [1.2, 1.25]
)
);
// minification - w/ tweak to avoid hitting triangle
// edges with face switchpoint.
else
this.m_cases.push(
new es3fTextureFilteringTests.TextureCubeFilteringCase.
FilterCase(
tex0, [-1.19, -1.3], [1.1, 1.35]
)
);
// magnification
this.m_cases.push(
new es3fTextureFilteringTests.TextureCubeFilteringCase.
FilterCase(
tex0, [0.8, 0.8], [1.25, 1.20]
)
);
// minification
this.m_cases.push(
new es3fTextureFilteringTests.TextureCubeFilteringCase.
FilterCase(
tex1, [-1.19, -1.3], [1.1, 1.35]
)
);
// magnification
this.m_cases.push(
new es3fTextureFilteringTests.TextureCubeFilteringCase.
FilterCase(
tex1, [-1.2, -1.1], [-0.8, -0.8]
)
);
}
this.m_caseNdx = 0;
}
catch (e) {
// Clean up to save memory.
this.deinit();
throw e;
}
};
/**
* deinit
*/
es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.deinit =
function() {
while (this.m_textures.length > 0) {
gl.deleteTexture(this.m_textures[0].getGLTexture());
this.m_textures.splice(0, 1);
}
};
/**
* @param {tcuTexture.CubeFace} face
* @return {string}
*/
es3fTextureFilteringTests.getFaceDesc = function(face) {
switch (face) {
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: return '-X';
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: return '+X';
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: return '-Y';
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: return '+Y';
case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: return '-Z';
case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: return '+Z';
default:
throw new Error('Invalid cube face specified');
}
};
/**
* @return {tcuTestCase.IterateResult}
*/
es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.iterate =
function() {
var viewportSize = 28;
/** @type {glsTextureTestUtil.RandomViewport} */
var viewport = new glsTextureTestUtil.RandomViewport(
gl.canvas, viewportSize,
viewportSize, deMath.binaryOp(
deString.deStringHash(this.fullName()),
deMath.deMathHash(this.m_caseNdx),
deMath.BinaryOp.XOR
)
);
bufferedLogToConsole('Test' + this.m_caseNdx);
/** @type {es3fTextureFilteringTests.
* TextureCubeFilteringCase.FilterCase}
*/
var curCase = this.m_cases[this.m_caseNdx];
/** @type {tcuTexture.TextureFormat} */
var texFmt = curCase.texture.getRefTexture().getFormat();
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
/** @type {glsTextureTestUtil.ReferenceParams} */
var sampleParams = new glsTextureTestUtil.ReferenceParams(
glsTextureTestUtil.textureType.TEXTURETYPE_CUBE
);
if (viewport.width < viewportSize || viewport.height < viewportSize)
throw new Error('Too small render target');
// Setup texture
gl.bindTexture(gl.TEXTURE_CUBE_MAP, curCase.texture.getGLTexture());
gl.texParameteri(
gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, this.m_minFilter
);
gl.texParameteri(
gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, this.m_magFilter
);
gl.texParameteri(
gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, this.m_wrapS
);
gl.texParameteri(
gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, this.m_wrapT
);
// Other state
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
// Params for reference computation.
sampleParams.sampler = gluTextureUtil.mapGLSamplerWrapST(
gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE,
this.m_minFilter, this.m_magFilter
);
sampleParams.sampler.seamlessCubeMap = true;
sampleParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
sampleParams.colorBias = fmtInfo.lookupBias;
sampleParams.colorScale = fmtInfo.lookupScale;
sampleParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
bufferedLogToConsole(
'Coordinates: ' + curCase.bottomLeft + ' -> ' + curCase.topRight
);
for (var faceNdx = 0;
faceNdx < Object.keys(tcuTexture.CubeFace).length;
faceNdx++) {
var face = /** @type {tcuTexture.CubeFace} */ (faceNdx);
/** @type {tcuSurface.Surface} */
var result = new tcuSurface.Surface(
viewport.width, viewport.height
);
/** @type {Array<number>} */ var texCoord;
texCoord = glsTextureTestUtil.computeQuadTexCoordCubeFace(
face, curCase.bottomLeft, curCase.topRight
);
bufferedLogToConsole(
'Face ' + es3fTextureFilteringTests.getFaceDesc(face)
);
// \todo Log texture coordinates.
this.m_renderer.renderQuad(0, texCoord, sampleParams);
result.readViewport(
gl, [viewport.x, viewport.y, viewport.width, viewport.height]
);
/** @type {boolean} */
var isNearestOnly = this.m_minFilter == gl.NEAREST &&
this.m_magFilter == gl.NEAREST;
/** @type {tcuPixelFormat.PixelFormat} */
var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
//(iVec4)
var colorBits = deMath.max(
deMath.addScalar(
glsTextureTestUtil.getBitsVec(pixelFormat),
// 1 inaccurate bit if nearest only, 2 otherwise
-1 * (isNearestOnly ? 1 : 2)
),
[0, 0, 0, 0]
);
/** @type {tcuTexLookupVerifier.LodPrecision} */
var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
/** @type {tcuTexLookupVerifier.LookupPrecision} */
var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
lodPrecision.derivateBits = 10;
lodPrecision.lodBits = 5;
lookupPrecision.colorThreshold = deMath.divide(
tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
sampleParams.colorScale
);
lookupPrecision.coordBits = [10, 10, 10];
lookupPrecision.uvwBits = [6, 6, 0];
lookupPrecision.colorMask =
glsTextureTestUtil.getCompareMask(pixelFormat);
var isHighQuality = glsTextureTestUtil.verifyTextureCubeResult(
result.getAccess(), curCase.texture.getRefTexture(),
texCoord, sampleParams, lookupPrecision, lodPrecision,
pixelFormat
);
if (!isHighQuality) {
// Evaluate against lower precision requirements.
lodPrecision.lodBits = 2;
lookupPrecision.uvwBits = [3, 3, 0];
bufferedLogToConsole('Warning: Verification against high ' +
'precision requirements failed, trying with lower ' +
'requirements.');
var isOk = glsTextureTestUtil.verifyTextureCubeResult(
result.getAccess(), curCase.texture.getRefTexture(),
texCoord, sampleParams, lookupPrecision, lodPrecision,
pixelFormat
);
if (!isOk) {
bufferedLogToConsole('ERROR: Verification against low' +
'precision requirements failed, failing test case.');
testFailedOptions('Image verification failed', false);
//In JS version, one mistake and you're out
return tcuTestCase.IterateResult.STOP;
} else
checkMessage(
false,
'Low-quality filtering result in iteration no. ' +
this.m_caseNdx
);
}
}
this.m_caseNdx += 1;
if (this.m_caseNdx < this.m_cases.length)
return tcuTestCase.IterateResult.CONTINUE;
testPassed('Verified');
return tcuTestCase.IterateResult.STOP;
};
// 2D array filtering
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
* @param {string} name
* @param {string} desc
* @param {number} minFilter
* @param {number} magFilter
* @param {number} wrapS
* @param {number} wrapT
* @param {number} internalFormat
* @param {number} width
* @param {number} height
* @param {number} numLayers
*/
es3fTextureFilteringTests.Texture2DArrayFilteringCase = function(
name, desc, minFilter, magFilter, wrapS, wrapT,
internalFormat, width, height, numLayers
) {
tcuTestCase.DeqpTest.call(this, name, desc);
this.m_minFilter = minFilter;
this.m_magFilter = magFilter;
this.m_wrapS = wrapS;
this.m_wrapT = wrapT;
this.m_internalFormat = internalFormat;
this.m_width = width;
this.m_height = height;
this.m_numLayers = numLayers;
this.m_gradientTex = null;
this.m_gridTex = null;
/** @type {glsTextureTestUtil.TextureRenderer} */
this.m_renderer = new glsTextureTestUtil.TextureRenderer(
es3fTextureFilteringTests.version,
gluShaderUtil.precision.PRECISION_HIGHP
);
this.m_textures = [];
this.m_caseNdx = 0;
this.m_cases = [];
};
es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.
constructor = es3fTextureFilteringTests.Texture2DArrayFilteringCase;
/**
* @constructor
* @param {gluTexture.Texture2DArray} tex_
* @param {Array<number>} lod_
* @param {Array<number>} offset_
* @param {Array<number>} layerRange_
*/
es3fTextureFilteringTests.Texture2DArrayFilteringCase.FilterCase =
function(
tex_, lod_, offset_, layerRange_
) {
this.texture = tex_;
this.lod = lod_;
this.offset = offset_;
this.layerRange = layerRange_;
};
/*
* init
*/
es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.init =
function() {
try {
/** @type {tcuTexture.TextureFormat} */
var texFmt = gluTextureUtil.mapGLInternalFormat(
this.m_internalFormat
);
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
var cScale = deMath.subtract(
fmtInfo.valueMax, fmtInfo.valueMin
);
var cBias = fmtInfo.valueMin;
var numLevels = deMath.logToFloor(
Math.max(this.m_width, this.m_height)
) + 1;
// Create textures.
this.m_gradientTex = gluTexture.texture2DArrayFromInternalFormat(
gl,
this.m_internalFormat, this.m_width,
this.m_height, this.m_numLayers
);
this.m_gridTex = gluTexture.texture2DArrayFromInternalFormat(
gl,
this.m_internalFormat, this.m_width,
this.m_height, this.m_numLayers
);
var levelSwz = [
[0, 1, 2, 3],
[2, 1, 3, 0],
[3, 0, 1, 2],
[1, 3, 2, 0]
];
// Fill first gradient texture
// (gradient direction varies between layers).
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
this.m_gradientTex.getRefTexture().allocLevel(levelNdx);
var levelBuf =
this.m_gradientTex.getRefTexture().getLevel(levelNdx);
for (var layerNdx = 0;
layerNdx < this.m_numLayers;
layerNdx++) {
var swz = levelSwz[layerNdx % levelSwz.length];
var gMin = deMath.add(deMath.multiply(deMath.swizzle(
[0.0, 0.0, 0.0, 1.0], [swz[0], swz[1], swz[2], swz[3]]
), cScale), cBias);
var gMax = deMath.add(deMath.multiply(deMath.swizzle(
[1.0, 1.0, 1.0, 0.0], [swz[0], swz[1], swz[2], swz[3]]
), cScale), cBias);
tcuTextureUtil.fillWithComponentGradients2D(
tcuTextureUtil.getSubregion(
levelBuf, 0, 0, layerNdx, levelBuf.getWidth(),
levelBuf.getHeight(), 1
), gMin, gMax
);
}
}
// Fill second with grid texture (each layer has unique colors).
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
this.m_gridTex.getRefTexture().allocLevel(levelNdx);
/** @type {tcuTexture.PixelBufferAccess} */ var levelBuf =
this.m_gridTex.getRefTexture().getLevel(levelNdx);
for (
var layerNdx = 0;
layerNdx < this.m_numLayers;
layerNdx++) {
var step = 0x00ffffff / (numLevels * this.m_numLayers - 1);
var rgb = step * (levelNdx + layerNdx * numLevels);
/** @type {number} */ var colorA = deMath.binaryOp(
0xff000000, rgb, deMath.BinaryOp.OR
);
/** @type {number} */ var colorB = deMath.binaryOp(
0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
);
tcuTextureUtil.fillWithGrid(
tcuTextureUtil.getSubregion(
levelBuf, 0, 0, layerNdx, levelBuf.getWidth(),
levelBuf.getHeight(), 1
), 4,
deMath.add(
deMath.multiply(
tcuRGBA.newRGBAFromValue(colorA).toVec(),
cScale
), cBias
),
deMath.add(
deMath.multiply(
tcuRGBA.newRGBAFromValue(colorB).toVec(),
cScale
), cBias
)
);
}
}
// Upload.
this.m_gradientTex.upload();
this.m_gridTex.upload();
// Test cases
this.m_cases.push(
new es3fTextureFilteringTests.
Texture2DArrayFilteringCase.FilterCase(
this.m_gradientTex, [1.5, 2.8], [-1.0, -2.7],
[-0.5, this.m_numLayers + 0.5]
)
);
this.m_cases.push(
new es3fTextureFilteringTests.
Texture2DArrayFilteringCase.FilterCase(
this.m_gridTex, [0.2, 0.175], [-2.0, -3.7],
[-0.5, this.m_numLayers + 0.5]
)
);
this.m_cases.push(
new es3fTextureFilteringTests.
Texture2DArrayFilteringCase.FilterCase(
this.m_gridTex, [-0.8, -2.3], [0.2, -0.1],
[this.m_numLayers + 0.5, -0.5]
)
);
// Level rounding - only in single-sample configs as
// multisample configs may produce smooth transition at the middle.
if (gl.getParameter(gl.SAMPLES) == 0)
this.m_cases.push(
new es3fTextureFilteringTests.
Texture2DArrayFilteringCase.FilterCase(
this.m_gradientTex, [-2.0, -1.5], [-0.1, 0.9],
[1.50001, 1.49999]
)
);
this.m_caseNdx = 0;
}
catch (e) {
// Clean up to save memory.
this.deinit();
throw e;
}
};
/**
* deinit
*/
es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.deinit =
function() {
if (this.m_gradientTex)
gl.deleteTexture(this.m_gradientTex.getGLTexture());
if (this.m_gridTex)
gl.deleteTexture(this.m_gridTex.getGLTexture());
this.m_gradientTex = null;
this.m_gridTex = null;
};
/**
* iterate
* @return {tcuTestCase.IterateResult}
*/
es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.iterate =
function() {
/** @type {glsTextureTestUtil.RandomViewport} */
var viewport = new glsTextureTestUtil.RandomViewport(
gl.canvas, TEX3D_VIEWPORT_WIDTH,
TEX3D_VIEWPORT_HEIGHT, deMath.binaryOp(
deString.deStringHash(this.fullName()),
deMath.deMathHash(this.m_caseNdx),
deMath.BinaryOp.XOR
)
);
/** @type {es3fTextureFilteringTests.Texture2DArrayFilteringCase.
* FilterCase} */ var curCase = this.m_cases[this.m_caseNdx];
/** @type {tcuTexture.TextureFormat} */
var texFmt = curCase.texture.getRefTexture().getFormat();
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
bufferedLogToConsole('Test' + this.m_caseNdx);
/** @type {glsTextureTestUtil.ReferenceParams} */
var refParams = new glsTextureTestUtil.ReferenceParams(
glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY
);
/** @type {tcuSurface.Surface} */
var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH ||
viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
throw new Error('Too small render target');
// Setup params for reference.
refParams.sampler = gluTextureUtil.mapGLSampler(
this.m_wrapS, this.m_wrapT, this.m_wrapT,
this.m_minFilter, this.m_magFilter
);
refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
refParams.colorBias = fmtInfo.lookupBias;
refParams.colorScale = fmtInfo.lookupScale;
// Compute texture coordinates.
bufferedLogToConsole(
'Approximate lod per axis = ' + curCase.lod +
', offset = ' + curCase.offset
);
/** @type {number} */ var lodX = curCase.lod[0];
/** @type {number} */ var lodY = curCase.lod[1];
/** @type {number} */ var oX = curCase.offset[0];
/** @type {number} */ var oY = curCase.offset[1];
/** @type {number} */ var sX = Math.pow(2, lodX) * viewport.width /
this.m_gradientTex.getRefTexture().getWidth();
/** @type {number} */ var sY = Math.pow(2, lodY) * viewport.height /
this.m_gradientTex.getRefTexture().getHeight();
/** @type {number} */ var l0 = curCase.layerRange[0];
/** @type {number} */ var l1 = curCase.layerRange[1];
/** @type {Array<number>}*/
var texCoord = [
oX, oY, l0,
oX, oY + sY, l0 * 0.5 + l1 * 0.5,
oX + sX, oY, l0 * 0.5 + l1 * 0.5,
oX + sX, oY + sY, l1
];
gl.bindTexture(gl.TEXTURE_2D_ARRAY, curCase.texture.getGLTexture());
gl.texParameteri(
gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, this.m_minFilter
);
gl.texParameteri(
gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, this.m_magFilter
);
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, this.m_wrapS);
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, this.m_wrapT);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
this.m_renderer.renderQuad(
0, texCoord,
refParams
);
rendered.readViewport(
gl, [viewport.x, viewport.y, viewport.width, viewport.height]
);
/** @type {boolean} */
var isNearestOnly = this.m_minFilter == gl.NEAREST &&
this.m_magFilter == gl.NEAREST;
/** @type {tcuPixelFormat.PixelFormat} */
var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
//(iVec4)
var colorBits = deMath.max(
deMath.addScalar(
glsTextureTestUtil.getBitsVec(pixelFormat),
// 1 inaccurate bit if nearest only, 2 otherwise
-1 * (isNearestOnly ? 1 : 2)
),
[0, 0, 0, 0]
);
/** @type {tcuTexLookupVerifier.LodPrecision} */
var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
/** @type {tcuTexLookupVerifier.LookupPrecision} */
var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
lodPrecision.derivateBits = 18;
lodPrecision.lodBits = 6;
lookupPrecision.colorThreshold = deMath.divide(
tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
refParams.colorScale
);
lookupPrecision.coordBits = [20, 20, 20];
lookupPrecision.uvwBits = [7, 7, 0];
lookupPrecision.colorMask =
glsTextureTestUtil.getCompareMask(pixelFormat);
var isHighQuality = glsTextureTestUtil.verifyTexture2DArrayResult(
rendered.getAccess(), curCase.texture.getRefTexture().getView(),
texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat);
if (!isHighQuality) {
// Evaluate against lower precision requirements.
lodPrecision.lodBits = 3;
lookupPrecision.uvwBits = [3, 3, 0];
bufferedLogToConsole(
'Warning: Verification against high ' +
'precision requirements failed, ' +
'trying with lower requirements.'
);
var isOk = glsTextureTestUtil.verifyTexture2DArrayResult(
rendered.getAccess(), curCase.texture.getRefTexture().getView(),
texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
);
if (!isOk) {
bufferedLogToConsole(
'ERROR: Verification against low precision requirements ' +
'failed, failing test case.'
);
testFailedOptions('Image verification failed', false);
//In JS version, one mistake and you're out
return tcuTestCase.IterateResult.STOP;
} else
checkMessage(
false,
'Low-quality filtering result in iteration no. ' +
this.m_caseNdx
);
}
this.m_caseNdx += 1;
if (this.m_caseNdx < this.m_cases.length)
return tcuTestCase.IterateResult.CONTINUE;
testPassed('Verified');
return tcuTestCase.IterateResult.STOP;
};
// 3D filtering
/**
* @constructor
* @extends {tcuTestCase.DeqpTest}
* @param {string} name
* @param {string} desc
* @param {number} minFilter
* @param {number} magFilter
* @param {number} wrapS
* @param {number} wrapT
* @param {number} wrapR
* @param {number} internalFormat
* @param {number} width
* @param {number} height
* @param {number} depth
*/
es3fTextureFilteringTests.Texture3DFilteringCase = function(
name, desc, minFilter, magFilter, wrapS, wrapT, wrapR, internalFormat,
width, height, depth
) {
tcuTestCase.DeqpTest.call(this, name, desc);
this.m_minFilter = minFilter;
this.m_magFilter = magFilter;
this.m_wrapS = wrapS;
this.m_wrapT = wrapT;
this.m_wrapR = wrapR;
this.m_internalFormat = internalFormat;
this.m_width = width;
this.m_height = height;
this.m_depth = depth;
this.m_gradientTex = null;
this.m_gridTex = null;
/** @type {glsTextureTestUtil.TextureRenderer} */
this.m_renderer = new glsTextureTestUtil.TextureRenderer(
es3fTextureFilteringTests.version,
gluShaderUtil.precision.PRECISION_HIGHP
);
this.m_caseNdx = 0;
this.m_cases = [];
};
es3fTextureFilteringTests.Texture3DFilteringCase.prototype =
Object.create(tcuTestCase.DeqpTest.prototype);
es3fTextureFilteringTests.Texture3DFilteringCase.prototype.constructor =
es3fTextureFilteringTests.Texture3DFilteringCase;
/**
* @constructor
* @param {gluTexture.Texture3D} tex_
* @param {Array<number>} lod_
* @param {Array<number>} offset_
*/
es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase = function(
tex_, lod_, offset_
) {
this.texture = tex_;
this.lod = lod_;
this.offset = offset_;
};
/**
* init
*/
es3fTextureFilteringTests.Texture3DFilteringCase.prototype.init = function(
) {
try {
/** @type {tcuTexture.TextureFormat} */
var texFmt =
gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
var cScale = deMath.subtract(
fmtInfo.valueMax, fmtInfo.valueMin
);
var cBias = fmtInfo.valueMin;
var numLevels = deMath.logToFloor(
Math.max(Math.max(this.m_width, this.m_height), this.m_depth)
) + 1;
// Create textures.
this.m_gradientTex = gluTexture.texture3DFromInternalFormat(
gl, this.m_internalFormat,
this.m_width, this.m_height, this.m_depth
);
this.m_gridTex = gluTexture.texture3DFromInternalFormat(
gl, this.m_internalFormat,
this.m_width, this.m_height, this.m_depth
);
// Fill first gradient texture.
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
var gMin = deMath.add(
deMath.multiply([0.0, 0.0, 0.0, 1.0], cScale), cBias
);
var gMax = deMath.add(
deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias
);
this.m_gradientTex.getRefTexture().allocLevel(levelNdx);
tcuTextureUtil.fillWithComponentGradients(
this.m_gradientTex.getRefTexture().getLevel(levelNdx),
gMin, gMax
);
}
// Fill second with grid texture.
for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
/** @type {number} */ var step = 0x00ffffff / numLevels;
/** @type {number} */ var rgb = step * levelNdx;
/** @type {number} */ var colorA = deMath.binaryOp(
0xff000000, rgb, deMath.BinaryOp.OR
);
/** @type {number} */ var colorB = deMath.binaryOp(
0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
);
this.m_gridTex.getRefTexture().allocLevel(levelNdx);
tcuTextureUtil.fillWithGrid(
this.m_gridTex.getRefTexture().getLevel(levelNdx), 4,
deMath.add(
deMath.multiply(
tcuRGBA.newRGBAFromValue(colorA).toVec(),
cScale
),
cBias
),
deMath.add(
deMath.multiply(
tcuRGBA.newRGBAFromValue(colorB).toVec(),
cScale
),
cBias
)
);
}
// Upload.
this.m_gradientTex.upload();
this.m_gridTex.upload();
// Test cases
this.m_cases.push(
new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
this.m_gradientTex, [1.5, 2.8, 1.0], [-1.0, -2.7, -2.275]
)
);
this.m_cases.push(
new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
this.m_gradientTex, [-2.0, -1.5, -1.8], [-0.1, 0.9, -0.25]
)
);
this.m_cases.push(
new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
this.m_gridTex, [0.2, 0.175, 0.3], [-2.0, -3.7, -1.825]
)
);
this.m_cases.push(
new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
this.m_gridTex, [-0.8, -2.3, -2.5], [0.2, -0.1, 1.325]
)
);
this.m_caseNdx = 0;
}
catch (e) {
// Clean up to save memory.
this.deinit();
throw e;
}
};
/**
* deinit
*/
es3fTextureFilteringTests.Texture3DFilteringCase.prototype.deinit =
function() {
if (this.m_gradientTex)
gl.deleteTexture(this.m_gradientTex.getGLTexture());
if (this.m_gridTex)
gl.deleteTexture(this.m_gridTex.getGLTexture());
this.m_gradientTex = null;
this.m_gridTex = null;
};
/**
* @return {tcuTestCase.IterateResult}
*/
es3fTextureFilteringTests.Texture3DFilteringCase.prototype.iterate =
function() {
/** @type {glsTextureTestUtil.RandomViewport} */
var viewport = new glsTextureTestUtil.RandomViewport(
gl.canvas, TEX3D_VIEWPORT_WIDTH,
TEX3D_VIEWPORT_HEIGHT, deMath.binaryOp(
deString.deStringHash(this.fullName()),
deMath.deMathHash(this.m_caseNdx),
deMath.BinaryOp.XOR
)
);
/** @type {es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase}
*/ var curCase = this.m_cases[this.m_caseNdx];
/** @type {tcuTexture.TextureFormat} */
var texFmt = curCase.texture.getRefTexture().getFormat();
/** @type {tcuTextureUtil.TextureFormatInfo} */
var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
bufferedLogToConsole('Test' + this.m_caseNdx);
/** @type {glsTextureTestUtil.ReferenceParams} */
var refParams = new glsTextureTestUtil.ReferenceParams(
glsTextureTestUtil.textureType.TEXTURETYPE_3D
);
/** @type {tcuSurface.Surface} */
var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
/** @type {Array<number>}*/
var texCoord = [];
if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH ||
viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
throw new Error('Too small render target');
// Setup params for reference.
refParams.sampler = gluTextureUtil.mapGLSampler(
this.m_wrapS, this.m_wrapT, this.m_wrapR,
this.m_minFilter, this.m_magFilter
);
// Setup params for reference.
refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
refParams.colorBias = fmtInfo.lookupBias;
refParams.colorScale = fmtInfo.lookupScale;
// Compute texture coordinates.
bufferedLogToConsole('Approximate lod per axis = ' + curCase.lod +
', offset = ' + curCase.offset);
/** @type {number} */ var lodX = curCase.lod[0];
/** @type {number} */ var lodY = curCase.lod[1];
/** @type {number} */ var lodZ = curCase.lod[2];
/** @type {number} */ var oX = curCase.offset[0];
/** @type {number} */ var oY = curCase.offset[1];
/** @type {number} */ var oZ = curCase.offset[2];
/** @type {number} */ var sX = Math.pow(2, lodX) * viewport.width /
this.m_gradientTex.getRefTexture().getWidth();
/** @type {number} */ var sY = Math.pow(2, lodY) * viewport.height /
this.m_gradientTex.getRefTexture().getHeight();
/** @type {number} */ var sZ = Math.pow(2, lodZ) *
Math.max(viewport.width, viewport.height) /
this.m_gradientTex.getRefTexture().getDepth();
texCoord[0] = oX; texCoord[1] = oY; texCoord[2] = oZ;
texCoord[3] = oX; texCoord[4] = oY + sY; texCoord[5] = oZ + sZ * 0.5;
texCoord[6] = oX + sX; texCoord[7] = oY; texCoord[8] = oZ + sZ * 0.5;
texCoord[9] = oX + sX; texCoord[10] = oY + sY; texCoord[11] = oZ + sZ;
gl.bindTexture(gl.TEXTURE_3D, curCase.texture.getGLTexture());
gl.texParameteri(
gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, this.m_minFilter
);
gl.texParameteri(
gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, this.m_magFilter
);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, this.m_wrapS);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, this.m_wrapT);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, this.m_wrapR);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
this.m_renderer.renderQuad(0, texCoord, refParams);
rendered.readViewport(
gl, [viewport.x, viewport.y, viewport.width, viewport.height]
);
var isNearestOnly = this.m_minFilter == gl.NEAREST &&
this.m_magFilter == gl.NEAREST;
/** @type {tcuPixelFormat.PixelFormat} */
var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
//(iVec4)
var colorBits = deMath.max(
deMath.addScalar(
glsTextureTestUtil.getBitsVec(pixelFormat),
// 1 inaccurate bit if nearest only, 2 otherwise
-1 * (isNearestOnly ? 1 : 2)
),
[0, 0, 0, 0]
);
/** @type {tcuTexLookupVerifier.LodPrecision} */
var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
/** @type {tcuTexLookupVerifier.LookupPrecision} */
var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
lodPrecision.derivateBits = 18;
lodPrecision.lodBits = 6;
lookupPrecision.colorThreshold = deMath.divide(
tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
refParams.colorScale
);
lookupPrecision.coordBits = [20, 20, 20];
lookupPrecision.uvwBits = [7, 7, 7];
lookupPrecision.colorMask =
glsTextureTestUtil.getCompareMask(pixelFormat);
var isHighQuality = glsTextureTestUtil.verifyTexture3DResult(
rendered.getAccess(), curCase.texture.getRefTexture(),
texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
);
if (!isHighQuality) {
// Evaluate against lower precision requirements.
lodPrecision.lodBits = 4;
lookupPrecision.uvwBits = [4, 4, 4];
bufferedLogToConsole(
'Warning: Verification against high precision ' +
'requirements failed, trying with lower requirements.'
);
var isOk = glsTextureTestUtil.verifyTexture3DResult(
rendered.getAccess(), curCase.texture.getRefTexture(),
texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
);
if (!isOk) {
bufferedLogToConsole('ERROR: Verification against low ' +
'precision requirements failed, failing test case.'
);
testFailedOptions('Image verification failed', false);
//In JS version, one mistake and you're out
return tcuTestCase.IterateResult.STOP;
} else
checkMessage(
false,
'Low-quality filtering result in iteration no. ' +
this.m_caseNdx
);
}
this.m_caseNdx += 1;
if (this.m_caseNdx < this.m_cases.length)
return tcuTestCase.IterateResult.CONTINUE;
testPassed('Verified');
return tcuTestCase.IterateResult.STOP;
};
/** @typedef {{name: string, mode: number}} */
es3fTextureFilteringTests.WrapMode;
/** @typedef {{name: string, mode: number}} */
es3fTextureFilteringTests.MinFilterMode;
/** @typedef {{name: string, mode: number}} */
es3fTextureFilteringTests.MagFilterModes;
/** @typedef {{width: number, height: number}} */
es3fTextureFilteringTests.Sizes2D;
/** @typedef {{width: number, height: number}} */
es3fTextureFilteringTests.SizesCube;
/** @typedef {{width: number, height: number, numLayers: number}} */
es3fTextureFilteringTests.Sizes2DArray;
/** @typedef {{width: number, height: number, depth: number}} */
es3fTextureFilteringTests.Sizes3D;
/** @typedef {{name: string, format: number}} */
es3fTextureFilteringTests.FilterableFormatsByType;
/**
* init
*/
es3fTextureFilteringTests.TextureFilteringTests.prototype.init =
function() {
/** @type {Array<es3fTextureFilteringTests.WrapMode>} */
var wrapModes = [{
name: 'clamp', mode: gl.CLAMP_TO_EDGE
}, {
name: 'repeat', mode: gl.REPEAT
}, {
name: 'mirror', mode: gl.MIRRORED_REPEAT
}
];
/** @type {Array<es3fTextureFilteringTests.MinFilterMode>} */
var minFilterModes = [{
name: 'nearest', mode: gl.NEAREST
}, {
name: 'linear', mode: gl.LINEAR
}, {
name: 'nearest_mipmap_nearest', mode: gl.NEAREST_MIPMAP_NEAREST
}, {
name: 'linear_mipmap_nearest', mode: gl.LINEAR_MIPMAP_NEAREST
}, {
name: 'nearest_mipmap_linear', mode: gl.NEAREST_MIPMAP_LINEAR
}, {
name: 'linear_mipmap_linear', mode: gl.LINEAR_MIPMAP_LINEAR
}
];
/** @type {Array<es3fTextureFilteringTests.MagFilterModes>} */
var magFilterModes = [{
name: 'nearest', mode: gl.NEAREST
}, {
name: 'linear', mode: gl.LINEAR
}
];
/** @type {Array<es3fTextureFilteringTests.Sizes2D>} */
var sizes2D = [{
width: 4, height: 8
}, {
width: 32, height: 64
}, {
width: 128, height: 128
}, {
width: 3, height: 7
}, {
width: 31, height: 55
}, {
width: 127, height: 99
}
];
/** @type {Array<es3fTextureFilteringTests.SizesCube>} */
var sizesCube = [{
width: 8, height: 8
}, {
width: 64, height: 64
}, {
width: 128, height: 128
}, {
width: 7, height: 7
}, {
width: 63, height: 63
}
];
/** @type {Array<es3fTextureFilteringTests.Sizes2DArray>} */
var sizes2DArray = [{
width: 4, height: 8, numLayers: 8
}, {
width: 32, height: 64, numLayers: 16
}, {
width: 128, height: 32, numLayers: 64
}, {
width: 3, height: 7, numLayers: 5
}, {
width: 63, height: 63, numLayers: 63
}
];
/** @type {Array<es3fTextureFilteringTests.Sizes3D>} */
var sizes3D = [{
width: 4, height: 8, depth: 8
}, {
width: 32, height: 64, depth: 16
}, {
width: 128, height: 32, depth: 64
}, {
width: 3, height: 7, depth: 5
}, {
width: 63, height: 63, depth: 63
}
];
/** @type {Array<es3fTextureFilteringTests.FilterableFormatsByType>} */
var filterableFormatsByType = [{
name: 'rgba16f', format: gl.RGBA16F
}, {
name: 'r11f_g11f_b10f', format: gl.R11F_G11F_B10F
}, {
name: 'rgb9_e5', format: gl.RGB9_E5
}, {
name: 'rgba8', format: gl.RGBA8
}, {
name: 'rgba8_snorm', format: gl.RGBA8_SNORM
}, {
name: 'rgb565', format: gl.RGB565
}, {
name: 'rgba4', format: gl.RGBA4
}, {
name: 'rgb5_a1', format: gl.RGB5_A1
}, {
name: 'srgb8_alpha8', format: gl.SRGB8_ALPHA8
}, {
name: 'rgb10_a2', format: gl.RGB10_A2
}
];
// 2D texture filtering.
// Formats.
/** @type {tcuTestCase.DeqpTest} */
var formatsGroup;
for (var fmtNdx = 0;
fmtNdx < filterableFormatsByType.length;
fmtNdx++) {
formatsGroup = new tcuTestCase.DeqpTest(
'2d_formats', '2D Texture Formats');
this.addChild(formatsGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
/** @type {number} */
var minFilter = minFilterModes[filterNdx].mode;
/** @type {string} */
var filterName = minFilterModes[filterNdx].name;
/** @type {number} */
var format = filterableFormatsByType[fmtNdx].format;
/** @type {string} */
var formatName = filterableFormatsByType[fmtNdx].name;
var isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
/** @type {number} */
var magFilter = isMipmap ? gl.LINEAR : minFilter;
/** @type {string} */
var name = formatName + '_' + filterName;
/** @type {number} */
var wrapS = gl.REPEAT;
/** @type {number} */
var wrapT = gl.REPEAT;
/** @type {number} */ var width = 64;
/** @type {number} */ var height = 64;
formatsGroup.addChild(
new es3fTextureFilteringTests.Texture2DFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
format, width, height
)
);
}
}
// Sizes.
/** @type {tcuTestCase.DeqpTest} */
var sizesGroup;
for (var sizeNdx = 0; sizeNdx < sizes2D.length; sizeNdx++) {
sizesGroup = new tcuTestCase.DeqpTest(
'2d_sizes', '2D Texture Sizes');
this.addChild(sizesGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
format = gl.RGBA8;
isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
magFilter = isMipmap ? gl.LINEAR : minFilter;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
width = sizes2D[sizeNdx].width;
height = sizes2D[sizeNdx].height;
name = '' + width + 'x' + height + '_' + filterName;
sizesGroup.addChild(
new es3fTextureFilteringTests.Texture2DFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
format, width, height
)
);
}
}
// Wrap modes.
/** @type {tcuTestCase.DeqpTest} */
var combinationsGroup;
for (var minFilterNdx = 0;
minFilterNdx < minFilterModes.length;
minFilterNdx++) {
combinationsGroup = new tcuTestCase.DeqpTest(
'2d_combinations', '2D Filter and wrap mode combinations');
this.addChild(combinationsGroup);
for (var magFilterNdx = 0;
magFilterNdx < magFilterModes.length;
magFilterNdx++) {
for (var wrapSNdx = 0;
wrapSNdx < wrapModes.length;
wrapSNdx++) {
for (var wrapTNdx = 0;
wrapTNdx < wrapModes.length;
wrapTNdx++) {
minFilter = minFilterModes[minFilterNdx].mode;
magFilter = magFilterModes[magFilterNdx].mode;
format = gl.RGBA8;
wrapS = wrapModes[wrapSNdx].mode;
wrapT = wrapModes[wrapTNdx].mode;
width = 63;
height = 57;
name = minFilterModes[minFilterNdx].name + '_' +
magFilterModes[magFilterNdx].name + '_' +
wrapModes[wrapSNdx].name + '_' +
wrapModes[wrapTNdx].name;
combinationsGroup.addChild(
new
es3fTextureFilteringTests.Texture2DFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
format, width, height
)
);
}
}
}
}
// Cube map texture filtering.
// Formats.
for (var fmtNdx = 0;
fmtNdx < filterableFormatsByType.length;
fmtNdx++) {
formatsGroup = new tcuTestCase.DeqpTest(
'cube_formats', 'Cube Texture Formats');
this.addChild(formatsGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
format = filterableFormatsByType[fmtNdx].format;
formatName = filterableFormatsByType[fmtNdx].name;
isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
magFilter = isMipmap ? gl.LINEAR : minFilter;
name = formatName + '_' + filterName;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
width = 64;
height = 64;
formatsGroup.addChild(
new es3fTextureFilteringTests.TextureCubeFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
false /* always sample exterior as well */,
format, width, height
)
);
}
}
// Sizes.
for (var sizeNdx = 0; sizeNdx < sizesCube.length; sizeNdx++) {
sizesGroup = new tcuTestCase.DeqpTest(
'cube_sizes', 'Cube Texture Sizes');
this.addChild(sizesGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
var format = gl.RGBA8;
isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
magFilter = isMipmap ? gl.LINEAR : minFilter;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
width = sizesCube[sizeNdx].width;
height = sizesCube[sizeNdx].height;
name = '' + width + 'x' + height + '_' + filterName;
sizesGroup.addChild(
new es3fTextureFilteringTests.TextureCubeFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
false, format, width, height
)
);
}
}
// Filter/wrap mode combinations.
for (var minFilterNdx = 0;
minFilterNdx < minFilterModes.length;
minFilterNdx++) {
combinationsGroup = new tcuTestCase.DeqpTest(
'cube_combinations', 'Cube Filter and wrap mode combinations'
);
this.addChild(combinationsGroup);
for (var magFilterNdx = 0;
magFilterNdx < magFilterModes.length;
magFilterNdx++) {
for (var wrapSNdx = 0;
wrapSNdx < wrapModes.length;
wrapSNdx++) {
for (var wrapTNdx = 0;
wrapTNdx < wrapModes.length;
wrapTNdx++) {
minFilter = minFilterModes[minFilterNdx].mode;
magFilter = magFilterModes[magFilterNdx].mode;
format = gl.RGBA8;
wrapS = wrapModes[wrapSNdx].mode;
wrapT = wrapModes[wrapTNdx].mode;
width = 63;
height = 63;
name = minFilterModes[minFilterNdx].name + '_' +
magFilterModes[magFilterNdx].name + '_' +
wrapModes[wrapSNdx].name + '_' +
wrapModes[wrapTNdx].name;
combinationsGroup.addChild(
new es3fTextureFilteringTests.
TextureCubeFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
false, format, width, height
)
);
}
}
}
}
// Cases with no visible cube edges.
/** @type {tcuTestCase.DeqpTest} */
var onlyFaceInteriorGroup = new tcuTestCase.DeqpTest(
'cube_no_edges_visible', "Don't sample anywhere near a face's edges"
);
this.addChild(onlyFaceInteriorGroup);
for (var isLinearI = 0; isLinearI <= 1; isLinearI++) {
var isLinear = isLinearI != 0;
var filter = isLinear ? gl.LINEAR : gl.NEAREST;
onlyFaceInteriorGroup.addChild(
new es3fTextureFilteringTests.TextureCubeFilteringCase(
isLinear ? 'linear' : 'nearest', '',
filter, filter, gl.REPEAT, gl.REPEAT,
true, gl.RGBA8, 63, 63
)
);
}
// Formats.
for (var fmtNdx = 0;
fmtNdx < filterableFormatsByType.length;
fmtNdx++) {
formatsGroup = new tcuTestCase.DeqpTest(
'2d_array_formats', '2D Array Texture Formats');
this.addChild(formatsGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
format = filterableFormatsByType[fmtNdx].format;
var formatName = filterableFormatsByType[fmtNdx].name;
isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
magFilter = isMipmap ? gl.LINEAR : minFilter;
name = formatName + '_' + filterName;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
width = 128;
height = 128;
/** @type {number} */ var numLayers = 8;
formatsGroup.addChild(
new es3fTextureFilteringTests.Texture2DArrayFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
format, width, height, numLayers
)
);
}
}
// Sizes.
for (var sizeNdx = 0; sizeNdx < sizes2DArray.length; sizeNdx++) {
sizesGroup = new tcuTestCase.DeqpTest(
'2d_array_sizes', '2D Array Texture Sizes');
this.addChild(sizesGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
format = gl.RGBA8;
isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
magFilter = isMipmap ? gl.LINEAR : minFilter;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
width = sizes2DArray[sizeNdx].width;
height = sizes2DArray[sizeNdx].height;
numLayers = sizes2DArray[sizeNdx].numLayers;
name = '' + width + 'x' + height + 'x' +
numLayers + '_' + filterName;
sizesGroup.addChild(
new es3fTextureFilteringTests.Texture2DArrayFilteringCase(
name, '', minFilter, magFilter, wrapS, wrapT,
format, width, height, numLayers
)
);
}
}
// Wrap modes.
for (var minFilterNdx = 0;
minFilterNdx < minFilterModes.length;
minFilterNdx++) {
combinationsGroup = new tcuTestCase.DeqpTest(
'2d_array_combinations',
'2D Array Filter and wrap mode combinations');
this.addChild(combinationsGroup);
for (var magFilterNdx = 0;
magFilterNdx < magFilterModes.length;
magFilterNdx++) {
for (var wrapSNdx = 0;
wrapSNdx < wrapModes.length;
wrapSNdx++) {
for (var wrapTNdx = 0;
wrapTNdx < wrapModes.length;
wrapTNdx++) {
minFilter = minFilterModes[minFilterNdx].mode;
magFilter = magFilterModes[magFilterNdx].mode;
format = gl.RGBA8;
wrapS = wrapModes[wrapSNdx].mode;
wrapT = wrapModes[wrapTNdx].mode;
width = 123;
height = 107;
numLayers = 7;
name = minFilterModes[minFilterNdx].name + '_' +
magFilterModes[magFilterNdx].name + '_' +
wrapModes[wrapSNdx].name + '_' +
wrapModes[wrapTNdx].name;
combinationsGroup.addChild(
new es3fTextureFilteringTests.
Texture2DArrayFilteringCase(
name, '', minFilter, magFilter,
wrapS, wrapT, format,
width, height, numLayers
)
);
}
}
}
}
// 3D texture filtering.
// Formats.
/** @type {number} */ var depth = 64;
for (var fmtNdx = 0;
fmtNdx < filterableFormatsByType.length;
fmtNdx++) {
formatsGroup = new tcuTestCase.DeqpTest(
'3d_formats', '3D Texture Formats');
this.addChild(formatsGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
format = filterableFormatsByType[fmtNdx].format;
formatName = filterableFormatsByType[fmtNdx].name;
isMipmap = minFilter != gl.NEAREST &&
minFilter != gl.LINEAR;
magFilter = isMipmap ? gl.LINEAR : minFilter;
name = formatName + '_' + filterName;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
/** @type {number} */ var wrapR = gl.REPEAT;
width = 64;
height = 64;
depth = 64;
formatsGroup.addChild(
new es3fTextureFilteringTests.Texture3DFilteringCase(
name, '', minFilter, magFilter,
wrapS, wrapT, wrapR, format,
width, height, depth
)
);
}
}
// Sizes.
for (var sizeNdx = 0; sizeNdx < sizes3D.length; sizeNdx++) {
sizesGroup = new tcuTestCase.DeqpTest(
'3d_sizes', '3D Texture Sizes');
this.addChild(sizesGroup);
for (var filterNdx = 0;
filterNdx < minFilterModes.length;
filterNdx++) {
minFilter = minFilterModes[filterNdx].mode;
filterName = minFilterModes[filterNdx].name;
format = gl.RGBA8;
isMipmap =
minFilter != gl.NEAREST && minFilter != gl.LINEAR;
magFilter =
isMipmap ? gl.LINEAR : minFilter;
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
wrapR = gl.REPEAT;
width = sizes3D[sizeNdx].width;
height = sizes3D[sizeNdx].height;
depth = sizes3D[sizeNdx].depth;
name = '' + width + 'x' + height + 'x' + depth +
'_' + filterName;
sizesGroup.addChild(
new es3fTextureFilteringTests.Texture3DFilteringCase(
name, '', minFilter, magFilter,
wrapS, wrapT, wrapR, format,
width, height, depth
)
);
}
}
// Wrap modes.
for (var minFilterNdx = 0;
minFilterNdx < minFilterModes.length;
minFilterNdx++) {
for (var magFilterNdx = 0;
magFilterNdx < magFilterModes.length;
magFilterNdx++) {
for (var wrapSNdx = 0;
wrapSNdx < wrapModes.length;
wrapSNdx++) {
combinationsGroup = new tcuTestCase.DeqpTest(
'3d_combinations',
'3D Filter and wrap mode combinations');
this.addChild(combinationsGroup);
for (var wrapTNdx = 0;
wrapTNdx < wrapModes.length;
wrapTNdx++) {
for (var wrapRNdx = 0;
wrapRNdx < wrapModes.length;
wrapRNdx++) {
minFilter = minFilterModes[minFilterNdx].mode;
magFilter = magFilterModes[magFilterNdx].mode;
format = gl.RGBA8;
wrapS = wrapModes[wrapSNdx].mode;
wrapT = wrapModes[wrapTNdx].mode;
wrapR = wrapModes[wrapRNdx].mode;
width = 63;
height = 57;
depth = 67;
name = minFilterModes[minFilterNdx].name + '_' +
magFilterModes[magFilterNdx].name + '_' +
wrapModes[wrapSNdx].name + '_' +
wrapModes[wrapTNdx].name + '_' +
wrapModes[wrapRNdx].name;
combinationsGroup.addChild(
new
es3fTextureFilteringTests.
Texture3DFilteringCase(
name, '', minFilter, magFilter,
wrapS, wrapT, wrapR, format,
width, height, depth
)
);
}
}
}
}
}
};
/**
* Create and execute the test cases
* @param {WebGL2RenderingContext} context
* @param {Array<number>=} range Test range
*/
es3fTextureFilteringTests.run = function(context, range) {
gl = context;
const canvas = gl.canvas;
canvas.width = canvasWH;
canvas.height = canvasWH;
//Set up Test Root parameters
var state = tcuTestCase.runner;
state.setRoot(new es3fTextureFilteringTests.TextureFilteringTests());
if (range)
state.setRange(range);
//Set up name and description of this test series.
setCurrentTestName(state.testCases.fullName());
description(state.testCases.getDescription());
try {
//Run test cases
tcuTestCase.runTestCases();
}
catch (err) {
testFailedOptions('Failed to run tests', false);
tcuTestCase.runner.terminate();
}
};
});