1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/canvas/test/webgl-conformance/conformance/renderbuffers/framebuffer-object-attachment.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,423 @@ 1.4 +<!-- 1.5 +Copyright (c) 2011 The Chromium Authors. 1.6 +Copyright (c) 2011 Mozilla Foundation. 1.7 + 1.8 +All rights reserved. 1.9 +Use of this source code is governed by a BSD-style license that can be 1.10 +found in the LICENSE file. 1.11 + --> 1.12 +<!DOCTYPE html> 1.13 +<html> 1.14 +<head> 1.15 +<meta charset="utf-8"> 1.16 +<link rel="stylesheet" href="../../resources/js-test-style.css"/> 1.17 +<script src="../../resources/js-test-pre.js"></script> 1.18 +<script src="../resources/webgl-test.js"></script> 1.19 +<script src="../resources/webgl-test-utils.js"></script> 1.20 +</head> 1.21 +<body> 1.22 +<div id="description"></div> 1.23 +<div id="console"></div> 1.24 + 1.25 +<script> 1.26 +var wtu = WebGLTestUtils; 1.27 +var gl; 1.28 +var fbo; 1.29 +var depthBuffer; 1.30 +var stencilBuffer; 1.31 +var depthStencilBuffer; 1.32 +var colorBuffer; 1.33 +var width; 1.34 +var height; 1.35 + 1.36 +const ALLOW_COMPLETE = 0x01; 1.37 +const ALLOW_UNSUPPORTED = 0x02; 1.38 +const ALLOW_INCOMPLETE_ATTACHMENT = 0x04; 1.39 + 1.40 +function checkFramebufferForAllowedStatuses(allowedStatuses) 1.41 +{ 1.42 + // If the framebuffer is in an error state for multiple reasons, 1.43 + // we can't guarantee which one will be reported. 1.44 + var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); 1.45 + var statusAllowed = ((allowedStatuses & ALLOW_COMPLETE) && (status == gl.FRAMEBUFFER_COMPLETE)) || 1.46 + ((allowedStatuses & ALLOW_UNSUPPORTED) && (status == gl.FRAMEBUFFER_UNSUPPORTED)) || 1.47 + ((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) && (status == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT)); 1.48 + var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) returned " + status; 1.49 + if (statusAllowed) 1.50 + testPassed(msg); 1.51 + else 1.52 + testFailed(msg); 1.53 +} 1.54 + 1.55 +function testAttachment(attachment, buffer, allowedStatuses) 1.56 +{ 1.57 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.58 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.59 + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.60 + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer); 1.61 + glErrorShouldBe(gl, gl.NO_ERROR); 1.62 + checkFramebufferForAllowedStatuses(allowedStatuses); 1.63 + if ((allowedStatuses & ALLOW_COMPLETE) == 0) { 1.64 + gl.clear(gl.COLOR_BUFFER_BIT); 1.65 + glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION); 1.66 + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4)); 1.67 + glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION); 1.68 + } 1.69 + gl.deleteFramebuffer(fbo); 1.70 +} 1.71 + 1.72 +function testAttachments(attachment0, buffer0, attachment1, buffer1, allowedStatuses) 1.73 +{ 1.74 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.75 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.76 + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.77 + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0); 1.78 + glErrorShouldBe(gl, gl.NO_ERROR); 1.79 + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1); 1.80 + glErrorShouldBe(gl, gl.NO_ERROR); 1.81 + checkFramebufferForAllowedStatuses(allowedStatuses); 1.82 + gl.deleteFramebuffer(fbo); 1.83 +} 1.84 + 1.85 +function testColorRenderbuffer(internalformat, allowedStatuses) 1.86 +{ 1.87 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.88 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.89 + gl.renderbufferStorage(gl.RENDERBUFFER, internalformat, width, height); 1.90 + glErrorShouldBe(gl, gl.NO_ERROR); 1.91 + testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, allowedStatuses); 1.92 +} 1.93 + 1.94 +function testDepthStencilRenderbuffer(allowedStatuses) 1.95 +{ 1.96 + shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()"); 1.97 + gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer); 1.98 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); 1.99 + glErrorShouldBe(gl, gl.NO_ERROR); 1.100 + 1.101 + // OpenGL itself doesn't seem to guarantee that e.g. a 2 x 0 1.102 + // renderbuffer will report 2 for its width when queried. 1.103 + if (!(height == 0 && width > 0)) 1.104 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH)", "width"); 1.105 + if (!(width == 0 && height > 0)) 1.106 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT)", "height"); 1.107 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_INTERNAL_FORMAT)", "gl.DEPTH_STENCIL"); 1.108 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_RED_SIZE)", "0"); 1.109 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_GREEN_SIZE)", "0"); 1.110 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_BLUE_SIZE)", "0"); 1.111 + shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_ALPHA_SIZE)", "0"); 1.112 + // Avoid verifying these for zero-sized renderbuffers for the time 1.113 + // being since it appears that even OpenGL doesn't guarantee them. 1.114 + if (width > 0 && height > 0) { 1.115 + shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_DEPTH_SIZE) > 0"); 1.116 + shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE) > 0"); 1.117 + } 1.118 + glErrorShouldBe(gl, gl.NO_ERROR); 1.119 + testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatuses); 1.120 +} 1.121 + 1.122 +description("Test framebuffer object attachment behaviors"); 1.123 + 1.124 +for (width = 0; width <= 2; width += 2) 1.125 +{ 1.126 + for (height = 0; height <= 2; height += 2) 1.127 + { 1.128 + debug(""); 1.129 + debug("Dimensions " + width + " x " + height); 1.130 + 1.131 + debug("Create renderbuffers"); 1.132 + shouldBeNonNull("gl = create3DContext()"); 1.133 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.134 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.135 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height); 1.136 + glErrorShouldBe(gl, gl.NO_ERROR); 1.137 + shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); 1.138 + gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); 1.139 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); 1.140 + glErrorShouldBe(gl, gl.NO_ERROR); 1.141 + shouldBeNonNull("stencilBuffer = gl.createRenderbuffer()"); 1.142 + gl.bindRenderbuffer(gl.RENDERBUFFER, stencilBuffer); 1.143 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, width, height); 1.144 + glErrorShouldBe(gl, gl.NO_ERROR); 1.145 + shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()"); 1.146 + gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer); 1.147 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); 1.148 + glErrorShouldBe(gl, gl.NO_ERROR); 1.149 + 1.150 + var allowedStatusForGoodCase 1.151 + = (width == 0 || height == 0) ? ALLOW_INCOMPLETE_ATTACHMENT : ALLOW_COMPLETE; 1.152 + 1.153 + // some cases involving stencil seem to be implementation-dependent 1.154 + var allowedStatusForImplDependentCase = allowedStatusForGoodCase | ALLOW_UNSUPPORTED; 1.155 + 1.156 + debug("Attach depth using DEPTH_ATTACHMENT"); 1.157 + testAttachment(gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForGoodCase); 1.158 + debug("Attach depth using STENCIL_ATTACHMENT"); 1.159 + testAttachment(gl.STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT); 1.160 + debug("Attach depth using DEPTH_STENCIL_ATTACHMENT"); 1.161 + testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT); 1.162 + debug("Attach stencil using STENCIL_ATTACHMENT"); 1.163 + testAttachment(gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForImplDependentCase); 1.164 + debug("Attach stencil using DEPTH_ATTACHMENT"); 1.165 + testAttachment(gl.DEPTH_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); 1.166 + debug("Attach stencil using DEPTH_STENCIL_ATTACHMENT"); 1.167 + testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); 1.168 + debug("Attach depthStencil using DEPTH_STENCIL_ATTACHMENT"); 1.169 + testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForGoodCase); 1.170 + debug("Attach depthStencil using DEPTH_ATTACHMENT"); 1.171 + testAttachment(gl.DEPTH_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); 1.172 + debug("Attach depthStencil using STENCIL_ATTACHMENT"); 1.173 + testAttachment(gl.STENCIL_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); 1.174 + 1.175 + var allowedStatusForConflictedAttachment 1.176 + = (width == 0 || height == 0) ? ALLOW_UNSUPPORTED | ALLOW_INCOMPLETE_ATTACHMENT 1.177 + : ALLOW_UNSUPPORTED; 1.178 + 1.179 + debug("Attach depth, then stencil, causing conflict"); 1.180 + testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment); 1.181 + debug("Attach stencil, then depth, causing conflict"); 1.182 + testAttachments(gl.STENCIL_ATTACHMENT, stencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment); 1.183 + debug("Attach depth, then depthStencil, causing conflict"); 1.184 + testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment); 1.185 + debug("Attach depthStencil, then depth, causing conflict"); 1.186 + testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment); 1.187 + debug("Attach stencil, then depthStencil, causing conflict"); 1.188 + testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment); 1.189 + debug("Attach depthStencil, then stencil, causing conflict"); 1.190 + testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment); 1.191 + 1.192 + debug("Attach color renderbuffer with internalformat == RGBA4"); 1.193 + testColorRenderbuffer(gl.RGBA4, allowedStatusForGoodCase); 1.194 + 1.195 + debug("Attach color renderbuffer with internalformat == RGB5_A1"); 1.196 + testColorRenderbuffer(gl.RGB5_A1, allowedStatusForGoodCase); 1.197 + 1.198 + debug("Attach color renderbuffer with internalformat == RGB565"); 1.199 + testColorRenderbuffer(gl.RGB565, allowedStatusForGoodCase); 1.200 + 1.201 + debug("Create and attach depthStencil renderbuffer"); 1.202 + testDepthStencilRenderbuffer(allowedStatusForGoodCase); 1.203 + } 1.204 +} 1.205 + 1.206 +// Determine if we can attach both color and depth or color and depth_stencil 1.207 +var depthFormat; 1.208 +var depthAttachment; 1.209 + 1.210 +function checkValidColorDepthCombination() { 1.211 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.212 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.213 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.214 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.215 + gl.framebufferRenderbuffer( 1.216 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.217 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.218 + 1.219 + shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); 1.220 + gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); 1.221 + 1.222 + return tryDepth(gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT) || tryDepth(gl.DEPTH_STENCIL, gl.DEPTH_STENCIL_ATTACHMENT); 1.223 + 1.224 + function tryDepth(try_format, try_attachment) { 1.225 + if (depthAttachment) { 1.226 + // If we've tried once unattach the old one. 1.227 + gl.framebufferRenderbuffer( 1.228 + gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, null); 1.229 + } 1.230 + depthFormat = try_format; 1.231 + depthAttachment = try_attachment; 1.232 + gl.framebufferRenderbuffer( 1.233 + gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer); 1.234 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); 1.235 + glErrorShouldBe(gl, gl.NO_ERROR); 1.236 + return gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE; 1.237 + } 1.238 +} 1.239 + 1.240 +if (checkValidColorDepthCombination()) { 1.241 + testFramebufferIncompleteDimensions(); 1.242 + testFramebufferIncompleteAttachment(); 1.243 + testFramebufferIncompleteMissingAttachment(); 1.244 + testUsingIncompleteFramebuffer(); 1.245 +} 1.246 + 1.247 +function checkFramebuffer(expected) { 1.248 + var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER); 1.249 + var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be " + wtu.glEnumToString(gl, expected) + " was " + wtu.glEnumToString(gl, actual); 1.250 + if (expected != gl.FRAMEBUFFER_COMPLETE) { 1.251 + msg += " or FRAMEBUFFER_UNSUPPORTED"; 1.252 + } 1.253 + if (actual == expected || 1.254 + (expected != gl.FRAMEBUFFER_COMPLETE && 1.255 + actual == gl.FRAMBUFFER_UNSUPPORTED)) { 1.256 + testPassed(msg); 1.257 + } else { 1.258 + testFailed(msg); 1.259 + } 1.260 +} 1.261 + 1.262 +function testUsingIncompleteFramebuffer() { 1.263 + debug(""); 1.264 + debug("Test drawing or reading from an incomplete framebuffer"); 1.265 + var program = wtu.setupTexturedQuad(gl); 1.266 + var tex = gl.createTexture(); 1.267 + wtu.fillTexture(gl, tex, 1, 1, [0,255,0,255]); 1.268 + 1.269 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.270 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.271 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.272 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.273 + gl.framebufferRenderbuffer( 1.274 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.275 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.276 + 1.277 + shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); 1.278 + gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); 1.279 + gl.framebufferRenderbuffer( 1.280 + gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer); 1.281 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); 1.282 + glErrorShouldBe(gl, gl.NO_ERROR); 1.283 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.284 + 1.285 + // We pick this combination because it works on desktop OpenGL but should not work on OpenGL ES 2.0 1.286 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16); 1.287 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); 1.288 + debug(""); 1.289 + debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION"); 1.290 + testRenderingAndReading(); 1.291 + 1.292 + shouldBeNonNull("fbo2 = gl.createFramebuffer()"); 1.293 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2); 1.294 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); 1.295 + debug(""); 1.296 + debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION"); 1.297 + testRenderingAndReading(); 1.298 + 1.299 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.300 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.301 + gl.framebufferRenderbuffer( 1.302 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.303 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0); 1.304 + debug(""); 1.305 + debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION"); 1.306 + testRenderingAndReading(); 1.307 + 1.308 + function testRenderingAndReading() { 1.309 + glErrorShouldBe(gl, gl.NO_ERROR); 1.310 + wtu.drawQuad(gl); 1.311 + glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer"); 1.312 + gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4)); 1.313 + glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer"); 1.314 + // copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because 1.315 + // the framebuffer is invalid OR INVALID_OPERATION because in the case of no attachments 1.316 + // the framebuffer is not of a compatible type. 1.317 + gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1); 1.318 + glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexImage2D from incomplete framebuffer"); 1.319 + gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0); 1.320 + glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexSubImage2D from incomplete framebuffer"); 1.321 + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 1.322 + glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer"); 1.323 + } 1.324 +} 1.325 + 1.326 +function testFramebufferIncompleteAttachment() { 1.327 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.328 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.329 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.330 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.331 + gl.framebufferRenderbuffer( 1.332 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.333 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.334 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.335 + 1.336 + debug(""); 1.337 + debug("Wrong storage type for type of attachment be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)"); 1.338 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); 1.339 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT); 1.340 + 1.341 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.342 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.343 + 1.344 + debug(""); 1.345 + debug("0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)"); 1.346 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0); 1.347 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT); 1.348 + 1.349 + glErrorShouldBe(gl, gl.NO_ERROR); 1.350 +} 1.351 + 1.352 +function testFramebufferIncompleteMissingAttachment() { 1.353 + debug(""); 1.354 + debug("No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT (OpenGL ES 2.0 4.4.5)"); 1.355 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.356 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.357 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); 1.358 + 1.359 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.360 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.361 + gl.framebufferRenderbuffer( 1.362 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.363 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.364 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.365 + 1.366 + gl.framebufferRenderbuffer( 1.367 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null); 1.368 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); 1.369 + 1.370 + glErrorShouldBe(gl, gl.NO_ERROR); 1.371 +} 1.372 + 1.373 +function testFramebufferIncompleteDimensions() { 1.374 + debug(""); 1.375 + debug("Attachments of different sizes should be FRAMEBUFFER_INCOMPLETE_DIMENSIONS (OpenGL ES 2.0 4.4.5)"); 1.376 + 1.377 + shouldBeNonNull("fbo = gl.createFramebuffer()"); 1.378 + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1.379 + shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); 1.380 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.381 + gl.framebufferRenderbuffer( 1.382 + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); 1.383 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.384 + 1.385 + shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); 1.386 + gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); 1.387 + gl.framebufferRenderbuffer( 1.388 + gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer); 1.389 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); 1.390 + glErrorShouldBe(gl, gl.NO_ERROR); 1.391 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.392 + 1.393 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16); 1.394 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); 1.395 + gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); 1.396 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.397 + gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); 1.398 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32); 1.399 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); 1.400 + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); 1.401 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.402 + glErrorShouldBe(gl, gl.NO_ERROR); 1.403 + 1.404 + var tex = gl.createTexture(); 1.405 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.406 + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 1.407 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); 1.408 + glErrorShouldBe(gl, gl.NO_ERROR); 1.409 + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { 1.410 + return; 1.411 + } 1.412 + 1.413 + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 1.414 + checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); 1.415 + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 1.416 + checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); 1.417 + 1.418 + glErrorShouldBe(gl, gl.NO_ERROR); 1.419 +} 1.420 + 1.421 +successfullyParsed = true; 1.422 +</script> 1.423 + 1.424 +<script>finishTest();</script> 1.425 +</body> 1.426 +</html>