summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js1261
1 files changed, 1261 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js
new file mode 100644
index 0000000000..ffc6a0c68c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js
@@ -0,0 +1,1261 @@
+/*-------------------------------------------------------------------------
+ * 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.es3fFramebufferBlitTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+ var es3fFramebufferBlitTests = functional.gles3.es3fFramebufferBlitTests;
+ var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+ var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deMath = framework.delibs.debase.deMath;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var rrUtil = framework.referencerenderer.rrUtil;
+ var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+ /**
+ * es3fFramebufferBlitTests.BlitRectCase class, inherits from FboTestCase
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} filter deUint32
+ * @param {Array<number>} srcSize
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstSize
+ * @param {Array<number>} dstRect
+ * @param {number=} cellSize
+ */
+ es3fFramebufferBlitTests.BlitRectCase = function(name, desc, filter, srcSize, srcRect, dstSize, dstRect, cellSize) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @const {number} */ this.m_filter = filter;
+ /** @const {Array<number>} */ this.m_srcSize = srcSize;
+ /** @const {Array<number>} */ this.m_srcRect = srcRect;
+ /** @const {Array<number>} */ this.m_dstSize = dstSize;
+ /** @const {Array<number>} */ this.m_dstRect = dstRect;
+ /** @const {number} */ this.m_cellSize = cellSize === undefined ? 8 : cellSize;
+ /** @const {Array<number>} */ this.m_gridCellColorA = [0.2, 0.7, 0.1, 1.0];
+ /** @const {Array<number>} */ this.m_gridCellColorB = [0.7, 0.1, 0.5, 0.8];
+ };
+
+ es3fFramebufferBlitTests.BlitRectCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitRectCase.prototype.constructor = es3fFramebufferBlitTests.BlitRectCase;
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitRectCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {number} */ var colorFormat = gl.RGBA8;
+
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradShader = new es3fFboTestUtil.GradientShader(
+ gluShaderUtil.DataType.FLOAT_VEC4);
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D],
+ gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var gradShaderID = ctx.createProgram(gradShader);
+ var texShaderID = ctx.createProgram(texShader);
+
+ var srcFbo;
+ var dstFbo;
+ var srcRbo;
+ var dstRbo;
+
+ // Setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // Create framebuffers.
+
+ /** @type {Array<number>} */ var size;
+
+ // source framebuffers
+ srcFbo = ctx.createFramebuffer();
+ srcRbo = ctx.createRenderbuffer();
+ size = this.m_srcSize;
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, size[0], size[1]);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // destination framebuffers
+ dstFbo = ctx.createFramebuffer();
+ dstRbo = ctx.createRenderbuffer();
+ size = this.m_dstSize;
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, size[0], size[1]);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Fill destination with gradient.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
+
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Fill source with grid pattern.
+ /** @const {number} */ var format = gl.RGBA;
+ /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
+ /** @const {number} */ var texW = this.m_srcSize[0];
+ /** @const {number} */ var texH = this.m_srcSize[1];
+ var gridTex;
+ /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), this.m_cellSize, this.m_gridCellColorA, this.m_gridCellColorB);
+
+ gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Perform copy.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
+ ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3],
+ this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3],
+ gl.COLOR_BUFFER_BIT, this.m_filter);
+
+ // Read back results.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo);
+
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_dstSize[0], this.m_dstSize[1],
+ gluTextureUtil.mapGLInternalFormat(colorFormat),
+ [1.0, 1.0, 1.0, 1.0],
+ [0.0, 0.0, 0.0, 0.0]);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFramebufferBlitTests.BlitRectCase.prototype.compare = function(reference, result) {
+ // Use pixel-threshold compare for rect cases since 1px off will mean failure.
+ var threshold = [7, 7, 7, 7];
+ return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold);
+ };
+
+ /**
+ * es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase class
+ * @constructor
+ * @extends {es3fFramebufferBlitTests.BlitRectCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {Array<number>} srcSize
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstSize
+ * @param {Array<number>} dstRect
+ */
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase = function(name, desc, srcSize, srcRect, dstSize, dstRect) {
+ es3fFramebufferBlitTests.BlitRectCase.call(this, name, desc, gl.NEAREST, srcSize, srcRect, dstSize, dstRect, 1);
+ };
+
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype = Object.create(es3fFramebufferBlitTests.BlitRectCase.prototype);
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.constructor = es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase;
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.compare = function(reference, result) {
+ assertMsgOptions(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight(),
+ 'Reference and result images have different dimensions', false, true);
+
+ // Image origin must be visible (for baseColor)
+ DE_ASSERT(Math.min(this.m_dstRect[0], this.m_dstRect[2]) >= 0);
+ DE_ASSERT(Math.min(this.m_dstRect[1], this.m_dstRect[3]) >= 0);
+ /** @const {tcuRGBA.RGBA} */ var cellColorA = tcuRGBA.newRGBAFromVec(this.m_gridCellColorA);
+ /** @const {tcuRGBA.RGBA} */ var cellColorB = tcuRGBA.newRGBAFromVec(this.m_gridCellColorB);
+ // TODO: implement
+ // const tcu::RGBA threshold = this.m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
+ /** @type {tcuRGBA.RGBA} */ var threshold = tcuRGBA.newRGBAComponents(7, 7, 7, 7);
+ /** @const {Array<number>} */ //IVec4.xyzw
+ var destinationArea = [
+ deMath.clamp(Math.min(this.m_dstRect[0], this.m_dstRect[2]), 0, result.getWidth()),
+ deMath.clamp(Math.min(this.m_dstRect[1], this.m_dstRect[3]), 0, result.getHeight()),
+ deMath.clamp(Math.max(this.m_dstRect[0], this.m_dstRect[2]), 0, result.getWidth()),
+ deMath.clamp(Math.max(this.m_dstRect[1], this.m_dstRect[3]), 0, result.getHeight())];
+
+ /** @const {tcuRGBA.RGBA} */ var baseColor = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1]));
+
+ /** @const {boolean} */ var signConfig = tcuRGBA.compareThreshold(baseColor, cellColorA, threshold);
+
+ /** @type {boolean} */ var error = false;
+ /** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
+ /** @type {Array<boolean>} */ var horisontalSign = [];
+ /** @type {Array<boolean>} */ var verticalSign = [];
+
+ errorMask.getAccess().clear([0.0, 1.0, 0.0, 1.0]);
+
+ // Checking only area in our destination rect
+
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Verifying consistency of NEAREST filtering. Verifying rect ' << m_dstRect << '.\n'
+ // << 'Rounding direction of the NEAREST filter at the horisontal texel edge (x = n + 0.5) should not depend on the y-coordinate.\n'
+ // << 'Rounding direction of the NEAREST filter at the vertical texel edge (y = n + 0.5) should not depend on the x-coordinate.\n'
+ // << 'Blitting a grid (with uniform sized cells) should result in a grid (with non-uniform sized cells).'
+ // << tcu::TestLog::EndMessage;
+
+ // Verify that destination only contains valid colors
+
+ /** @type {tcuRGBA.RGBA} */ var color;
+
+ for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
+ for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1] + dy));
+
+ /** @const {boolean} */
+ var isValidColor =
+ tcuRGBA.compareThreshold(color, cellColorA, threshold) ||
+ tcuRGBA.compareThreshold(color, cellColorB, threshold);
+
+ if (!isValidColor) {
+ errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec());
+ error = true;
+ }
+ }
+ }
+
+ if (error) {
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Image verification failed, destination rect contains unexpected values. '
+ // << 'Expected either ' << cellColorA << ' or ' << cellColorB << '.'
+ // << tcu::TestLog::EndMessage
+ // << tcu::TestLog::ImageSet('Result', 'Image verification result')
+ // << tcu::TestLog::Image('Result', 'Result', result)
+ // << tcu::TestLog::Image('ErrorMask', 'Error mask', errorMask)
+ // << tcu::TestLog::EndImageSet;
+ return false;
+ }
+
+ // Detect result edges by reading the first row and first column of the blitted area.
+ // Blitting a grid should result in a grid-like image. ('sign changes' should be consistent)
+
+ for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1]));
+ if (tcuRGBA.compareThreshold(color, cellColorA, threshold))
+ horisontalSign[dx] = true;
+ else if (tcuRGBA.compareThreshold(color, cellColorB, threshold))
+ horisontalSign[dx] = false;
+ else
+ DE_ASSERT(false);
+ }
+ for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1] + dy));
+
+ if (tcuRGBA.compareThreshold(color, cellColorA, threshold))
+ verticalSign[dy] = true;
+ else if (tcuRGBA.compareThreshold(color, cellColorB, threshold))
+ verticalSign[dy] = false;
+ else
+ DE_ASSERT(false);
+ }
+
+ // Verify grid-like image
+
+ for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
+ for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1] + dy));
+ /** @const {boolean} */ var resultSign = tcuRGBA.compareThreshold(cellColorA, color, threshold);
+ /** @const {boolean} */ var correctSign = (horisontalSign[dx] == verticalSign[dy]) == signConfig;
+
+ if (resultSign != correctSign) {
+ errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec());
+ error = true;
+ }
+ }
+ }
+ // Report result
+
+ // if (error)
+ // {
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Image verification failed, nearest filter is not consistent.'
+ // << tcu::TestLog::EndMessage
+ // << tcu::TestLog::ImageSet('Result', 'Image verification result')
+ // << tcu::TestLog::Image('Result', 'Result', result)
+ // << tcu::TestLog::Image('ErrorMask', 'Error mask', errorMask)
+ // << tcu::TestLog::EndImageSet;
+ // }
+ // else
+ // {
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Image verification passed.'
+ // << tcu::TestLog::EndMessage
+ // << tcu::TestLog::ImageSet('Result', 'Image verification result')
+ // << tcu::TestLog::Image('Result', 'Result', result)
+ // << tcu::TestLog::EndImageSet;
+ // }
+
+ return !error;
+ };
+
+ /**
+ * es3fFramebufferBlitTests.FramebufferBlitTests class, inherits from TestCase
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFramebufferBlitTests.FramebufferBlitTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'blit', 'Framebuffer blit tests');
+ };
+
+ es3fFramebufferBlitTests.FramebufferBlitTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFramebufferBlitTests.FramebufferBlitTests.prototype.constructor = es3fFramebufferBlitTests.FramebufferBlitTests;
+
+ es3fFramebufferBlitTests.FramebufferBlitTests.prototype.init = function() {
+ /** @const {Array<number>} */ var colorFormats = [
+ // RGBA formats
+ gl.RGBA32I,
+ gl.RGBA32UI,
+ gl.RGBA16I,
+ gl.RGBA16UI,
+ gl.RGBA8,
+ gl.RGBA8I,
+ gl.RGBA8UI,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGB10_A2UI,
+ gl.RGBA4,
+ gl.RGB5_A1,
+
+ // RGB formats
+ gl.RGB8,
+ gl.RGB565,
+
+ // RG formats
+ gl.RG32I,
+ gl.RG32UI,
+ gl.RG16I,
+ gl.RG16UI,
+ gl.RG8,
+ gl.RG8I,
+ gl.RG8UI,
+
+ // R formats
+ gl.R32I,
+ gl.R32UI,
+ gl.R16I,
+ gl.R16UI,
+ gl.R8,
+ gl.R8I,
+ gl.R8UI,
+
+ // gl.EXT_color_buffer_float
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F
+ ];
+
+ /** @const {Array<number>} */ var depthStencilFormats = [
+ gl.DEPTH_COMPONENT32F,
+ gl.DEPTH_COMPONENT24,
+ gl.DEPTH_COMPONENT16,
+ gl.DEPTH32F_STENCIL8,
+ gl.DEPTH24_STENCIL8,
+ gl.STENCIL_INDEX8
+ ];
+
+ // .rect
+ /** @constructor
+ * @param {string} name
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstRect
+ */
+ var CopyRect = function(name, srcRect, dstRect) {
+ /** @const {string} */ this.name = name;
+ /** @type {Array<number>} */ this.srcRect = srcRect;
+ /** @type {Array<number>} */ this.dstRect = dstRect;
+ };
+
+ /** @const {Array<CopyRect>} */ var copyRects = [
+ new CopyRect('basic', [10, 20, 65, 100], [45, 5, 100, 85]),
+ new CopyRect('scale', [10, 20, 65, 100], [25, 30, 125, 94]),
+ new CopyRect('out_of_bounds', [-10, -15, 100, 63], [50, 30, 136, 144])
+ ];
+
+ /** @const {Array<CopyRect>} */ var filterConsistencyRects = [
+
+ new CopyRect('mag', [20, 10, 74, 88], [10, 10, 91, 101]),
+ new CopyRect('min', [10, 20, 78, 100], [20, 20, 71, 80]),
+ new CopyRect('out_of_bounds_mag', [21, 10, 73, 82], [11, 43, 141, 151]),
+ new CopyRect('out_of_bounds_min', [11, 21, 77, 97], [80, 82, 135, 139])
+ ];
+
+ /** @constructor
+ * @param {?string} name
+ * @param {Array<number>} srcSwizzle
+ * @param {Array<number>} dstSwizzle
+ */
+ var Swizzle = function(name, srcSwizzle, dstSwizzle) {
+ /** @const {?string} */ this.name = name;
+ /** @type {Array<number>} */ this.srcSwizzle = srcSwizzle;
+ /** @type {Array<number>} */ this.dstSwizzle = dstSwizzle;
+ };
+
+ /** @const {Array<Swizzle>} */ var swizzles = [
+ new Swizzle(null, [0, 1, 2, 3], [0, 1, 2, 3]),
+ new Swizzle('reverse_src_x', [2, 1, 0, 3], [0, 1, 2, 3]),
+ new Swizzle('reverse_src_y', [0, 3, 2, 1], [0, 1, 2, 3]),
+ new Swizzle('reverse_dst_x', [0, 1, 2, 3], [2, 1, 0, 3]),
+ new Swizzle('reverse_dst_y', [0, 1, 2, 3], [0, 3, 2, 1]),
+ new Swizzle('reverse_src_dst_x', [2, 1, 0, 3], [2, 1, 0, 3]),
+ new Swizzle('reverse_src_dst_y', [0, 3, 2, 1], [0, 3, 2, 1])
+ ];
+
+ /** @const {Array<number>} */ var srcSize = [127, 119];
+ /** @const {Array<number>} */ var dstSize = [132, 128];
+
+ // Blit rectangle tests.
+ for (var rectNdx = 0; rectNdx < copyRects.length; rectNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var rectGroup = tcuTestCase.newTest('rect', 'Blit rectangle tests');
+ this.addChild(rectGroup);
+
+ for (var swzNdx = 0; swzNdx < swizzles.length; swzNdx++) {
+ /** @type {string} */ var name = copyRects[rectNdx].name + (swizzles[swzNdx].name ? ('_' + swizzles[swzNdx].name) : '');
+ /** @type {Array<number>} */ var srcSwz = swizzles[swzNdx].srcSwizzle;
+ /** @type {Array<number>} */ var dstSwz = swizzles[swzNdx].dstSwizzle;
+ /** @type {Array<number>} */ var srcRect = deMath.swizzle(copyRects[rectNdx].srcRect, srcSwz);
+ /** @type {Array<number>} */ var dstRect = deMath.swizzle(copyRects[rectNdx].dstRect, dstSwz);
+
+ rectGroup.addChild(new es3fFramebufferBlitTests.BlitRectCase((name + '_nearest'), '', gl.NEAREST, srcSize, srcRect, dstSize, dstRect));
+ rectGroup.addChild(new es3fFramebufferBlitTests.BlitRectCase((name + '_linear'), '', gl.LINEAR, srcSize, srcRect, dstSize, dstRect));
+ }
+ }
+
+ // Nearest filter tests
+ for (var rectNdx = 0; rectNdx < filterConsistencyRects.length; rectNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var rectGroup = tcuTestCase.newTest('rect', 'Blit rectangle tests');
+ this.addChild(rectGroup);
+ for (var swzNdx = 0; swzNdx < swizzles.length; swzNdx++) {
+ var name = 'nearest_consistency_' + filterConsistencyRects[rectNdx].name + (swizzles[swzNdx].name ? ('_' + swizzles[swzNdx].name) : '');
+ var srcSwz = swizzles[swzNdx].srcSwizzle;
+ var dstSwz = swizzles[swzNdx].dstSwizzle;
+ var srcRect = deMath.swizzle(filterConsistencyRects[rectNdx].srcRect, srcSwz);
+ var dstRect = deMath.swizzle(filterConsistencyRects[rectNdx].dstRect, dstSwz);
+
+ rectGroup.addChild(new es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase(name, 'Test consistency of the nearest filter', srcSize, srcRect, dstSize, dstRect));
+ }
+ }
+
+ // .conversion
+ for (var srcFmtNdx = 0; srcFmtNdx < colorFormats.length; srcFmtNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var conversionGroup = tcuTestCase.newTest('conversion', 'Color conversion tests');
+ this.addChild(conversionGroup);
+ for (var dstFmtNdx = 0; dstFmtNdx < colorFormats.length; dstFmtNdx++) {
+ /** @type {number} */ var srcFormat = colorFormats[srcFmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var srcTexFmt = gluTextureUtil.mapGLInternalFormat(srcFormat);
+ /** @type {tcuTexture.TextureChannelClass} */ var srcType = tcuTexture.getTextureChannelClass(srcTexFmt.type);
+ /** @type {number} */ var dstFormat = colorFormats[dstFmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var dstTexFmt = gluTextureUtil.mapGLInternalFormat(dstFormat);
+ /** @type {tcuTexture.TextureChannelClass} */ var dstType = tcuTexture.getTextureChannelClass(dstTexFmt.type);
+
+ if (((srcType == tcuTexture.TextureChannelClass.FLOATING_POINT || srcType == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT) !=
+ (dstType == tcuTexture.TextureChannelClass.FLOATING_POINT || dstType == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT)) ||
+ ((srcType == tcuTexture.TextureChannelClass.SIGNED_INTEGER) != (dstType == tcuTexture.TextureChannelClass.SIGNED_INTEGER)) ||
+ ((srcType == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER) != (dstType == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)))
+ continue; // Conversion not supported.
+
+ var name = es3fFboTestUtil.getFormatName(srcFormat) + '_to_' + es3fFboTestUtil.getFormatName(dstFormat);
+
+ conversionGroup.addChild(new es3fFramebufferBlitTests.BlitColorConversionCase(name, '', srcFormat, dstFormat, [127, 113]));
+ }
+ }
+
+ // .depth_stencil
+ /** @type {tcuTestCase.DeqpTest} */ var depthStencilGroup = tcuTestCase.newTest('depth_stencil', 'Depth and stencil blits');
+ this.addChild(depthStencilGroup);
+
+ for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
+ /** @type {number} */ var format = depthStencilFormats[fmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
+ /** @type {string} */ var fmtName = es3fFboTestUtil.getFormatName(format);
+ /** @type {boolean} */ var depth = texFmt.order == tcuTexture.ChannelOrder.D || texFmt.order == tcuTexture.ChannelOrder.DS;
+ /** @type {boolean} */ var stencil = texFmt.order == tcuTexture.ChannelOrder.S || texFmt.order == tcuTexture.ChannelOrder.DS;
+ /** @type {number} */ var buffers = (depth ? gl.DEPTH_BUFFER_BIT : 0) | (stencil ? gl.STENCIL_BUFFER_BIT : 0);
+
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_basic'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], buffers));
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_scale'), '', format, buffers, [127, 119], [10, 30, 100, 70], buffers, [111, 130], [20, 5, 80, 130], buffers));
+
+ if (depth && stencil) {
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_depth_only'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], gl.DEPTH_BUFFER_BIT));
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_stencil_only'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], gl.STENCIL_BUFFER_BIT));
+ }
+ }
+
+ // .default_framebuffer
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {es3fFramebufferBlitTests.BlitArea} area
+ */
+ var Area = function(name, area) {
+ /** @type {string} name */ this.name = name;
+ /** @type {es3fFramebufferBlitTests.BlitArea} area */ this.area = area;
+ };
+
+ /** @type {Array<Area>} */ var areas = [
+ new Area('scale', es3fFramebufferBlitTests.BlitArea.AREA_SCALE),
+ new Area('out_of_bounds', es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS)
+ ];
+
+ var numDefaultFbSubGroups = 7;
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var defaultFbGroup = [];
+ for (var ii = 0; ii < numDefaultFbSubGroups; ++ii) {
+ defaultFbGroup[ii] = tcuTestCase.newTest('default_framebuffer', 'Blits with default framebuffer');
+ this.addChild(defaultFbGroup[ii]);
+ }
+ for (var fmtNdx = 0; fmtNdx < colorFormats.length; fmtNdx++) {
+ var format = colorFormats[fmtNdx];
+ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
+ var fmtClass = tcuTexture.getTextureChannelClass(texFmt.type);
+ var filter = gluTextureUtil.isGLInternalColorFormatFilterable(format) ? gl.LINEAR : gl.NEAREST;
+ var filterable = gluTextureUtil.isGLInternalColorFormatFilterable(format);
+
+ if (fmtClass != tcuTexture.TextureChannelClass.FLOATING_POINT &&
+ fmtClass != tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT &&
+ fmtClass != tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT)
+ continue; // Conversion not supported.
+
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.BlitDefaultFramebufferCase(es3fFboTestUtil.getFormatName(format), '', format, filter));
+
+ for (var areaNdx = 0; areaNdx < areas.length; areaNdx++) {
+ var name = areas[areaNdx].name;
+ var addLinear = filterable;
+ var addNearest = !addLinear || (areas[areaNdx].area != es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS); // No need to check out-of-bounds with different filtering
+
+ if (addNearest) {
+
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_nearest_' + name + '_blit_from_default'), '', format, gl.NEAREST, es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET, areas[areaNdx].area));
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_nearest_' + name + '_blit_to_default'), '', format, gl.NEAREST, es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET, areas[areaNdx].area));
+ }
+
+ if (addLinear) {
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_linear_' + name + '_blit_from_default'), '', format, gl.LINEAR, es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET, areas[areaNdx].area));
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_linear_' + name + '_blit_to_default'), '', format, gl.LINEAR, es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET, areas[areaNdx].area));
+ }
+ }
+ }
+ };
+
+ /**
+ * @param {?tcuTexture.ChannelOrder} order
+ * @return {Array<boolean>}
+ */
+ es3fFramebufferBlitTests.getChannelMask = function(order) {
+ switch (order) {
+ case tcuTexture.ChannelOrder.R: return [true, false, false, false];
+ case tcuTexture.ChannelOrder.RG: return [true, true, false, false];
+ case tcuTexture.ChannelOrder.RGB: return [true, true, true, false];
+ case tcuTexture.ChannelOrder.RGBA: return [true, true, true, true];
+ case tcuTexture.ChannelOrder.sRGB: return [true, true, true, false];
+ case tcuTexture.ChannelOrder.sRGBA: return [true, true, true, true];
+ default:
+ DE_ASSERT(false);
+ return [false, false, false, false];
+ }
+ };
+
+ /**
+ * es3fFramebufferBlitTests.BlitColorConversionCase class, inherits from FboTestCase
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} srcFormat
+ * @param {number} dstFormat
+ * @param {Array<number>} size
+ */
+ es3fFramebufferBlitTests.BlitColorConversionCase = function(name, desc, srcFormat, dstFormat, size) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_srcFormat = srcFormat;
+ /** @type {number} */ this.m_dstFormat = dstFormat;
+ /** @type {Array<number>} */ this.m_size = size;
+ };
+
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.constructor = es3fFramebufferBlitTests.BlitColorConversionCase;
+
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_srcFormat);
+ this.checkFormatSupport(this.m_dstFormat);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {tcuTexture.TextureFormat} */ var srcFormat = gluTextureUtil.mapGLInternalFormat(this.m_srcFormat);
+ /** @type {tcuTexture.TextureFormat} */ var dstFormat = gluTextureUtil.mapGLInternalFormat(this.m_dstFormat);
+
+ /** @type {gluShaderUtil.DataType} */ var srcOutputType = es3fFboTestUtil.getFragmentOutputType(srcFormat);
+ /** @type {gluShaderUtil.DataType} */ var dstOutputType = es3fFboTestUtil.getFragmentOutputType(dstFormat);
+
+ // Compute ranges \note Doesn't handle case where src or dest is not subset of the another!
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var srcFmtRangeInfo = tcuTextureUtil.getTextureFormatInfo(srcFormat);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var dstFmtRangeInfo = tcuTextureUtil.getTextureFormatInfo(dstFormat);
+
+ /** @type {Array<boolean>} */ var copyMask = deMath.logicalAndBool(es3fFramebufferBlitTests.getChannelMask(srcFormat.order), es3fFramebufferBlitTests.getChannelMask(dstFormat.order));
+ /** @type {Array<boolean>} */ var srcIsGreater = deMath.greaterThan(deMath.subtract(srcFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMin), deMath.subtract(dstFmtRangeInfo.valueMax, dstFmtRangeInfo.valueMin));
+
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var srcRangeInfo = new tcuTextureUtil.TextureFormatInfo(
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMin, srcFmtRangeInfo.valueMin, deMath.logicalAndBool(copyMask, srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMax, deMath.logicalAndBool(copyMask, srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupScale, srcFmtRangeInfo.lookupScale, deMath.logicalAndBool(copyMask, srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupBias, srcFmtRangeInfo.lookupBias, deMath.logicalAndBool(copyMask, srcIsGreater)));
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var dstRangeInfo = new tcuTextureUtil.TextureFormatInfo(
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMin, srcFmtRangeInfo.valueMin, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMax, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupScale, srcFmtRangeInfo.lookupScale, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupBias, srcFmtRangeInfo.lookupBias, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)));
+
+ // Shaders.
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradientToSrcShader = new es3fFboTestUtil.GradientShader(srcOutputType);
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradientToDstShader = new es3fFboTestUtil.GradientShader(dstOutputType);
+
+ var gradShaderSrcID = ctx.createProgram(gradientToSrcShader);
+ var gradShaderDstID = ctx.createProgram(gradientToDstShader);
+
+ var srcFbo;
+ var dstFbo;
+ var srcRbo;
+ var dstRbo;
+
+ // Create framebuffers.
+ // Source framebuffers
+ srcFbo = ctx.createFramebuffer();
+ srcRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_srcFormat, this.m_size[0], this.m_size[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Destination framebuffers
+ dstFbo = ctx.createFramebuffer();
+ dstRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_dstFormat, this.m_size[0], this.m_size[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
+
+ // Render gradients.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, ndx ? dstFbo : srcFbo);
+ if (ndx) {
+ gradientToDstShader.setGradient(ctx, gradShaderDstID, dstRangeInfo.valueMax, dstRangeInfo.valueMin);
+ rrUtil.drawQuad(ctx, gradShaderDstID, [-1, -1, 0], [1, 1, 0]);
+ } else {
+ gradientToSrcShader.setGradient(ctx, gradShaderSrcID, srcRangeInfo.valueMin, srcRangeInfo.valueMax);
+ rrUtil.drawQuad(ctx, gradShaderSrcID, [-1, -1, 0], [1, 1, 0]);
+ }
+ }
+
+ // Execute copy.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
+ ctx.blitFramebuffer(0, 0, this.m_size[0], this.m_size[1], 0, 0, this.m_size[0], this.m_size[1], gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.checkError();
+
+ // Read results.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo);
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], dstFormat, dstRangeInfo.lookupScale, dstRangeInfo.lookupBias);
+
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ */
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.compare = function(reference, result) {
+ /** @const {tcuTexture.TextureFormat} */ var srcFormat = gluTextureUtil.mapGLInternalFormat(this.m_srcFormat);
+ /** @const {tcuTexture.TextureFormat} */ var dstFormat = gluTextureUtil.mapGLInternalFormat(this.m_dstFormat);
+ /** @const {boolean} */ var srcIsSRGB = (srcFormat.order == tcuTexture.ChannelOrder.sRGBA);
+ /** @const {boolean} */ var dstIsSRGB = (dstFormat.order == tcuTexture.ChannelOrder.sRGBA);
+ /** @type {tcuRGBA.RGBA} */ var threshold = new tcuRGBA.RGBA();
+
+ if (dstIsSRGB)
+ threshold = es3fFboTestUtil.getToSRGBConversionThreshold(srcFormat, dstFormat);
+ else {
+ /** @type {tcuRGBA.RGBA} */ var srcMaxDiff = es3fFboTestUtil.getThresholdFromTextureFormat(srcFormat);
+ /** @type {tcuRGBA.RGBA} */ var dstMaxDiff = es3fFboTestUtil.getThresholdFromTextureFormat(dstFormat);
+ if (srcIsSRGB)
+ srcMaxDiff = tcuRGBA.multiply(srcMaxDiff, 2);
+
+ threshold = tcuRGBA.max(srcMaxDiff, dstMaxDiff);
+ }
+
+ // m_testCtx.getLog() << tcu::TestLog::Message << 'threshold = ' << threshold << tcu::TestLog::EndMessage;
+ return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold.toIVec());
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format deUint32
+ * @param {number} srcBuffers deUint32
+ * @param {Array<number>} srcSize IVec2
+ * @param {Array<number>} srcRect IVec4
+ * @param {number} dstBuffers deUint32
+ * @param {Array<number>} dstSize IVec2
+ * @param {Array<number>} dstRect IVec4
+ * @param {number} copyBuffers deUint32
+ */
+ es3fFramebufferBlitTests.BlitDepthStencilCase = function(name, desc, format, srcBuffers, srcSize, srcRect, dstBuffers, dstSize, dstRect, copyBuffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_format = format;
+ /** @type {number} */ this.m_srcBuffers = srcBuffers;
+ /** @type {Array<number>} */ this.m_srcSize = srcSize;
+ /** @type {Array<number>} */ this.m_srcRect = srcRect;
+ /** @type {number} */ this.m_dstBuffers = dstBuffers;
+ /** @type {Array<number>} */ this.m_dstSize = dstSize;
+ /** @type {Array<number>} */ this.m_dstRect = dstRect;
+ /** @type {number} */ this.m_copyBuffers = copyBuffers;
+ };
+
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.constructor = es3fFramebufferBlitTests.BlitDepthStencilCase;
+
+ /**
+ * @protected
+ */
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @protected
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @const {number} */ var colorFormat = gl.RGBA8;
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D] ,
+ gluShaderUtil.DataType.FLOAT_VEC4);
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var flatShaderID = ctx.createProgram(flatShader);
+ var texShaderID = ctx.createProgram(texShader);
+ var gradShaderID = ctx.createProgram(gradShader);
+
+ var srcFbo;
+ var dstFbo;
+ var srcColorRbo;
+ var dstColorRbo;
+ var srcDepthStencilRbo;
+ var dstDepthStencilRbo;
+
+ // setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // Create framebuffers
+ // Source framebuffers
+ srcFbo = ctx.createFramebuffer();
+ srcColorRbo = ctx.createRenderbuffer();
+ srcDepthStencilRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcColorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_srcSize[0], this.m_srcSize[1]);
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcDepthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_srcSize[0], this.m_srcSize[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcColorRbo);
+
+ if (this.m_srcBuffers & gl.DEPTH_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, srcDepthStencilRbo);
+ if (this.m_srcBuffers & gl.STENCIL_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, srcDepthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Clear depth to 1 and stencil to 0.
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Destination framebuffers
+ dstFbo = ctx.createFramebuffer();
+ dstColorRbo = ctx.createRenderbuffer();
+ dstDepthStencilRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstColorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_dstSize[0], this.m_dstSize[1]);
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstDepthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_dstSize[0], this.m_dstSize[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstColorRbo);
+
+ if (this.m_dstBuffers & gl.DEPTH_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, dstDepthStencilRbo);
+ if (this.m_dstBuffers & gl.STENCIL_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, dstDepthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Clear depth to 1 and stencil to 0.
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Fill source with gradient, depth = [-1..1], stencil = 7
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]);
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 7, 0xff);
+
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ // Fill destination with grid pattern, depth = 0 and stencil = 1
+ /** @const {number} */ var format = gl.RGBA;
+ /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
+ /** @const {number} */ var texW = this.m_srcSize[0];
+ /** @const {number} */ var texH = this.m_srcSize[1];
+ /** @type {WebGLTexture|sglrReferenceContext.TextureContainer} */ var gridTex = null;
+ /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
+
+ gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Perform copy.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
+ ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3], this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3], this.m_copyBuffers, gl.NEAREST);
+
+ // Render blue color where depth < 0, decrement on depth failure.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
+ ctx.stencilOp(gl.KEEP, gl.DECR, gl.KEEP);
+ ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]);
+
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ if (this.m_dstBuffers & gl.STENCIL_BUFFER_BIT) {
+ // Render green color where stencil == 6.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ ctx.stencilFunc(gl.EQUAL, 6, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ }
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_dstSize[0], this.m_dstSize[1], gluTextureUtil.mapGLInternalFormat(colorFormat), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
+
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} filter
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase = function(name, desc, format, filter) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @const {number} */ this.m_format = format;
+ /** @const {number} */ this.m_filter = filter;
+ };
+
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.constructor = es3fFramebufferBlitTests.BlitDefaultFramebufferCase;
+
+ /**
+ * @protected
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @protected
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {tcuTexture.TextureFormat} */ var colorFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(colorFormat);
+
+ /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ /** @type {es3fFboTestUtil.Texture2DShader} */ var texShader = new es3fFboTestUtil.Texture2DShader([gluTextureUtil.getSampler2DType(colorFormat)], gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var gradShaderID = ctx.createProgram(gradShader);
+ var texShaderID = ctx.createProgram(texShader);
+ var fbo;
+ var tex;
+ /** @const {number} */ var texW = 128;
+ /** @const {number} */ var texH = 128;
+
+ // Setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // FBO
+ fbo = ctx.createFramebuffer();
+ tex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_filter);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_filter);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, texW, texH, 0, transferFmt.format, transferFmt.dataType, null);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Render gradient to screen.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Blit gradient from screen to fbo.
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
+ ctx.blitFramebuffer(0, 0, ctx.getWidth(), ctx.getHeight(), 0, 0, texW, texH, gl.COLOR_BUFFER_BIT, this.m_filter);
+
+ // Fill left half of viewport with quad that uses texture.
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ ctx.clearBufferfv(gl.COLOR, 0, [1.0, 0.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Blit fbo to right half.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo);
+ ctx.blitFramebuffer(0, 0, texW, texH, Math.floor(ctx.getWidth() / 2), 0, ctx.getWidth(), ctx.getHeight(), gl.COLOR_BUFFER_BIT, this.m_filter);
+
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
+
+ };
+
+ /**
+ * @protected
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.compare = function(reference, result) {
+ /** @const {tcuRGBA.RGBA} */
+ var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_format), tcuRGBA.newRGBAComponents(12, 12, 12, 12));
+
+ //m_testCtx.getLog() << TestLog::Message << 'Comparing images, threshold: ' << threshold << TestLog::EndMessage;
+
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
+ };
+
+ /** @enum */
+ es3fFramebufferBlitTests.BlitDirection = {
+ BLIT_DEFAULT_TO_TARGET: 0,
+ BLIT_TO_DEFAULT_FROM_TARGET: 1
+ };
+
+ /** @enum */
+ es3fFramebufferBlitTests.BlitArea = {
+ AREA_SCALE: 0,
+ AREA_OUT_OF_BOUNDS: 1
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFramebufferBlitTests.BlitDefaultFramebufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} filter
+ * @param {es3fFramebufferBlitTests.BlitDirection} dir
+ * @param {es3fFramebufferBlitTests.BlitArea} area
+ */
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase = function(name, desc, format, filter, dir, area) {
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.call(this, name, desc, format, filter);
+ /** @const {es3fFramebufferBlitTests.BlitDirection} */ this.m_blitDir = dir;
+ /** @const {es3fFramebufferBlitTests.BlitArea} */ this.m_blitArea = area;
+ /** @type {Array<number>} */ this.m_srcRect = [-1, -1, -1, -1];
+ /** @type {Array<number>} */ this.m_dstRect = [-1, -1, -1, -1];
+ /** @type {Array<number>} */ this.m_interestingArea = [-1, -1, -1, -1];
+ };
+
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype = Object.create(es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype);
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.constructor = es3fFramebufferBlitTests.DefaultFramebufferBlitCase;
+
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.init = function() {
+ // requirements
+ /** @const {number} */ var minViewportSize = 128;
+ if (gl.drawingBufferWidth < minViewportSize ||
+ gl.drawingBufferHeight < minViewportSize)
+ throw new Error('Viewport size ' + minViewportSize + 'x' + minViewportSize + ' required');
+
+ // prevent viewport randoming
+ this.m_viewportWidth = gl.drawingBufferWidth;
+ this.m_viewportHeight = gl.drawingBufferHeight;
+
+ // set proper areas
+ if (this.m_blitArea == es3fFramebufferBlitTests.BlitArea.AREA_SCALE) {
+ this.m_srcRect = [10, 20, 65, 100];
+ this.m_dstRect = [25, 30, 125, 94];
+ this.m_interestingArea = [0, 0, 128, 128];
+ } else if (this.m_blitArea == es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS) {
+ /** @const {Array<number>} */
+ var ubound = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ?
+ ([128, 128]) :
+ ([gl.drawingBufferWidth, gl.drawingBufferHeight]);
+
+ this.m_srcRect = [-10, -15, 100, 63];
+ this.m_dstRect = deMath.add(deMath.swizzle(ubound, [0, 1, 0, 1]), [-75, -99, 8, 16]);
+ this.m_interestingArea = [ubound[0] - 128, ubound[1] - 128, ubound[0], ubound[1]];
+ }
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.render = function(dst) {
+ /** @type {es3fFboTestCase.Context} */
+ var ctx = this.getCurrentContext();
+ // TOOD: implement
+ /** @type {tcuTexture.TextureFormat} */ var colorFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(colorFormat);
+ /** @const {tcuTexture.TextureChannelClass} */
+ var targetClass = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ?
+ (tcuTexture.getTextureChannelClass(colorFormat.type)) :
+ (tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT);
+
+ var fbo;
+ var fboTex;
+ /** @const {number} */ var fboTexW = 128;
+ /** @const {number} */ var fboTexH = 128;
+ /** @const {number} */ var sourceWidth = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (ctx.getWidth()) : (fboTexW);
+ /** @const {number} */ var sourceHeight = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (ctx.getHeight()) : (fboTexH);
+ /** @const {number} */ var gridRenderWidth = Math.min(256, sourceWidth);
+ /** @const {number} */ var gridRenderHeight = Math.min(256, sourceHeight);
+
+ var targetFbo;
+ var sourceFbo;
+
+ // FBO
+ fbo = ctx.createFramebuffer();
+ fboTex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_2D, fboTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_filter);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_filter);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, fboTexW, fboTexH, 0, transferFmt.format, transferFmt.dataType, null);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fboTex, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ targetFbo = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (fbo) : (null);
+ sourceFbo = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (null) : (fbo);
+
+ // Render grid to source framebuffer
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D],
+ gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShaderID = this.getCurrentContext().createProgram(texShader);
+ /** @const {number} */ var internalFormat = gl.RGBA8;
+ /** @const {number} */ var format = gl.RGBA;
+ /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
+ /** @const {number} */ var gridTexW = 128;
+ /** @const {number} */ var gridTexH = 128;
+ /** @type {WebGLTexture|framework.opengl.simplereference.sglrReferenceContext.TextureContainer|null} */
+ var gridTex = null;
+ /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), gridTexW, gridTexH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 9, [0.9, 0.5, 0.1, 0.9], [0.2, 0.8, 0.2, 0.7]);
+
+ gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, internalFormat, gridTexW, gridTexH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, sourceFbo);
+ ctx.viewport(0, 0, gridRenderWidth, gridRenderHeight);
+ ctx.clearBufferfv(gl.COLOR, 0, [1.0, 0.0, 0.0, 1.0]);
+
+ texShader.setUniforms(this.getCurrentContext(), texShaderID);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ ctx.useProgram(null);
+
+ // Blit source framebuffer to destination
+
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, sourceFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targetFbo);
+ this.checkError();
+
+ if (targetClass == tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT ||
+ targetClass == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT ||
+ targetClass == tcuTexture.TextureChannelClass.FLOATING_POINT)
+ ctx.clearBufferfv(gl.COLOR, 0, [1.0, 1.0, 0.0, 1.0]);
+ else if (targetClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER)
+ ctx.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
+ else if (targetClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)
+ ctx.clearBufferuiv(gl.COLOR, 0, [0, 0, 0, 0]);
+ else
+ DE_ASSERT(false);
+
+ ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3], this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3], gl.COLOR_BUFFER_BIT, this.m_filter);
+ this.checkError();
+
+ // Read target
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, targetFbo);
+
+ if (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET)
+ this.readPixels(dst, this.m_interestingArea[0], this.m_interestingArea[1], this.m_interestingArea[2] - this.m_interestingArea[0], this.m_interestingArea[3] - this.m_interestingArea[1]);
+ else
+ this.readPixelsUsingFormat(dst, this.m_interestingArea[0], this.m_interestingArea[1], this.m_interestingArea[2] - this.m_interestingArea[0], this.m_interestingArea[3] - this.m_interestingArea[1], colorFormat, [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
+
+ this.checkError();
+ };
+
+ es3fFramebufferBlitTests.run = function(context, range) {
+ gl = context;
+ //Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = new es3fFramebufferBlitTests.FramebufferBlitTests();
+ var testName = test.fullName();
+ var testDescription = test.getDescription() || '';
+
+ state.testName = testName;
+ state.setRoot(test);
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ test.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole(err);
+ testFailedOptions('Failed to es3fFramebufferBlitTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});