es3fFramebufferBlitTests.js (63513B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 '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'); 36 37 goog.scope(function() { 38 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; 54 55 var DE_ASSERT = function(x) { 56 if (!x) 57 throw new Error('Assert failed'); 58 }; 59 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 73 */ 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]; 84 }; 85 86 es3fFramebufferBlitTests.BlitRectCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype); 87 es3fFramebufferBlitTests.BlitRectCase.prototype.constructor = es3fFramebufferBlitTests.BlitRectCase; 88 89 /** 90 * @param {tcuSurface.Surface} dst 91 */ 92 es3fFramebufferBlitTests.BlitRectCase.prototype.render = function(dst) { 93 var ctx = this.getCurrentContext(); 94 /** @type {number} */ var colorFormat = gl.RGBA8; 95 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); 103 104 var gradShaderID = ctx.createProgram(gradShader); 105 var texShaderID = ctx.createProgram(texShader); 106 107 var srcFbo; 108 var dstFbo; 109 var srcRbo; 110 var dstRbo; 111 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); 115 116 // Create framebuffers. 117 118 /** @type {Array<number>} */ var size; 119 120 // source framebuffers 121 srcFbo = ctx.createFramebuffer(); 122 srcRbo = ctx.createRenderbuffer(); 123 size = this.m_srcSize; 124 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); 131 132 // destination framebuffers 133 dstFbo = ctx.createFramebuffer(); 134 dstRbo = ctx.createRenderbuffer(); 135 size = this.m_dstSize; 136 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); 143 144 // Fill destination with gradient. 145 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo); 146 ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]); 147 148 rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]); 149 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); 157 158 tcuTextureUtil.fillWithGrid(data.getAccess(), this.m_cellSize, this.m_gridCellColorA, this.m_gridCellColorB); 159 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()); 167 168 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo); 169 ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]); 170 171 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]); 172 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); 179 180 // Read back results. 181 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo); 182 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]); 187 }; 188 189 /** 190 * @param {tcuSurface.Surface} reference 191 * @param {tcuSurface.Surface} result 192 * @return {boolean} 193 */ 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); 198 }; 199 200 /** 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 210 */ 211 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase = function(name, desc, srcSize, srcRect, dstSize, dstRect) { 212 es3fFramebufferBlitTests.BlitRectCase.call(this, name, desc, gl.NEAREST, srcSize, srcRect, dstSize, dstRect, 1); 213 }; 214 215 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype = Object.create(es3fFramebufferBlitTests.BlitRectCase.prototype); 216 es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.constructor = es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase; 217 218 /** 219 * @param {tcuSurface.Surface} reference 220 * @param {tcuSurface.Surface} result 221 * @return {boolean} 222 */ 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); 226 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())]; 241 242 /** @const {tcuRGBA.RGBA} */ var baseColor = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1])); 243 244 /** @const {boolean} */ var signConfig = tcuRGBA.compareThreshold(baseColor, cellColorA, threshold); 245 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 = []; 250 251 errorMask.getAccess().clear([0.0, 1.0, 0.0, 1.0]); 252 253 // Checking only area in our destination rect 254 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; 262 263 // Verify that destination only contains valid colors 264 265 /** @type {tcuRGBA.RGBA} */ var color; 266 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)); 270 271 /** @const {boolean} */ 272 var isValidColor = 273 tcuRGBA.compareThreshold(color, cellColorA, threshold) || 274 tcuRGBA.compareThreshold(color, cellColorB, threshold); 275 276 if (!isValidColor) { 277 errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec()); 278 error = true; 279 } 280 } 281 } 282 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; 294 } 295 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) 298 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); 307 } 308 for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) { 309 color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1] + dy)); 310 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); 317 } 318 319 // Verify grid-like image 320 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; 326 327 if (resultSign != correctSign) { 328 errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec()); 329 error = true; 330 } 331 } 332 } 333 // Report result 334 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 // } 356 357 return !error; 358 }; 359 360 /** 361 * es3fFramebufferBlitTests.FramebufferBlitTests class, inherits from TestCase 362 * @constructor 363 * @extends {tcuTestCase.DeqpTest} 364 */ 365 es3fFramebufferBlitTests.FramebufferBlitTests = function() { 366 tcuTestCase.DeqpTest.call(this, 'blit', 'Framebuffer blit tests'); 367 }; 368 369 es3fFramebufferBlitTests.FramebufferBlitTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 370 es3fFramebufferBlitTests.FramebufferBlitTests.prototype.constructor = es3fFramebufferBlitTests.FramebufferBlitTests; 371 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, 387 388 // RGB formats 389 gl.RGB8, 390 gl.RGB565, 391 392 // RG formats 393 gl.RG32I, 394 gl.RG32UI, 395 gl.RG16I, 396 gl.RG16UI, 397 gl.RG8, 398 gl.RG8I, 399 gl.RG8UI, 400 401 // R formats 402 gl.R32I, 403 gl.R32UI, 404 gl.R16I, 405 gl.R16UI, 406 gl.R8, 407 gl.R8I, 408 gl.R8UI, 409 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 418 ]; 419 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 427 ]; 428 429 // .rect 430 /** @constructor 431 * @param {string} name 432 * @param {Array<number>} srcRect 433 * @param {Array<number>} dstRect 434 */ 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; 439 }; 440 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]) 445 ]; 446 447 /** @const {Array<CopyRect>} */ var filterConsistencyRects = [ 448 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]) 453 ]; 454 455 /** @constructor 456 * @param {?string} name 457 * @param {Array<number>} srcSwizzle 458 * @param {Array<number>} dstSwizzle 459 */ 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; 464 }; 465 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]) 474 ]; 475 476 /** @const {Array<number>} */ var srcSize = [127, 119]; 477 /** @const {Array<number>} */ var dstSize = [132, 128]; 478 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); 483 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); 490 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)); 493 } 494 } 495 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); 506 507 rectGroup.addChild(new es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase(name, 'Test consistency of the nearest filter', srcSize, srcRect, dstSize, dstRect)); 508 } 509 } 510 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); 522 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. 528 529 var name = es3fFboTestUtil.getFormatName(srcFormat) + '_to_' + es3fFboTestUtil.getFormatName(dstFormat); 530 531 conversionGroup.addChild(new es3fFramebufferBlitTests.BlitColorConversionCase(name, '', srcFormat, dstFormat, [127, 113])); 532 } 533 } 534 535 // .depth_stencil 536 /** @type {tcuTestCase.DeqpTest} */ var depthStencilGroup = tcuTestCase.newTest('depth_stencil', 'Depth and stencil blits'); 537 this.addChild(depthStencilGroup); 538 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); 546 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)); 549 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)); 553 } 554 } 555 556 // .default_framebuffer 557 /** 558 * @constructor 559 * @param {string} name 560 * @param {es3fFramebufferBlitTests.BlitArea} area 561 */ 562 var Area = function(name, area) { 563 /** @type {string} name */ this.name = name; 564 /** @type {es3fFramebufferBlitTests.BlitArea} area */ this.area = area; 565 }; 566 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) 570 ]; 571 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]); 577 } 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); 584 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. 589 590 defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.BlitDefaultFramebufferCase(es3fFboTestUtil.getFormatName(format), '', format, filter)); 591 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 596 597 if (addNearest) { 598 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)); 601 } 602 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)); 606 } 607 } 608 } 609 }; 610 611 /** 612 * @param {?tcuTexture.ChannelOrder} order 613 * @return {Array<boolean>} 614 */ 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]; 626 } 627 }; 628 629 /** 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 638 */ 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; 644 }; 645 646 es3fFramebufferBlitTests.BlitColorConversionCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype); 647 es3fFramebufferBlitTests.BlitColorConversionCase.prototype.constructor = es3fFramebufferBlitTests.BlitColorConversionCase; 648 649 es3fFramebufferBlitTests.BlitColorConversionCase.prototype.preCheck = function() { 650 this.checkFormatSupport(this.m_srcFormat); 651 this.checkFormatSupport(this.m_dstFormat); 652 return true; // No exception thrown 653 }; 654 655 /** 656 * @param {tcuSurface.Surface} dst 657 */ 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); 662 663 /** @type {gluShaderUtil.DataType} */ var srcOutputType = es3fFboTestUtil.getFragmentOutputType(srcFormat); 664 /** @type {gluShaderUtil.DataType} */ var dstOutputType = es3fFboTestUtil.getFragmentOutputType(dstFormat); 665 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); 669 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)); 672 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))); 683 684 // Shaders. 685 /** @type {es3fFboTestUtil.GradientShader} */ 686 var gradientToSrcShader = new es3fFboTestUtil.GradientShader(srcOutputType); 687 /** @type {es3fFboTestUtil.GradientShader} */ 688 var gradientToDstShader = new es3fFboTestUtil.GradientShader(dstOutputType); 689 690 var gradShaderSrcID = ctx.createProgram(gradientToSrcShader); 691 var gradShaderDstID = ctx.createProgram(gradientToDstShader); 692 693 var srcFbo; 694 var dstFbo; 695 var srcRbo; 696 var dstRbo; 697 698 // Create framebuffers. 699 // Source framebuffers 700 srcFbo = ctx.createFramebuffer(); 701 srcRbo = ctx.createRenderbuffer(); 702 703 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo); 704 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_srcFormat, this.m_size[0], this.m_size[1]); 705 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); 710 711 // Destination framebuffers 712 dstFbo = ctx.createFramebuffer(); 713 dstRbo = ctx.createRenderbuffer(); 714 715 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo); 716 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_dstFormat, this.m_size[0], this.m_size[1]); 717 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); 722 723 ctx.viewport(0, 0, this.m_size[0], this.m_size[1]); 724 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]); 734 } 735 } 736 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(); 742 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); 746 747 }; 748 749 /** 750 * @param {tcuSurface.Surface} reference 751 * @param {tcuSurface.Surface} result 752 */ 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(); 759 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); 767 768 threshold = tcuRGBA.max(srcMaxDiff, dstMaxDiff); 769 } 770 771 // m_testCtx.getLog() << tcu::TestLog::Message << 'threshold = ' << threshold << tcu::TestLog::EndMessage; 772 return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold.toIVec()); 773 }; 774 775 /** 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 788 */ 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; 799 }; 800 801 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype); 802 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.constructor = es3fFramebufferBlitTests.BlitDepthStencilCase; 803 804 /** 805 * @protected 806 */ 807 es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.preCheck = function() { 808 this.checkFormatSupport(this.m_format); 809 return true; // No exception thrown 810 }; 811 812 /** 813 * @protected 814 * @param {tcuSurface.Surface} dst 815 */ 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); 824 825 var flatShaderID = ctx.createProgram(flatShader); 826 var texShaderID = ctx.createProgram(texShader); 827 var gradShaderID = ctx.createProgram(gradShader); 828 829 var srcFbo; 830 var dstFbo; 831 var srcColorRbo; 832 var dstColorRbo; 833 var srcDepthStencilRbo; 834 var dstDepthStencilRbo; 835 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); 839 840 // Create framebuffers 841 // Source framebuffers 842 srcFbo = ctx.createFramebuffer(); 843 srcColorRbo = ctx.createRenderbuffer(); 844 srcDepthStencilRbo = ctx.createRenderbuffer(); 845 846 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcColorRbo); 847 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_srcSize[0], this.m_srcSize[1]); 848 849 ctx.bindRenderbuffer(gl.RENDERBUFFER, srcDepthStencilRbo); 850 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_srcSize[0], this.m_srcSize[1]); 851 852 ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo); 853 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcColorRbo); 854 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); 859 860 this.checkError(); 861 this.checkFramebufferStatus(gl.FRAMEBUFFER); 862 863 // Clear depth to 1 and stencil to 0. 864 ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0); 865 866 // Destination framebuffers 867 dstFbo = ctx.createFramebuffer(); 868 dstColorRbo = ctx.createRenderbuffer(); 869 dstDepthStencilRbo = ctx.createRenderbuffer(); 870 871 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstColorRbo); 872 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_dstSize[0], this.m_dstSize[1]); 873 874 ctx.bindRenderbuffer(gl.RENDERBUFFER, dstDepthStencilRbo); 875 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_dstSize[0], this.m_dstSize[1]); 876 877 ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo); 878 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstColorRbo); 879 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); 884 885 this.checkError(); 886 this.checkFramebufferStatus(gl.FRAMEBUFFER); 887 888 // Clear depth to 1 and stencil to 0. 889 ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0); 890 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); 898 899 rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]); 900 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); 908 909 tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]); 910 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()); 918 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); 922 923 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]); 924 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); 929 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); 935 936 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]); 937 938 rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]); 939 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); 945 946 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]); 947 948 rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]); 949 950 } 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]); 952 953 }; 954 955 /** 956 * @constructor 957 * @extends {es3fFboTestCase.FboTestCase} 958 * @param {string} name 959 * @param {string} desc 960 * @param {number} format 961 * @param {number} filter 962 */ 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; 967 }; 968 969 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype); 970 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.constructor = es3fFramebufferBlitTests.BlitDefaultFramebufferCase; 971 972 /** 973 * @protected 974 */ 975 es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.preCheck = function() { 976 this.checkFormatSupport(this.m_format); 977 return true; // No exception thrown 978 }; 979 980 /** 981 * @protected 982 * @param {tcuSurface.Surface} dst 983 */ 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); 988 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); 991 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; 998 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); 1002 1003 // FBO 1004 fbo = ctx.createFramebuffer(); 1005 tex = ctx.createTexture(); 1006 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); 1013 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); 1018 1019 // Render gradient to screen. 1020 ctx.bindFramebuffer(gl.FRAMEBUFFER, null); 1021 1022 rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]); 1023 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); 1027 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]); 1031 1032 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]); 1033 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); 1037 1038 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null); 1039 this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight()); 1040 1041 }; 1042 1043 /** 1044 * @protected 1045 * @param {tcuSurface.Surface} reference 1046 * @param {tcuSurface.Surface} result 1047 */ 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)); 1051 1052 //m_testCtx.getLog() << TestLog::Message << 'Comparing images, threshold: ' << threshold << TestLog::EndMessage; 1053 1054 return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold); 1055 }; 1056 1057 /** @enum */ 1058 es3fFramebufferBlitTests.BlitDirection = { 1059 BLIT_DEFAULT_TO_TARGET: 0, 1060 BLIT_TO_DEFAULT_FROM_TARGET: 1 1061 }; 1062 1063 /** @enum */ 1064 es3fFramebufferBlitTests.BlitArea = { 1065 AREA_SCALE: 0, 1066 AREA_OUT_OF_BOUNDS: 1 1067 }; 1068 1069 /** 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 1078 */ 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]; 1086 }; 1087 1088 es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype = Object.create(es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype); 1089 es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.constructor = es3fFramebufferBlitTests.DefaultFramebufferBlitCase; 1090 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'); 1097 1098 // prevent viewport randoming 1099 this.m_viewportWidth = gl.drawingBufferWidth; 1100 this.m_viewportHeight = gl.drawingBufferHeight; 1101 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]); 1112 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]]; 1116 } 1117 }; 1118 1119 /** 1120 * @param {tcuSurface.Surface} dst 1121 */ 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); 1132 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); 1141 1142 var targetFbo; 1143 var sourceFbo; 1144 1145 // FBO 1146 fbo = ctx.createFramebuffer(); 1147 fboTex = ctx.createTexture(); 1148 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); 1155 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); 1160 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); 1163 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); 1178 1179 tcuTextureUtil.fillWithGrid(data.getAccess(), 9, [0.9, 0.5, 0.1, 0.9], [0.2, 0.8, 0.2, 0.7]); 1180 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()); 1188 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]); 1192 1193 texShader.setUniforms(this.getCurrentContext(), texShaderID); 1194 1195 rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]); 1196 1197 ctx.useProgram(null); 1198 1199 // Blit source framebuffer to destination 1200 1201 ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, sourceFbo); 1202 ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targetFbo); 1203 this.checkError(); 1204 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); 1215 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(); 1218 1219 // Read target 1220 1221 ctx.bindFramebuffer(gl.FRAMEBUFFER, targetFbo); 1222 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]); 1227 1228 this.checkError(); 1229 }; 1230 1231 es3fFramebufferBlitTests.run = function(context, range) { 1232 gl = context; 1233 //Set up root Test 1234 var state = tcuTestCase.runner; 1235 1236 var test = new es3fFramebufferBlitTests.FramebufferBlitTests(); 1237 var testName = test.fullName(); 1238 var testDescription = test.getDescription() || ''; 1239 1240 state.testName = testName; 1241 state.setRoot(test); 1242 //Set up name and description of this test series. 1243 setCurrentTestName(testName); 1244 description(testDescription); 1245 1246 try { 1247 //Create test cases 1248 test.init(); 1249 if (range) 1250 state.setRange(range); 1251 //Run test cases 1252 tcuTestCase.runTestCases(); 1253 } 1254 catch (err) { 1255 bufferedLogToConsole(err); 1256 testFailedOptions('Failed to es3fFramebufferBlitTests.run tests', false); 1257 tcuTestCase.runner.terminate(); 1258 } 1259 }; 1260 1261 });