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.
10 <meta charset=
"utf-8">
11 <title>Read or Draw when Attachment(s) Miss Image
</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>
17 <canvas id=
"example" width=
"8" height=
"8"></canvas>
18 <div id=
"description"></div>
19 <div id=
"console"></div>
24 var wtu
= WebGLTestUtils
;
25 description("This test verifies the functionality of reading/drawing when color attachment(s) miss image.");
27 var gl
= wtu
.create3DContext("example", undefined, 2);
29 var tex_read
= gl
.createTexture();
30 var tex_draw
= gl
.createTexture();
31 var tex_depth
= gl
.createTexture();
32 var tex_stencil
= gl
.createTexture();
33 var fbo_read
= gl
.createFramebuffer();
34 var fbo_draw
= gl
.createFramebuffer();
38 testFailed("WebGL context does not exist");
40 testPassed("WebGL context exists");
42 // READ_FRAMEBUFFER has image at COLOR_ATTACHMENT0. READ_FRAMEBUFFER is framebuffer complete.
43 // Read from COLOR_ATTACHMENT1, which has no image attached.
47 // DRAW_FRAMEBUFFER has image at COLOR_ATTACHMENT0. DRAW_FRAMEBUFFER is framebuffer complete.
48 // Clear and draw COLOR_ATTACHMENT1 or COLOR_ATTACHMENT0 + COLOR_ATTACHMENT1 attaching point(s).
56 function init_read_fbo() {
57 gl
.bindTexture(gl
.TEXTURE_2D
, tex_read
);
58 wtu
.fillTexture(gl
, tex_read
, size
, size
, [0x0, 0xff, 0xff, 0xff], 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, gl
.RGBA8
);
59 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
60 gl
.framebufferTexture2D(gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex_read
, 0);
61 if (gl
.checkFramebufferStatus(gl
.READ_FRAMEBUFFER
) != gl
.FRAMEBUFFER_COMPLETE
) {
62 testFailed("Framebuffer incomplete.");
65 testPassed("framebuffer complete!");
69 function init_draw_fbo() {
70 gl
.bindTexture(gl
.TEXTURE_2D
, tex_draw
);
71 wtu
.fillTexture(gl
, tex_draw
, size
, size
, [0x0, 0xff, 0xff, 0xff], 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, gl
.RGBA8
);
72 wtu
.fillTexture(gl
, tex_depth
, size
, size
, [0x80], 0, gl
.DEPTH_COMPONENT
, gl
.UNSIGNED_INT
, gl
.DEPTH_COMPONENT16
);
73 wtu
.fillTexture(gl
, tex_stencil
, size
, size
, [0x40], 0, gl
.DEPTH_STENCIL
, gl
.UNSIGNED_INT_24_8
, gl
.DEPTH24_STENCIL8
);
74 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
75 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex_draw
, 0);
76 if (gl
.checkFramebufferStatus(gl
.DRAW_FRAMEBUFFER
) != gl
.FRAMEBUFFER_COMPLETE
) {
77 testFailed("Framebuffer incomplete.");
80 testPassed("framebuffer complete!");
86 debug("read from a color buffer which has no image attached");
88 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo_read
);
89 gl
.readBuffer(gl
.COLOR_ATTACHMENT1
);
91 var data
= new Uint8Array(size
* size
* 4);
92 gl
.readPixels(0, 0, size
, size
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, data
);
93 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
95 var copy_2d
= gl
.createTexture();
96 gl
.bindTexture(gl
.TEXTURE_2D
, copy_2d
);
97 gl
.copyTexImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8
, 0, 0, size
, size
, 0);
98 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
100 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
101 gl
.copyTexSubImage2D(gl
.TEXTURE_2D
, 0, size
/ 2, size
/ 2, 0, 0, size
/ 2, size
/ 2);
102 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
104 var copy_3d
= gl
.createTexture();
105 gl
.bindTexture(gl
.TEXTURE_3D
, copy_3d
);
106 gl
.texImage3D(gl
.TEXTURE_3D
, 0, gl
.RGBA8
, size
, size
, 2, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
107 gl
.copyTexSubImage3D(gl
.TEXTURE_3D
, 0, size
/ 2, size
/ 2, 0, 0, 0, size
/ 2, size
/ 2);
108 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
110 gl
.bindTexture(gl
.TEXTURE_2D
, null);
111 gl
.deleteTexture(copy_2d
);
112 gl
.bindTexture(gl
.TEXTURE_3D
, null);
113 gl
.deleteTexture(copy_3d
);
116 function checkTextureValue(fbo
, buffer
, value
) {
117 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo
);
118 gl
.readBuffer(buffer
);
119 wtu
.checkCanvas(gl
, value
);
120 gl
.readBuffer(gl
.COLOR_ATTACHMENT0
);
121 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, null);
126 debug("clear a color buffer which has no image attached");
128 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
129 var color
= [0.0, 1.0, 0.0, 1.0];
130 gl
.clearColor(color
[0], color
[1], color
[2], color
[3]);
131 gl
.drawBuffers([gl
.NONE
, gl
.COLOR_ATTACHMENT1
]);
132 gl
.clear(gl
.COLOR_BUFFER_BIT
);
133 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
134 // The image color at COLOR_ATTACHMENT0 should not be changed.
135 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 255, 255]);
137 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
138 gl
.drawBuffers([gl
.COLOR_ATTACHMENT0
, gl
.COLOR_ATTACHMENT1
]);
139 gl
.clear(gl
.COLOR_BUFFER_BIT
);
140 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
141 // The image color at COLOR_ATTACHMENT0 should be changed.
142 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 0, 255]);
144 var data
= new Float32Array(color
);
145 gl
.clearBufferfv(gl
.COLOR
, 1, data
);
146 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
151 debug("draw to a color buffer which has no image attached");
153 var program
= wtu
.setupSimpleColorProgram(gl
, 0);
154 gl
.uniform4f(gl
.getUniformLocation(program
, "u_color"), 1, 0, 0, 1);
155 wtu
.setupUnitQuad(gl
, 0);
157 // Call to drawArrays
158 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
159 gl
.drawBuffers([gl
.NONE
, gl
.COLOR_ATTACHMENT1
]);
160 wtu
.drawUnitQuad(gl
);
161 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
162 // The image color at COLOR_ATTACHMENT0 should not be changed.
163 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 0, 255]);
165 gl
.drawBuffers([gl
.COLOR_ATTACHMENT0
, gl
.COLOR_ATTACHMENT1
]);
166 wtu
.drawUnitQuad(gl
);
167 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
168 // The image color at COLOR_ATTACHMENT0 should be changed.
169 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [255, 0, 0, 255]);
171 // Call to drawElements
172 gl
.uniform4f(gl
.getUniformLocation(program
, "u_color"), 1, 1, 0, 1);
173 wtu
.setupIndexedQuad(gl
, 1);
174 gl
.drawBuffers([gl
.NONE
, gl
.COLOR_ATTACHMENT1
]);
175 wtu
.drawIndexedQuad(gl
, 1);
176 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
177 // The image color at COLOR_ATTACHMENT0 should not be changed.
178 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [255, 0, 0, 255]);
180 gl
.drawBuffers([gl
.COLOR_ATTACHMENT0
, gl
.COLOR_ATTACHMENT1
]);
181 wtu
.drawIndexedQuad(gl
, 1);
182 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
183 // The image color at COLOR_ATTACHMENT0 should be changed.
184 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [255, 255, 0, 255]);
189 debug("blit color buffer(s) which have no image attached");
190 // Some or all draw buffers have no image. Read buffer have image. It should be OK.
191 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
192 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
193 gl
.readBuffer(gl
.COLOR_ATTACHMENT0
);
194 gl
.drawBuffers([gl
.NONE
, gl
.COLOR_ATTACHMENT1
]);
195 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.COLOR_BUFFER_BIT
, gl
.NEAREST
);
196 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
197 // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
198 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [255, 255, 0, 255]);
200 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
201 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
202 gl
.readBuffer(gl
.COLOR_ATTACHMENT0
);
203 gl
.drawBuffers([gl
.COLOR_ATTACHMENT0
, gl
.COLOR_ATTACHMENT1
]);
204 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.COLOR_BUFFER_BIT
, gl
.NEAREST
);
205 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
206 // The image color at COLOR_ATTACHMENT0 in draw fbo should be changed.
207 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 255, 255]);
209 // Draw buffer(s) have no image. Read buffer have no image. It should be OK.
210 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
211 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
212 gl
.readBuffer(gl
.COLOR_ATTACHMENT1
);
213 gl
.drawBuffers([gl
.NONE
, gl
.COLOR_ATTACHMENT1
]);
214 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.COLOR_BUFFER_BIT
, gl
.NEAREST
);
215 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
216 // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
217 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 255, 255]);
219 // Read buffer have no image. Some or all draw buffers have image. It should generate INVALID_OPERATION.
220 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
221 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
222 gl
.readBuffer(gl
.COLOR_ATTACHMENT1
);
223 gl
.drawBuffers([gl
.COLOR_ATTACHMENT0
]);
224 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.COLOR_BUFFER_BIT
, gl
.NEAREST
);
225 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when read buffer misses image.");
226 // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
227 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 255, 255]);
229 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
230 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
231 gl
.readBuffer(gl
.COLOR_ATTACHMENT1
);
232 gl
.drawBuffers([gl
.COLOR_ATTACHMENT0
, gl
.COLOR_ATTACHMENT1
]);
233 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.COLOR_BUFFER_BIT
, gl
.NEAREST
);
234 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when read buffer misses image.");
235 // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
236 checkTextureValue(fbo_draw
, gl
.COLOR_ATTACHMENT0
, [0, 255, 255, 255]);
238 // Depth buffer in read fbo has no image. It should generate INVALID_OPERATION if depth buffer in draw fbo has image.
239 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
240 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
241 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.DEPTH_ATTACHMENT
, gl
.TEXTURE_2D
, tex_depth
, 0);
242 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.DEPTH_BUFFER_BIT
, gl
.NEAREST
);
243 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when depth buffer misses image.");
245 // Depth buffer in read fbo has no image. It should be OK if depth buffer in draw fbo has no image too.
246 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
247 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
248 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.DEPTH_ATTACHMENT
, gl
.TEXTURE_2D
, null, 0);
249 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.DEPTH_BUFFER_BIT
, gl
.NEAREST
);
250 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
251 // Validate some other parameters as usual
252 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.DEPTH_BUFFER_BIT
, gl
.LINEAR
);
253 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "invalid filter");
255 // Stencil buffer in read fbo has no image. It should generate INVALID_OPERATION if stencil buffer in draw fbo has image.
256 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
257 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
258 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.STENCIL_ATTACHMENT
, gl
.TEXTURE_2D
, tex_stencil
, 0);
259 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.STENCIL_BUFFER_BIT
, gl
.NEAREST
);
260 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "Should generate INVALID_OPERATION when stencil buffer misses image.");
262 // Stencil buffer in read fbo has no image. It should be OK if stencil buffer in draw fbo has no image too.
263 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
264 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
265 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.STENCIL_ATTACHMENT
, gl
.TEXTURE_2D
, null, 0);
266 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.STENCIL_BUFFER_BIT
, gl
.NEAREST
);
267 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no error.");
268 // Validate some other parameters as usual
269 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, size
, size
, gl
.STENCIL_BUFFER_BIT
, gl
.LINEAR
);
270 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "invalid filter");
273 gl
.bindTexture(gl
.TEXTURE_2D
, null);
274 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, null);
275 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, null);
276 gl
.deleteTexture(tex_read
);
277 gl
.deleteTexture(tex_draw
);
278 gl
.deleteTexture(tex_depth
);
279 gl
.deleteTexture(tex_stencil
);
280 gl
.deleteFramebuffer(fbo_read
);
281 gl
.deleteFramebuffer(fbo_draw
);
283 var successfullyParsed
= true;
285 <script src=
"../../js/js-test-post.js"></script>