diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-render-shared-exponent.html')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-render-shared-exponent.html | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-render-shared-exponent.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-render-shared-exponent.html new file mode 100644 index 0000000000..11d505fcc6 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-render-shared-exponent.html @@ -0,0 +1,251 @@ +<!-- +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_render_shared_exponent 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_render_shared_exponent extension, if it is available."); + +debug(""); + +var wtu = WebGLTestUtils; +var gl = wtu.create3DContext(null, null, 2); +var ext; +const color = [64.0, 32.0, 16.0, 1.0]; + +function drawTest() { + wtu.clearAndDrawUnitQuad(gl); + + wtu.checkCanvasRect(gl, 0, 0, 1, 1, color, + "reading with the RGBA format and FLOAT type", 1, + new Float32Array(4), gl.FLOAT, gl.RGBA); + + const implementationType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE); + const implementationFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT); + if (implementationFormat == gl.RGB && implementationType == gl.UNSIGNED_INT_5_9_9_9_REV) { + // Shared exponent value may be implementation + // specific, so compare decoded values. + const value = new Uint32Array(1); + gl.readPixels(0, 0, 1, 1, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, value); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + let r = (value >> 0) & 0x1FF; + let g = (value >> 9) & 0x1FF; + let b = (value >> 18) & 0x1FF; + let e = (value >> 27) & 0x01F; + debug(`Raw value: 0x${value[0].toString(16).toUpperCase()}, ` + + `Raw components: R = ${r}, G = ${g}, B = ${b}, E = ${e}`); + + e = Math.pow(2, e - 24); + r *= e; + g *= e; + b *= e; + debug(`Decoded color: (${r}, ${g}, ${b})`); + + if (r == color[0] && g == color[1] && b == color[2]) { + testPassed("reading with the exact format/type"); + } else { + testFailed("reading with the exact format/type"); + } + } +} + +function renderbufferTest(isSupported) { + debug(""); + debug(`RGB9_E5 renderbuffer: ` + + `${!isSupported ? "NOT " : ""}supported`); + + const rbo = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB9_E5, 1, 1); + if (!isSupported) { + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "renderbuffer allocation failed"); + return; + } + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "renderbuffer allocation succeeded"); + + const fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo); + + wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE); + + drawTest(); +} + +function textureTest(isRenderable) { + debug(""); + debug(`RGB9_E5 texture: ` + + `${!isRenderable ? "NOT " : ""}renderable`); + + const tex = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, tex); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB9_E5, 1, 1, 0, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, null); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture allocation succeeded"); + + const fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); + + if (!isRenderable) { + wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT); + return; + } + wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE); + + drawTest(); +} + +function formatTest(isEnabled) { + const program = wtu.setupProgram(gl, [wtu.simpleVertexShader, + wtu.simpleColorFragmentShader]); + gl.useProgram(program); + gl.uniform4fv(gl.getUniformLocation(program, "u_color"), color); + + wtu.setupUnitQuad(gl); + + renderbufferTest(isEnabled); + textureTest(isEnabled); +} + +function colorMaskTest() { + debug(""); + debug("Test color write masks with shared exponent color buffers"); + + const fs = `#version 300 es + precision highp float; + layout(location = 0) out vec4 color0; + layout(location = 1) out vec4 color1; + void main() { + color0 = vec4(1.0, 0.0, 0.0, 1.0); + color1 = vec4(0.0, 1.0, 0.0, 1.0); + }`; + const program = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, fs]); + gl.useProgram(program); + + const fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + + const rb0 = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rb0); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB9_E5, 4, 4); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0); + + const rb1 = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, rb1); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 4, 4); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE); + + const clearValue = new Float32Array(4); + const dbiExt = gl.getExtension("OES_draw_buffers_indexed"); + + function expectError(enabled, effectiveMask, operation) { + if (!enabled || + effectiveMask == 0x0 /* 0000 */ || + effectiveMask == 0x8 /* 000A */ || + effectiveMask == 0x7 /* RGB0 */ || + effectiveMask == 0xF /* RGBA */ ) { + wtu.glErrorShouldBe(gl, gl.NO_ERROR, operation); + } else { + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, operation); + } + } + + function runOps(enabled, mask0) { + wtu.drawUnitQuad(gl); + expectError(enabled, mask0, "draw"); + + gl.clear(gl.COLOR_BUFFER_BIT); + expectError(enabled, mask0, "clear"); + + gl.clearBufferfv(gl.COLOR, 0, clearValue); + expectError(enabled, mask0, "clearBufferfv(RGB9_E5)"); + gl.clearBufferfv(gl.COLOR, 1, clearValue); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBufferfv(RGBA8)"); + } + + for (let mask = 0; mask < 16; mask++) { + for (const enabled of [false, true]) { + debug(""); + debug(`Setting common color mask ` + + `${mask & 1 ? "R" : "0"}` + + `${mask & 2 ? "G" : "0"}` + + `${mask & 4 ? "B" : "0"}` + + `${mask & 8 ? "A" : "0"}` + + " with RGB9_E5 attachment " + + (enabled ? "enabled" : "disabled")); + gl.colorMask(mask & 1, mask & 2, mask & 4, mask & 8); + gl.drawBuffers([enabled ? gl.COLOR_ATTACHMENT0 : gl.NONE, + gl.COLOR_ATTACHMENT1]); + + runOps(enabled, mask); + + if (dbiExt) { + debug("Setting incompatible color mask on unused draw buffer") + dbiExt.colorMaskiOES(2, true, false, false, false); + runOps(enabled, mask); // common mask remains on draw buffer 0 + + debug("Setting incompatible color mask on RGBA8 draw buffer") + dbiExt.colorMaskiOES(1, true, false, false, false); + runOps(enabled, mask); // common mask remains on draw buffer 0 + + debug("Setting incompatible color mask on RGB9_E5 draw buffer") + dbiExt.colorMaskiOES(0, true, false, false, false); + runOps(enabled, 1); // overridden + + debug("Setting compatible color mask on RGB9_E5 draw buffer") + dbiExt.colorMaskiOES(0, true, true, true, false); + runOps(enabled, 7); // overridden + } + } + } +} + +function runTest() { + if (!gl) { + testFailed("context does not exist"); + return; + } + testPassed("context exists"); + + debug(""); + debug("Testing shared exponent rendering with extension disabled"); + formatTest(false); + + ext = gl.getExtension("WEBGL_render_shared_exponent"); + wtu.runExtensionSupportedTest(gl, "WEBGL_render_shared_exponent", ext !== null); + + if (ext !== null) { + debug(""); + debug("Testing shared exponent rendering with extension enabled"); + formatTest(true); + colorMaskTest(); + } else { + testPassed("No WEBGL_render_shared_exponent support -- this is legal"); + } +} + +runTest(); + +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> +</body> +</html> |