diff options
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.html | 143 |
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> |