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