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