diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html new file mode 100644 index 0000000000..700bb053c1 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html @@ -0,0 +1,573 @@ +<!-- +Copyright (c) 2020 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL OES_draw_buffers_indexed Conformance Tests</title> +<LINK rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<canvas width="20" height="20" style="border: 1px solid blue;" id="c"></canvas> +<div id="description"></div> +<div id="console"></div> +<script> +"use strict"; +description("This test verifies the functionality of the OES_draw_buffers_indexed extension, if it is available."); + +debug(""); + +var wtu = WebGLTestUtils; +var gl = wtu.create3DContext("c", null, 2); +var ext; + +const vs = `#version 300 es +layout(location=0) in vec4 vPosition; +void main() +{ + gl_Position = vPosition; +} +`; + +const fs = `#version 300 es +precision lowp float; +layout(location = 0) out vec4 o_color0; +layout(location = 1) out vec4 o_color1; +void main() +{ + o_color0 = vec4(1, 0, 0, 0); + o_color1 = vec4(1, 0, 0, 0); +} +`; + +function setup() { + const program = wtu.setupProgram(gl, [vs, fs]); + gl.useProgram(program); + wtu.setupUnitQuad(gl, 0); + wtu.glErrorShouldBe(gl, 0, 'No errors from program'); + + const tex1 = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex1); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + wtu.glErrorShouldBe(gl, 0, 'Create texture 1 successfully'); + + const tex2 = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex2); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + wtu.glErrorShouldBe(gl, 0, 'Create texture 2 successfully'); + + const attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]; + + const fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, tex1, 0); + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, tex2, 0); + shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); + + gl.drawBuffers(attachments); + wtu.glErrorShouldBe(gl, 0, 'Set draw buffers without errors'); +} + +function enableDisableTest() { + debug("Testing enableiOES/disableiOES"); + + // Invalid input + ext.enableiOES(gl.DEPTH_TEST, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND'); + + ext.disableiOES(gl.DEPTH_TEST, 0); + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND'); + + gl.disable(gl.BLEND); + + // Valid input + ext.enableiOES(gl.BLEND, 0); + shouldBe('gl.isEnabled(gl.BLEND)', 'true'); + ext.disableiOES(gl.BLEND, 0); + ext.enableiOES(gl.BLEND, 1); + shouldBe('gl.isEnabled(gl.BLEND)', 'false'); + gl.enable(gl.BLEND); + shouldBe('gl.isEnabled(gl.BLEND)', 'true'); + wtu.glErrorShouldBe(gl, 0, 'No errors from enable and disable draw buffers blend state'); +} + +function constantAlphaBlendColorValidationTest() { + debug("Testing CONSTANT_COLOR/ALPHA blend functions limit validation"); + function isConstantColorAndAlphaBlendFunctions(first, second) + { + return (first == gl.CONSTANT_COLOR || first == gl.ONE_MINUS_CONSTANT_COLOR) && + (second == gl.CONSTANT_ALPHA || second == gl.ONE_MINUS_CONSTANT_ALPHA); + } + + function checkBlendFunctions(src, dst) + { + if (isConstantColorAndAlphaBlendFunctions(src, dst) || + isConstantColorAndAlphaBlendFunctions(dst, src)) + { + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'invalid combinations'); + return false; + } + else + { + wtu.glErrorShouldBe(gl, 0, 'No error'); + return true; + } + } + + const srcFunc = [ + gl.ZERO, + gl.ONE, + gl.SRC_COLOR, + gl.ONE_MINUS_SRC_COLOR, + gl.DST_COLOR, + gl.ONE_MINUS_DST_COLOR, + gl.SRC_ALPHA, + gl.ONE_MINUS_SRC_ALPHA, + gl.DST_ALPHA, + gl.ONE_MINUS_DST_ALPHA, + gl.CONSTANT_COLOR, + gl.ONE_MINUS_CONSTANT_COLOR, + gl.CONSTANT_ALPHA, + gl.ONE_MINUS_CONSTANT_ALPHA, + gl.SRC_ALPHA_SATURATE, + ]; + + const dstFunc = [ + gl.ZERO, gl.ONE, + gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR, + gl.DST_COLOR, gl.ONE_MINUS_DST_COLOR, + gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, + gl.DST_ALPHA, gl.ONE_MINUS_DST_ALPHA, + gl.CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_COLOR, + gl.CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_ALPHA, + ]; + + let src, dst; + + // CONSTANT_COLOR/ALPHA invalid combination check + for (let i = 0, leni = srcFunc.length; i < leni; i++) + { + src = srcFunc[i]; + for (let j = 0, lenj = dstFunc.length; j < lenj; j++) + { + dst = dstFunc[j]; + ext.blendFunciOES(0, src, dst); + checkBlendFunctions(src, dst); + ext.blendFuncSeparateiOES(0, src, dst, gl.ONE, gl.ONE); + checkBlendFunctions(src, dst); + } + } +} + +function indexedBlendColorTest() { + debug(''); + debug("Testing blendEquationiOES and blendFunciOES"); + wtu.glErrorShouldBe(gl, 0, 'top of indexedBlendColorTest'); + + gl.clearColor(0, 0, 1, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + + ext.blendEquationiOES(0, gl.FUNC_ADD); + ext.blendFunciOES(0, gl.ONE, gl.ONE); + ext.blendEquationiOES(1, gl.FUNC_ADD); + ext.blendFunciOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + gl.drawArrays(gl.TRIANGLES, 0, 6); + wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors'); + + gl.readBuffer(gl.COLOR_ATTACHMENT0); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 255]); + + gl.readBuffer(gl.COLOR_ATTACHMENT1); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]); + + debug("Testing blendEquationSeparateiOES and blendFuncSeparateiOES"); + gl.clear(gl.COLOR_BUFFER_BIT); + + ext.blendEquationSeparateiOES(0, gl.FUNC_ADD, gl.FUNC_SUBTRACT); + ext.blendFuncSeparateiOES(0, gl.ONE, gl.ONE, gl.ZERO, gl.ZERO); + ext.blendEquationSeparateiOES(1, gl.FUNC_ADD, gl.FUNC_SUBTRACT); + ext.blendFuncSeparateiOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ZERO); + gl.drawArrays(gl.TRIANGLES, 0, 6); + wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors'); + + gl.readBuffer(gl.COLOR_ATTACHMENT0); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 0]); + + gl.readBuffer(gl.COLOR_ATTACHMENT1); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]); + + debug("Testing colorMaskiOES"); + gl.clear(gl.COLOR_BUFFER_BIT); + ext.colorMaskiOES(0, false, false, false, false); + ext.colorMaskiOES(1, true, true, true, true); + + gl.drawArrays(gl.TRIANGLES, 0, 6); + wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors'); + + gl.readBuffer(gl.COLOR_ATTACHMENT0); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]); + + gl.readBuffer(gl.COLOR_ATTACHMENT1); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]); + + debug(''); + debug(`Testing that new tokens aren't on the extension.`); + shouldBe('ext.BLEND_EQUATION_RGB', 'undefined'); + shouldBe('ext.BLEND_EQUATION_ALPHA', 'undefined'); + shouldBe('ext.BLEND_SRC_RGB', 'undefined'); + shouldBe('ext.BLEND_SRC_ALPHA', 'undefined'); + shouldBe('ext.BLEND_DST_RGB', 'undefined'); + shouldBe('ext.BLEND_DST_ALPHA', 'undefined'); + shouldBe('ext.COLOR_WRITEMASK', 'undefined'); + + debug("Testing new tokens for getIndexedParameterTest"); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_ADD'); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_SUBTRACT'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.ONE'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ZERO'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ZERO'); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_ADD'); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_SUBTRACT'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.SRC_ALPHA'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.ONE_MINUS_SRC_ALPHA'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ZERO'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ZERO'); + + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[false, false, false, false]'); + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, true, true, true]'); + + debug("Testing non-indexed getParamter get state from draw buffer 0"); + shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE'); + shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.ONE'); + shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ZERO'); + shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ZERO'); + shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_ADD'); + shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_SUBTRACT'); + shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[false, false, false, false]'); + + debug("Testing non-indexed calls modify all draw buffers state"); + gl.blendEquationSeparate(gl.FUNC_SUBTRACT, gl.FUNC_ADD); + gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE); + gl.colorMask(true, false, true, false); + wtu.glErrorShouldBe(gl, 0, 'Non-indexed state set without errors'); + + shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_SUBTRACT'); + shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_ADD'); + shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE_MINUS_DST_ALPHA'); + shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.DST_ALPHA'); + shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ONE'); + shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ONE'); + shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[true, false, true, false]'); + + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_SUBTRACT'); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_ADD'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE_MINUS_DST_ALPHA'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.DST_ALPHA'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ONE'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ONE'); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_SUBTRACT'); + shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_ADD'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.ONE_MINUS_DST_ALPHA'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.DST_ALPHA'); + shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ONE'); + shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ONE'); + + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, true, false]'); + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, false, true, false]'); +} + +function runTestExtension() { + setup(); + + testInvalidValues(); + + enableDisableTest(); + + // blending should be enabled for drawBuffers 0 and 1 at this point + + constantAlphaBlendColorValidationTest(); + + indexedBlendColorTest(); + + testColorMaskDrawNoOp(); + + testColorMaskAfterComposite(); +} + +function runInvalidEnumsTest() { + debug("Testing new enums for getIndexedParameterTest being invalid before requesting the extension"); + shouldBeNull("gl.getIndexedParameter(0x8009, 0)"); // BLEND_EQUATION_RGB + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_RGB'); + shouldBeNull("gl.getIndexedParameter(0x883D, 0)"); // BLEND_EQUATION_ALPHA + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_ALPHA'); + shouldBeNull("gl.getIndexedParameter(0x80C9, 0)"); // BLEND_SRC_RGB + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_RGB'); + shouldBeNull("gl.getIndexedParameter(0x80CB, 0)"); // BLEND_SRC_ALPHA + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_ALPHA'); + shouldBeNull("gl.getIndexedParameter(0x80C8, 0)"); // BLEND_DST_RGB + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_RGB'); + shouldBeNull("gl.getIndexedParameter(0x80CA, 0)"); // BLEND_DST_ALPHA + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_ALPHA'); + shouldBeNull("gl.getIndexedParameter(0x0C23, 0)"); // COLOR_WRITEMASK + wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], 'invalid operations or invalid enums for COLOR_WRITEMASK'); +} + +function testInvalidValues() { + const numDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS); + if (!numDrawBuffers) throw new Error('!numDrawBuffers'); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, -1)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, ${numDrawBuffers})`); + wtu.shouldGenerateGLError(gl, 0, `ext.enableiOES(gl.BLEND, ${numDrawBuffers-1})`); + + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, -1)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, ${numDrawBuffers})`); + wtu.shouldGenerateGLError(gl, 0, `ext.disableiOES(gl.BLEND, ${numDrawBuffers-1})`); + + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(-1, gl.FUNC_ADD)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(${numDrawBuffers}, gl.FUNC_ADD)`); + wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationiOES(${numDrawBuffers-1}, gl.FUNC_ADD)`); + + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(-1, gl.FUNC_ADD, gl.FUNC_ADD)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(${numDrawBuffers}, gl.FUNC_ADD, gl.FUNC_ADD)`); + wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationSeparateiOES(${numDrawBuffers-1}, gl.FUNC_ADD, gl.FUNC_ADD)`); + + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(-1, gl.ONE, gl.ONE)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(${numDrawBuffers}, gl.ONE, gl.ONE)`); + wtu.shouldGenerateGLError(gl, 0, `ext.blendFunciOES(${numDrawBuffers-1}, gl.ONE, gl.ONE)`); + + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(-1, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(${numDrawBuffers}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`); + wtu.shouldGenerateGLError(gl, 0, `ext.blendFuncSeparateiOES(${numDrawBuffers-1}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`); + + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(-1, 1,1,1,1)`); + wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(${numDrawBuffers}, 1,1,1,1)`); + wtu.shouldGenerateGLError(gl, 0, `ext.colorMaskiOES(${numDrawBuffers-1}, 1,1,1,1)`); +} + +function* range(n) { + for (let i = 0; i < n; i++) { + yield i; + } +} + +function testColorMaskDrawNoOp() { + debug(''); + debug('testColorMaskDrawNoOp') + // > If any draw buffer with an attachment does not have a defined + // fragment shader output, draws generate INVALID_OPERATION, + // unless all 4 channels of colorMask are set to false. + const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS); + shouldBeTrue(`${NUM_OUTPUTS} > 1`); + + const fb = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.viewport(0,0,1,1); + + const DRAW_BUFFERS = []; + for (const i of range(NUM_OUTPUTS)) { + const tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 1, 1); + const ca = gl.COLOR_ATTACHMENT0+i; + DRAW_BUFFERS.push(ca) + gl.framebufferTexture2D(gl.FRAMEBUFFER, ca, + gl.TEXTURE_2D, tex, 0); + } + shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); + + gl.drawBuffers(DRAW_BUFFERS); + gl.colorMask(1, 1, 1, 1); + gl.disable(gl.BLEND); + + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + for (const i of range(NUM_OUTPUTS)) { + gl.readBuffer(gl.COLOR_ATTACHMENT0+i); + wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 0], `COLOR_ATTACHMENT${i} initially black`); + } + + for (const validOutput of range(NUM_OUTPUTS)) { + const invalidOutput = validOutput ^ 0b11; + debug(`validOutput: ${validOutput}, invalidOutput: ${invalidOutput}`); + const prog = wtu.setupProgram(gl, [ + `\ +#version 300 es +void main() { + gl_Position = vec4(0,0,0,1); + gl_PointSize = 1.0f; +} +`, + `\ +#version 300 es +precision mediump float; +layout(location=${validOutput}) out vec4 o_color; +void main() { + o_color = vec4(1,1,1,1); +} +` + ]); + gl.useProgram(prog); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + 'After init.'); + + gl.colorMask(1,1,1,1); + gl.drawBuffers(DRAW_BUFFERS); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, + 'Drawing with unmasked undefined color outputs.'); + + gl.colorMask(0,0,0,0); + gl.drawBuffers(DRAW_BUFFERS); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + 'Drawing with colorMask-masked-out undefined color outputs.'); + + gl.colorMask(1,1,1,1); + gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == invalidOutput) ? x : 0)); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, + 'Drawing with wrong-id drawBuffer-masked-out undefined color outputs.'); + + gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0)); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + 'Drawing with drawBuffer-masked-out undefined color outputs.'); + + gl.colorMask(0,0,0,0); + gl.drawBuffers([]); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + 'Drawing with colorMask+drawBuffer-masked-out undefined color outputs.'); + + const testMask = (r,g,b,a) => { + debug(`testMask(${[r,g,b,a]})`); + gl.drawBuffers(DRAW_BUFFERS); + + gl.colorMask(1,1,1,1); + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.colorMask(0,0,0,0); + ext.colorMaskiOES(validOutput, r,g,b,a); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + `Drawing with sole defined color${validOutput} output writemask: ${[r,g,b,a]}.`); + + for (const i of range(NUM_OUTPUTS)) { + gl.readBuffer(gl.COLOR_ATTACHMENT0+i); + let expect = [0,0,0,0]; + if (i == validOutput) { + expect = [r,g,b,a].map(x => 0xff*x); + } + wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`); + } + + gl.colorMask(1,1,1,1); + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.colorMask(r,g,b,a); + for (const i of range(NUM_OUTPUTS)) { + if (i == validOutput) continue; + ext.colorMaskiOES(i, 0,0,0,0); + } + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + `Drawing with sole remaining defined color${validOutput} output writemask: ${[r,g,b,a]}.`); + + for (const i of range(NUM_OUTPUTS)) { + gl.readBuffer(gl.COLOR_ATTACHMENT0+i); + let expect = [0,0,0,0]; + if (i == validOutput) { + expect = [r,g,b,a].map(x => 0xff*x); + } + wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`); + } + + if (r || g || b || a) { + gl.colorMask(0,0,0,0); + ext.colorMaskiOES(invalidOutput, r,g,b,a); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, + `Drawing with wrong-id undefined color output color masked: ${[r,g,b,a]}.`); + + gl.drawBuffers([]); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + 'Drawing with wrong-id colorMask, but all-off drawBuffers.'); + + gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0)); + gl.drawArrays(gl.POINTS, 0, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, + 'Drawing with wrong-id colorMask, but right-id drawBuffers masked.'); + } + }; + + testMask(0,0,0,0); + testMask(1,0,0,0); + testMask(0,1,0,0); + testMask(0,0,1,0); + testMask(0,0,0,1); + testMask(1,1,1,1); + } +} + +function testColorMaskAfterComposite() { + debug(''); + debug('testColorMaskAfterComposite') + + const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS); + shouldBeTrue(`${NUM_OUTPUTS} > 2`); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.colorMask(0, 0, 1, 0); + ext.colorMaskiOES(0, 1, 0, 0, 0); + ext.colorMaskiOES(1, 0, 1, 0, 0); + + function check() { + gl.clear(gl.COLOR_BUFFER_BIT); + + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, false, false]'); + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[false, true, false, false]'); + shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 2)', '[false, false, true, false]'); + finishTest(); + } + + wtu.waitForComposite(check); +} + +function runTest() { + if (!gl) { + testFailed("context does not exist"); + } else { + testPassed("context exists"); + + runInvalidEnumsTest(); + + ext = gl.getExtension("OES_draw_buffers_indexed"); + + wtu.runExtensionSupportedTest(gl, "OES_draw_buffers_indexed", ext !== null); + + if (ext !== null) { + runTestExtension(); + } else { + testPassed("No OES_draw_buffers_indexed support -- this is legal"); + } + } +} + +runTest(); + +var successfullyParsed = true; +</script> +</body> +</html> |