es3fFboStencilbufferTests.js (15083B)
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.es3fFboStencilbufferTests'); 22 goog.require('framework.common.tcuSurface'); 23 goog.require('framework.common.tcuTestCase'); 24 goog.require('framework.common.tcuTexture'); 25 goog.require('framework.opengl.gluShaderUtil'); 26 goog.require('framework.opengl.gluTextureUtil'); 27 goog.require('framework.referencerenderer.rrUtil'); 28 goog.require('functional.gles3.es3fFboTestCase'); 29 goog.require('functional.gles3.es3fFboTestUtil'); 30 31 goog.scope(function() { 32 33 var es3fFboStencilbufferTests = functional.gles3.es3fFboStencilbufferTests; 34 var es3fFboTestCase = functional.gles3.es3fFboTestCase; 35 var es3fFboTestUtil = functional.gles3.es3fFboTestUtil; 36 var tcuTestCase = framework.common.tcuTestCase; 37 var tcuSurface = framework.common.tcuSurface; 38 var tcuTexture = framework.common.tcuTexture; 39 var rrUtil = framework.referencerenderer.rrUtil; 40 var gluShaderUtil = framework.opengl.gluShaderUtil; 41 var gluTextureUtil = framework.opengl.gluTextureUtil; 42 43 /** @type {WebGL2RenderingContext} */ var gl; 44 45 var DE_ASSERT = function(x) { 46 if (!x) 47 throw new Error('Assert failed'); 48 }; 49 50 /** 51 * @constructor 52 * @extends {es3fFboTestCase.FboTestCase} 53 * @param {string} name 54 * @param {string} desc 55 * @param {number} format 56 * @param {Array<number>} size 57 * @param {boolean} useDepth 58 */ 59 es3fFboStencilbufferTests.BasicFboStencilCase = function(name, desc, format, size, useDepth) { 60 es3fFboTestCase.FboTestCase.call(this, name, desc); 61 /** @type {number} */ this.m_format = format; 62 /** @type {Array<number>} */ this.m_size = size; 63 /** @type {boolean} */ this.m_useDepth = useDepth; 64 }; 65 66 es3fFboStencilbufferTests.BasicFboStencilCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype); 67 es3fFboStencilbufferTests.BasicFboStencilCase.prototype.constructor = es3fFboStencilbufferTests.BasicFboStencilCase; 68 69 es3fFboStencilbufferTests.BasicFboStencilCase.prototype.preCheck = function() { 70 this.checkFormatSupport(this.m_format); 71 return true; // No exception thrown 72 }; 73 74 /** 75 * @param {tcuSurface.Surface} dst 76 */ 77 es3fFboStencilbufferTests.BasicFboStencilCase.prototype.render = function(dst) { 78 var ctx = this.getCurrentContext(); 79 /** @const {number} */ var colorFormat = gl.RGBA8; 80 81 /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4); 82 /** @type {es3fFboTestUtil.FlatColorShader} */ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4); 83 var flatShaderID = this.getCurrentContext().createProgram(flatShader); 84 var gradShaderID = this.getCurrentContext().createProgram(gradShader); 85 86 var fbo = 0; 87 var colorRbo = 0; 88 var depthStencilRbo = 0; 89 90 // Colorbuffer. 91 colorRbo = ctx.createRenderbuffer(); 92 ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo); 93 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_size[0], this.m_size[1]); 94 95 // Stencil (and depth) buffer. 96 depthStencilRbo = ctx.createRenderbuffer(); 97 ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo); 98 ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_size[0], this.m_size[1]); 99 100 // Framebuffer. 101 fbo = ctx.createFramebuffer(); 102 ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo); 103 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo); 104 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo); 105 if (this.m_useDepth) 106 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo); 107 this.checkError(); 108 this.checkFramebufferStatus(gl.FRAMEBUFFER); 109 110 ctx.viewport(0, 0, this.m_size[0], this.m_size[1]); 111 112 // Clear framebuffer. 113 ctx.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]); 114 ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0); 115 116 // Render intersecting quads - increment stencil on depth pass 117 ctx.enable(gl.DEPTH_TEST); 118 ctx.enable(gl.STENCIL_TEST); 119 ctx.stencilFunc(gl.ALWAYS, 0, 0xff); 120 ctx.stencilOp(gl.KEEP, gl.KEEP, gl.INCR); 121 122 flatShader.setColor(this.getCurrentContext(), flatShaderID, [1.0, 0.0, 0.0, 1.0]); 123 124 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]); 125 126 gradShader.setGradient(this.getCurrentContext(), gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]); 127 128 rrUtil.drawQuad(this.getCurrentContext(), gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]); 129 130 ctx.disable(gl.DEPTH_TEST); 131 132 // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure 133 ctx.stencilFunc(gl.EQUAL, this.m_useDepth ? 2 : 1, 0xff); 134 ctx.stencilOp(gl.DECR, gl.KEEP, gl.KEEP); 135 136 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]); 137 138 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-0.5, -0.5, 0.0], [0.5, 0.5, 0.0]); 139 140 // Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer 141 ctx.stencilFunc(gl.GREATER, this.m_useDepth ? 1 : 2, 0xff); 142 143 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]); 144 145 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]); 146 147 this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], gluTextureUtil.mapGLInternalFormat(colorFormat), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]); 148 }; 149 150 /** 151 * @constructor 152 * @extends {es3fFboTestCase.FboTestCase} 153 * @param {string} name 154 * @param {string} desc 155 * @param {number} attachDepth 156 */ 157 es3fFboStencilbufferTests.DepthStencilAttachCase = function(name, desc, attachDepth, attachStencil) { 158 es3fFboTestCase.FboTestCase.call(this, name, desc); 159 /** @type {number} */ this.m_attachDepth = attachDepth; 160 /** @type {number} */ this.m_attachStencil = attachStencil; 161 DE_ASSERT(this.m_attachDepth == gl.DEPTH_ATTACHMENT || this.m_attachDepth == gl.DEPTH_STENCIL_ATTACHMENT || this.m_attachDepth == gl.NONE); 162 DE_ASSERT(this.m_attachStencil == gl.STENCIL_ATTACHMENT || this.m_attachStencil == gl.NONE); 163 DE_ASSERT(this.m_attachDepth != gl.DEPTH_STENCIL || this.m_attachStencil == gl.NONE); 164 }; 165 166 es3fFboStencilbufferTests.DepthStencilAttachCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype); 167 es3fFboStencilbufferTests.DepthStencilAttachCase.prototype.constructor = es3fFboStencilbufferTests.DepthStencilAttachCase; 168 169 /** 170 * @param {tcuSurface.Surface} dst 171 */ 172 es3fFboStencilbufferTests.DepthStencilAttachCase.prototype.render = function(dst) { 173 174 var ctx = this.getCurrentContext(); 175 /** @const {number} */ var colorFormat = gl.RGBA8; 176 /** @const {number} */ var depthStencilFormat = gl.DEPTH24_STENCIL8; 177 /** @const {number} */ var width = 128; 178 /** @const {number} */ var height = 128; 179 /** @const {boolean} */ var hasDepth = this.m_attachDepth == gl.DEPTH_STENCIL || this.m_attachDepth == gl.DEPTH_ATTACHMENT; 180 // /** @const {boolean} */ var hasStencil = this.m_attachDepth == gl.DEPTH_STENCIL || this.m_attachStencil == gl.DEPTH_STENCIL_ATTACHMENT); // commented out in original code 181 182 /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4); 183 /** @type {es3fFboTestUtil.FlatColorShader} */ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4); 184 var flatShaderID = this.getCurrentContext().createProgram(flatShader); 185 var gradShaderID = this.getCurrentContext().createProgram(gradShader); 186 187 var fbo = 0; 188 var colorRbo = 0; 189 var depthStencilRbo = 0; 190 191 // Colorbuffer. 192 colorRbo = ctx.createRenderbuffer(); 193 ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo); 194 ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, width, height); 195 196 // Depth-stencil buffer. 197 depthStencilRbo = ctx.createRenderbuffer(); 198 ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo); 199 ctx.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, width, height); 200 201 // Framebuffer. 202 fbo = ctx.createFramebuffer(); 203 ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo); 204 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo); 205 206 if (this.m_attachDepth != gl.NONE) 207 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, this.m_attachDepth, gl.RENDERBUFFER, depthStencilRbo); 208 if (this.m_attachStencil != gl.NONE) 209 ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, this.m_attachStencil, gl.RENDERBUFFER, depthStencilRbo); 210 211 this.checkError(); 212 this.checkFramebufferStatus(gl.FRAMEBUFFER); 213 214 ctx.viewport(0, 0, width, height); 215 216 // Clear framebuffer. 217 ctx.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]); 218 ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0); 219 220 // Render intersecting quads - increment stencil on depth pass 221 ctx.enable(gl.DEPTH_TEST); 222 ctx.enable(gl.STENCIL_TEST); 223 ctx.stencilFunc(gl.ALWAYS, 0, 0xff); 224 ctx.stencilOp(gl.KEEP, gl.KEEP, gl.INCR); 225 226 flatShader.setColor(this.getCurrentContext(), flatShaderID, [1.0, 0.0, 0.0, 1.0]); 227 228 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]); 229 230 gradShader.setGradient(this.getCurrentContext(), gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]); 231 232 rrUtil.drawQuad(this.getCurrentContext(), gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]); 233 234 ctx.disable(gl.DEPTH_TEST); 235 236 // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure 237 ctx.stencilFunc(gl.EQUAL, hasDepth ? 2 : 1, 0xff); 238 ctx.stencilOp(gl.DECR, gl.KEEP, gl.KEEP); 239 240 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]); 241 242 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-0.5, -0.5, 0.0], [0.5, 0.5, 0.0]); 243 244 // Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer 245 ctx.stencilFunc(gl.GREATER, hasDepth ? 1 : 2, 0xff); 246 247 flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]); 248 249 rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]); 250 251 this.readPixelsUsingFormat(dst, 0, 0, width, height, gluTextureUtil.mapGLInternalFormat(colorFormat), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]); 252 }; 253 254 /** 255 * @constructor 256 * @extends {tcuTestCase.DeqpTest} 257 */ 258 es3fFboStencilbufferTests.FboStencilTests = function() { 259 tcuTestCase.DeqpTest.call(this, 'stencil', 'FBO Stencilbuffer tests'); 260 }; 261 262 es3fFboStencilbufferTests.FboStencilTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 263 es3fFboStencilbufferTests.FboStencilTests.prototype.constructor = es3fFboStencilbufferTests.FboStencilTests; 264 265 es3fFboStencilbufferTests.FboStencilTests.prototype.init = function() { 266 /** @const {Array<number>} */ var stencilFormats = [ 267 gl.DEPTH32F_STENCIL8, 268 gl.DEPTH24_STENCIL8, 269 gl.STENCIL_INDEX8 270 ]; 271 272 // .basic 273 /** @type {tcuTestCase.DeqpTest} */ 274 var basicGroup = tcuTestCase.newTest('basic', 'Basic stencil tests'); 275 this.addChild(basicGroup); 276 277 for (var fmtNdx = 0; fmtNdx < stencilFormats.length; fmtNdx++) { 278 /** @type {number} */ var format = stencilFormats[fmtNdx]; 279 /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(format); 280 281 basicGroup.addChild(new es3fFboStencilbufferTests.BasicFboStencilCase(es3fFboTestUtil.getFormatName(format), '', format, [111, 132], false)); 282 283 if (texFmt.order == tcuTexture.ChannelOrder.DS) 284 basicGroup.addChild(new es3fFboStencilbufferTests.BasicFboStencilCase(es3fFboTestUtil.getFormatName(format) + '_depth', '', format, [111, 132], true)); 285 } 286 287 // .attach 288 /** @type {tcuTestCase.DeqpTest} */ 289 var attachGroup = tcuTestCase.newTest('attach', 'Attaching depth stencil'); 290 this.addChild(attachGroup); 291 292 attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('depth_only', 'Only depth part of depth-stencil RBO attached', gl.DEPTH_ATTACHMENT, gl.NONE)); 293 attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('stencil_only', 'Only stencil part of depth-stencil RBO attached', gl.NONE, gl.STENCIL_ATTACHMENT)); 294 attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('depth_stencil_separate', 'Depth and stencil attached separately', gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT)); 295 attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('depth_stencil_attachment', 'Depth and stencil attached with DEPTH_STENCIL_ATTACHMENT', gl.DEPTH_STENCIL_ATTACHMENT, gl.NONE)); 296 }; 297 298 es3fFboStencilbufferTests.run = function(context) { 299 gl = context; 300 //Set up root Test 301 var state = tcuTestCase.runner; 302 303 var test = new es3fFboStencilbufferTests.FboStencilTests(); 304 var testName = test.fullName(); 305 var testDescription = test.getDescription(); 306 307 state.testName = testName; 308 state.setRoot(test); 309 //Set up name and description of this test series. 310 setCurrentTestName(testName); 311 description(testDescription); 312 313 try { 314 //Create test cases 315 test.init(); 316 //Run test cases 317 tcuTestCase.runTestCases(); 318 } 319 catch (err) { 320 testFailedOptions('Failed to es3fFboStencilbufferTests.run tests', false); 321 tcuTestCase.runner.terminate(); 322 } 323 }; 324 325 });