Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / fast / canvas / webgl / framebuffer-object-attachment.html
blobaae290d8e7a625265e4674b493fdafaa76bf18d3
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <script src="../../../resources/js-test.js"></script>
6 <script src="resources/webgl-test.js"></script>
7 <script src="resources/webgl-test-utils.js"></script>
8 </head>
9 <body>
10 <div id="description"></div>
11 <div id="console"></div>
13 <script>
14 if (window.internals)
15 window.internals.settings.setWebGLErrorsToConsoleEnabled(false);
17 var wtu = WebGLTestUtils;
18 var gl;
19 var fbo;
20 var depthBuffer;
21 var stencilBuffer;
22 var depthStencilBuffer;
23 var colorBuffer;
24 var width;
25 var height;
27 const ALLOW_COMPLETE = 0x01;
28 const ALLOW_UNSUPPORTED = 0x02;
29 const ALLOW_INCOMPLETE_ATTACHMENT = 0x04;
31 function checkFramebufferForAllowedStatuses(allowedStatuses)
33 // If the framebuffer is in an error state for multiple reasons,
34 // we can't guarantee which one will be reported.
35 var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
36 var statusAllowed = ((allowedStatuses & ALLOW_COMPLETE) && (status == gl.FRAMEBUFFER_COMPLETE)) ||
37 ((allowedStatuses & ALLOW_UNSUPPORTED) && (status == gl.FRAMEBUFFER_UNSUPPORTED)) ||
38 ((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) && (status == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
39 var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) returned " + status;
40 if (statusAllowed)
41 testPassed(msg);
42 else
43 testFailed(msg);
46 function checkBufferBits(attachment0, attachment1)
48 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)
49 return;
51 var haveDepthBuffer = attachment0 == gl.DEPTH_ATTACHMENT ||
52 attachment0 == gl.DEPTH_STENCIL_ATTACHMENT ||
53 attachment1 == gl.DEPTH_ATTACHMENT ||
54 attachment1 == gl.DEPTH_STENCIL_ATTACHMENT;
55 var haveStencilBuffer = attachment0 == gl.STENCIL_ATTACHMENT ||
56 attachment0 == gl.DEPTH_STENCIL_ATTACHMENT ||
57 attachment1 == gl.STENCIL_ATTACHMENT ||
58 attachment1 == gl.DEPTH_STENCIL_ATTACHMENT;
60 shouldBeTrue("gl.getParameter(gl.RED_BITS) + gl.getParameter(gl.GREEN_BITS) + gl.getParameter(gl.BLUE_BITS) + gl.getParameter(gl.ALPHA_BITS) >= 16");
62 if (haveDepthBuffer)
63 shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16");
64 else
65 shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0");
67 if (haveStencilBuffer)
68 shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) >= 8");
69 else
70 shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0");
73 function testAttachment(attachment, buffer, allowedStatuses)
75 shouldBeNonNull("fbo = gl.createFramebuffer()");
76 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
77 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
78 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer);
79 glErrorShouldBe(gl, gl.NO_ERROR);
80 checkFramebufferForAllowedStatuses(allowedStatuses);
81 if ((allowedStatuses & ALLOW_COMPLETE) == 0) {
82 gl.clear(gl.COLOR_BUFFER_BIT);
83 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
84 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4));
85 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
87 checkBufferBits(attachment);
88 gl.deleteFramebuffer(fbo);
91 function testAttachments(attachment0, buffer0, attachment1, buffer1, allowedStatuses)
93 shouldBeNonNull("fbo = gl.createFramebuffer()");
94 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
95 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
96 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0);
97 glErrorShouldBe(gl, gl.NO_ERROR);
98 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
99 glErrorShouldBe(gl, gl.NO_ERROR);
100 checkFramebufferForAllowedStatuses(allowedStatuses);
101 checkBufferBits(attachment0, attachment1);
102 gl.deleteFramebuffer(fbo);
105 function testColorRenderbuffer(internalformat, allowedStatuses)
107 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
108 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
109 gl.renderbufferStorage(gl.RENDERBUFFER, internalformat, width, height);
110 glErrorShouldBe(gl, gl.NO_ERROR);
111 testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, allowedStatuses);
114 function testDepthStencilRenderbuffer(allowedStatuses)
116 shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()");
117 gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
118 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
119 glErrorShouldBe(gl, gl.NO_ERROR);
121 // OpenGL itself doesn't seem to guarantee that e.g. a 2 x 0
122 // renderbuffer will report 2 for its width when queried.
123 if (!(height == 0 && width > 0))
124 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH)", "width");
125 if (!(width == 0 && height > 0))
126 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT)", "height");
127 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_INTERNAL_FORMAT)", "gl.DEPTH_STENCIL");
128 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_RED_SIZE)", "0");
129 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_GREEN_SIZE)", "0");
130 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_BLUE_SIZE)", "0");
131 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_ALPHA_SIZE)", "0");
132 // Avoid verifying these for zero-sized renderbuffers for the time
133 // being since it appears that even OpenGL doesn't guarantee them.
134 if (width > 0 && height > 0) {
135 shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_DEPTH_SIZE) > 0");
136 shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE) > 0");
138 glErrorShouldBe(gl, gl.NO_ERROR);
139 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatuses);
140 testDepthStencilDepthStencil();
143 function testDepthStencilDepthStencil()
145 if (!width || !height) {
146 return;
149 var tests = [
150 { firstFormat: gl.DEPTH_COMPONENT16,
151 firstAttach: gl.DEPTH_ATTACHMENT,
152 secondFormat: gl.DEPTH_STENCIL,
153 secondAttach: gl.DEPTH_STENCIL_ATTACHMENT
155 { firstFormat: gl.DEPTH_STENCIL,
156 firstAttach: gl.DEPTH_STENCIL_ATTACHMENT,
157 secondFormat: gl.DEPTH_COMPONENT16,
158 secondAttach: gl.DEPTH_ATTACHMENT
161 for (var ii = 0; ii < tests.length; ++ii) {
162 var test = tests[ii];
163 for (var jj = 0; jj < 2; ++jj) {
164 var fbo = gl.createFramebuffer();
165 var tex = gl.createTexture();
166 var firstRb = gl.createRenderbuffer();
168 debug("");
169 debug("test: " + wtu.glEnumToString(gl, test.firstFormat) + " vs " + wtu.glEnumToString(gl, test.secondFormat) + " with " + (jj ? "unbind" : "delete"));
171 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
172 // attach texture as color
173 gl.bindTexture(gl.TEXTURE_2D, tex);
174 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
175 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
177 // attach first
178 gl.bindRenderbuffer(gl.RENDERBUFFER, firstRb);
179 gl.renderbufferStorage(gl.RENDERBUFFER, test.firstFormat, width, height);
180 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, test.firstAttach, gl.RENDERBUFFER, firstRb);
182 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
183 gl.enable(gl.DEPTH_TEST);
184 var program = wtu.setupColorQuad(gl);
185 // Test it works
186 wtu.drawUByteColorQuad(gl, [0, 255, 0, 255]);
187 wtu.drawUByteColorQuad(gl, [255, 0, 0, 255]); // should not draw since DEPTH_FUNC == LESS
188 wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 0, 255], "should be green");
190 var secondRb = gl.createRenderbuffer();
192 // attach second
193 gl.bindRenderbuffer(gl.RENDERBUFFER, secondRb);
194 gl.renderbufferStorage(gl.RENDERBUFFER, test.secondFormat, width, height);
195 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, test.secondAttach, gl.RENDERBUFFER, secondRb);
197 if (jj == 0) {
198 // now delete it
199 debug("test deleting second renderbuffer");
200 gl.deleteRenderbuffer(secondRb);
201 } else {
202 // unbind it
203 debug("test unbinding second renderbuffer");
204 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, test.secondAttach, gl.RENDERBUFFER, null);
207 // If the first attachment is not restored this may fail
208 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
209 glErrorShouldBe(gl, gl.NO_ERROR);
211 // If the first attachment is not restored this may fail.
212 gl.clear(gl.DEPTH_BUFFER_BIT);
213 wtu.drawUByteColorQuad(gl, [0, 255, 0, 255]);
214 wtu.drawUByteColorQuad(gl, [255, 0, 0, 255]); // should not draw since DEPTH_FUNC == LESS
215 wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 0, 255], "should be green");
216 gl.disable(gl.DEPTH_TEST);
218 if (jj == 1) {
219 gl.deleteRenderbuffer(secondRb);
223 gl.deleteRenderbuffer(secondRb);
224 gl.deleteFramebuffer(fbo);
227 glErrorShouldBe(gl, gl.NO_ERROR);
230 description("Test framebuffer object attachment behaviors");
232 for (width = 0; width <= 2; width += 2)
234 for (height = 0; height <= 2; height += 2)
236 debug("");
237 debug("Dimensions " + width + " x " + height);
239 debug("Create renderbuffers");
240 shouldBeNonNull("gl = create3DContext()");
241 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
242 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
243 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height);
244 glErrorShouldBe(gl, gl.NO_ERROR);
245 shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
246 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
247 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
248 glErrorShouldBe(gl, gl.NO_ERROR);
249 shouldBeNonNull("stencilBuffer = gl.createRenderbuffer()");
250 gl.bindRenderbuffer(gl.RENDERBUFFER, stencilBuffer);
251 gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, width, height);
252 glErrorShouldBe(gl, gl.NO_ERROR);
253 shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()");
254 gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
255 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
256 glErrorShouldBe(gl, gl.NO_ERROR);
258 var allowedStatusForGoodCase
259 = (width == 0 || height == 0) ? ALLOW_INCOMPLETE_ATTACHMENT : ALLOW_COMPLETE;
261 // some cases involving stencil seem to be implementation-dependent
262 var allowedStatusForImplDependentCase = allowedStatusForGoodCase | ALLOW_UNSUPPORTED;
264 debug("Attach depth using DEPTH_ATTACHMENT");
265 testAttachment(gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForGoodCase);
266 debug("Attach depth using STENCIL_ATTACHMENT");
267 testAttachment(gl.STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
268 debug("Attach depth using DEPTH_STENCIL_ATTACHMENT");
269 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
270 debug("Attach stencil using STENCIL_ATTACHMENT");
271 testAttachment(gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForImplDependentCase);
272 debug("Attach stencil using DEPTH_ATTACHMENT");
273 testAttachment(gl.DEPTH_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
274 debug("Attach stencil using DEPTH_STENCIL_ATTACHMENT");
275 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
276 debug("Attach depthStencil using DEPTH_STENCIL_ATTACHMENT");
277 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForGoodCase);
278 debug("Attach depthStencil using DEPTH_ATTACHMENT");
279 testAttachment(gl.DEPTH_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
280 debug("Attach depthStencil using STENCIL_ATTACHMENT");
281 testAttachment(gl.STENCIL_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
283 var allowedStatusForConflictedAttachment
284 = (width == 0 || height == 0) ? ALLOW_UNSUPPORTED | ALLOW_INCOMPLETE_ATTACHMENT
285 : ALLOW_UNSUPPORTED;
287 debug("Attach depth, then stencil, causing conflict");
288 testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment);
289 debug("Attach stencil, then depth, causing conflict");
290 testAttachments(gl.STENCIL_ATTACHMENT, stencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment);
291 debug("Attach depth, then depthStencil, causing conflict");
292 testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment);
293 debug("Attach depthStencil, then depth, causing conflict");
294 testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment);
295 debug("Attach stencil, then depthStencil, causing conflict");
296 testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment);
297 debug("Attach depthStencil, then stencil, causing conflict");
298 testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment);
300 debug("Attach color renderbuffer with internalformat == RGBA4");
301 testColorRenderbuffer(gl.RGBA4, allowedStatusForGoodCase);
303 debug("Attach color renderbuffer with internalformat == RGB5_A1");
304 testColorRenderbuffer(gl.RGB5_A1, allowedStatusForGoodCase);
306 debug("Attach color renderbuffer with internalformat == RGB565");
307 testColorRenderbuffer(gl.RGB565, allowedStatusForGoodCase);
309 debug("Create and attach depthStencil renderbuffer");
310 testDepthStencilRenderbuffer(allowedStatusForGoodCase);
314 // Determine if we can attach both color and depth or color and depth_stencil
315 var depthFormat;
316 var depthAttachment;
318 function checkValidColorDepthCombination() {
319 shouldBeNonNull("fbo = gl.createFramebuffer()");
320 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
321 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
322 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
323 gl.framebufferRenderbuffer(
324 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
325 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
327 shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
328 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
330 return tryDepth(gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT) || tryDepth(gl.DEPTH_STENCIL, gl.DEPTH_STENCIL_ATTACHMENT);
332 function tryDepth(try_format, try_attachment) {
333 if (depthAttachment) {
334 // If we've tried once unattach the old one.
335 gl.framebufferRenderbuffer(
336 gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, null);
338 depthFormat = try_format;
339 depthAttachment = try_attachment;
340 gl.framebufferRenderbuffer(
341 gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
342 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
343 glErrorShouldBe(gl, gl.NO_ERROR);
344 return gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
348 if (checkValidColorDepthCombination()) {
349 testFramebufferIncompleteDimensions();
350 testFramebufferIncompleteAttachment();
351 testFramebufferIncompleteMissingAttachment();
352 testUsingIncompleteFramebuffer();
355 function checkFramebuffer(expected) {
356 var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
357 var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be " + wtu.glEnumToString(gl, expected) + " was " + wtu.glEnumToString(gl, actual);
358 if (expected != gl.FRAMEBUFFER_COMPLETE) {
359 msg += " or FRAMEBUFFER_UNSUPPORTED";
361 if (actual == expected ||
362 (expected != gl.FRAMEBUFFER_COMPLETE &&
363 actual == gl.FRAMBUFFER_UNSUPPORTED)) {
364 testPassed(msg);
365 } else {
366 testFailed(msg);
370 function testUsingIncompleteFramebuffer() {
371 debug("");
372 debug("Test drawing or reading from an incomplete framebuffer");
373 var program = wtu.setupTexturedQuad(gl);
374 var tex = gl.createTexture();
375 wtu.fillTexture(gl, tex, 1, 1, [0,255,0,255]);
377 shouldBeNonNull("fbo = gl.createFramebuffer()");
378 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
379 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
380 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
381 gl.framebufferRenderbuffer(
382 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
383 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
385 shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
386 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
387 gl.framebufferRenderbuffer(
388 gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
389 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
390 glErrorShouldBe(gl, gl.NO_ERROR);
391 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
393 // We pick this combination because it works on desktop OpenGL but should not work on OpenGL ES 2.0
394 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
395 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
396 debug("");
397 debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
398 testRenderingAndReading();
400 shouldBeNonNull("fbo2 = gl.createFramebuffer()");
401 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2);
402 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
403 debug("");
404 debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
405 testRenderingAndReading();
407 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
408 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
409 gl.framebufferRenderbuffer(
410 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
411 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
412 debug("");
413 debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
414 testRenderingAndReading();
416 function testRenderingAndReading() {
417 glErrorShouldBe(gl, gl.NO_ERROR);
418 wtu.drawQuad(gl);
419 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer");
420 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
421 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer");
422 // copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because
423 // the framebuffer is invalid OR INVALID_OPERATION because in the case of no attachments
424 // the framebuffer is not of a compatible type.
425 gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
426 glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexImage2D from incomplete framebuffer");
427 gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0);
428 glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexSubImage2D from incomplete framebuffer");
429 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
430 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer");
434 function testFramebufferIncompleteAttachment() {
435 shouldBeNonNull("fbo = gl.createFramebuffer()");
436 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
437 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
438 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
439 gl.framebufferRenderbuffer(
440 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
441 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
442 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
444 debug("");
445 debug("Wrong storage type for type of attachment be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
446 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
447 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
449 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
450 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
452 debug("");
453 debug("0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
454 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
455 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
457 glErrorShouldBe(gl, gl.NO_ERROR);
460 function testFramebufferIncompleteMissingAttachment() {
461 debug("");
462 debug("No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
463 shouldBeNonNull("fbo = gl.createFramebuffer()");
464 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
465 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
467 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
468 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
469 gl.framebufferRenderbuffer(
470 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
471 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
472 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
474 gl.framebufferRenderbuffer(
475 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
476 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
478 glErrorShouldBe(gl, gl.NO_ERROR);
481 function testFramebufferIncompleteDimensions() {
482 debug("");
483 debug("Attachments of different sizes should be FRAMEBUFFER_INCOMPLETE_DIMENSIONS (OpenGL ES 2.0 4.4.5)");
485 shouldBeNonNull("fbo = gl.createFramebuffer()");
486 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
487 shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
488 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
489 gl.framebufferRenderbuffer(
490 gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
491 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
493 shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
494 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
495 gl.framebufferRenderbuffer(
496 gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
497 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
498 glErrorShouldBe(gl, gl.NO_ERROR);
499 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
501 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
502 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
503 gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
504 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
505 gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
506 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32);
507 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
508 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
509 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
510 glErrorShouldBe(gl, gl.NO_ERROR);
512 var tex = gl.createTexture();
513 gl.bindTexture(gl.TEXTURE_2D, tex);
514 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
515 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
516 glErrorShouldBe(gl, gl.NO_ERROR);
517 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
518 return;
521 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
522 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
523 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
524 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE);
526 glErrorShouldBe(gl, gl.NO_ERROR);
529 successfullyParsed = true;
530 </script>
532 </body>
533 </html>