Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / rendering / multisampling-fragment-evaluation.html
blobdf7bce9b0913ce409292bccdc899806af60644b0
1 <!--
2 Copyright (c) 2019 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 multisampling fragment shader evaluation</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>
16 <script id="vshader" type="x-shader/x-vertex">#version 300 es
17 layout(location=0) in vec4 aPosition;
18 out vec4 vPosition;
19 void main()
21 gl_Position = vec4(aPosition);
22 vPosition = aPosition;
24 </script>
25 <script id="fshader" type="x-shader/x-fragment">#version 300 es
26 precision highp float;
27 in vec4 vPosition;
28 layout(location=0) out vec4 oColor;
29 void main()
31 if (vPosition.x < 0.0) {
32 oColor = vec4(1, 0, 0, 1);
33 } else if (vPosition.y < 0.0) {
34 oColor = vec4(0, 1, 0, 1);
35 } else {
36 oColor = vec4(0, 0, 1, 1);
39 </script>
41 </head>
42 <body>
43 <div id="description"></div>
44 <div id="console"></div>
46 <script>
47 "use strict";
49 var wtu = WebGLTestUtils;
50 description("Verify that fragment shader is evaluated only once per framebuffer pixel when multisampling is used.");
52 // GLES 3.0.5 section 3.6.3. Polygon Multisample Rasterization:
53 // "Polygon rasterization produces a fragment for each framebuffer pixel with one or more sample points that satisfy
54 // the point sampling criteria described in section 3.6.1."
56 debug("Regression test for <a href='http://crbug.com/682815'>http://crbug.com/682815</a>");
58 function runTest(testParams) {
59 let canvas = document.createElement('canvas');
60 canvas.width = 1;
61 canvas.height = 1;
62 let gl = wtu.create3DContext(canvas, {antialias: false}, 2);
64 // Find the supported samples for a multisampled renderbuffer of the appropriate internal format.
65 let samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
66 if (!samples || !samples.length) {
67 testFailed("Could not query supported sample counts for required multisampling format " + testParams.internalformat);
68 return;
71 // Note that supported sample counts are required to be reported in descending order.
72 debug('Testing with sample count ' + samples[0]);
73 // Create a framebuffer with a multisampled renderbuffer with the maximum supported number of samples.
74 let rb = gl.createRenderbuffer();
75 gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
76 gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl[testParams.internalformat], 1, 1);
77 let fb = gl.createFramebuffer();
78 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
79 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
80 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
81 testFailed("Rendering to a multisampled renderbuffer of format " + testParams.internalformat + " is required.");
82 return;
85 // Create a program that will choose between one of different possible colors in the fragment shader.
86 // It should be evaluated only once per framebuffer pixel, so only one of the colors will end up in the framebuffer.
87 // However, if the multisampling mode is incorrectly implemented by supersampling, the samples may have different
88 // colors.
89 let program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"]);
91 // Render one triangle using the program. The triangle needs to extend far outside the viewport on all sides, so
92 // that we can safely assume all samples fall inside the triangle. GLES 3.0.5:
93 // "The sample points associated with a pixel may be located inside or outside of the unit square that is considered to bound the pixel."
94 // Here we assume that sample points are less than 9999 pixels away from the pixel they are associated with.
95 let buffer = gl.createBuffer();
96 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
97 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 10000, 30000,
98 -30000, -10000,
99 10000, -10000]), gl.STATIC_DRAW);
100 gl.enableVertexAttribArray(0);
101 gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
102 gl.drawArrays(gl.TRIANGLES, 0, 3);
104 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
105 gl.blitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
106 gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
108 let readBuffer = new Uint8Array(4);
109 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer);
111 // Check that the canvas is one of the colors that the fragment shader may generate, and not a blend of them.
112 let possibleColors = [
113 [255, 0, 0, 255],
114 [0, 255, 0, 255],
115 [0, 0, 255, 255]
117 let anyColorMatched = false;
118 for (let i = 0; i < possibleColors.length; ++i) {
119 let colorMatched = true;
120 for (let j = 0; j < 4; ++j) {
121 if (Math.abs(readBuffer[j] - possibleColors[i][j]) > 2) {
122 colorMatched = false;
125 if (colorMatched) {
126 anyColorMatched = true;
129 if (!anyColorMatched) {
130 testFailed("Color in framebuffer was not one of the colors generated by the fragment shader: " + readBuffer);
131 } else {
132 testPassed("Color in framebuffer was one of the colors generated by the fragment shader: " + readBuffer);
136 runTest({internalformat: 'RGBA8'});
138 var successfullyParsed = true;
139 </script>
140 <script src="../../js/js-test-post.js"></script>
142 </body>
143 </html>