Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / rendering / multisampling-depth-resolve.html
blob14aeab4f87f4728ce1a3caa82444e43033e95b01
1 <!--
2 Copyright (c) 2022 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 framebuffer to texture conformance test.</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 <canvas id="canvas"></canvas>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script>
21 "use strict";
22 description("Test resolving multisample depth buffer");
23 debug('Reduced test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=238118">https://bugs.webkit.org/show_bug.cgi?id=238118</a>');
25 // Reproduces an inconistent behavior where if:
26 // 1) You render into a multisampling frame buffer
27 // 2) Geometry is drawn with DEPTH_TEST disabled and then enabled
28 // 3) More than one frame is rendered via requestAnimationFrame
30 const size = 64;
31 const halfSize = size / 2;
33 let wtu = WebGLTestUtils;
34 let canvas = document.getElementById("canvas");
35 canvas.width = size;
36 canvas.height = size;
38 let gl = wtu.create3DContext("canvas", {}, 2);
40 function createTexture(res, format, bytes) {
41 let texture = gl.createTexture();
42 gl.bindTexture(gl.TEXTURE_2D, texture);
43 gl.texStorage2D(gl.TEXTURE_2D, 1, format, res, res);
44 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
45 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
46 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
47 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
48 gl.bindTexture(gl.TEXTURE_2D, null);
49 return texture;
52 function createRenderBuffer(res, format, samples) {
53 let rb = gl.createRenderbuffer();
54 gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
55 if (samples > 1)
56 gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, format, res, res);
57 else
58 gl.renderbufferStorage(gl.RENDERBUFFER, format, res, res);
59 return rb;
62 let yellowQuadVAO = gl.createVertexArray();
63 gl.bindVertexArray(yellowQuadVAO);
64 let yellowQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.75 });
66 let blueQuadVAO = gl.createVertexArray();
67 gl.bindVertexArray(blueQuadVAO);
68 let blueQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.5 });
70 let fsVAO = gl.createVertexArray();
71 gl.bindVertexArray(fsVAO);
72 let fsProgram = wtu.setupTexturedQuad(gl, 0, 1);
73 gl.useProgram(fsProgram);
74 let fsTexLoc = gl.getUniformLocation(fsProgram, "tex");
75 gl.uniform1i(fsTexLoc, 0);
77 // An incorrect render can occur if...
79 // 1) You use renderbufferStorageMultisample.
80 const msaaSamples = 4;
81 const colorRB = createRenderBuffer(size, gl.RGBA8, msaaSamples);
82 const depthRB = createRenderBuffer(size, gl.DEPTH_COMPONENT16, msaaSamples);
83 const resolveTex = createTexture(size, gl.RGBA8);
85 let renderFBO = gl.createFramebuffer();
86 gl.bindFramebuffer(gl.FRAMEBUFFER, renderFBO);
87 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRB);
88 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
90 let resolveFBO = gl.createFramebuffer();
91 gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFBO);
92 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resolveTex, 0);
93 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
95 gl.disable(gl.CULL_FACE);
96 gl.disable(gl.BLEND);
98 var frameCount = 0;
99 function runTest() {
100 // 2) Render from requestAnimationFrame, only starting with the 2nd frame.
101 gl.bindFramebuffer(gl.FRAMEBUFFER, renderFBO);
103 // Clear background red
104 gl.clearColor(1, 0, 0, 1);
105 gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
107 // 3) You disable gl.DEPTH_TEST
108 gl.disable(gl.DEPTH_TEST);
109 gl.depthMask(false);
111 gl.bindVertexArray(yellowQuadVAO);
112 gl.useProgram(yellowQuadProgram);
113 wtu.drawUByteColorQuad(gl, [ 255, 255, 0, 255 ]);
115 // 4) And re-enable gl.DEPTH_TEST
116 gl.enable(gl.DEPTH_TEST);
117 gl.depthMask(true);
119 gl.bindVertexArray(blueQuadVAO);
120 gl.useProgram(blueQuadProgram);
121 wtu.drawUByteColorQuad(gl, [ 0, 0, 255, 255 ]);
123 // Resolve the multisample framebuffer to a texture
124 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, renderFBO);
125 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFBO);
126 gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]);
127 gl.blitFramebuffer(0, 0, size, size,
128 0, 0, size, size,
129 gl.COLOR_BUFFER_BIT, gl.LINEAR);
130 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
131 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
133 // Draw the resolved texture to the backbuffer
134 gl.bindTexture(gl.TEXTURE_2D, resolveTex);
135 gl.useProgram(fsProgram);
136 gl.bindVertexArray(fsVAO);
137 wtu.drawUnitQuad(gl);
139 // 5) The incorrect render can occur on the second rendered frame, called from
140 // requestAnimationFrame.
141 frameCount++;
142 if (frameCount == 2) {
143 checkRenderingResults("multisampling-depth-resolve");
144 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at the end of the test.");
145 finishTest();
146 } else {
147 requestAnimationFrame(runTest);
151 requestAnimationFrame(runTest);
153 function checkRenderingResults(prefix) {
154 // Outer color should be red
155 wtu.checkCanvasRect(gl,
156 1, 1,
157 2, 2,
158 [255, 0, 0, 255],
159 prefix + ": outer pixels should be red");
161 // Outer quad should be rendered yellow.
162 wtu.checkCanvasRect(gl,
163 10, 10,
164 2, 2,
165 [255, 255, 0, 255],
166 prefix + ": outer quad should be yellow");
168 // Center quad should be rendered blue.
169 wtu.checkCanvasRect(gl,
170 halfSize / 2 + 1, halfSize / 2 + 1,
171 2, 2,
172 [0, 0, 255, 255],
173 prefix + ": center quad should be blue");
176 var successfullyParsed = true;
177 </script>
178 </body>
179 </html>