Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / rendering / blitframebuffer-test.html
blobc470b02e4e81f012ec89938859e72feb9d3906c6
1 <!--
2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>WebGL BlitFramebuffer Tests</title>
12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
13 <script src="../../js/js-test-pre.js"></script>
14 <script src="../../js/webgl-test-utils.js"></script>
15 </head>
16 <body>
17 <canvas id="example" width="8" height="8"></canvas>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script>
21 "use strict";
23 var wtu = WebGLTestUtils;
24 description("This test verifies the functionality of blitFramebuffer for some corner cases.");
26 var width = 8;
27 var height = 8;
29 var gl = wtu.create3DContext("example", undefined, 2);
30 if (!gl) {
31 testFailed("WebGL context does not exist");
32 } else {
33 testPassed("WebGL context exists");
34 blit_framebuffer_repeated();
35 blit_framebuffer_feedback_loop();
36 blit_framebuffer_multisampling_srgb();
39 function blit_framebuffer_repeated() {
40 debug("");
41 debug("This test verifies repeated calls to blitFramebuffer.");
43 // Create offscreen fbo and its color attachment.
44 var tex_2d = gl.createTexture();
45 gl.bindTexture(gl.TEXTURE_2D, tex_2d);
46 gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, width, height);
47 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
48 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
49 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
50 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
52 var fb = gl.createFramebuffer();
53 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
54 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
55 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
56 testFailed("Framebuffer incomplete.");
57 return;
60 var prog = wtu.setupColorQuad(gl, 0);
61 wtu.setFloatDrawColor(gl, [ 1.0, 0.0, 0.0, 1.0 ]);
62 wtu.drawUnitQuad(gl);
63 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb);
64 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
65 gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
66 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
67 wtu.checkCanvas(gl, [ 255, 0, 0, 255 ], "should be red at first");
69 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
70 wtu.setFloatDrawColor(gl, [ 0.0, 1.0, 0.0, 1.0 ]);
71 wtu.drawUnitQuad(gl);
72 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb);
73 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
74 gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
75 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
76 wtu.checkCanvas(gl, [ 0, 255, 0, 255 ], "should be green");
79 function blit_framebuffer_feedback_loop() {
81 debug("");
82 debug("This test checks whether the src resource and dst resource have identical images.");
83 // Create read fbo and its color attachment.
84 var tex_2d = gl.createTexture();
85 gl.bindTexture(gl.TEXTURE_2D, tex_2d);
86 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
87 gl.generateMipmap(gl.TEXTURE_2D);
89 var fb0 = gl.createFramebuffer();
90 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
91 gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
92 if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
93 testFailed("Framebuffer incomplete.");
94 return;
97 // Create draw fbo and its color attachment.
98 var rb0 = gl.createRenderbuffer();
99 gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
100 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, width, height);
102 var fb1 = gl.createFramebuffer();
103 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
104 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
105 if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
106 testFailed("Framebuffer incomplete.");
107 return;
110 // Blit framebuffer, all conditions are OK.
111 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
112 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
114 // Blit framebuffer, the src buffer and the dst buffer should not be identical.
115 // Exactly the same read/draw fbo
116 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
117 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb0);
118 gl.blitFramebuffer(0, 0, 2, 2, 4, 4, 6, 6, gl.COLOR_BUFFER_BIT, gl.NEAREST);
119 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw buffer are identical.");
121 // Exactly the same read/draw framebuffer: default framebuffer
122 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
123 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
124 gl.blitFramebuffer(0, 0, 2, 2, 4, 4, 6, 6, gl.COLOR_BUFFER_BIT, gl.NEAREST);
125 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw buffer are identical.");
127 // The same image with the same level bound to read/draw buffer.
128 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
129 gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
130 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
131 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
132 if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
133 gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
134 testFailed("Framebuffer incomplete.");
135 return;
137 gl.blitFramebuffer(0, 0, 2, 2, 4, 4, 6, 6, gl.COLOR_BUFFER_BIT, gl.NEAREST);
138 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw color buffer are identical.");
140 // The same image in read/draw buffer, but different levels are bound to read/draw buffer respectively.
141 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
142 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 1);
143 if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
144 testFailed("Framebuffer incomplete.");
145 return;
147 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
148 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed if read/draw buffer has the same image with different levels.");
150 // The same cube_map image in read/draw buffer, but different faces are bound to read/draw buffer respectively.
151 var tex_cube_map = gl.createTexture();
152 gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex_cube_map);
153 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
154 gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
155 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
156 gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
157 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
158 gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
159 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
160 gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
161 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
162 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, tex_cube_map, 0);
163 if ((gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) ||
164 (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)) {
165 testFailed("Framebuffer incomplete.");
166 return;
168 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
169 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed if read/draw buffer has the same CUBE_MAP image with different faces.");
171 // The same 3D/2D_ARRAY image in read/draw buffer, but different layers are bound to read/draw buffer respectively.
172 var tex_2d_array = gl.createTexture();
173 gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex_2d_array);
174 var depth = 2;
175 gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
176 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
177 var level = 0, layer = 0;
178 gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex_2d_array, level, layer);
179 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
180 layer = 1;
181 gl.framebufferTextureLayer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex_2d_array, level, layer);
182 if ((gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) ||
183 (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)) {
184 testFailed("Framebuffer incomplete.");
185 return;
187 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
188 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed if read/draw buffer has the same 3D/2D_ARRAY image with different layers.");
190 // The same image are bound as depth buffer in both read framebuffer and draw framebuffer
191 var rb1 = gl.createRenderbuffer();
192 gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
193 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, width, height);
194 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
195 gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
196 gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb1);
197 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
198 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, tex_cube_map, 0);
199 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb1);
200 if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
201 gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
202 testFailed("Framebuffer incomplete.");
203 return;
205 // But the mask doesn't have depth buffer bit.
206 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
207 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
209 // The mask has depth buffer bit.
210 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.NEAREST);
211 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw framebuffer have identical depth buffer attachment.");
213 // The same image are bound as stencil buffer in both read framebuffer and draw framebuffer
214 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
215 gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb1);
216 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
217 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb1);
218 if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
219 gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
220 testFailed("Framebuffer incomplete.");
221 return;
223 // But the mask doesn't have stencil buffer bit.
224 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
225 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
227 // The mask has stencil buffer bit.
228 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.NEAREST);
229 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw framebuffer have identical stencil buffer attachment.");
231 // The same image are bound as color buffer in both read framebuffer and draw framebuffer
232 var rb2 = gl.createRenderbuffer();
233 gl.bindRenderbuffer(gl.RENDERBUFFER, rb2);
234 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, width, height);
235 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
236 gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
237 gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
238 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
239 gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb2);
240 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
241 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, tex_cube_map, 0);
242 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
243 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb1);
244 if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
245 gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
246 testFailed("Framebuffer incomplete.");
247 return;
249 // But the mask doesn't have color buffer bit.
250 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
251 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
253 // The mask has color buffer bit, but the same image is not specified as draw buffer.
254 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.NEAREST);
255 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
257 // The mask has color buffer bit, the same image is specified as both read buffer and draw buffer.
258 gl.drawBuffers([gl.COLOR_ATTACHENT0, gl.COLOR_ATTACHMENT1]);
259 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.NEAREST);
260 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw buffers have identical color buffer attachment.");
262 gl.bindTexture(gl.TEXTURE_2D, null);
263 gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
264 gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
265 gl.bindRenderbuffer(gl.RENDERBUFFER, null);
266 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
267 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
268 gl.deleteTexture(tex_2d);
269 gl.deleteTexture(tex_cube_map);
270 gl.deleteTexture(tex_2d_array);
271 gl.deleteRenderbuffer(rb0);
272 gl.deleteRenderbuffer(rb1);
273 gl.deleteRenderbuffer(rb2);
274 gl.deleteFramebuffer(fb0);
275 gl.deleteFramebuffer(fb1);
278 function blit_framebuffer_multisampling_srgb() {
280 debug("");
281 debug("This test vefify the functionality of blitframebuffer from or to a multisampled srgb image.");
283 // Read buffer can have multisampled srgb image, but draw buffers can not.
284 var rb0 = gl.createRenderbuffer();
285 var fb0 = gl.createFramebuffer();
286 var rb1 = gl.createRenderbuffer();
287 var fb1 = gl.createFramebuffer();
288 var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, gl.SAMPLES);
289 gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
290 gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.SRGB8_ALPHA8, width, height);
291 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
292 gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
294 gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
295 gl.renderbufferStorage(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, width, height);
296 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
297 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb1);
298 if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
299 gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
300 testFailed("Framebuffer incomplete.");
301 return;
303 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.LINEAR);
304 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer from multisampled srgb image should succeed.");
306 gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
307 gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.SRGB8_ALPHA8, width, height);
308 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
309 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb1);
310 if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
311 testFailed("Framebuffer incomplete.");
312 return;
314 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.LINEAR);
315 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer to a multisampled srgb image should generate INVALID_OPERATION.");
317 // BlitFramebuffer from a multisampled srgb image, the src region and the dst region must be exactly the same.
318 gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
319 gl.renderbufferStorage(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, width, height);
320 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
321 gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb1);
322 if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
323 testFailed("Framebuffer incomplete.");
324 return;
326 gl.blitFramebuffer(0, 0, 2, 2, 2, 2, 4, 4, gl.COLOR_BUFFER_BIT, gl.LINEAR);
327 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer from a multisampled srgb image, the src region and the dst region must be exactly the same.");
329 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 4, 4, gl.COLOR_BUFFER_BIT, gl.LINEAR);
330 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer from a multisampled srgb image, the src region and the dst region must be exactly the same.");
332 // BlitFramebuffer from a multisampled srgb image, the format/type must be exactly the same. So blit from a multisampled srgb image to a linear image is invalid.
333 var tex = gl.createTexture();
334 gl.bindTexture(gl.TEXTURE_2D, tex);
335 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
336 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
337 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
338 if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
339 testFailed("Framebuffer incomplete.");
340 return;
342 gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.LINEAR);
343 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer from a multisampled srgb image, the format/type must be exactly the same.");
345 gl.bindRenderbuffer(gl.RENDERBUFFER, null);
346 gl.bindTexture(gl.TEXTURE_2D, null);
347 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
348 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
349 gl.deleteRenderbuffer(rb0);
350 gl.deleteRenderbuffer(rb1);
351 gl.deleteTexture(tex);
352 gl.deleteFramebuffer(fb0);
353 gl.deleteFramebuffer(fb1);
356 var successfullyParsed = true;
357 </script>
358 <script src="../../js/js-test-post.js"></script>
360 </body>
361 </html>