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>WebGL Framebuffer Test Against WebGL
2</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 <div id=
"description"></div>
18 <div id=
"console"></div>
19 <canvas id=
"canvas" width=
"2" height=
"2"> </canvas>
22 var wtu
= WebGLTestUtils
;
25 function testFramebufferRenderbuffer() {
27 debug("Checking framebuffer/renderbuffer stuff.");
29 gl
.getFramebufferAttachmentParameter(
30 gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
);
31 wtu
.glErrorShouldBe(gl
, gl
.INVALID_ENUM
,
32 "getFramebufferAttachmentParameter(COLOR_ATTACHMENT0) on the default framebuffer.");
33 gl
.getFramebufferAttachmentParameter(
34 gl
.FRAMEBUFFER
, gl
.BACK
, gl
.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
);
35 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
36 "getFramebufferAttachmentParameter(BACK) on the default framebuffer.");
37 gl
.checkFramebufferStatus(gl
.FRAMEBUFFER
);
38 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "checkFramebufferStatus on the default framebuffer.");
40 var tex
= gl
.createTexture();
41 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
42 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.NEAREST
);
43 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAG_FILTER
, gl
.NEAREST
);
44 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_WRAP_S
, gl
.CLAMP_TO_EDGE
);
45 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_WRAP_T
, gl
.CLAMP_TO_EDGE
);
47 gl
.TEXTURE_2D
, 0, gl
.RGBA
, canvas
.width
, canvas
.height
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
48 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex
, 0);
49 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "attach a texture to default framebuffer.");
51 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, null);
52 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
53 "detach default renderbuffer from default framebuffer.");
55 var rb
= gl
.createRenderbuffer();
56 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, rb
);
57 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.RGBA4
, canvas
.width
, canvas
.height
);
58 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
59 "allocate renderbuffer storage of a newly created renderbuffer.");
61 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rb
);
62 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "attach a renderbuffer to the default framebuffer.");
64 var fbtex
= gl
.createTexture();
65 gl
.bindTexture(gl
.TEXTURE_2D
, fbtex
);
67 gl
.TEXTURE_2D
, 0, gl
.RGBA
, canvas
.width
, canvas
.height
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
68 var fb
= gl
.createFramebuffer();
70 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fb
);
71 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "bind a newly created framebuffer.");
73 var target
= gl
.READ_FRAMEBUFFER
;
74 gl
.getFramebufferAttachmentParameter(
75 target
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
);
76 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "getFramebufferAttachmentParameter(READ_FRAMEBUFFER).");
77 assertMsg(gl
.checkFramebufferStatus(target
) != 0,
78 "checkFramebufferStatus(READ_FRAMEBUFFER) should succeed.");
79 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "checkFramebufferStatus(READ_FRAMEBUFFER).");
80 var readFB
= gl
.createFramebuffer();
81 gl
.bindFramebuffer(target
, readFB
);
82 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "bindFramebuffer(READ_FRAMEBUFFER).");
83 assertMsg(readFB
== gl
.getParameter(gl
.READ_FRAMEBUFFER_BINDING
),
84 "bindFramebuffer(READ_FRAMEBUFFER) should change READ_FRAMEBUFFER_BINDING.");
85 assertMsg(fb
== gl
.getParameter(gl
.DRAW_FRAMEBUFFER_BINDING
),
86 "bindFramebuffer(READ_FRAMEBUFFER) should not change DRAW_FRAMEBUFFER_BINDING.");
87 gl
.getFramebufferAttachmentParameter(
88 target
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
);
89 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
90 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) with no attachment.");
91 gl
.framebufferTexture2D(target
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex
, 0);
92 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "framebufferTexImage2D(READ_FRAMEBUFFER).");
93 gl
.framebufferRenderbuffer(target
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rb
);
94 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "framebufferRenderbuffer(READ_FRAMEBUFFER).");
96 var colorAttachmentsNum
= gl
.getParameter(gl
.MAX_COLOR_ATTACHMENTS
);
97 if (colorAttachmentsNum
>= 2) {
98 var attachment
= gl
.COLOR_ATTACHMENT1
;
99 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, attachment
, gl
.TEXTURE_2D
, fbtex
, 0);
100 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "framebufferTexImage2D(COLOR_ATTACHMENT1).");
101 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, attachment
, gl
.TEXTURE_2D
, null, 0);
102 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, attachment
, gl
.RENDERBUFFER
, rb
);
103 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "framebufferRenderbuffer(COLOR_ATTACHMENT1).");
104 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, attachment
, gl
.RENDERBUFFER
, null);
107 gl
.getFramebufferAttachmentParameter(
108 gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
109 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
110 "getFramebufferAttachmentParameter(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
111 "with no attachment.");
113 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex
, 0);
114 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "attach a texture to a framebuffer.");
116 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, null, 0);
117 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "detach a texture from a framebuffer.");
119 function numLevelsFromSize(size
) {
121 while ((size
>> levels
) > 0) {
127 var maxTexSize
= gl
.getParameter(gl
.MAX_TEXTURE_SIZE
);
128 var maxLevels
= numLevelsFromSize(maxTexSize
);
129 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex
, maxLevels
- 1);
130 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "framebufferTexture2D with an appropriate mipmap level.");
131 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex
, maxLevels
);
132 wtu
.glErrorShouldBe(gl
, gl
.INVALID_VALUE
, "framebufferTexture2D with a mipmap level out of range.");
134 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rb
);
135 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "attach a renderbuffer to a framebuffer.");
137 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, null);
138 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "detach a renderbuffer from a framebuffer.");
140 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
141 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "bind default (null) framebuffer.");
143 // attach/detach a 2d texture to one framebuffer binding point,
144 // while no attachment to the other binding point.
145 function attachAndDetachTexture(targetA
, targetB
) {
146 gl
.framebufferTexture2D(targetA
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex
, 0);
147 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
148 "attach a texture to read/draw framebuffer binding point.");
149 gl
.getFramebufferAttachmentParameter(
150 targetA
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
151 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
152 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
153 "on read/draw framebuffer.");
154 gl
.getFramebufferAttachmentParameter(
155 targetB
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
156 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
157 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
158 "on read/draw framebuffer with no attachment.");
159 gl
.framebufferTexture2D(targetA
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, null, 0);
160 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "detach a texture from read/draw framebuffer.");
163 var readFBWithTexture
= gl
.createFramebuffer();
164 var drawFBWithTexture
= gl
.createFramebuffer();
165 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, readFBWithTexture
);
166 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, drawFBWithTexture
);
167 attachAndDetachTexture(gl
.READ_FRAMEBUFFER
, gl
.DRAW_FRAMEBUFFER
);
168 attachAndDetachTexture(gl
.DRAW_FRAMEBUFFER
, gl
.READ_FRAMEBUFFER
);
170 // attach different textures as color attachment to read and draw framebuffer respectively,
171 // then detach these attachments.
172 var fbtex1
= gl
.createTexture();
173 gl
.bindTexture(gl
.TEXTURE_2D
, fbtex1
);
175 gl
.TEXTURE_2D
, 0, gl
.RG8
, canvas
.width
, canvas
.height
, 0, gl
.RG
, gl
.UNSIGNED_BYTE
, null);
176 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex1
, 0);
177 gl
.framebufferTexture2D(gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, fbtex
, 0);
178 shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.READ_FRAMEBUFFER, ' +
179 'gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE)');
180 shouldBe('gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ' +
181 'gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE)', '0');
183 gl
.framebufferTexture2D(gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, null, 0);
184 gl
.getFramebufferAttachmentParameter(
185 gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
186 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
187 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
188 "on read framebuffer with no attachment.");
189 gl
.getFramebufferAttachmentParameter(
190 gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
191 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
192 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
193 "on draw framebuffer.");
194 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, null, 0);
195 gl
.getFramebufferAttachmentParameter(
196 gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
197 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
198 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
199 "on draw framebuffer with no attachment.");
201 // attach/detach a renderbuffer to one framebuffer binding point,
202 // while no attachment to the other binding point.
203 function attachAndDetachRenderbuffer(targetA
, targetB
) {
204 gl
.framebufferRenderbuffer(targetA
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rb
);
205 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "attaching a renderbuffer to a read/draw framebuffer.");
206 gl
.getFramebufferAttachmentParameter(
207 targetA
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
208 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
209 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
210 "on read/draw framebuffer.");
211 gl
.getFramebufferAttachmentParameter(
212 targetB
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
);
213 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
214 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
215 "on read/draw framebuffer with no attachment.");
216 gl
.framebufferRenderbuffer(targetA
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, null);
217 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "detach a renderbuffer from a read/draw framebuffer.");
220 var readFBWithRenderbuffer
= gl
.createFramebuffer();
221 var drawFBWithRenderbuffer
= gl
.createFramebuffer();
222 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, readFBWithRenderbuffer
);
223 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, drawFBWithRenderbuffer
);
224 attachAndDetachRenderbuffer(gl
.READ_FRAMEBUFFER
, gl
.DRAW_FRAMEBUFFER
);
225 attachAndDetachRenderbuffer(gl
.DRAW_FRAMEBUFFER
, gl
.READ_FRAMEBUFFER
);
227 // attach different renderbuffers to read and draw framebuffer respectively,
228 // then detach these attachments.
229 var depthRB
= gl
.createRenderbuffer();
230 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, depthRB
);
231 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.DEPTH_COMPONENT16
, canvas
.width
, canvas
.height
);
232 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
,
233 "allocating renderbuffer storage of a newly created renderbuffer.");
234 gl
.framebufferRenderbuffer(gl
.DRAW_FRAMEBUFFER
, gl
.DEPTH_ATTACHMENT
, gl
.RENDERBUFFER
, depthRB
);
235 gl
.framebufferRenderbuffer(gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, rb
);
236 shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.READ_FRAMEBUFFER, ' +
237 'gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_RED_SIZE)');
238 gl
.getFramebufferAttachmentParameter(
239 gl
.READ_FRAMEBUFFER
, gl
.DEPTH_ATTACHMENT
, gl
.FRAMEBUFFER_DEPTH_SIZE
);
240 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
241 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) " +
242 "on read framebuffer without depth attachment.");
243 shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, ' +
244 'gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE)');
245 gl
.getFramebufferAttachmentParameter(
246 gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_RED_SIZE
);
247 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
248 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) " +
249 "on draw framebuffer without color attachment.");
251 gl
.framebufferRenderbuffer(gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, null);
252 gl
.getFramebufferAttachmentParameter(
253 gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.FRAMEBUFFER_RED_SIZE
);
254 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
255 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) " +
256 "on read framebuffer with no attachment.");
257 shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, ' +
258 'gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE)');
259 gl
.framebufferRenderbuffer(gl
.DRAW_FRAMEBUFFER
, gl
.DEPTH_ATTACHMENT
, gl
.RENDERBUFFER
, null);
260 gl
.getFramebufferAttachmentParameter(
261 gl
.DRAW_FRAMEBUFFER
, gl
.DEPTH_ATTACHMENT
, gl
.FRAMEBUFFER_DEPTH_SIZE
);
262 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
,
263 "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) " +
264 "on draw framebuffer with no attachment.");
266 // binding read/draw framebuffer to default framebuffer
267 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, null);
268 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "bind read framebuffer to default (null) framebuffer.");
270 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, null);
271 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "bind draw framebuffer to default (null) framebuffer.");
274 description("This tests framebuffer/renderbuffer-related functions");
276 var canvas
= document
.getElementById("canvas");
277 shouldBeNonNull("gl = wtu.create3DContext(canvas, undefined, 2)");
279 testFramebufferRenderbuffer();
282 var successfullyParsed
= true;
285 <script src=
"../../js/js-test-post.js"></script>