blob: 3be7717bc414d5572bc9b37a99b8301ea9125dee [file] [log] [blame]
<!--
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>
<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 canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(null, 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);
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("Testing blendEquationiOES and blendFunciOES");
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("Testing new tokens for getIndexedParameterTest");
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_RGB, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_RGB, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_ALPHA, 0)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_ALPHA, 0)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_RGB, 1)', 'gl.SRC_ALPHA');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_RGB, 1)', 'gl.ONE_MINUS_SRC_ALPHA');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_ALPHA, 1)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_ALPHA, 1)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(ext.COLOR_WRITEMASK, 0)', '[false, false, false, false]');
shouldBe('gl.getIndexedParameter(ext.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(ext.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_RGB, 0)', 'gl.ONE_MINUS_DST_ALPHA');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_RGB, 0)', 'gl.DST_ALPHA');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_ALPHA, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_ALPHA, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(ext.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_RGB, 1)', 'gl.ONE_MINUS_DST_ALPHA');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_RGB, 1)', 'gl.DST_ALPHA');
shouldBe('gl.getIndexedParameter(ext.BLEND_SRC_ALPHA, 1)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(ext.BLEND_DST_ALPHA, 1)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(ext.COLOR_WRITEMASK, 0)', '[true, false, true, false]');
shouldBe('gl.getIndexedParameter(ext.COLOR_WRITEMASK, 1)', '[true, false, true, false]');
}
function runTestExtension() {
setup();
enableDisableTest();
// blending should be enabled for drawBuffers 0 and 1 at this point
constantAlphaBlendColorValidationTest();
indexedBlendColorTest();
}
function runInvalidEnumsTest() {
debug("Testing new enums for getIndexedParameterTest being invalid before requesting the extension");
gl.getIndexedParameter(0x8009, 0); // BLEND_EQUATION_RGB
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_RGB');
gl.getIndexedParameter(0x883D, 0); // BLEND_EQUATION_ALPHA
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_ALPHA');
gl.getIndexedParameter(0x80C9, 0); // BLEND_SRC_RGB
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_RGB');
gl.getIndexedParameter(0x80CB, 0); // BLEND_SRC_ALPHA
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_ALPHA');
gl.getIndexedParameter(0x80C8, 0); // BLEND_DST_RGB
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_RGB');
gl.getIndexedParameter(0x80CA, 0); // BLEND_DST_ALPHA
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_ALPHA');
gl.getIndexedParameter(0x0C23, 0); // COLOR_WRITEMASK
wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], 'invalid operations or invalid enums for COLOR_WRITEMASK');
}
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>
<script src="../../js/js-test-post.js"></script>
</body>
</html>