summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html143
1 files changed, 143 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html
new file mode 100644
index 0000000000..df7bce9b09
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html
@@ -0,0 +1,143 @@
+<!--
+Copyright (c) 2019 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 multisampling fragment shader evaluation</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>
+
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+layout(location=0) in vec4 aPosition;
+out vec4 vPosition;
+void main()
+{
+ gl_Position = vec4(aPosition);
+ vPosition = aPosition;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+in vec4 vPosition;
+layout(location=0) out vec4 oColor;
+void main()
+{
+ if (vPosition.x < 0.0) {
+ oColor = vec4(1, 0, 0, 1);
+ } else if (vPosition.y < 0.0) {
+ oColor = vec4(0, 1, 0, 1);
+ } else {
+ oColor = vec4(0, 0, 1, 1);
+ }
+}
+</script>
+
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("Verify that fragment shader is evaluated only once per framebuffer pixel when multisampling is used.");
+
+// GLES 3.0.5 section 3.6.3. Polygon Multisample Rasterization:
+// "Polygon rasterization produces a fragment for each framebuffer pixel with one or more sample points that satisfy
+// the point sampling criteria described in section 3.6.1."
+
+debug("Regression test for <a href='http://crbug.com/682815'>http://crbug.com/682815</a>");
+
+function runTest(testParams) {
+ let canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ let gl = wtu.create3DContext(canvas, {antialias: false}, 2);
+
+ // Find the supported samples for a multisampled renderbuffer of the appropriate internal format.
+ let samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
+ if (!samples || !samples.length) {
+ testFailed("Could not query supported sample counts for required multisampling format " + testParams.internalformat);
+ return;
+ }
+
+ // Note that supported sample counts are required to be reported in descending order.
+ debug('Testing with sample count ' + samples[0]);
+ // Create a framebuffer with a multisampled renderbuffer with the maximum supported number of samples.
+ let rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl[testParams.internalformat], 1, 1);
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Rendering to a multisampled renderbuffer of format " + testParams.internalformat + " is required.");
+ return;
+ }
+
+ // Create a program that will choose between one of different possible colors in the fragment shader.
+ // It should be evaluated only once per framebuffer pixel, so only one of the colors will end up in the framebuffer.
+ // However, if the multisampling mode is incorrectly implemented by supersampling, the samples may have different
+ // colors.
+ let program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"]);
+
+ // Render one triangle using the program. The triangle needs to extend far outside the viewport on all sides, so
+ // that we can safely assume all samples fall inside the triangle. GLES 3.0.5:
+ // "The sample points associated with a pixel may be located inside or outside of the unit square that is considered to bound the pixel."
+ // Here we assume that sample points are less than 9999 pixels away from the pixel they are associated with.
+ let buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 10000, 30000,
+ -30000, -10000,
+ 10000, -10000]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+
+ let readBuffer = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer);
+
+ // Check that the canvas is one of the colors that the fragment shader may generate, and not a blend of them.
+ let possibleColors = [
+ [255, 0, 0, 255],
+ [0, 255, 0, 255],
+ [0, 0, 255, 255]
+ ];
+ let anyColorMatched = false;
+ for (let i = 0; i < possibleColors.length; ++i) {
+ let colorMatched = true;
+ for (let j = 0; j < 4; ++j) {
+ if (Math.abs(readBuffer[j] - possibleColors[i][j]) > 2) {
+ colorMatched = false;
+ }
+ }
+ if (colorMatched) {
+ anyColorMatched = true;
+ }
+ }
+ if (!anyColorMatched) {
+ testFailed("Color in framebuffer was not one of the colors generated by the fragment shader: " + readBuffer);
+ } else {
+ testPassed("Color in framebuffer was one of the colors generated by the fragment shader: " + readBuffer);
+ }
+}
+
+runTest({internalformat: 'RGBA8'});
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>