|
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.FRAMEBUFFER_COMPLETE)) || |
|
43 ((allowedStatuses & ALLOW_UNSUPPORTED) && (status == gl.FRAMEBUFFER_UNSUPPORTED)) || |
|
44 ((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) && (status == 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.RENDERBUFFER, colorBuffer); |
|
57 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer); |
|
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 Uint8Array(width * height * 4)); |
|
64 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION); |
|
65 } |
|
66 gl.deleteFramebuffer(fbo); |
|
67 } |
|
68 |
|
69 function testAttachments(attachment0, buffer0, attachment1, buffer1, allowedStatuses) |
|
70 { |
|
71 shouldBeNonNull("fbo = gl.createFramebuffer()"); |
|
72 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
|
73 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer); |
|
74 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0); |
|
75 glErrorShouldBe(gl, gl.NO_ERROR); |
|
76 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1); |
|
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_WIDTH)", "width"); |
|
102 if (!(width == 0 && height > 0)) |
|
103 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT)", "height"); |
|
104 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_INTERNAL_FORMAT)", "gl.DEPTH_STENCIL"); |
|
105 shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_RED_SIZE)", "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.RENDERBUFFER_DEPTH_SIZE) > 0"); |
|
113 shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE) > 0"); |
|
114 } |
|
115 glErrorShouldBe(gl, gl.NO_ERROR); |
|
116 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatuses); |
|
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, height); |
|
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, allowedStatusForGoodCase); |
|
155 debug("Attach depth using STENCIL_ATTACHMENT"); |
|
156 testAttachment(gl.STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
|
157 debug("Attach depth using DEPTH_STENCIL_ATTACHMENT"); |
|
158 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
|
159 debug("Attach stencil using STENCIL_ATTACHMENT"); |
|
160 testAttachment(gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForImplDependentCase); |
|
161 debug("Attach stencil using DEPTH_ATTACHMENT"); |
|
162 testAttachment(gl.DEPTH_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
|
163 debug("Attach stencil using DEPTH_STENCIL_ATTACHMENT"); |
|
164 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT); |
|
165 debug("Attach depthStencil using DEPTH_STENCIL_ATTACHMENT"); |
|
166 testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForGoodCase); |
|
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_INCOMPLETE_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_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment); |
|
180 debug("Attach depth, then depthStencil, causing conflict"); |
|
181 testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment); |
|
182 debug("Attach depthStencil, then depth, causing conflict"); |
|
183 testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment); |
|
184 debug("Attach stencil, then depthStencil, causing conflict"); |
|
185 testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment); |
|
186 debug("Attach depthStencil, then stencil, causing conflict"); |
|
187 testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.STENCIL_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.DEPTH_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_COMPLETE; |
|
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.glEnumToString(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 not 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 INVALID_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 INVALID_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 INVALID_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 incomplete 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 incomplete framebuffer"); |
|
311 // copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because |
|
312 // the framebuffer is invalid OR INVALID_OPERATION because in the case of 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_OPERATION], "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_OPERATION], "copyTexSubImage2D from incomplete framebuffer"); |
|
318 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
|
319 glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete 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_ATTACHMENT (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 (OpenGL 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_DIMENSIONS (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_BYTE, 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_BYTE, null); |
|
411 checkFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS); |
|
412 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); |
|
413 checkFramebuffer(gl.FRAMEBUFFER_COMPLETE); |
|
414 |
|
415 glErrorShouldBe(gl, gl.NO_ERROR); |
|
416 } |
|
417 |
|
418 successfullyParsed = true; |
|
419 </script> |
|
420 |
|
421 <script>finishTest();</script> |
|
422 </body> |
|
423 </html> |