Backed out changeset 8fc3326bce7f (bug 1943032) for causing failures at browser_tab_g...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fFramebufferBlitTests.js
blobffc6a0c68cec01cdc590b176624fec701c73e3bd
1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 'use strict';
21 goog.provide('functional.gles3.es3fFramebufferBlitTests');
22 goog.require('framework.common.tcuImageCompare');
23 goog.require('framework.common.tcuRGBA');
24 goog.require('framework.common.tcuSurface');
25 goog.require('framework.common.tcuTestCase');
26 goog.require('framework.common.tcuTexture');
27 goog.require('framework.common.tcuTextureUtil');
28 goog.require('framework.delibs.debase.deMath');
29 goog.require('framework.opengl.gluShaderUtil');
30 goog.require('framework.opengl.gluTextureUtil');
31 goog.require('framework.opengl.simplereference.sglrGLContext');
32 goog.require('framework.opengl.simplereference.sglrReferenceContext');
33 goog.require('framework.referencerenderer.rrUtil');
34 goog.require('functional.gles3.es3fFboTestCase');
35 goog.require('functional.gles3.es3fFboTestUtil');
37 goog.scope(function() {
39 var es3fFramebufferBlitTests = functional.gles3.es3fFramebufferBlitTests;
40 var es3fFboTestCase = functional.gles3.es3fFboTestCase;
41 var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
42 var tcuTestCase = framework.common.tcuTestCase;
43 var tcuSurface = framework.common.tcuSurface;
44 var tcuRGBA = framework.common.tcuRGBA;
45 var tcuImageCompare = framework.common.tcuImageCompare;
46 var tcuTexture = framework.common.tcuTexture;
47 var tcuTextureUtil = framework.common.tcuTextureUtil;
48 var deMath = framework.delibs.debase.deMath;
49 var gluTextureUtil = framework.opengl.gluTextureUtil;
50 var gluShaderUtil = framework.opengl.gluShaderUtil;
51 var rrUtil = framework.referencerenderer.rrUtil;
52 var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
53 var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
55 var DE_ASSERT = function(x) {
56 if (!x)
57 throw new Error('Assert failed');
60 /** @type {WebGL2RenderingContext} */ var gl;
61 /**
62 * es3fFramebufferBlitTests.BlitRectCase class, inherits from FboTestCase
63 * @constructor
64 * @extends {es3fFboTestCase.FboTestCase}
65 * @param {string} name
66 * @param {string} desc
67 * @param {number} filter deUint32
68 * @param {Array<number>} srcSize
69 * @param {Array<number>} srcRect
70 * @param {Array<number>} dstSize
71 * @param {Array<number>} dstRect
72 * @param {number=} cellSize
74 es3fFramebufferBlitTests.BlitRectCase = function(name, desc, filter, srcSize, srcRect, dstSize, dstRect, cellSize) {
75 es3fFboTestCase.FboTestCase.call(this, name, desc);
76 /** @const {number} */ this.m_filter = filter;
77 /** @const {Array<number>} */ this.m_srcSize = srcSize;
78 /** @const {Array<number>} */ this.m_srcRect = srcRect;
79 /** @const {Array<number>} */ this.m_dstSize = dstSize;
80 /** @const {Array<number>} */ this.m_dstRect = dstRect;
81 /** @const {number} */ this.m_cellSize = cellSize === undefined ? 8 : cellSize;
82 /** @const {Array<number>} */ this.m_gridCellColorA = [0.2, 0.7, 0.1, 1.0];
83 /** @const {Array<number>} */ this.m_gridCellColorB = [0.7, 0.1, 0.5, 0.8];
86 es3fFramebufferBlitTests.BlitRectCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
87 es3fFramebufferBlitTests.BlitRectCase.prototype.constructor = es3fFramebufferBlitTests.BlitRectCase;
89 /**
90 * @param {tcuSurface.Surface} dst
92 es3fFramebufferBlitTests.BlitRectCase.prototype.render = function(dst) {
93 var ctx = this.getCurrentContext();
94 /** @type {number} */ var colorFormat = gl.RGBA8;
96 /** @type {es3fFboTestUtil.GradientShader} */
97 var gradShader = new es3fFboTestUtil.GradientShader(
98 gluShaderUtil.DataType.FLOAT_VEC4);
99 /** @type {es3fFboTestUtil.Texture2DShader} */
100 var texShader = new es3fFboTestUtil.Texture2DShader(
101 [gluShaderUtil.DataType.SAMPLER_2D],
102 gluShaderUtil.DataType.FLOAT_VEC4);
104 var gradShaderID = ctx.createProgram(gradShader);
105 var texShaderID = ctx.createProgram(texShader);
107 var srcFbo;
108 var dstFbo;
109 var srcRbo;
110 var dstRbo;
112 // Setup shaders
113 gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
114 texShader.setUniforms(ctx, texShaderID);
116 // Create framebuffers.
118 /** @type {Array<number>} */ var size;
120 // source framebuffers
121 srcFbo = ctx.createFramebuffer();
122 srcRbo = ctx.createRenderbuffer();
123 size = this.m_srcSize;
125 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo);
126 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, size[0], size[1]);
127 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
128 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcRbo);
129 this.checkError();
130 this.checkFramebufferStatus(gl.FRAMEBUFFER);
132 // destination framebuffers
133 dstFbo = ctx.createFramebuffer();
134 dstRbo = ctx.createRenderbuffer();
135 size = this.m_dstSize;
137 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo);
138 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, size[0], size[1]);
139 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
140 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstRbo);
141 this.checkError();
142 this.checkFramebufferStatus(gl.FRAMEBUFFER);
144 // Fill destination with gradient.
145 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
146 ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
148 rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
150 // Fill source with grid pattern.
151 /** @const {number} */ var format = gl.RGBA;
152 /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
153 /** @const {number} */ var texW = this.m_srcSize[0];
154 /** @const {number} */ var texH = this.m_srcSize[1];
155 var gridTex;
156 /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
158 tcuTextureUtil.fillWithGrid(data.getAccess(), this.m_cellSize, this.m_gridCellColorA, this.m_gridCellColorB);
160 gridTex = ctx.createTexture();
161 ctx.bindTexture(gl.TEXTURE_2D, gridTex);
162 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
163 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
164 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
165 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
166 ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
168 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
169 ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]);
171 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
173 // Perform copy.
174 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
175 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
176 ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3],
177 this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3],
178 gl.COLOR_BUFFER_BIT, this.m_filter);
180 // Read back results.
181 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo);
183 this.readPixelsUsingFormat(dst, 0, 0, this.m_dstSize[0], this.m_dstSize[1],
184 gluTextureUtil.mapGLInternalFormat(colorFormat),
185 [1.0, 1.0, 1.0, 1.0],
186 [0.0, 0.0, 0.0, 0.0]);
190 * @param {tcuSurface.Surface} reference
191 * @param {tcuSurface.Surface} result
192 * @return {boolean}
194 es3fFramebufferBlitTests.BlitRectCase.prototype.compare = function(reference, result) {
195 // Use pixel-threshold compare for rect cases since 1px off will mean failure.
196 var threshold = [7, 7, 7, 7];
197 return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold);
201 * es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase class
202 * @constructor
203 * @extends {es3fFramebufferBlitTests.BlitRectCase}
204 * @param {string} name
205 * @param {string} desc
206 * @param {Array<number>} srcSize
207 * @param {Array<number>} srcRect
208 * @param {Array<number>} dstSize
209 * @param {Array<number>} dstRect
211 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase = function(name, desc, srcSize, srcRect, dstSize, dstRect) {
212 es3fFramebufferBlitTests.BlitRectCase.call(this, name, desc, gl.NEAREST, srcSize, srcRect, dstSize, dstRect, 1);
215 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype = Object.create(es3fFramebufferBlitTests.BlitRectCase.prototype);
216 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.constructor = es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase;
219 * @param {tcuSurface.Surface} reference
220 * @param {tcuSurface.Surface} result
221 * @return {boolean}
223 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.compare = function(reference, result) {
224 assertMsgOptions(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight(),
225 'Reference and result images have different dimensions', false, true);
227 // Image origin must be visible (for baseColor)
228 DE_ASSERT(Math.min(this.m_dstRect[0], this.m_dstRect[2]) >= 0);
229 DE_ASSERT(Math.min(this.m_dstRect[1], this.m_dstRect[3]) >= 0);
230 /** @const {tcuRGBA.RGBA} */ var cellColorA = tcuRGBA.newRGBAFromVec(this.m_gridCellColorA);
231 /** @const {tcuRGBA.RGBA} */ var cellColorB = tcuRGBA.newRGBAFromVec(this.m_gridCellColorB);
232 // TODO: implement
233 // const tcu::RGBA threshold = this.m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
234 /** @type {tcuRGBA.RGBA} */ var threshold = tcuRGBA.newRGBAComponents(7, 7, 7, 7);
235 /** @const {Array<number>} */ //IVec4.xyzw
236 var destinationArea = [
237 deMath.clamp(Math.min(this.m_dstRect[0], this.m_dstRect[2]), 0, result.getWidth()),
238 deMath.clamp(Math.min(this.m_dstRect[1], this.m_dstRect[3]), 0, result.getHeight()),
239 deMath.clamp(Math.max(this.m_dstRect[0], this.m_dstRect[2]), 0, result.getWidth()),
240 deMath.clamp(Math.max(this.m_dstRect[1], this.m_dstRect[3]), 0, result.getHeight())];
242 /** @const {tcuRGBA.RGBA} */ var baseColor = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1]));
244 /** @const {boolean} */ var signConfig = tcuRGBA.compareThreshold(baseColor, cellColorA, threshold);
246 /** @type {boolean} */ var error = false;
247 /** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
248 /** @type {Array<boolean>} */ var horisontalSign = [];
249 /** @type {Array<boolean>} */ var verticalSign = [];
251 errorMask.getAccess().clear([0.0, 1.0, 0.0, 1.0]);
253 // Checking only area in our destination rect
255 // m_testCtx.getLog()
256 // << tcu::TestLog::Message
257 // << 'Verifying consistency of NEAREST filtering. Verifying rect ' << m_dstRect << '.\n'
258 // << 'Rounding direction of the NEAREST filter at the horisontal texel edge (x = n + 0.5) should not depend on the y-coordinate.\n'
259 // << 'Rounding direction of the NEAREST filter at the vertical texel edge (y = n + 0.5) should not depend on the x-coordinate.\n'
260 // << 'Blitting a grid (with uniform sized cells) should result in a grid (with non-uniform sized cells).'
261 // << tcu::TestLog::EndMessage;
263 // Verify that destination only contains valid colors
265 /** @type {tcuRGBA.RGBA} */ var color;
267 for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
268 for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
269 color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1] + dy));
271 /** @const {boolean} */
272 var isValidColor =
273 tcuRGBA.compareThreshold(color, cellColorA, threshold) ||
274 tcuRGBA.compareThreshold(color, cellColorB, threshold);
276 if (!isValidColor) {
277 errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec());
278 error = true;
283 if (error) {
284 // m_testCtx.getLog()
285 // << tcu::TestLog::Message
286 // << 'Image verification failed, destination rect contains unexpected values. '
287 // << 'Expected either ' << cellColorA << ' or ' << cellColorB << '.'
288 // << tcu::TestLog::EndMessage
289 // << tcu::TestLog::ImageSet('Result', 'Image verification result')
290 // << tcu::TestLog::Image('Result', 'Result', result)
291 // << tcu::TestLog::Image('ErrorMask', 'Error mask', errorMask)
292 // << tcu::TestLog::EndImageSet;
293 return false;
296 // Detect result edges by reading the first row and first column of the blitted area.
297 // Blitting a grid should result in a grid-like image. ('sign changes' should be consistent)
299 for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
300 color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1]));
301 if (tcuRGBA.compareThreshold(color, cellColorA, threshold))
302 horisontalSign[dx] = true;
303 else if (tcuRGBA.compareThreshold(color, cellColorB, threshold))
304 horisontalSign[dx] = false;
305 else
306 DE_ASSERT(false);
308 for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
309 color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1] + dy));
311 if (tcuRGBA.compareThreshold(color, cellColorA, threshold))
312 verticalSign[dy] = true;
313 else if (tcuRGBA.compareThreshold(color, cellColorB, threshold))
314 verticalSign[dy] = false;
315 else
316 DE_ASSERT(false);
319 // Verify grid-like image
321 for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
322 for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
323 color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1] + dy));
324 /** @const {boolean} */ var resultSign = tcuRGBA.compareThreshold(cellColorA, color, threshold);
325 /** @const {boolean} */ var correctSign = (horisontalSign[dx] == verticalSign[dy]) == signConfig;
327 if (resultSign != correctSign) {
328 errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec());
329 error = true;
333 // Report result
335 // if (error)
336 // {
337 // m_testCtx.getLog()
338 // << tcu::TestLog::Message
339 // << 'Image verification failed, nearest filter is not consistent.'
340 // << tcu::TestLog::EndMessage
341 // << tcu::TestLog::ImageSet('Result', 'Image verification result')
342 // << tcu::TestLog::Image('Result', 'Result', result)
343 // << tcu::TestLog::Image('ErrorMask', 'Error mask', errorMask)
344 // << tcu::TestLog::EndImageSet;
345 // }
346 // else
347 // {
348 // m_testCtx.getLog()
349 // << tcu::TestLog::Message
350 // << 'Image verification passed.'
351 // << tcu::TestLog::EndMessage
352 // << tcu::TestLog::ImageSet('Result', 'Image verification result')
353 // << tcu::TestLog::Image('Result', 'Result', result)
354 // << tcu::TestLog::EndImageSet;
355 // }
357 return !error;
361 * es3fFramebufferBlitTests.FramebufferBlitTests class, inherits from TestCase
362 * @constructor
363 * @extends {tcuTestCase.DeqpTest}
365 es3fFramebufferBlitTests.FramebufferBlitTests = function() {
366 tcuTestCase.DeqpTest.call(this, 'blit', 'Framebuffer blit tests');
369 es3fFramebufferBlitTests.FramebufferBlitTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
370 es3fFramebufferBlitTests.FramebufferBlitTests.prototype.constructor = es3fFramebufferBlitTests.FramebufferBlitTests;
372 es3fFramebufferBlitTests.FramebufferBlitTests.prototype.init = function() {
373 /** @const {Array<number>} */ var colorFormats = [
374 // RGBA formats
375 gl.RGBA32I,
376 gl.RGBA32UI,
377 gl.RGBA16I,
378 gl.RGBA16UI,
379 gl.RGBA8,
380 gl.RGBA8I,
381 gl.RGBA8UI,
382 gl.SRGB8_ALPHA8,
383 gl.RGB10_A2,
384 gl.RGB10_A2UI,
385 gl.RGBA4,
386 gl.RGB5_A1,
388 // RGB formats
389 gl.RGB8,
390 gl.RGB565,
392 // RG formats
393 gl.RG32I,
394 gl.RG32UI,
395 gl.RG16I,
396 gl.RG16UI,
397 gl.RG8,
398 gl.RG8I,
399 gl.RG8UI,
401 // R formats
402 gl.R32I,
403 gl.R32UI,
404 gl.R16I,
405 gl.R16UI,
406 gl.R8,
407 gl.R8I,
408 gl.R8UI,
410 // gl.EXT_color_buffer_float
411 gl.RGBA32F,
412 gl.RGBA16F,
413 gl.R11F_G11F_B10F,
414 gl.RG32F,
415 gl.RG16F,
416 gl.R32F,
417 gl.R16F
420 /** @const {Array<number>} */ var depthStencilFormats = [
421 gl.DEPTH_COMPONENT32F,
422 gl.DEPTH_COMPONENT24,
423 gl.DEPTH_COMPONENT16,
424 gl.DEPTH32F_STENCIL8,
425 gl.DEPTH24_STENCIL8,
426 gl.STENCIL_INDEX8
429 // .rect
430 /** @constructor
431 * @param {string} name
432 * @param {Array<number>} srcRect
433 * @param {Array<number>} dstRect
435 var CopyRect = function(name, srcRect, dstRect) {
436 /** @const {string} */ this.name = name;
437 /** @type {Array<number>} */ this.srcRect = srcRect;
438 /** @type {Array<number>} */ this.dstRect = dstRect;
441 /** @const {Array<CopyRect>} */ var copyRects = [
442 new CopyRect('basic', [10, 20, 65, 100], [45, 5, 100, 85]),
443 new CopyRect('scale', [10, 20, 65, 100], [25, 30, 125, 94]),
444 new CopyRect('out_of_bounds', [-10, -15, 100, 63], [50, 30, 136, 144])
447 /** @const {Array<CopyRect>} */ var filterConsistencyRects = [
449 new CopyRect('mag', [20, 10, 74, 88], [10, 10, 91, 101]),
450 new CopyRect('min', [10, 20, 78, 100], [20, 20, 71, 80]),
451 new CopyRect('out_of_bounds_mag', [21, 10, 73, 82], [11, 43, 141, 151]),
452 new CopyRect('out_of_bounds_min', [11, 21, 77, 97], [80, 82, 135, 139])
455 /** @constructor
456 * @param {?string} name
457 * @param {Array<number>} srcSwizzle
458 * @param {Array<number>} dstSwizzle
460 var Swizzle = function(name, srcSwizzle, dstSwizzle) {
461 /** @const {?string} */ this.name = name;
462 /** @type {Array<number>} */ this.srcSwizzle = srcSwizzle;
463 /** @type {Array<number>} */ this.dstSwizzle = dstSwizzle;
466 /** @const {Array<Swizzle>} */ var swizzles = [
467 new Swizzle(null, [0, 1, 2, 3], [0, 1, 2, 3]),
468 new Swizzle('reverse_src_x', [2, 1, 0, 3], [0, 1, 2, 3]),
469 new Swizzle('reverse_src_y', [0, 3, 2, 1], [0, 1, 2, 3]),
470 new Swizzle('reverse_dst_x', [0, 1, 2, 3], [2, 1, 0, 3]),
471 new Swizzle('reverse_dst_y', [0, 1, 2, 3], [0, 3, 2, 1]),
472 new Swizzle('reverse_src_dst_x', [2, 1, 0, 3], [2, 1, 0, 3]),
473 new Swizzle('reverse_src_dst_y', [0, 3, 2, 1], [0, 3, 2, 1])
476 /** @const {Array<number>} */ var srcSize = [127, 119];
477 /** @const {Array<number>} */ var dstSize = [132, 128];
479 // Blit rectangle tests.
480 for (var rectNdx = 0; rectNdx < copyRects.length; rectNdx++) {
481 /** @type {tcuTestCase.DeqpTest} */ var rectGroup = tcuTestCase.newTest('rect', 'Blit rectangle tests');
482 this.addChild(rectGroup);
484 for (var swzNdx = 0; swzNdx < swizzles.length; swzNdx++) {
485 /** @type {string} */ var name = copyRects[rectNdx].name + (swizzles[swzNdx].name ? ('_' + swizzles[swzNdx].name) : '');
486 /** @type {Array<number>} */ var srcSwz = swizzles[swzNdx].srcSwizzle;
487 /** @type {Array<number>} */ var dstSwz = swizzles[swzNdx].dstSwizzle;
488 /** @type {Array<number>} */ var srcRect = deMath.swizzle(copyRects[rectNdx].srcRect, srcSwz);
489 /** @type {Array<number>} */ var dstRect = deMath.swizzle(copyRects[rectNdx].dstRect, dstSwz);
491 rectGroup.addChild(new es3fFramebufferBlitTests.BlitRectCase((name + '_nearest'), '', gl.NEAREST, srcSize, srcRect, dstSize, dstRect));
492 rectGroup.addChild(new es3fFramebufferBlitTests.BlitRectCase((name + '_linear'), '', gl.LINEAR, srcSize, srcRect, dstSize, dstRect));
496 // Nearest filter tests
497 for (var rectNdx = 0; rectNdx < filterConsistencyRects.length; rectNdx++) {
498 /** @type {tcuTestCase.DeqpTest} */ var rectGroup = tcuTestCase.newTest('rect', 'Blit rectangle tests');
499 this.addChild(rectGroup);
500 for (var swzNdx = 0; swzNdx < swizzles.length; swzNdx++) {
501 var name = 'nearest_consistency_' + filterConsistencyRects[rectNdx].name + (swizzles[swzNdx].name ? ('_' + swizzles[swzNdx].name) : '');
502 var srcSwz = swizzles[swzNdx].srcSwizzle;
503 var dstSwz = swizzles[swzNdx].dstSwizzle;
504 var srcRect = deMath.swizzle(filterConsistencyRects[rectNdx].srcRect, srcSwz);
505 var dstRect = deMath.swizzle(filterConsistencyRects[rectNdx].dstRect, dstSwz);
507 rectGroup.addChild(new es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase(name, 'Test consistency of the nearest filter', srcSize, srcRect, dstSize, dstRect));
511 // .conversion
512 for (var srcFmtNdx = 0; srcFmtNdx < colorFormats.length; srcFmtNdx++) {
513 /** @type {tcuTestCase.DeqpTest} */ var conversionGroup = tcuTestCase.newTest('conversion', 'Color conversion tests');
514 this.addChild(conversionGroup);
515 for (var dstFmtNdx = 0; dstFmtNdx < colorFormats.length; dstFmtNdx++) {
516 /** @type {number} */ var srcFormat = colorFormats[srcFmtNdx];
517 /** @type {tcuTexture.TextureFormat} */ var srcTexFmt = gluTextureUtil.mapGLInternalFormat(srcFormat);
518 /** @type {tcuTexture.TextureChannelClass} */ var srcType = tcuTexture.getTextureChannelClass(srcTexFmt.type);
519 /** @type {number} */ var dstFormat = colorFormats[dstFmtNdx];
520 /** @type {tcuTexture.TextureFormat} */ var dstTexFmt = gluTextureUtil.mapGLInternalFormat(dstFormat);
521 /** @type {tcuTexture.TextureChannelClass} */ var dstType = tcuTexture.getTextureChannelClass(dstTexFmt.type);
523 if (((srcType == tcuTexture.TextureChannelClass.FLOATING_POINT || srcType == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT) !=
524 (dstType == tcuTexture.TextureChannelClass.FLOATING_POINT || dstType == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT)) ||
525 ((srcType == tcuTexture.TextureChannelClass.SIGNED_INTEGER) != (dstType == tcuTexture.TextureChannelClass.SIGNED_INTEGER)) ||
526 ((srcType == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER) != (dstType == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)))
527 continue; // Conversion not supported.
529 var name = es3fFboTestUtil.getFormatName(srcFormat) + '_to_' + es3fFboTestUtil.getFormatName(dstFormat);
531 conversionGroup.addChild(new es3fFramebufferBlitTests.BlitColorConversionCase(name, '', srcFormat, dstFormat, [127, 113]));
535 // .depth_stencil
536 /** @type {tcuTestCase.DeqpTest} */ var depthStencilGroup = tcuTestCase.newTest('depth_stencil', 'Depth and stencil blits');
537 this.addChild(depthStencilGroup);
539 for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
540 /** @type {number} */ var format = depthStencilFormats[fmtNdx];
541 /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
542 /** @type {string} */ var fmtName = es3fFboTestUtil.getFormatName(format);
543 /** @type {boolean} */ var depth = texFmt.order == tcuTexture.ChannelOrder.D || texFmt.order == tcuTexture.ChannelOrder.DS;
544 /** @type {boolean} */ var stencil = texFmt.order == tcuTexture.ChannelOrder.S || texFmt.order == tcuTexture.ChannelOrder.DS;
545 /** @type {number} */ var buffers = (depth ? gl.DEPTH_BUFFER_BIT : 0) | (stencil ? gl.STENCIL_BUFFER_BIT : 0);
547 depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_basic'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], buffers));
548 depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_scale'), '', format, buffers, [127, 119], [10, 30, 100, 70], buffers, [111, 130], [20, 5, 80, 130], buffers));
550 if (depth && stencil) {
551 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));
552 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));
556 // .default_framebuffer
558 * @constructor
559 * @param {string} name
560 * @param {es3fFramebufferBlitTests.BlitArea} area
562 var Area = function(name, area) {
563 /** @type {string} name */ this.name = name;
564 /** @type {es3fFramebufferBlitTests.BlitArea} area */ this.area = area;
567 /** @type {Array<Area>} */ var areas = [
568 new Area('scale', es3fFramebufferBlitTests.BlitArea.AREA_SCALE),
569 new Area('out_of_bounds', es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS)
572 var numDefaultFbSubGroups = 7;
573 /** @type {Array<tcuTestCase.DeqpTest>} */ var defaultFbGroup = [];
574 for (var ii = 0; ii < numDefaultFbSubGroups; ++ii) {
575 defaultFbGroup[ii] = tcuTestCase.newTest('default_framebuffer', 'Blits with default framebuffer');
576 this.addChild(defaultFbGroup[ii]);
578 for (var fmtNdx = 0; fmtNdx < colorFormats.length; fmtNdx++) {
579 var format = colorFormats[fmtNdx];
580 var texFmt = gluTextureUtil.mapGLInternalFormat(format);
581 var fmtClass = tcuTexture.getTextureChannelClass(texFmt.type);
582 var filter = gluTextureUtil.isGLInternalColorFormatFilterable(format) ? gl.LINEAR : gl.NEAREST;
583 var filterable = gluTextureUtil.isGLInternalColorFormatFilterable(format);
585 if (fmtClass != tcuTexture.TextureChannelClass.FLOATING_POINT &&
586 fmtClass != tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT &&
587 fmtClass != tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT)
588 continue; // Conversion not supported.
590 defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.BlitDefaultFramebufferCase(es3fFboTestUtil.getFormatName(format), '', format, filter));
592 for (var areaNdx = 0; areaNdx < areas.length; areaNdx++) {
593 var name = areas[areaNdx].name;
594 var addLinear = filterable;
595 var addNearest = !addLinear || (areas[areaNdx].area != es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS); // No need to check out-of-bounds with different filtering
597 if (addNearest) {
599 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));
600 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));
603 if (addLinear) {
604 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));
605 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));
612 * @param {?tcuTexture.ChannelOrder} order
613 * @return {Array<boolean>}
615 es3fFramebufferBlitTests.getChannelMask = function(order) {
616 switch (order) {
617 case tcuTexture.ChannelOrder.R: return [true, false, false, false];
618 case tcuTexture.ChannelOrder.RG: return [true, true, false, false];
619 case tcuTexture.ChannelOrder.RGB: return [true, true, true, false];
620 case tcuTexture.ChannelOrder.RGBA: return [true, true, true, true];
621 case tcuTexture.ChannelOrder.sRGB: return [true, true, true, false];
622 case tcuTexture.ChannelOrder.sRGBA: return [true, true, true, true];
623 default:
624 DE_ASSERT(false);
625 return [false, false, false, false];
630 * es3fFramebufferBlitTests.BlitColorConversionCase class, inherits from FboTestCase
631 * @constructor
632 * @extends {es3fFboTestCase.FboTestCase}
633 * @param {string} name
634 * @param {string} desc
635 * @param {number} srcFormat
636 * @param {number} dstFormat
637 * @param {Array<number>} size
639 es3fFramebufferBlitTests.BlitColorConversionCase = function(name, desc, srcFormat, dstFormat, size) {
640 es3fFboTestCase.FboTestCase.call(this, name, desc);
641 /** @type {number} */ this.m_srcFormat = srcFormat;
642 /** @type {number} */ this.m_dstFormat = dstFormat;
643 /** @type {Array<number>} */ this.m_size = size;
646 es3fFramebufferBlitTests.BlitColorConversionCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
647 es3fFramebufferBlitTests.BlitColorConversionCase.prototype.constructor = es3fFramebufferBlitTests.BlitColorConversionCase;
649 es3fFramebufferBlitTests.BlitColorConversionCase.prototype.preCheck = function() {
650 this.checkFormatSupport(this.m_srcFormat);
651 this.checkFormatSupport(this.m_dstFormat);
652 return true; // No exception thrown
656 * @param {tcuSurface.Surface} dst
658 es3fFramebufferBlitTests.BlitColorConversionCase.prototype.render = function(dst) {
659 var ctx = this.getCurrentContext();
660 /** @type {tcuTexture.TextureFormat} */ var srcFormat = gluTextureUtil.mapGLInternalFormat(this.m_srcFormat);
661 /** @type {tcuTexture.TextureFormat} */ var dstFormat = gluTextureUtil.mapGLInternalFormat(this.m_dstFormat);
663 /** @type {gluShaderUtil.DataType} */ var srcOutputType = es3fFboTestUtil.getFragmentOutputType(srcFormat);
664 /** @type {gluShaderUtil.DataType} */ var dstOutputType = es3fFboTestUtil.getFragmentOutputType(dstFormat);
666 // Compute ranges \note Doesn't handle case where src or dest is not subset of the another!
667 /** @type {tcuTextureUtil.TextureFormatInfo} */ var srcFmtRangeInfo = tcuTextureUtil.getTextureFormatInfo(srcFormat);
668 /** @type {tcuTextureUtil.TextureFormatInfo} */ var dstFmtRangeInfo = tcuTextureUtil.getTextureFormatInfo(dstFormat);
670 /** @type {Array<boolean>} */ var copyMask = deMath.logicalAndBool(es3fFramebufferBlitTests.getChannelMask(srcFormat.order), es3fFramebufferBlitTests.getChannelMask(dstFormat.order));
671 /** @type {Array<boolean>} */ var srcIsGreater = deMath.greaterThan(deMath.subtract(srcFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMin), deMath.subtract(dstFmtRangeInfo.valueMax, dstFmtRangeInfo.valueMin));
673 /** @type {tcuTextureUtil.TextureFormatInfo} */ var srcRangeInfo = new tcuTextureUtil.TextureFormatInfo(
674 tcuTextureUtil.select(dstFmtRangeInfo.valueMin, srcFmtRangeInfo.valueMin, deMath.logicalAndBool(copyMask, srcIsGreater)),
675 tcuTextureUtil.select(dstFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMax, deMath.logicalAndBool(copyMask, srcIsGreater)),
676 tcuTextureUtil.select(dstFmtRangeInfo.lookupScale, srcFmtRangeInfo.lookupScale, deMath.logicalAndBool(copyMask, srcIsGreater)),
677 tcuTextureUtil.select(dstFmtRangeInfo.lookupBias, srcFmtRangeInfo.lookupBias, deMath.logicalAndBool(copyMask, srcIsGreater)));
678 /** @type {tcuTextureUtil.TextureFormatInfo} */ var dstRangeInfo = new tcuTextureUtil.TextureFormatInfo(
679 tcuTextureUtil.select(dstFmtRangeInfo.valueMin, srcFmtRangeInfo.valueMin, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
680 tcuTextureUtil.select(dstFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMax, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
681 tcuTextureUtil.select(dstFmtRangeInfo.lookupScale, srcFmtRangeInfo.lookupScale, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
682 tcuTextureUtil.select(dstFmtRangeInfo.lookupBias, srcFmtRangeInfo.lookupBias, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)));
684 // Shaders.
685 /** @type {es3fFboTestUtil.GradientShader} */
686 var gradientToSrcShader = new es3fFboTestUtil.GradientShader(srcOutputType);
687 /** @type {es3fFboTestUtil.GradientShader} */
688 var gradientToDstShader = new es3fFboTestUtil.GradientShader(dstOutputType);
690 var gradShaderSrcID = ctx.createProgram(gradientToSrcShader);
691 var gradShaderDstID = ctx.createProgram(gradientToDstShader);
693 var srcFbo;
694 var dstFbo;
695 var srcRbo;
696 var dstRbo;
698 // Create framebuffers.
699 // Source framebuffers
700 srcFbo = ctx.createFramebuffer();
701 srcRbo = ctx.createRenderbuffer();
703 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo);
704 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_srcFormat, this.m_size[0], this.m_size[1]);
706 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
707 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcRbo);
708 this.checkError();
709 this.checkFramebufferStatus(gl.FRAMEBUFFER);
711 // Destination framebuffers
712 dstFbo = ctx.createFramebuffer();
713 dstRbo = ctx.createRenderbuffer();
715 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo);
716 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_dstFormat, this.m_size[0], this.m_size[1]);
718 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
719 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstRbo);
720 this.checkError();
721 this.checkFramebufferStatus(gl.FRAMEBUFFER);
723 ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
725 // Render gradients.
726 for (var ndx = 0; ndx < 2; ndx++) {
727 ctx.bindFramebuffer(gl.FRAMEBUFFER, ndx ? dstFbo : srcFbo);
728 if (ndx) {
729 gradientToDstShader.setGradient(ctx, gradShaderDstID, dstRangeInfo.valueMax, dstRangeInfo.valueMin);
730 rrUtil.drawQuad(ctx, gradShaderDstID, [-1, -1, 0], [1, 1, 0]);
731 } else {
732 gradientToSrcShader.setGradient(ctx, gradShaderSrcID, srcRangeInfo.valueMin, srcRangeInfo.valueMax);
733 rrUtil.drawQuad(ctx, gradShaderSrcID, [-1, -1, 0], [1, 1, 0]);
737 // Execute copy.
738 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
739 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
740 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);
741 this.checkError();
743 // Read results.
744 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo);
745 this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], dstFormat, dstRangeInfo.lookupScale, dstRangeInfo.lookupBias);
750 * @param {tcuSurface.Surface} reference
751 * @param {tcuSurface.Surface} result
753 es3fFramebufferBlitTests.BlitColorConversionCase.prototype.compare = function(reference, result) {
754 /** @const {tcuTexture.TextureFormat} */ var srcFormat = gluTextureUtil.mapGLInternalFormat(this.m_srcFormat);
755 /** @const {tcuTexture.TextureFormat} */ var dstFormat = gluTextureUtil.mapGLInternalFormat(this.m_dstFormat);
756 /** @const {boolean} */ var srcIsSRGB = (srcFormat.order == tcuTexture.ChannelOrder.sRGBA);
757 /** @const {boolean} */ var dstIsSRGB = (dstFormat.order == tcuTexture.ChannelOrder.sRGBA);
758 /** @type {tcuRGBA.RGBA} */ var threshold = new tcuRGBA.RGBA();
760 if (dstIsSRGB)
761 threshold = es3fFboTestUtil.getToSRGBConversionThreshold(srcFormat, dstFormat);
762 else {
763 /** @type {tcuRGBA.RGBA} */ var srcMaxDiff = es3fFboTestUtil.getThresholdFromTextureFormat(srcFormat);
764 /** @type {tcuRGBA.RGBA} */ var dstMaxDiff = es3fFboTestUtil.getThresholdFromTextureFormat(dstFormat);
765 if (srcIsSRGB)
766 srcMaxDiff = tcuRGBA.multiply(srcMaxDiff, 2);
768 threshold = tcuRGBA.max(srcMaxDiff, dstMaxDiff);
771 // m_testCtx.getLog() << tcu::TestLog::Message << 'threshold = ' << threshold << tcu::TestLog::EndMessage;
772 return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold.toIVec());
776 * @constructor
777 * @extends {es3fFboTestCase.FboTestCase}
778 * @param {string} name
779 * @param {string} desc
780 * @param {number} format deUint32
781 * @param {number} srcBuffers deUint32
782 * @param {Array<number>} srcSize IVec2
783 * @param {Array<number>} srcRect IVec4
784 * @param {number} dstBuffers deUint32
785 * @param {Array<number>} dstSize IVec2
786 * @param {Array<number>} dstRect IVec4
787 * @param {number} copyBuffers deUint32
789 es3fFramebufferBlitTests.BlitDepthStencilCase = function(name, desc, format, srcBuffers, srcSize, srcRect, dstBuffers, dstSize, dstRect, copyBuffers) {
790 es3fFboTestCase.FboTestCase.call(this, name, desc);
791 /** @type {number} */ this.m_format = format;
792 /** @type {number} */ this.m_srcBuffers = srcBuffers;
793 /** @type {Array<number>} */ this.m_srcSize = srcSize;
794 /** @type {Array<number>} */ this.m_srcRect = srcRect;
795 /** @type {number} */ this.m_dstBuffers = dstBuffers;
796 /** @type {Array<number>} */ this.m_dstSize = dstSize;
797 /** @type {Array<number>} */ this.m_dstRect = dstRect;
798 /** @type {number} */ this.m_copyBuffers = copyBuffers;
801 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
802 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.constructor = es3fFramebufferBlitTests.BlitDepthStencilCase;
805 * @protected
807 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.preCheck = function() {
808 this.checkFormatSupport(this.m_format);
809 return true; // No exception thrown
813 * @protected
814 * @param {tcuSurface.Surface} dst
816 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.render = function(dst) {
817 var ctx = this.getCurrentContext();
818 /** @const {number} */ var colorFormat = gl.RGBA8;
819 var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
820 var texShader = new es3fFboTestUtil.Texture2DShader(
821 [gluShaderUtil.DataType.SAMPLER_2D] ,
822 gluShaderUtil.DataType.FLOAT_VEC4);
823 var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
825 var flatShaderID = ctx.createProgram(flatShader);
826 var texShaderID = ctx.createProgram(texShader);
827 var gradShaderID = ctx.createProgram(gradShader);
829 var srcFbo;
830 var dstFbo;
831 var srcColorRbo;
832 var dstColorRbo;
833 var srcDepthStencilRbo;
834 var dstDepthStencilRbo;
836 // setup shaders
837 gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
838 texShader.setUniforms(ctx, texShaderID);
840 // Create framebuffers
841 // Source framebuffers
842 srcFbo = ctx.createFramebuffer();
843 srcColorRbo = ctx.createRenderbuffer();
844 srcDepthStencilRbo = ctx.createRenderbuffer();
846 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcColorRbo);
847 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_srcSize[0], this.m_srcSize[1]);
849 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcDepthStencilRbo);
850 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_srcSize[0], this.m_srcSize[1]);
852 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
853 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcColorRbo);
855 if (this.m_srcBuffers & gl.DEPTH_BUFFER_BIT)
856 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, srcDepthStencilRbo);
857 if (this.m_srcBuffers & gl.STENCIL_BUFFER_BIT)
858 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, srcDepthStencilRbo);
860 this.checkError();
861 this.checkFramebufferStatus(gl.FRAMEBUFFER);
863 // Clear depth to 1 and stencil to 0.
864 ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
866 // Destination framebuffers
867 dstFbo = ctx.createFramebuffer();
868 dstColorRbo = ctx.createRenderbuffer();
869 dstDepthStencilRbo = ctx.createRenderbuffer();
871 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstColorRbo);
872 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_dstSize[0], this.m_dstSize[1]);
874 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstDepthStencilRbo);
875 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_dstSize[0], this.m_dstSize[1]);
877 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
878 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstColorRbo);
880 if (this.m_dstBuffers & gl.DEPTH_BUFFER_BIT)
881 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, dstDepthStencilRbo);
882 if (this.m_dstBuffers & gl.STENCIL_BUFFER_BIT)
883 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, dstDepthStencilRbo);
885 this.checkError();
886 this.checkFramebufferStatus(gl.FRAMEBUFFER);
888 // Clear depth to 1 and stencil to 0.
889 ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
891 // Fill source with gradient, depth = [-1..1], stencil = 7
892 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
893 ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]);
894 ctx.enable(gl.DEPTH_TEST);
895 ctx.enable(gl.STENCIL_TEST);
896 ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
897 ctx.stencilFunc(gl.ALWAYS, 7, 0xff);
899 rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
901 // Fill destination with grid pattern, depth = 0 and stencil = 1
902 /** @const {number} */ var format = gl.RGBA;
903 /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
904 /** @const {number} */ var texW = this.m_srcSize[0];
905 /** @const {number} */ var texH = this.m_srcSize[1];
906 /** @type {WebGLTexture|sglrReferenceContext.TextureContainer} */ var gridTex = null;
907 /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
909 tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
911 gridTex = ctx.createTexture();
912 ctx.bindTexture(gl.TEXTURE_2D, gridTex);
913 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
914 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
915 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
916 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
917 ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
919 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
920 ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
921 ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
923 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
925 // Perform copy.
926 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
927 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
928 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);
930 // Render blue color where depth < 0, decrement on depth failure.
931 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
932 ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
933 ctx.stencilOp(gl.KEEP, gl.DECR, gl.KEEP);
934 ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
936 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]);
938 rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
940 if (this.m_dstBuffers & gl.STENCIL_BUFFER_BIT) {
941 // Render green color where stencil == 6.
942 ctx.disable(gl.DEPTH_TEST);
943 ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
944 ctx.stencilFunc(gl.EQUAL, 6, 0xff);
946 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]);
948 rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
951 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]);
956 * @constructor
957 * @extends {es3fFboTestCase.FboTestCase}
958 * @param {string} name
959 * @param {string} desc
960 * @param {number} format
961 * @param {number} filter
963 es3fFramebufferBlitTests.BlitDefaultFramebufferCase = function(name, desc, format, filter) {
964 es3fFboTestCase.FboTestCase.call(this, name, desc);
965 /** @const {number} */ this.m_format = format;
966 /** @const {number} */ this.m_filter = filter;
969 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
970 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.constructor = es3fFramebufferBlitTests.BlitDefaultFramebufferCase;
973 * @protected
975 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.preCheck = function() {
976 this.checkFormatSupport(this.m_format);
977 return true; // No exception thrown
981 * @protected
982 * @param {tcuSurface.Surface} dst
984 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.render = function(dst) {
985 var ctx = this.getCurrentContext();
986 /** @type {tcuTexture.TextureFormat} */ var colorFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
987 /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(colorFormat);
989 /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
990 /** @type {es3fFboTestUtil.Texture2DShader} */ var texShader = new es3fFboTestUtil.Texture2DShader([gluTextureUtil.getSampler2DType(colorFormat)], gluShaderUtil.DataType.FLOAT_VEC4);
992 var gradShaderID = ctx.createProgram(gradShader);
993 var texShaderID = ctx.createProgram(texShader);
994 var fbo;
995 var tex;
996 /** @const {number} */ var texW = 128;
997 /** @const {number} */ var texH = 128;
999 // Setup shaders
1000 gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
1001 texShader.setUniforms(ctx, texShaderID);
1003 // FBO
1004 fbo = ctx.createFramebuffer();
1005 tex = ctx.createTexture();
1007 ctx.bindTexture(gl.TEXTURE_2D, tex);
1008 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1009 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1010 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_filter);
1011 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_filter);
1012 ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, texW, texH, 0, transferFmt.format, transferFmt.dataType, null);
1014 ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
1015 ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
1016 this.checkError();
1017 this.checkFramebufferStatus(gl.FRAMEBUFFER);
1019 // Render gradient to screen.
1020 ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
1022 rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
1024 // Blit gradient from screen to fbo.
1025 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
1026 ctx.blitFramebuffer(0, 0, ctx.getWidth(), ctx.getHeight(), 0, 0, texW, texH, gl.COLOR_BUFFER_BIT, this.m_filter);
1028 // Fill left half of viewport with quad that uses texture.
1029 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
1030 ctx.clearBufferfv(gl.COLOR, 0, [1.0, 0.0, 0.0, 1.0]);
1032 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
1034 // Blit fbo to right half.
1035 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo);
1036 ctx.blitFramebuffer(0, 0, texW, texH, Math.floor(ctx.getWidth() / 2), 0, ctx.getWidth(), ctx.getHeight(), gl.COLOR_BUFFER_BIT, this.m_filter);
1038 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
1039 this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
1044 * @protected
1045 * @param {tcuSurface.Surface} reference
1046 * @param {tcuSurface.Surface} result
1048 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.compare = function(reference, result) {
1049 /** @const {tcuRGBA.RGBA} */
1050 var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_format), tcuRGBA.newRGBAComponents(12, 12, 12, 12));
1052 //m_testCtx.getLog() << TestLog::Message << 'Comparing images, threshold: ' << threshold << TestLog::EndMessage;
1054 return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
1057 /** @enum */
1058 es3fFramebufferBlitTests.BlitDirection = {
1059 BLIT_DEFAULT_TO_TARGET: 0,
1060 BLIT_TO_DEFAULT_FROM_TARGET: 1
1063 /** @enum */
1064 es3fFramebufferBlitTests.BlitArea = {
1065 AREA_SCALE: 0,
1066 AREA_OUT_OF_BOUNDS: 1
1070 * @constructor
1071 * @extends {es3fFramebufferBlitTests.BlitDefaultFramebufferCase}
1072 * @param {string} name
1073 * @param {string} desc
1074 * @param {number} format
1075 * @param {number} filter
1076 * @param {es3fFramebufferBlitTests.BlitDirection} dir
1077 * @param {es3fFramebufferBlitTests.BlitArea} area
1079 es3fFramebufferBlitTests.DefaultFramebufferBlitCase = function(name, desc, format, filter, dir, area) {
1080 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.call(this, name, desc, format, filter);
1081 /** @const {es3fFramebufferBlitTests.BlitDirection} */ this.m_blitDir = dir;
1082 /** @const {es3fFramebufferBlitTests.BlitArea} */ this.m_blitArea = area;
1083 /** @type {Array<number>} */ this.m_srcRect = [-1, -1, -1, -1];
1084 /** @type {Array<number>} */ this.m_dstRect = [-1, -1, -1, -1];
1085 /** @type {Array<number>} */ this.m_interestingArea = [-1, -1, -1, -1];
1088 es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype = Object.create(es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype);
1089 es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.constructor = es3fFramebufferBlitTests.DefaultFramebufferBlitCase;
1091 es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.init = function() {
1092 // requirements
1093 /** @const {number} */ var minViewportSize = 128;
1094 if (gl.drawingBufferWidth < minViewportSize ||
1095 gl.drawingBufferHeight < minViewportSize)
1096 throw new Error('Viewport size ' + minViewportSize + 'x' + minViewportSize + ' required');
1098 // prevent viewport randoming
1099 this.m_viewportWidth = gl.drawingBufferWidth;
1100 this.m_viewportHeight = gl.drawingBufferHeight;
1102 // set proper areas
1103 if (this.m_blitArea == es3fFramebufferBlitTests.BlitArea.AREA_SCALE) {
1104 this.m_srcRect = [10, 20, 65, 100];
1105 this.m_dstRect = [25, 30, 125, 94];
1106 this.m_interestingArea = [0, 0, 128, 128];
1107 } else if (this.m_blitArea == es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS) {
1108 /** @const {Array<number>} */
1109 var ubound = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ?
1110 ([128, 128]) :
1111 ([gl.drawingBufferWidth, gl.drawingBufferHeight]);
1113 this.m_srcRect = [-10, -15, 100, 63];
1114 this.m_dstRect = deMath.add(deMath.swizzle(ubound, [0, 1, 0, 1]), [-75, -99, 8, 16]);
1115 this.m_interestingArea = [ubound[0] - 128, ubound[1] - 128, ubound[0], ubound[1]];
1120 * @param {tcuSurface.Surface} dst
1122 es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.render = function(dst) {
1123 /** @type {es3fFboTestCase.Context} */
1124 var ctx = this.getCurrentContext();
1125 // TOOD: implement
1126 /** @type {tcuTexture.TextureFormat} */ var colorFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
1127 /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(colorFormat);
1128 /** @const {tcuTexture.TextureChannelClass} */
1129 var targetClass = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ?
1130 (tcuTexture.getTextureChannelClass(colorFormat.type)) :
1131 (tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT);
1133 var fbo;
1134 var fboTex;
1135 /** @const {number} */ var fboTexW = 128;
1136 /** @const {number} */ var fboTexH = 128;
1137 /** @const {number} */ var sourceWidth = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (ctx.getWidth()) : (fboTexW);
1138 /** @const {number} */ var sourceHeight = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (ctx.getHeight()) : (fboTexH);
1139 /** @const {number} */ var gridRenderWidth = Math.min(256, sourceWidth);
1140 /** @const {number} */ var gridRenderHeight = Math.min(256, sourceHeight);
1142 var targetFbo;
1143 var sourceFbo;
1145 // FBO
1146 fbo = ctx.createFramebuffer();
1147 fboTex = ctx.createTexture();
1149 ctx.bindTexture(gl.TEXTURE_2D, fboTex);
1150 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1151 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1152 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_filter);
1153 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_filter);
1154 ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, fboTexW, fboTexH, 0, transferFmt.format, transferFmt.dataType, null);
1156 ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
1157 ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fboTex, 0);
1158 this.checkError();
1159 this.checkFramebufferStatus(gl.FRAMEBUFFER);
1161 targetFbo = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (fbo) : (null);
1162 sourceFbo = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (null) : (fbo);
1164 // Render grid to source framebuffer
1165 /** @type {es3fFboTestUtil.Texture2DShader} */
1166 var texShader = new es3fFboTestUtil.Texture2DShader(
1167 [gluShaderUtil.DataType.SAMPLER_2D],
1168 gluShaderUtil.DataType.FLOAT_VEC4);
1169 var texShaderID = this.getCurrentContext().createProgram(texShader);
1170 /** @const {number} */ var internalFormat = gl.RGBA8;
1171 /** @const {number} */ var format = gl.RGBA;
1172 /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
1173 /** @const {number} */ var gridTexW = 128;
1174 /** @const {number} */ var gridTexH = 128;
1175 /** @type {WebGLTexture|framework.opengl.simplereference.sglrReferenceContext.TextureContainer|null} */
1176 var gridTex = null;
1177 /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), gridTexW, gridTexH, 1);
1179 tcuTextureUtil.fillWithGrid(data.getAccess(), 9, [0.9, 0.5, 0.1, 0.9], [0.2, 0.8, 0.2, 0.7]);
1181 gridTex = ctx.createTexture();
1182 ctx.bindTexture(gl.TEXTURE_2D, gridTex);
1183 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1184 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1185 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
1186 ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
1187 ctx.texImage2D(gl.TEXTURE_2D, 0, internalFormat, gridTexW, gridTexH, 0, format, dataType, data.getAccess().getDataPtr());
1189 ctx.bindFramebuffer(gl.FRAMEBUFFER, sourceFbo);
1190 ctx.viewport(0, 0, gridRenderWidth, gridRenderHeight);
1191 ctx.clearBufferfv(gl.COLOR, 0, [1.0, 0.0, 0.0, 1.0]);
1193 texShader.setUniforms(this.getCurrentContext(), texShaderID);
1195 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
1197 ctx.useProgram(null);
1199 // Blit source framebuffer to destination
1201 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, sourceFbo);
1202 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targetFbo);
1203 this.checkError();
1205 if (targetClass == tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT ||
1206 targetClass == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT ||
1207 targetClass == tcuTexture.TextureChannelClass.FLOATING_POINT)
1208 ctx.clearBufferfv(gl.COLOR, 0, [1.0, 1.0, 0.0, 1.0]);
1209 else if (targetClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER)
1210 ctx.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
1211 else if (targetClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)
1212 ctx.clearBufferuiv(gl.COLOR, 0, [0, 0, 0, 0]);
1213 else
1214 DE_ASSERT(false);
1216 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);
1217 this.checkError();
1219 // Read target
1221 ctx.bindFramebuffer(gl.FRAMEBUFFER, targetFbo);
1223 if (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET)
1224 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]);
1225 else
1226 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]);
1228 this.checkError();
1231 es3fFramebufferBlitTests.run = function(context, range) {
1232 gl = context;
1233 //Set up root Test
1234 var state = tcuTestCase.runner;
1236 var test = new es3fFramebufferBlitTests.FramebufferBlitTests();
1237 var testName = test.fullName();
1238 var testDescription = test.getDescription() || '';
1240 state.testName = testName;
1241 state.setRoot(test);
1242 //Set up name and description of this test series.
1243 setCurrentTestName(testName);
1244 description(testDescription);
1246 try {
1247 //Create test cases
1248 test.init();
1249 if (range)
1250 state.setRange(range);
1251 //Run test cases
1252 tcuTestCase.runTestCases();
1254 catch (err) {
1255 bufferedLogToConsole(err);
1256 testFailedOptions('Failed to es3fFramebufferBlitTests.run tests', false);
1257 tcuTestCase.runner.terminate();