Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | <!-- |
michael@0 | 2 | Copyright (c) 2011 The Chromium Authors. |
michael@0 | 3 | Copyright (c) 2011 Mozilla Foundation. |
michael@0 | 4 | |
michael@0 | 5 | All rights reserved. |
michael@0 | 6 | Use of this source code is governed by a BSD-style license that can be |
michael@0 | 7 | found in the LICENSE file. |
michael@0 | 8 | --> |
michael@0 | 9 | <!DOCTYPE html> |
michael@0 | 10 | <html> |
michael@0 | 11 | <head> |
michael@0 | 12 | <meta charset="utf-8"> |
michael@0 | 13 | <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
michael@0 | 14 | <script src="../../resources/js-test-pre.js"></script> |
michael@0 | 15 | <script src="../resources/webgl-test.js"></script> |
michael@0 | 16 | <script src="../resources/webgl-test-utils.js"></script> |
michael@0 | 17 | </head> |
michael@0 | 18 | <body> |
michael@0 | 19 | <div id="description"></div> |
michael@0 | 20 | <div id="console"></div> |
michael@0 | 21 | |
michael@0 | 22 | <script> |
michael@0 | 23 | var wtu = WebGLTestUtils; |
michael@0 | 24 | var gl; |
michael@0 | 25 | var fbo; |
michael@0 | 26 | var depthBuffer; |
michael@0 | 27 | var stencilBuffer; |
michael@0 | 28 | var depthStencilBuffer; |
michael@0 | 29 | var colorBuffer; |
michael@0 | 30 | var width; |
michael@0 | 31 | var height; |
michael@0 | 32 | |
michael@0 | 33 | const ALLOW_COMPLETE = 0x01; |
michael@0 | 34 | const ALLOW_UNSUPPORTED = 0x02; |
michael@0 | 35 | const ALLOW_INCOMPLETE_ATTACHMENT = 0x04; |
michael@0 | 36 | |
michael@0 | 37 | function checkFramebufferForAllowedStatuses(allowedStatuses) |
michael@0 | 38 | { |
michael@0 | 39 | // If the framebuffer is in an error state for multiple reasons, |
michael@0 | 40 | // we can't guarantee which one will be reported. |
michael@0 | 41 | var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); |
michael@0 | 42 | var statusAllowed = ((allowedStatuses & ALLOW_COMPLETE) && (status == gl.FRAMEBUFFER_COMPLETE)) || |
michael@0 | 43 | ((allowedStatuses & ALLOW_UNSUPPORTED) && (status == gl.FRAMEBUFFER_UNSUPPORTED)) || |
michael@0 | 44 | ((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) && (status == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT)); |
michael@0 | 45 | var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) returned " + status; |
michael@0 | 46 | if (statusAllowed) |
michael@0 | 47 | testPassed(msg); |
michael@0 | 48 | else |
michael@0 | 49 | testFailed(msg); |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | function testAttachment(attachment, buffer, allowedStatuses) |
michael@0 | 53 | { |
michael@0 | 54 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 55 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 56 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 57 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer); |
michael@0 | 58 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 59 | checkFramebufferForAllowedStatuses(allowedStatuses); |
michael@0 | 60 | if ((allowedStatuses & ALLOW_COMPLETE) == 0) { |
michael@0 | 61 | gl.clear(gl.COLOR_BUFFER_BIT); |
michael@0 | 62 | glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION); |
michael@0 | 63 | gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4)); |
michael@0 | 64 | glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION); |
michael@0 | 65 | } |
michael@0 | 66 | gl.deleteFramebuffer(fbo); |
michael@0 | 67 | } |
michael@0 | 68 | |
michael@0 | 69 | function testAttachments(attachment0, buffer0, attachment1, buffer1, allowedStatuses) |
michael@0 | 70 | { |
michael@0 | 71 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 72 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 73 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 74 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0); |
michael@0 | 75 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 76 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1); |
michael@0 | 77 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 78 | checkFramebufferForAllowedStatuses(allowedStatuses); |
michael@0 | 79 | gl.deleteFramebuffer(fbo); |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | function testColorRenderbuffer(internalformat, allowedStatuses) |
michael@0 | 83 | { |
michael@0 | 84 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 85 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 86 | gl.renderbufferStorage(gl.RENDERBUFFER, internalformat, width, height); |
michael@0 | 87 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 88 | testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, allowedStatuses); |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | function testDepthStencilRenderbuffer(allowedStatuses) |
michael@0 | 92 | { |
michael@0 | 93 | shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()"); |
michael@0 | 94 | gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer); |
michael@0 | 95 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); |
michael@0 | 96 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 97 | |
michael@0 | 98 | // OpenGL itself doesn't seem to guarantee that e.g. a 2 x 0 |
michael@0 | 99 | // renderbuffer will report 2 for its width when queried. |
michael@0 | 100 | if (!(height == 0 && width > 0)) |
michael@0 | 101 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH)", "width"); |
michael@0 | 102 | if (!(width == 0 && height > 0)) |
michael@0 | 103 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT)", "height"); |
michael@0 | 104 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_INTERNAL_FORMAT)", "gl.DEPTH_STENCIL"); |
michael@0 | 105 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_RED_SIZE)", "0"); |
michael@0 | 106 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_GREEN_SIZE)", "0"); |
michael@0 | 107 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_BLUE_SIZE)", "0"); |
michael@0 | 108 | shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_ALPHA_SIZE)", "0"); |
michael@0 | 109 | // Avoid verifying these for zero-sized renderbuffers for the time |
michael@0 | 110 | // being since it appears that even OpenGL doesn't guarantee them. |
michael@0 | 111 | if (width > 0 && height > 0) { |
michael@0 | 112 | shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_DEPTH_SIZE) > 0"); |
michael@0 | 113 | shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE) > 0"); |
michael@0 | 114 | } |
michael@0 | 115 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 116 | testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatuses); |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | description("Test framebuffer object attachment behaviors"); |
michael@0 | 120 | |
michael@0 | 121 | for (width = 0; width <= 2; width += 2) |
michael@0 | 122 | { |
michael@0 | 123 | for (height = 0; height <= 2; height += 2) |
michael@0 | 124 | { |
michael@0 | 125 | debug(""); |
michael@0 | 126 | debug("Dimensions " + width + " x " + height); |
michael@0 | 127 | |
michael@0 | 128 | debug("Create renderbuffers"); |
michael@0 | 129 | shouldBeNonNull("gl = create3DContext()"); |
michael@0 | 130 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 131 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 132 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height); |
michael@0 | 133 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 134 | shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); |
michael@0 | 135 | gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); |
michael@0 | 136 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); |
michael@0 | 137 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 138 | shouldBeNonNull("stencilBuffer = gl.createRenderbuffer()"); |
michael@0 | 139 | gl.bindRenderbuffer(gl.RENDERBUFFER, stencilBuffer); |
michael@0 | 140 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, width, height); |
michael@0 | 141 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 142 | shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()"); |
michael@0 | 143 | gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer); |
michael@0 | 144 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); |
michael@0 | 145 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 146 | |
michael@0 | 147 | var allowedStatusForGoodCase |
michael@0 | 148 | = (width == 0 || height == 0) ? ALLOW_INCOMPLETE_ATTACHMENT : ALLOW_COMPLETE; |
michael@0 | 149 | |
michael@0 | 150 | // some cases involving stencil seem to be implementation-dependent |
michael@0 | 151 | var allowedStatusForImplDependentCase = allowedStatusForGoodCase | ALLOW_UNSUPPORTED; |
michael@0 | 152 | |
michael@0 | 153 | debug("Attach depth using DEPTH_ATTACHMENT"); |
michael@0 | 154 | testAttachment(gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForGoodCase); |
michael@0 | 155 | debug("Attach depth using STENCIL_ATTACHMENT"); |
michael@0 | 156 | testAttachment(gl.STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
michael@0 | 157 | debug("Attach depth using DEPTH_STENCIL_ATTACHMENT"); |
michael@0 | 158 | testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
michael@0 | 159 | debug("Attach stencil using STENCIL_ATTACHMENT"); |
michael@0 | 160 | testAttachment(gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForImplDependentCase); |
michael@0 | 161 | debug("Attach stencil using DEPTH_ATTACHMENT"); |
michael@0 | 162 | testAttachment(gl.DEPTH_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
michael@0 | 163 | debug("Attach stencil using DEPTH_STENCIL_ATTACHMENT"); |
michael@0 | 164 | testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
michael@0 | 165 | debug("Attach depthStencil using DEPTH_STENCIL_ATTACHMENT"); |
michael@0 | 166 | testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForGoodCase); |
michael@0 | 167 | debug("Attach depthStencil using DEPTH_ATTACHMENT"); |
michael@0 | 168 | testAttachment(gl.DEPTH_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
michael@0 | 169 | debug("Attach depthStencil using STENCIL_ATTACHMENT"); |
michael@0 | 170 | testAttachment(gl.STENCIL_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
michael@0 | 171 | |
michael@0 | 172 | var allowedStatusForConflictedAttachment |
michael@0 | 173 | = (width == 0 || height == 0) ? ALLOW_UNSUPPORTED | ALLOW_INCOMPLETE_ATTACHMENT |
michael@0 | 174 | : ALLOW_UNSUPPORTED; |
michael@0 | 175 | |
michael@0 | 176 | debug("Attach depth, then stencil, causing conflict"); |
michael@0 | 177 | testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment); |
michael@0 | 178 | debug("Attach stencil, then depth, causing conflict"); |
michael@0 | 179 | testAttachments(gl.STENCIL_ATTACHMENT, stencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment); |
michael@0 | 180 | debug("Attach depth, then depthStencil, causing conflict"); |
michael@0 | 181 | testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment); |
michael@0 | 182 | debug("Attach depthStencil, then depth, causing conflict"); |
michael@0 | 183 | testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment); |
michael@0 | 184 | debug("Attach stencil, then depthStencil, causing conflict"); |
michael@0 | 185 | testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment); |
michael@0 | 186 | debug("Attach depthStencil, then stencil, causing conflict"); |
michael@0 | 187 | testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment); |
michael@0 | 188 | |
michael@0 | 189 | debug("Attach color renderbuffer with internalformat == RGBA4"); |
michael@0 | 190 | testColorRenderbuffer(gl.RGBA4, allowedStatusForGoodCase); |
michael@0 | 191 | |
michael@0 | 192 | debug("Attach color renderbuffer with internalformat == RGB5_A1"); |
michael@0 | 193 | testColorRenderbuffer(gl.RGB5_A1, allowedStatusForGoodCase); |
michael@0 | 194 | |
michael@0 | 195 | debug("Attach color renderbuffer with internalformat == RGB565"); |
michael@0 | 196 | testColorRenderbuffer(gl.RGB565, allowedStatusForGoodCase); |
michael@0 | 197 | |
michael@0 | 198 | debug("Create and attach depthStencil renderbuffer"); |
michael@0 | 199 | testDepthStencilRenderbuffer(allowedStatusForGoodCase); |
michael@0 | 200 | } |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | // Determine if we can attach both color and depth or color and depth_stencil |
michael@0 | 204 | var depthFormat; |
michael@0 | 205 | var depthAttachment; |
michael@0 | 206 | |
michael@0 | 207 | function checkValidColorDepthCombination() { |
michael@0 | 208 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 209 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 210 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 211 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 212 | gl.framebufferRenderbuffer( |
michael@0 | 213 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 214 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 215 | |
michael@0 | 216 | shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); |
michael@0 | 217 | gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); |
michael@0 | 218 | |
michael@0 | 219 | return tryDepth(gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT) || tryDepth(gl.DEPTH_STENCIL, gl.DEPTH_STENCIL_ATTACHMENT); |
michael@0 | 220 | |
michael@0 | 221 | function tryDepth(try_format, try_attachment) { |
michael@0 | 222 | if (depthAttachment) { |
michael@0 | 223 | // If we've tried once unattach the old one. |
michael@0 | 224 | gl.framebufferRenderbuffer( |
michael@0 | 225 | gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, null); |
michael@0 | 226 | } |
michael@0 | 227 | depthFormat = try_format; |
michael@0 | 228 | depthAttachment = try_attachment; |
michael@0 | 229 | gl.framebufferRenderbuffer( |
michael@0 | 230 | gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer); |
michael@0 | 231 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); |
michael@0 | 232 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 233 | return gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE; |
michael@0 | 234 | } |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | if (checkValidColorDepthCombination()) { |
michael@0 | 238 | testFramebufferIncompleteDimensions(); |
michael@0 | 239 | testFramebufferIncompleteAttachment(); |
michael@0 | 240 | testFramebufferIncompleteMissingAttachment(); |
michael@0 | 241 | testUsingIncompleteFramebuffer(); |
michael@0 | 242 | } |
michael@0 | 243 | |
michael@0 | 244 | function checkFramebuffer(expected) { |
michael@0 | 245 | var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER); |
michael@0 | 246 | var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be " + wtu.glEnumToString(gl, expected) + " was " + wtu.glEnumToString(gl, actual); |
michael@0 | 247 | if (expected != gl.FRAMEBUFFER_COMPLETE) { |
michael@0 | 248 | msg += " or FRAMEBUFFER_UNSUPPORTED"; |
michael@0 | 249 | } |
michael@0 | 250 | if (actual == expected || |
michael@0 | 251 | (expected != gl.FRAMEBUFFER_COMPLETE && |
michael@0 | 252 | actual == gl.FRAMBUFFER_UNSUPPORTED)) { |
michael@0 | 253 | testPassed(msg); |
michael@0 | 254 | } else { |
michael@0 | 255 | testFailed(msg); |
michael@0 | 256 | } |
michael@0 | 257 | } |
michael@0 | 258 | |
michael@0 | 259 | function testUsingIncompleteFramebuffer() { |
michael@0 | 260 | debug(""); |
michael@0 | 261 | debug("Test drawing or reading from an incomplete framebuffer"); |
michael@0 | 262 | var program = wtu.setupTexturedQuad(gl); |
michael@0 | 263 | var tex = gl.createTexture(); |
michael@0 | 264 | wtu.fillTexture(gl, tex, 1, 1, [0,255,0,255]); |
michael@0 | 265 | |
michael@0 | 266 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 267 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 268 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 269 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 270 | gl.framebufferRenderbuffer( |
michael@0 | 271 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 272 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 273 | |
michael@0 | 274 | shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); |
michael@0 | 275 | gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); |
michael@0 | 276 | gl.framebufferRenderbuffer( |
michael@0 | 277 | gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer); |
michael@0 | 278 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); |
michael@0 | 279 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 280 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 281 | |
michael@0 | 282 | // We pick this combination because it works on desktop OpenGL but should not work on OpenGL ES 2.0 |
michael@0 | 283 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16); |
michael@0 | 284 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); |
michael@0 | 285 | debug(""); |
michael@0 | 286 | debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION"); |
michael@0 | 287 | testRenderingAndReading(); |
michael@0 | 288 | |
michael@0 | 289 | shouldBeNonNull("fbo2 = gl.createFramebuffer()"); |
michael@0 | 290 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2); |
michael@0 | 291 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); |
michael@0 | 292 | debug(""); |
michael@0 | 293 | debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION"); |
michael@0 | 294 | testRenderingAndReading(); |
michael@0 | 295 | |
michael@0 | 296 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 297 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 298 | gl.framebufferRenderbuffer( |
michael@0 | 299 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 300 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0); |
michael@0 | 301 | debug(""); |
michael@0 | 302 | debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION"); |
michael@0 | 303 | testRenderingAndReading(); |
michael@0 | 304 | |
michael@0 | 305 | function testRenderingAndReading() { |
michael@0 | 306 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 307 | wtu.drawQuad(gl); |
michael@0 | 308 | glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer"); |
michael@0 | 309 | gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4)); |
michael@0 | 310 | glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer"); |
michael@0 | 311 | // copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because |
michael@0 | 312 | // the framebuffer is invalid OR INVALID_OPERATION because in the case of no attachments |
michael@0 | 313 | // the framebuffer is not of a compatible type. |
michael@0 | 314 | gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1); |
michael@0 | 315 | glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexImage2D from incomplete framebuffer"); |
michael@0 | 316 | gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0); |
michael@0 | 317 | glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexSubImage2D from incomplete framebuffer"); |
michael@0 | 318 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
michael@0 | 319 | glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer"); |
michael@0 | 320 | } |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | function testFramebufferIncompleteAttachment() { |
michael@0 | 324 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 325 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 326 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 327 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 328 | gl.framebufferRenderbuffer( |
michael@0 | 329 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 330 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 331 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 332 | |
michael@0 | 333 | debug(""); |
michael@0 | 334 | debug("Wrong storage type for type of attachment be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)"); |
michael@0 | 335 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); |
michael@0 | 336 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT); |
michael@0 | 337 | |
michael@0 | 338 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 339 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 340 | |
michael@0 | 341 | debug(""); |
michael@0 | 342 | debug("0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)"); |
michael@0 | 343 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0); |
michael@0 | 344 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT); |
michael@0 | 345 | |
michael@0 | 346 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | function testFramebufferIncompleteMissingAttachment() { |
michael@0 | 350 | debug(""); |
michael@0 | 351 | debug("No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT (OpenGL ES 2.0 4.4.5)"); |
michael@0 | 352 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 353 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 354 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); |
michael@0 | 355 | |
michael@0 | 356 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 357 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 358 | gl.framebufferRenderbuffer( |
michael@0 | 359 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 360 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 361 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 362 | |
michael@0 | 363 | gl.framebufferRenderbuffer( |
michael@0 | 364 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null); |
michael@0 | 365 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); |
michael@0 | 366 | |
michael@0 | 367 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 368 | } |
michael@0 | 369 | |
michael@0 | 370 | function testFramebufferIncompleteDimensions() { |
michael@0 | 371 | debug(""); |
michael@0 | 372 | debug("Attachments of different sizes should be FRAMEBUFFER_INCOMPLETE_DIMENSIONS (OpenGL ES 2.0 4.4.5)"); |
michael@0 | 373 | |
michael@0 | 374 | shouldBeNonNull("fbo = gl.createFramebuffer()"); |
michael@0 | 375 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 376 | shouldBeNonNull("colorBuffer = gl.createRenderbuffer()"); |
michael@0 | 377 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 378 | gl.framebufferRenderbuffer( |
michael@0 | 379 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
michael@0 | 380 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 381 | |
michael@0 | 382 | shouldBeNonNull("depthBuffer = gl.createRenderbuffer()"); |
michael@0 | 383 | gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); |
michael@0 | 384 | gl.framebufferRenderbuffer( |
michael@0 | 385 | gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer); |
michael@0 | 386 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); |
michael@0 | 387 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 388 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 389 | |
michael@0 | 390 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16); |
michael@0 | 391 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); |
michael@0 | 392 | gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16); |
michael@0 | 393 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 394 | gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer); |
michael@0 | 395 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32); |
michael@0 | 396 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); |
michael@0 | 397 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16); |
michael@0 | 398 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 399 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 400 | |
michael@0 | 401 | var tex = gl.createTexture(); |
michael@0 | 402 | gl.bindTexture(gl.TEXTURE_2D, tex); |
michael@0 | 403 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); |
michael@0 | 404 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); |
michael@0 | 405 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 406 | if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { |
michael@0 | 407 | return; |
michael@0 | 408 | } |
michael@0 | 409 | |
michael@0 | 410 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); |
michael@0 | 411 | checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); |
michael@0 | 412 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); |
michael@0 | 413 | checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
michael@0 | 414 | |
michael@0 | 415 | glErrorShouldBe(gl, gl.NO_ERROR); |
michael@0 | 416 | } |
michael@0 | 417 | |
michael@0 | 418 | successfullyParsed = true; |
michael@0 | 419 | </script> |
michael@0 | 420 | |
michael@0 | 421 | <script>finishTest();</script> |
michael@0 | 422 | </body> |
michael@0 | 423 | </html> |