summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-stencil-texturing.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-stencil-texturing.html')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-stencil-texturing.html279
1 files changed, 279 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-stencil-texturing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-stencil-texturing.html
new file mode 100644
index 0000000000..729a5bcf8a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-stencil-texturing.html
@@ -0,0 +1,279 @@
+<!--
+Copyright (c) 2023 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 WEBGL_stencil_texturing 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 WEBGL_stencil_texturing extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(null, null, 2);
+var ext;
+
+function runTestNoExtension() {
+ debug("");
+ debug("Check the texture parameter without the extension");
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ shouldBeNull("gl.getTexParameter(gl.TEXTURE_2D, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */)");
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+
+ gl.texParameteri(gl.TEXTURE_2D, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for texParameteri without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+
+ gl.texParameterf(gl.TEXTURE_2D, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for texParameterf without enabling the extension");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+
+ const sampler = gl.createSampler();
+ gl.samplerParameteri(sampler, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameteri");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+ gl.samplerParameterf(sampler, 0x90EA /* DEPTH_STENCIL_TEXTURE_MODE_WEBGL */, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameterf");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+}
+
+function checkEnums() {
+ debug("");
+ debug("Check enums");
+ shouldBe("ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL", "0x90EA");
+ shouldBe("ext.STENCIL_INDEX_WEBGL", "0x1901");
+}
+
+function checkQueries() {
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ debug("");
+ debug("Check default texture state");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
+ debug("");
+ debug("Check texture state updates using texParameteri");
+ gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, ext.STENCIL_INDEX_WEBGL);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'ext.STENCIL_INDEX_WEBGL');
+ gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
+ gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "invalid depth stencil mode value rejected by texParameteri");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
+ debug("");
+ debug("Check texture state updates using texParameterf");
+ gl.texParameterf(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, ext.STENCIL_INDEX_WEBGL);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'ext.STENCIL_INDEX_WEBGL');
+ gl.texParameterf(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
+ gl.texParameterf(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "invalid depth stencil mode value rejected by texParameterf");
+ shouldBe('gl.getTexParameter(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL)', 'gl.DEPTH_COMPONENT');
+
+ debug("");
+ debug("Check that depth stencil texture mode is not accepted as a sampler state");
+ const sampler = gl.createSampler();
+ gl.samplerParameteri(sampler, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameteri");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+ gl.samplerParameterf(sampler, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, gl.DEPTH_COMPONENT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "parameter unknown for samplerParameterf");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no more errors");
+}
+
+function checkSampling() {
+ const formats = [
+ {name: "DEPTH_COMPONENT16", internalFormat: gl.DEPTH_COMPONENT16,
+ format: gl.DEPTH_COMPONENT, type: gl.UNSIGNED_SHORT},
+ {name: "DEPTH_COMPONENT24", internalFormat: gl.DEPTH_COMPONENT24,
+ format: gl.DEPTH_COMPONENT, type: gl.UNSIGNED_INT},
+ {name: "DEPTH_COMPONENT32F", internalFormat: gl.DEPTH_COMPONENT32F,
+ format: gl.DEPTH_COMPONENT, type: gl.FLOAT},
+ {name: "DEPTH24_STENCIL8", internalFormat: gl.DEPTH24_STENCIL8,
+ format: gl.DEPTH_STENCIL, type: gl.UNSIGNED_INT_24_8},
+ {name: "DEPTH32F_STENCIL8", internalFormat: gl.DEPTH32F_STENCIL8,
+ format: gl.DEPTH_STENCIL, type: gl.FLOAT_32_UNSIGNED_INT_24_8_REV}
+ ];
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.enable(gl.STENCIL_TEST);
+ gl.stencilFunc(gl.ALWAYS, 170, 0xFF);
+ gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
+
+ wtu.setupUnitQuad(gl);
+
+ const drawProgram = wtu.setupProgram(gl, [wtu.simpleVertexShader,
+ wtu.simpleColorFragmentShader]);
+
+ const readDepthProgram = wtu.setupProgram(gl, [wtu.simpleTextureVertexShaderESSL300,
+ wtu.simpleTextureFragmentShaderESSL300]);
+
+ const readStencilShader = `#version 300 es
+ precision highp float;
+ uniform highp usampler2D tex;
+ in vec2 texCoord;
+ out vec4 out_color;
+ void main() {
+ out_color = vec4(texture(tex, texCoord)) / 255.0;
+ }`;
+ const readStencilProgram = wtu.setupProgram(gl, [wtu.simpleTextureVertexShaderESSL300,
+ readStencilShader]);
+
+ for (const format of formats) {
+ debug("");
+ debug(`Testing depth stencil texture modes with ${format.name}`);
+ const fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ const rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 1, 1);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, format.internalFormat, 1, 1, 0, format.format, format.type, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture created");
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, tex, 0);
+ if (format.format == gl.DEPTH_STENCIL) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, tex, 0);
+ }
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
+
+ gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ gl.useProgram(drawProgram);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors after drawing to the depth or depth stencil texture");
+
+ // Detach the depth or depth stencil texture to avoid feedback loop
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
+
+ const magFilters = ['NEAREST', 'LINEAR'];
+
+ const minFilters = [
+ 'NEAREST',
+ 'LINEAR',
+ 'NEAREST_MIPMAP_NEAREST',
+ 'LINEAR_MIPMAP_NEAREST',
+ 'NEAREST_MIPMAP_LINEAR',
+ 'LINEAR_MIPMAP_LINEAR'
+ ];
+
+ const modes = [
+ [gl.DEPTH_COMPONENT, 'DEPTH_COMPONENT'],
+ [ext.STENCIL_INDEX_WEBGL, 'STENCIL_INDEX_WEBGL']
+ ];
+
+ const programs = [
+ [readDepthProgram, 'depth'],
+ [readStencilProgram, 'stencil']
+ ];
+
+ function validFilters(magFilter, minFilter) {
+ return magFilter == gl.NEAREST &&
+ (minFilter == gl.NEAREST || minFilter == gl.NEAREST_MIPMAP_NEAREST);
+ }
+
+ for (const program of programs) {
+ gl.useProgram(program[0]);
+ for (const mode of modes) {
+ gl.texParameteri(gl.TEXTURE_2D, ext.DEPTH_STENCIL_TEXTURE_MODE_WEBGL, mode[0]);
+ for (const magFilter of magFilters) {
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl[magFilter]);
+ for (const minFilter of minFilters) {
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl[minFilter]);
+ debug(`Program: ${program[1]}, mode: ${mode[1]}, mag: ${magFilter}, min: ${minFilter}`);
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.drawUnitQuad(gl);
+
+ if (format.format == gl.DEPTH_COMPONENT || mode[0] == gl.DEPTH_COMPONENT) {
+ if (program[1] == 'depth') {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ if (validFilters(gl[magFilter], gl[minFilter])) {
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [128, 0, 0, 255], "sampling depth from complete texture", 1);
+ } else {
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255], "sampling depth from incomplete texture", 1);
+ }
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "sampling depth using incompatible program");
+ }
+ } else {
+ if (program[1] == 'stencil') {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ if (validFilters(gl[magFilter], gl[minFilter])) {
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [170, 0, 0, 1], "sampling stencil from complete texture", 1);
+ } else {
+ // Incomplete textures may produce [0, 0, 0, 1] or [0, 0, 0, 255].
+ const value = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, value);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ const msg = "sampling stencil from incomplete texture";
+ if (value[0] == 0 && value[1] == 0 && value[2] == 0 && (value[3] == 1 || value[3] == 255)) {
+ testPassed(msg);
+ } else {
+ testFailed(`${msg}: ${value}`);
+ }
+ }
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "sampling stencil using incompatible program");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ testPassed("context exists");
+
+ runTestNoExtension();
+
+ ext = gl.getExtension("WEBGL_stencil_texturing");
+ wtu.runExtensionSupportedTest(gl, "WEBGL_stencil_texturing", ext !== null);
+
+ if (ext !== null) {
+ checkEnums();
+ checkQueries();
+ checkSampling();
+ } else {
+ testPassed("No WEBGL_stencil_texturing support -- this is legal");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>