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/conformance/misc/webgl-specific-stencil-settings.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/conformance/misc/webgl-specific-stencil-settings.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance/misc/webgl-specific-stencil-settings.html | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/misc/webgl-specific-stencil-settings.html b/dom/canvas/test/webgl-conf/checkout/conformance/misc/webgl-specific-stencil-settings.html new file mode 100644 index 0000000000..770a107dc9 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance/misc/webgl-specific-stencil-settings.html @@ -0,0 +1,299 @@ +<!-- +Copyright (c) 2019 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 stencil mask/func front-state-back-state equality test</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"; +var wtu = WebGLTestUtils; +description("Tests that stencil mask/func are validated correctly when the front state and back state differ."); + +var gl; + +function checkDrawError(errIfMismatch) { + wtu.shouldGenerateGLError(gl, errIfMismatch, "wtu.dummySetProgramAndDrawNothing(gl)"); +} + +function setStencilMask(mask) { + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.stencilMaskSeparate(gl.FRONT, " + mask[0] + ")"); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.stencilMaskSeparate(gl.BACK, " + mask[1] + ")"); +} + +function testStencilMaskCase(mask, error) { + setStencilMask(mask); + // If an error is generated, it should be at draw time. + checkDrawError(error); +} + +function testStencilMask(errIfMismatch) { + testStencilMaskCase([0, 256], gl.NO_ERROR); + testStencilMaskCase([1, 256], errIfMismatch); + testStencilMaskCase([1, 257], gl.NO_ERROR); + testStencilMaskCase([1, 258], errIfMismatch); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.stencilMask(1023)", "resetting stencilMask"); +} + +function setStencilFunc(ref, mask) { + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.stencilFuncSeparate(gl.FRONT, gl.ALWAYS, " + ref[0] + ", " + mask[0] + ")"); + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.stencilFuncSeparate(gl.BACK, gl.ALWAYS, " + ref[1] + ", " + mask[1] + ")"); +} + +function testStencilFuncCase(ref, mask, error) { + setStencilFunc(ref, mask); + // If an error is generated, it should be at draw time. + checkDrawError(error); +} + +function testStencilFunc(errIfMismatch) { + testStencilFuncCase([ 256, 257], [1023, 1023], gl.NO_ERROR); + testStencilFuncCase([ 256, 254], [1023, 1023], errIfMismatch); + + testStencilFuncCase([ -1, 0], [1023, 1023], gl.NO_ERROR); + testStencilFuncCase([ -1, 254], [1023, 1023], errIfMismatch); + + testStencilFuncCase([ 0, 0], [ 1, 257], gl.NO_ERROR); + testStencilFuncCase([ 0, 0], [ 1, 258], errIfMismatch); + + testStencilFuncCase([ 1, 1], [1024, 2048], gl.NO_ERROR); + testStencilFuncCase([ 1, 1], [2048, 1024], gl.NO_ERROR); + + testStencilFuncCase([ -1, -1], [1023, 1023], gl.NO_ERROR); + testStencilFuncCase([ -1, 0], [1023, 1023], gl.NO_ERROR); + testStencilFuncCase([ 0, -1], [1023, 1023], gl.NO_ERROR); + testStencilFuncCase([ 0, 0], [1023, 1023], gl.NO_ERROR); + + testStencilFuncCase([ -1, 255], [1023, 1023], errIfMismatch); + testStencilFuncCase([ 0, 256], [1023, 1023], errIfMismatch); + testStencilFuncCase([ 0, 1024], [1023, 1023], errIfMismatch); + testStencilFuncCase([ 1, 257], [1023, 1023], errIfMismatch); + testStencilFuncCase([ 255, -1], [1023, 1023], errIfMismatch); + testStencilFuncCase([ 256, 0], [1023, 1023], errIfMismatch); + testStencilFuncCase([1024, 0], [1023, 1023], errIfMismatch); + testStencilFuncCase([ 257, 1], [1023, 1023], errIfMismatch); + + wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.stencilFunc(gl.ALWAYS, 0, 1023)", "resetting stencilFunc"); +} + +// +// Tests of the default framebuffer +// + +debug(""); + +debug("Testing default framebuffer with { stencil: true }"); +gl = wtu.create3DContext(undefined, { stencil: true }); +{ + gl.enable(gl.STENCIL_TEST); + testStencilMaskCase([1, 256], gl.INVALID_OPERATION); + testStencilFuncCase([256, 0], [1023, 1023], gl.INVALID_OPERATION); +} + +debug("Testing default framebuffer with { stencil: false }"); +gl = wtu.create3DContext(undefined, { stencil: false }); +{ + // with { stencil: false } + gl.enable(gl.STENCIL_TEST); + testStencilMaskCase([1, 256], gl.NO_ERROR); + testStencilFuncCase([256, 0], [1023, 1023], gl.NO_ERROR); +} +// (continue using this GL context for the other tests) + +// +// Tests with a framebuffer object +// + +const fb = gl.createFramebuffer(); +gl.bindFramebuffer(gl.FRAMEBUFFER, fb); +const colorRB = gl.createRenderbuffer(); +gl.bindRenderbuffer(gl.RENDERBUFFER, colorRB); +gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 1, 1); +gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRB); + +wtu.glErrorShouldBe(gl, gl.NO_ERROR, "initial framebuffer setup") + +function runWithStencilSettings(haveDepthBuffer, haveStencilBuffer, enableStencilTest, fn) { + let rbo = null; + let attachment; + if (haveDepthBuffer || haveStencilBuffer) { + rbo = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); + + let internalformat; + if (haveDepthBuffer && haveStencilBuffer) { + internalformat = gl.DEPTH_STENCIL; + attachment = gl.DEPTH_STENCIL_ATTACHMENT; + } else if (haveDepthBuffer) { + internalformat = gl.DEPTH_COMPONENT16; + attachment = gl.DEPTH_ATTACHMENT; + } else if (haveStencilBuffer) { + internalformat = gl.STENCIL_INDEX8; + attachment = gl.STENCIL_ATTACHMENT; + } + gl.renderbufferStorage(gl.RENDERBUFFER, internalformat, 1, 1); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, rbo); + } + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "depth/stencil renderbuffer setup") + + if (enableStencilTest) { + gl.enable(gl.STENCIL_TEST); + } else { + gl.disable(gl.STENCIL_TEST); + } + + fn(); + + if (rbo) { + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, null); + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.deleteRenderbuffer(rbo); + } + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "depth/stencil renderbuffer cleanup") +} + +function testStencilSettings(haveDepthBuffer, haveStencilBuffer, enableStencilTest, errIfMismatch) { + debug(""); + debug("With depthbuffer=" + haveDepthBuffer + + ", stencilbuffer=" + haveStencilBuffer + + ", stencilTest=" + enableStencilTest + + ", expecting error=" + wtu.glEnumToString(gl, errIfMismatch) + + " for mismatching mask or func settings."); + + runWithStencilSettings(haveDepthBuffer, haveStencilBuffer, enableStencilTest, () => { + // Errors should be the same for both mask and func, because stencil test + // and stencil write are always enabled/disabled in tandem. + testStencilMask(errIfMismatch); + testStencilFunc(errIfMismatch); + }); +} + +debug(""); +debug("Base case checks:"); +testStencilMaskCase([0, 0], gl.NO_ERROR); +testStencilFuncCase([0, 0], [1023, 1023], gl.NO_ERROR); + +// haveDepthBuffer +// | haveStencilBuffer +// | | enableStencilTest +// | | | errIfMismatch +testStencilSettings(false, false, false, gl.NO_ERROR); +testStencilSettings( true, false, false, gl.NO_ERROR); +testStencilSettings(false, true, false, gl.NO_ERROR); +testStencilSettings( true, true, false, gl.NO_ERROR); + +testStencilSettings(false, false, true, gl.NO_ERROR); +testStencilSettings( true, false, true, gl.NO_ERROR); +testStencilSettings(false, true, true, gl.INVALID_OPERATION); +testStencilSettings( true, true, true, gl.INVALID_OPERATION); + +// +// Tests to make sure the stencil validation check, if cached, is invalidated correctly. +// + +debug(""); + +debug("Setup for stencil validation cache invalidation tests"); +setStencilMask([1, 258]); +setStencilFunc([0, 256], [1023, 1023]); + +debug("Test with enabling/disabling stencil test"); +runWithStencilSettings(false, true, false, () => { + checkDrawError(gl.NO_ERROR); + gl.enable(gl.STENCIL_TEST); + checkDrawError(gl.INVALID_OPERATION); + gl.disable(gl.STENCIL_TEST); + checkDrawError(gl.NO_ERROR); +}); + +debug("Test with swapping in a new FBO"); +runWithStencilSettings(false, false, true, () => { + // no error with no stencil buffer + checkDrawError(gl.NO_ERROR); + + // swap in a new FBO with a stencil buffer + const fb2 = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fb2); + gl.bindRenderbuffer(gl.RENDERBUFFER, colorRB); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRB); + const rbo = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, 1, 1); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo); + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + // this draw sholud detect the new fbo state + checkDrawError(gl.INVALID_OPERATION); + + gl.deleteFramebuffer(fb2); + gl.deleteRenderbuffer(rbo) + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); +}); + +debug("Test with adding a stencil attachment"); +runWithStencilSettings(false, false, true, () => { + // no error with no stencil buffer + checkDrawError(gl.NO_ERROR); + + // add a stencil attachment + const rbo = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, 1, 1); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo); + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + // this draw sholud detect the new fbo state + checkDrawError(gl.INVALID_OPERATION); + + gl.deleteRenderbuffer(rbo) + wtu.glErrorShouldBe(gl, gl.NO_ERROR); +}); + +debug("Test with reallocating the DEPTH_STENCIL attachment from depth to depth+stencil"); +runWithStencilSettings(false, false, true, () => { + // attach a depth buffer to the DEPTH_STENCIL attachment + const rbo = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo); + shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + // this draw is invalid, but it still might trigger caching of the stencil validation + checkDrawError(gl.INVALID_FRAMEBUFFER_OPERATION); + + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, 1, 1); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + // this draw sholud detect the new fbo state + checkDrawError(gl.INVALID_OPERATION); + + gl.deleteRenderbuffer(rbo) + wtu.glErrorShouldBe(gl, gl.NO_ERROR); +}); + +gl.deleteFramebuffer(fb); +gl.deleteRenderbuffer(colorRB); + +var successfullyParsed = true; +</script> + +<script src="../../js/js-test-post.js"></script> +</body> +</html> |