Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / extensions / oes-draw-buffers-indexed.html
blob700bb053c1077b42f086301a54fa4b223596f010
1 <!--
2 Copyright (c) 2020 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 OES_draw_buffers_indexed Conformance 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 width="20" height="20" style="border: 1px solid blue;" id="c"></canvas>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script>
21 "use strict";
22 description("This test verifies the functionality of the OES_draw_buffers_indexed extension, if it is available.");
24 debug("");
26 var wtu = WebGLTestUtils;
27 var gl = wtu.create3DContext("c", null, 2);
28 var ext;
30 const vs = `#version 300 es
31 layout(location=0) in vec4 vPosition;
32 void main()
34 gl_Position = vPosition;
38 const fs = `#version 300 es
39 precision lowp float;
40 layout(location = 0) out vec4 o_color0;
41 layout(location = 1) out vec4 o_color1;
42 void main()
44 o_color0 = vec4(1, 0, 0, 0);
45 o_color1 = vec4(1, 0, 0, 0);
49 function setup() {
50 const program = wtu.setupProgram(gl, [vs, fs]);
51 gl.useProgram(program);
52 wtu.setupUnitQuad(gl, 0);
53 wtu.glErrorShouldBe(gl, 0, 'No errors from program');
55 const tex1 = gl.createTexture();
56 gl.bindTexture(gl.TEXTURE_2D, tex1);
57 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
58 wtu.glErrorShouldBe(gl, 0, 'Create texture 1 successfully');
60 const tex2 = gl.createTexture();
61 gl.bindTexture(gl.TEXTURE_2D, tex2);
62 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
63 wtu.glErrorShouldBe(gl, 0, 'Create texture 2 successfully');
65 const attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1];
67 const fb = gl.createFramebuffer();
68 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
69 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, tex1, 0);
70 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, tex2, 0);
71 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
73 gl.drawBuffers(attachments);
74 wtu.glErrorShouldBe(gl, 0, 'Set draw buffers without errors');
77 function enableDisableTest() {
78 debug("Testing enableiOES/disableiOES");
80 // Invalid input
81 ext.enableiOES(gl.DEPTH_TEST, 0);
82 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND');
84 ext.disableiOES(gl.DEPTH_TEST, 0);
85 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND');
87 gl.disable(gl.BLEND);
89 // Valid input
90 ext.enableiOES(gl.BLEND, 0);
91 shouldBe('gl.isEnabled(gl.BLEND)', 'true');
92 ext.disableiOES(gl.BLEND, 0);
93 ext.enableiOES(gl.BLEND, 1);
94 shouldBe('gl.isEnabled(gl.BLEND)', 'false');
95 gl.enable(gl.BLEND);
96 shouldBe('gl.isEnabled(gl.BLEND)', 'true');
97 wtu.glErrorShouldBe(gl, 0, 'No errors from enable and disable draw buffers blend state');
100 function constantAlphaBlendColorValidationTest() {
101 debug("Testing CONSTANT_COLOR/ALPHA blend functions limit validation");
102 function isConstantColorAndAlphaBlendFunctions(first, second)
104 return (first == gl.CONSTANT_COLOR || first == gl.ONE_MINUS_CONSTANT_COLOR) &&
105 (second == gl.CONSTANT_ALPHA || second == gl.ONE_MINUS_CONSTANT_ALPHA);
108 function checkBlendFunctions(src, dst)
110 if (isConstantColorAndAlphaBlendFunctions(src, dst) ||
111 isConstantColorAndAlphaBlendFunctions(dst, src))
113 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'invalid combinations');
114 return false;
116 else
118 wtu.glErrorShouldBe(gl, 0, 'No error');
119 return true;
123 const srcFunc = [
124 gl.ZERO,
125 gl.ONE,
126 gl.SRC_COLOR,
127 gl.ONE_MINUS_SRC_COLOR,
128 gl.DST_COLOR,
129 gl.ONE_MINUS_DST_COLOR,
130 gl.SRC_ALPHA,
131 gl.ONE_MINUS_SRC_ALPHA,
132 gl.DST_ALPHA,
133 gl.ONE_MINUS_DST_ALPHA,
134 gl.CONSTANT_COLOR,
135 gl.ONE_MINUS_CONSTANT_COLOR,
136 gl.CONSTANT_ALPHA,
137 gl.ONE_MINUS_CONSTANT_ALPHA,
138 gl.SRC_ALPHA_SATURATE,
141 const dstFunc = [
142 gl.ZERO, gl.ONE,
143 gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR,
144 gl.DST_COLOR, gl.ONE_MINUS_DST_COLOR,
145 gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA,
146 gl.DST_ALPHA, gl.ONE_MINUS_DST_ALPHA,
147 gl.CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_COLOR,
148 gl.CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_ALPHA,
151 let src, dst;
153 // CONSTANT_COLOR/ALPHA invalid combination check
154 for (let i = 0, leni = srcFunc.length; i < leni; i++)
156 src = srcFunc[i];
157 for (let j = 0, lenj = dstFunc.length; j < lenj; j++)
159 dst = dstFunc[j];
160 ext.blendFunciOES(0, src, dst);
161 checkBlendFunctions(src, dst);
162 ext.blendFuncSeparateiOES(0, src, dst, gl.ONE, gl.ONE);
163 checkBlendFunctions(src, dst);
168 function indexedBlendColorTest() {
169 debug('');
170 debug("Testing blendEquationiOES and blendFunciOES");
171 wtu.glErrorShouldBe(gl, 0, 'top of indexedBlendColorTest');
173 gl.clearColor(0, 0, 1, 1);
174 gl.clear(gl.COLOR_BUFFER_BIT);
176 ext.blendEquationiOES(0, gl.FUNC_ADD);
177 ext.blendFunciOES(0, gl.ONE, gl.ONE);
178 ext.blendEquationiOES(1, gl.FUNC_ADD);
179 ext.blendFunciOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
180 gl.drawArrays(gl.TRIANGLES, 0, 6);
181 wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
183 gl.readBuffer(gl.COLOR_ATTACHMENT0);
184 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 255]);
186 gl.readBuffer(gl.COLOR_ATTACHMENT1);
187 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]);
189 debug("Testing blendEquationSeparateiOES and blendFuncSeparateiOES");
190 gl.clear(gl.COLOR_BUFFER_BIT);
192 ext.blendEquationSeparateiOES(0, gl.FUNC_ADD, gl.FUNC_SUBTRACT);
193 ext.blendFuncSeparateiOES(0, gl.ONE, gl.ONE, gl.ZERO, gl.ZERO);
194 ext.blendEquationSeparateiOES(1, gl.FUNC_ADD, gl.FUNC_SUBTRACT);
195 ext.blendFuncSeparateiOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ZERO);
196 gl.drawArrays(gl.TRIANGLES, 0, 6);
197 wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
199 gl.readBuffer(gl.COLOR_ATTACHMENT0);
200 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 0]);
202 gl.readBuffer(gl.COLOR_ATTACHMENT1);
203 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]);
205 debug("Testing colorMaskiOES");
206 gl.clear(gl.COLOR_BUFFER_BIT);
207 ext.colorMaskiOES(0, false, false, false, false);
208 ext.colorMaskiOES(1, true, true, true, true);
210 gl.drawArrays(gl.TRIANGLES, 0, 6);
211 wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
213 gl.readBuffer(gl.COLOR_ATTACHMENT0);
214 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]);
216 gl.readBuffer(gl.COLOR_ATTACHMENT1);
217 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]);
219 debug('');
220 debug(`Testing that new tokens aren't on the extension.`);
221 shouldBe('ext.BLEND_EQUATION_RGB', 'undefined');
222 shouldBe('ext.BLEND_EQUATION_ALPHA', 'undefined');
223 shouldBe('ext.BLEND_SRC_RGB', 'undefined');
224 shouldBe('ext.BLEND_SRC_ALPHA', 'undefined');
225 shouldBe('ext.BLEND_DST_RGB', 'undefined');
226 shouldBe('ext.BLEND_DST_ALPHA', 'undefined');
227 shouldBe('ext.COLOR_WRITEMASK', 'undefined');
229 debug("Testing new tokens for getIndexedParameterTest");
230 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_ADD');
231 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_SUBTRACT');
232 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE');
233 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.ONE');
234 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ZERO');
235 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ZERO');
236 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_ADD');
237 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_SUBTRACT');
238 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.SRC_ALPHA');
239 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.ONE_MINUS_SRC_ALPHA');
240 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ZERO');
241 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ZERO');
243 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[false, false, false, false]');
244 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, true, true, true]');
246 debug("Testing non-indexed getParamter get state from draw buffer 0");
247 shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE');
248 shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.ONE');
249 shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ZERO');
250 shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ZERO');
251 shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_ADD');
252 shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_SUBTRACT');
253 shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[false, false, false, false]');
255 debug("Testing non-indexed calls modify all draw buffers state");
256 gl.blendEquationSeparate(gl.FUNC_SUBTRACT, gl.FUNC_ADD);
257 gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE);
258 gl.colorMask(true, false, true, false);
259 wtu.glErrorShouldBe(gl, 0, 'Non-indexed state set without errors');
261 shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_SUBTRACT');
262 shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_ADD');
263 shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE_MINUS_DST_ALPHA');
264 shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.DST_ALPHA');
265 shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ONE');
266 shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ONE');
267 shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[true, false, true, false]');
269 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_SUBTRACT');
270 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_ADD');
271 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE_MINUS_DST_ALPHA');
272 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.DST_ALPHA');
273 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ONE');
274 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ONE');
275 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_SUBTRACT');
276 shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_ADD');
277 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.ONE_MINUS_DST_ALPHA');
278 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.DST_ALPHA');
279 shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ONE');
280 shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ONE');
282 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, true, false]');
283 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, false, true, false]');
286 function runTestExtension() {
287 setup();
289 testInvalidValues();
291 enableDisableTest();
293 // blending should be enabled for drawBuffers 0 and 1 at this point
295 constantAlphaBlendColorValidationTest();
297 indexedBlendColorTest();
299 testColorMaskDrawNoOp();
301 testColorMaskAfterComposite();
304 function runInvalidEnumsTest() {
305 debug("Testing new enums for getIndexedParameterTest being invalid before requesting the extension");
306 shouldBeNull("gl.getIndexedParameter(0x8009, 0)"); // BLEND_EQUATION_RGB
307 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_RGB');
308 shouldBeNull("gl.getIndexedParameter(0x883D, 0)"); // BLEND_EQUATION_ALPHA
309 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_ALPHA');
310 shouldBeNull("gl.getIndexedParameter(0x80C9, 0)"); // BLEND_SRC_RGB
311 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_RGB');
312 shouldBeNull("gl.getIndexedParameter(0x80CB, 0)"); // BLEND_SRC_ALPHA
313 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_ALPHA');
314 shouldBeNull("gl.getIndexedParameter(0x80C8, 0)"); // BLEND_DST_RGB
315 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_RGB');
316 shouldBeNull("gl.getIndexedParameter(0x80CA, 0)"); // BLEND_DST_ALPHA
317 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_ALPHA');
318 shouldBeNull("gl.getIndexedParameter(0x0C23, 0)"); // COLOR_WRITEMASK
319 wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], 'invalid operations or invalid enums for COLOR_WRITEMASK');
322 function testInvalidValues() {
323 const numDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS);
324 if (!numDrawBuffers) throw new Error('!numDrawBuffers');
325 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, -1)`);
326 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, ${numDrawBuffers})`);
327 wtu.shouldGenerateGLError(gl, 0, `ext.enableiOES(gl.BLEND, ${numDrawBuffers-1})`);
329 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, -1)`);
330 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, ${numDrawBuffers})`);
331 wtu.shouldGenerateGLError(gl, 0, `ext.disableiOES(gl.BLEND, ${numDrawBuffers-1})`);
333 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(-1, gl.FUNC_ADD)`);
334 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(${numDrawBuffers}, gl.FUNC_ADD)`);
335 wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationiOES(${numDrawBuffers-1}, gl.FUNC_ADD)`);
337 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(-1, gl.FUNC_ADD, gl.FUNC_ADD)`);
338 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(${numDrawBuffers}, gl.FUNC_ADD, gl.FUNC_ADD)`);
339 wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationSeparateiOES(${numDrawBuffers-1}, gl.FUNC_ADD, gl.FUNC_ADD)`);
341 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(-1, gl.ONE, gl.ONE)`);
342 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(${numDrawBuffers}, gl.ONE, gl.ONE)`);
343 wtu.shouldGenerateGLError(gl, 0, `ext.blendFunciOES(${numDrawBuffers-1}, gl.ONE, gl.ONE)`);
345 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(-1, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
346 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(${numDrawBuffers}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
347 wtu.shouldGenerateGLError(gl, 0, `ext.blendFuncSeparateiOES(${numDrawBuffers-1}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
349 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(-1, 1,1,1,1)`);
350 wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(${numDrawBuffers}, 1,1,1,1)`);
351 wtu.shouldGenerateGLError(gl, 0, `ext.colorMaskiOES(${numDrawBuffers-1}, 1,1,1,1)`);
354 function* range(n) {
355 for (let i = 0; i < n; i++) {
356 yield i;
360 function testColorMaskDrawNoOp() {
361 debug('');
362 debug('testColorMaskDrawNoOp')
363 // > If any draw buffer with an attachment does not have a defined
364 // fragment shader output, draws generate INVALID_OPERATION,
365 // unless all 4 channels of colorMask are set to false.
366 const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
367 shouldBeTrue(`${NUM_OUTPUTS} > 1`);
369 const fb = gl.createFramebuffer();
370 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
371 gl.viewport(0,0,1,1);
373 const DRAW_BUFFERS = [];
374 for (const i of range(NUM_OUTPUTS)) {
375 const tex = gl.createTexture();
376 gl.bindTexture(gl.TEXTURE_2D, tex);
377 gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 1, 1);
378 const ca = gl.COLOR_ATTACHMENT0+i;
379 DRAW_BUFFERS.push(ca)
380 gl.framebufferTexture2D(gl.FRAMEBUFFER, ca,
381 gl.TEXTURE_2D, tex, 0);
383 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
385 gl.drawBuffers(DRAW_BUFFERS);
386 gl.colorMask(1, 1, 1, 1);
387 gl.disable(gl.BLEND);
389 gl.clearColor(0, 0, 0, 0);
390 gl.clear(gl.COLOR_BUFFER_BIT);
392 for (const i of range(NUM_OUTPUTS)) {
393 gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
394 wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 0], `COLOR_ATTACHMENT${i} initially black`);
397 for (const validOutput of range(NUM_OUTPUTS)) {
398 const invalidOutput = validOutput ^ 0b11;
399 debug(`validOutput: ${validOutput}, invalidOutput: ${invalidOutput}`);
400 const prog = wtu.setupProgram(gl, [
402 #version 300 es
403 void main() {
404 gl_Position = vec4(0,0,0,1);
405 gl_PointSize = 1.0f;
409 #version 300 es
410 precision mediump float;
411 layout(location=${validOutput}) out vec4 o_color;
412 void main() {
413 o_color = vec4(1,1,1,1);
417 gl.useProgram(prog);
419 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
420 'After init.');
422 gl.colorMask(1,1,1,1);
423 gl.drawBuffers(DRAW_BUFFERS);
424 gl.drawArrays(gl.POINTS, 0, 1);
425 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
426 'Drawing with unmasked undefined color outputs.');
428 gl.colorMask(0,0,0,0);
429 gl.drawBuffers(DRAW_BUFFERS);
430 gl.drawArrays(gl.POINTS, 0, 1);
431 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
432 'Drawing with colorMask-masked-out undefined color outputs.');
434 gl.colorMask(1,1,1,1);
435 gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == invalidOutput) ? x : 0));
436 gl.drawArrays(gl.POINTS, 0, 1);
437 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
438 'Drawing with wrong-id drawBuffer-masked-out undefined color outputs.');
440 gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0));
441 gl.drawArrays(gl.POINTS, 0, 1);
442 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
443 'Drawing with drawBuffer-masked-out undefined color outputs.');
445 gl.colorMask(0,0,0,0);
446 gl.drawBuffers([]);
447 gl.drawArrays(gl.POINTS, 0, 1);
448 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
449 'Drawing with colorMask+drawBuffer-masked-out undefined color outputs.');
451 const testMask = (r,g,b,a) => {
452 debug(`testMask(${[r,g,b,a]})`);
453 gl.drawBuffers(DRAW_BUFFERS);
455 gl.colorMask(1,1,1,1);
456 gl.clearColor(0, 0, 0, 0);
457 gl.clear(gl.COLOR_BUFFER_BIT);
458 gl.colorMask(0,0,0,0);
459 ext.colorMaskiOES(validOutput, r,g,b,a);
460 gl.drawArrays(gl.POINTS, 0, 1);
461 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
462 `Drawing with sole defined color${validOutput} output writemask: ${[r,g,b,a]}.`);
464 for (const i of range(NUM_OUTPUTS)) {
465 gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
466 let expect = [0,0,0,0];
467 if (i == validOutput) {
468 expect = [r,g,b,a].map(x => 0xff*x);
470 wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`);
473 gl.colorMask(1,1,1,1);
474 gl.clearColor(0, 0, 0, 0);
475 gl.clear(gl.COLOR_BUFFER_BIT);
476 gl.colorMask(r,g,b,a);
477 for (const i of range(NUM_OUTPUTS)) {
478 if (i == validOutput) continue;
479 ext.colorMaskiOES(i, 0,0,0,0);
481 gl.drawArrays(gl.POINTS, 0, 1);
482 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
483 `Drawing with sole remaining defined color${validOutput} output writemask: ${[r,g,b,a]}.`);
485 for (const i of range(NUM_OUTPUTS)) {
486 gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
487 let expect = [0,0,0,0];
488 if (i == validOutput) {
489 expect = [r,g,b,a].map(x => 0xff*x);
491 wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`);
494 if (r || g || b || a) {
495 gl.colorMask(0,0,0,0);
496 ext.colorMaskiOES(invalidOutput, r,g,b,a);
497 gl.drawArrays(gl.POINTS, 0, 1);
498 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
499 `Drawing with wrong-id undefined color output color masked: ${[r,g,b,a]}.`);
501 gl.drawBuffers([]);
502 gl.drawArrays(gl.POINTS, 0, 1);
503 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
504 'Drawing with wrong-id colorMask, but all-off drawBuffers.');
506 gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0));
507 gl.drawArrays(gl.POINTS, 0, 1);
508 wtu.glErrorShouldBe(gl, gl.NO_ERROR,
509 'Drawing with wrong-id colorMask, but right-id drawBuffers masked.');
513 testMask(0,0,0,0);
514 testMask(1,0,0,0);
515 testMask(0,1,0,0);
516 testMask(0,0,1,0);
517 testMask(0,0,0,1);
518 testMask(1,1,1,1);
522 function testColorMaskAfterComposite() {
523 debug('');
524 debug('testColorMaskAfterComposite')
526 const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
527 shouldBeTrue(`${NUM_OUTPUTS} > 2`);
529 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
530 gl.clear(gl.COLOR_BUFFER_BIT);
532 gl.colorMask(0, 0, 1, 0);
533 ext.colorMaskiOES(0, 1, 0, 0, 0);
534 ext.colorMaskiOES(1, 0, 1, 0, 0);
536 function check() {
537 gl.clear(gl.COLOR_BUFFER_BIT);
539 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, false, false]');
540 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[false, true, false, false]');
541 shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 2)', '[false, false, true, false]');
542 finishTest();
545 wtu.waitForComposite(check);
548 function runTest() {
549 if (!gl) {
550 testFailed("context does not exist");
551 } else {
552 testPassed("context exists");
554 runInvalidEnumsTest();
556 ext = gl.getExtension("OES_draw_buffers_indexed");
558 wtu.runExtensionSupportedTest(gl, "OES_draw_buffers_indexed", ext !== null);
560 if (ext !== null) {
561 runTestExtension();
562 } else {
563 testPassed("No OES_draw_buffers_indexed support -- this is legal");
568 runTest();
570 var successfullyParsed = true;
571 </script>
572 </body>
573 </html>