Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / extensions / webgl-render-shared-exponent.html
blob11d505fcc63b6bdcf4f09f3426f2a78c6a581ae2
1 <!--
2 Copyright (c) 2023 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>WebGL WEBGL_render_shared_exponent Conformance Tests</title>
12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
13 <script src="../../js/js-test-pre.js"></script>
14 <script src="../../js/webgl-test-utils.js"></script>
15 </head>
16 <body>
17 <div id="description"></div>
18 <div id="console"></div>
19 <script>
20 "use strict";
21 description("This test verifies the functionality of the WEBGL_render_shared_exponent extension, if it is available.");
23 debug("");
25 var wtu = WebGLTestUtils;
26 var gl = wtu.create3DContext(null, null, 2);
27 var ext;
28 const color = [64.0, 32.0, 16.0, 1.0];
30 function drawTest() {
31 wtu.clearAndDrawUnitQuad(gl);
33 wtu.checkCanvasRect(gl, 0, 0, 1, 1, color,
34 "reading with the RGBA format and FLOAT type", 1,
35 new Float32Array(4), gl.FLOAT, gl.RGBA);
37 const implementationType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
38 const implementationFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
39 if (implementationFormat == gl.RGB && implementationType == gl.UNSIGNED_INT_5_9_9_9_REV) {
40 // Shared exponent value may be implementation
41 // specific, so compare decoded values.
42 const value = new Uint32Array(1);
43 gl.readPixels(0, 0, 1, 1, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, value);
44 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
46 let r = (value >> 0) & 0x1FF;
47 let g = (value >> 9) & 0x1FF;
48 let b = (value >> 18) & 0x1FF;
49 let e = (value >> 27) & 0x01F;
50 debug(`Raw value: 0x${value[0].toString(16).toUpperCase()}, ` +
51 `Raw components: R = ${r}, G = ${g}, B = ${b}, E = ${e}`);
53 e = Math.pow(2, e - 24);
54 r *= e;
55 g *= e;
56 b *= e;
57 debug(`Decoded color: (${r}, ${g}, ${b})`);
59 if (r == color[0] && g == color[1] && b == color[2]) {
60 testPassed("reading with the exact format/type");
61 } else {
62 testFailed("reading with the exact format/type");
67 function renderbufferTest(isSupported) {
68 debug("");
69 debug(`RGB9_E5 renderbuffer: ` +
70 `${!isSupported ? "NOT " : ""}supported`);
72 const rbo = gl.createRenderbuffer();
73 gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
74 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB9_E5, 1, 1);
75 if (!isSupported) {
76 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "renderbuffer allocation failed");
77 return;
79 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "renderbuffer allocation succeeded");
81 const fbo = gl.createFramebuffer();
82 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
83 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
85 wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
87 drawTest();
90 function textureTest(isRenderable) {
91 debug("");
92 debug(`RGB9_E5 texture: ` +
93 `${!isRenderable ? "NOT " : ""}renderable`);
95 const tex = gl.createTexture();
96 gl.bindTexture(gl.TEXTURE_2D, tex);
97 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB9_E5, 1, 1, 0, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, null);
98 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture allocation succeeded");
100 const fbo = gl.createFramebuffer();
101 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
102 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
104 if (!isRenderable) {
105 wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
106 return;
108 wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
110 drawTest();
113 function formatTest(isEnabled) {
114 const program = wtu.setupProgram(gl, [wtu.simpleVertexShader,
115 wtu.simpleColorFragmentShader]);
116 gl.useProgram(program);
117 gl.uniform4fv(gl.getUniformLocation(program, "u_color"), color);
119 wtu.setupUnitQuad(gl);
121 renderbufferTest(isEnabled);
122 textureTest(isEnabled);
125 function colorMaskTest() {
126 debug("");
127 debug("Test color write masks with shared exponent color buffers");
129 const fs = `#version 300 es
130 precision highp float;
131 layout(location = 0) out vec4 color0;
132 layout(location = 1) out vec4 color1;
133 void main() {
134 color0 = vec4(1.0, 0.0, 0.0, 1.0);
135 color1 = vec4(0.0, 1.0, 0.0, 1.0);
137 const program = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, fs]);
138 gl.useProgram(program);
140 const fbo = gl.createFramebuffer();
141 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
143 const rb0 = gl.createRenderbuffer();
144 gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
145 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB9_E5, 4, 4);
146 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
148 const rb1 = gl.createRenderbuffer();
149 gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
150 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 4, 4);
151 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1);
153 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
154 wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
156 const clearValue = new Float32Array(4);
157 const dbiExt = gl.getExtension("OES_draw_buffers_indexed");
159 function expectError(enabled, effectiveMask, operation) {
160 if (!enabled ||
161 effectiveMask == 0x0 /* 0000 */ ||
162 effectiveMask == 0x8 /* 000A */ ||
163 effectiveMask == 0x7 /* RGB0 */ ||
164 effectiveMask == 0xF /* RGBA */ ) {
165 wtu.glErrorShouldBe(gl, gl.NO_ERROR, operation);
166 } else {
167 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, operation);
171 function runOps(enabled, mask0) {
172 wtu.drawUnitQuad(gl);
173 expectError(enabled, mask0, "draw");
175 gl.clear(gl.COLOR_BUFFER_BIT);
176 expectError(enabled, mask0, "clear");
178 gl.clearBufferfv(gl.COLOR, 0, clearValue);
179 expectError(enabled, mask0, "clearBufferfv(RGB9_E5)");
180 gl.clearBufferfv(gl.COLOR, 1, clearValue);
181 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBufferfv(RGBA8)");
184 for (let mask = 0; mask < 16; mask++) {
185 for (const enabled of [false, true]) {
186 debug("");
187 debug(`Setting common color mask ` +
188 `${mask & 1 ? "R" : "0"}` +
189 `${mask & 2 ? "G" : "0"}` +
190 `${mask & 4 ? "B" : "0"}` +
191 `${mask & 8 ? "A" : "0"}` +
192 " with RGB9_E5 attachment " +
193 (enabled ? "enabled" : "disabled"));
194 gl.colorMask(mask & 1, mask & 2, mask & 4, mask & 8);
195 gl.drawBuffers([enabled ? gl.COLOR_ATTACHMENT0 : gl.NONE,
196 gl.COLOR_ATTACHMENT1]);
198 runOps(enabled, mask);
200 if (dbiExt) {
201 debug("Setting incompatible color mask on unused draw buffer")
202 dbiExt.colorMaskiOES(2, true, false, false, false);
203 runOps(enabled, mask); // common mask remains on draw buffer 0
205 debug("Setting incompatible color mask on RGBA8 draw buffer")
206 dbiExt.colorMaskiOES(1, true, false, false, false);
207 runOps(enabled, mask); // common mask remains on draw buffer 0
209 debug("Setting incompatible color mask on RGB9_E5 draw buffer")
210 dbiExt.colorMaskiOES(0, true, false, false, false);
211 runOps(enabled, 1); // overridden
213 debug("Setting compatible color mask on RGB9_E5 draw buffer")
214 dbiExt.colorMaskiOES(0, true, true, true, false);
215 runOps(enabled, 7); // overridden
221 function runTest() {
222 if (!gl) {
223 testFailed("context does not exist");
224 return;
226 testPassed("context exists");
228 debug("");
229 debug("Testing shared exponent rendering with extension disabled");
230 formatTest(false);
232 ext = gl.getExtension("WEBGL_render_shared_exponent");
233 wtu.runExtensionSupportedTest(gl, "WEBGL_render_shared_exponent", ext !== null);
235 if (ext !== null) {
236 debug("");
237 debug("Testing shared exponent rendering with extension enabled");
238 formatTest(true);
239 colorMaskTest();
240 } else {
241 testPassed("No WEBGL_render_shared_exponent support -- this is legal");
245 runTest();
247 var successfullyParsed = true;
248 </script>
249 <script src="../../js/js-test-post.js"></script>
250 </body>
251 </html>