rasterizer-discard-and-implicit-clear.html (5031B)
1 <!-- 2 Copyright (c) 2020 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 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>RASTERIZER_DISCARD doesn't affect implicit clears</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 <script id="vshader" type="x-shader/x-vertex">#version 300 es 16 layout(location=0) in vec2 vPosition; 17 uniform float xTranslation; 18 void main(void) { 19 gl_Position = vec4(vPosition[0] + xTranslation, vPosition[1], 0.0, 1.0); 20 } 21 </script> 22 <script id="fshader" type="x-shader/x-fragment">#version 300 es 23 precision mediump float; 24 uniform vec4 color; 25 out vec4 outColor; 26 void main() { 27 outColor = color; 28 } 29 </script> 30 </head> 31 <body> 32 <canvas id="example"></canvas> 33 <div id="description"></div> 34 <div id="console"></div> 35 <script> 36 "use strict"; 37 debug(""); 38 39 description("Enabling RASTERIZER_DISCARD should not affect implicit clears"); 40 41 const wtu = WebGLTestUtils; 42 const canvas = document.getElementById("example"); 43 const sz = canvas.width = canvas.height = 256; 44 const gl = wtu.create3DContext(canvas, undefined, 2); 45 const NUM_FRAMES = 15; 46 let framesToGo = NUM_FRAMES; 47 let xTranslationLoc; 48 let colorLoc; 49 const positionLocation = 0; 50 const red = [ 1.0, 0.0, 0.0, 1.0 ]; 51 const green = [ 0.0, 1.0, 0.0, 1.0 ]; 52 const transparentBlackRender = [ 0, 0, 0, 0 ]; 53 const greenRender = [ 0, 255, 0, 255 ]; 54 55 if (!gl) { 56 testFailed("WebGL context creation failed"); 57 finishTest(); 58 } else { 59 testPassed("WebGL context creation succeeded"); 60 runDrawTest(); 61 } 62 63 function runDrawTest() { 64 debug("Verify that draws with rasterizer discard enabled do not interfere with implicit clears"); 65 let prog = wtu.loadProgramFromScript(gl, "vshader", "fshader"); 66 gl.useProgram(prog); 67 xTranslationLoc = gl.getUniformLocation(prog, "xTranslation"); 68 colorLoc = gl.getUniformLocation(prog, "color"); 69 let leftRectBuffer = gl.createBuffer(); 70 gl.enableVertexAttribArray(positionLocation); 71 gl.bindBuffer(gl.ARRAY_BUFFER, leftRectBuffer); 72 // Create a rectangle covering the left half of the viewport, in 73 // normalized device coordinates. 74 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 75 0.0, 1.0, 76 -1.0, 1.0, 77 -1.0, -1.0, 78 0.0, 1.0, 79 -1.0, -1.0, 80 0.0, -1.0]), gl.STATIC_DRAW); 81 gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); 82 requestAnimationFrame(renderDrawTestFrame); 83 } 84 85 function renderDrawTestFrame() { 86 // Animation is required in order to expose this bug. When it 87 // occurs, the rectangle leaves trails behind it. 88 gl.uniform1f(xTranslationLoc, 0.0); 89 gl.enable(gl.RASTERIZER_DISCARD); 90 gl.uniform4fv(colorLoc, red); 91 gl.drawArrays(gl.TRIANGLES, 0, 6); 92 gl.disable(gl.RASTERIZER_DISCARD); 93 94 // Animate the rectangle from the left to the right half of the viewport. 95 gl.uniform1f(xTranslationLoc, (NUM_FRAMES - framesToGo) / NUM_FRAMES); 96 // Draw the last frame with green so any (incorrect) trails are visibly red. 97 if (framesToGo == 0) 98 gl.uniform4fv(colorLoc, green); 99 gl.drawArrays(gl.TRIANGLES, 0, 6); 100 101 if (framesToGo-- == 0) { 102 // The left half of the canvas should be transparent black, 103 // which comes from the implicit clear just before drawing the 104 // rectangle without rasterizer discard enabled. 105 wtu.checkCanvasRect(gl, 0, 0, sz / 2, sz, transparentBlackRender, "left half of canvas should be clear", 3); 106 // The right half of the canvas should be solid green, from 107 // the last render of the translated rectangle. 108 wtu.checkCanvasRect(gl, sz / 2, 0, sz / 2, sz, greenRender, "right half of canvas should be green", 3); 109 runReadPixelsTest(); 110 } else { 111 requestAnimationFrame(renderDrawTestFrame); 112 } 113 } 114 115 function runReadPixelsTest() { 116 debug("Verify that readPixels with rasterizer discard enabled receives implicitly cleared data"); 117 framesToGo = NUM_FRAMES; // Reset state. 118 // Clear to transparent black. 119 gl.clearColor(0.0, 0.0, 0.0, 0.0); 120 gl.clear(gl.COLOR_BUFFER_BIT); 121 // Start with rasterizer discard enabled. 122 gl.enable(gl.RASTERIZER_DISCARD); 123 requestAnimationFrame(renderReadPixelsTestFrame); 124 } 125 126 function renderReadPixelsTestFrame() { 127 // Rasterizer discard is enabled at the beginning of this test. 128 129 // The canvas should always contain transparent black at the beginning of the frame. 130 wtu.checkCanvasRect(gl, 0, 0, sz, sz, transparentBlackRender, undefined, 3); 131 132 gl.disable(gl.RASTERIZER_DISCARD); 133 // Clear to red. 134 gl.clearColor(1.0, 0.0, 0.0, 1.0); 135 gl.clear(gl.COLOR_BUFFER_BIT); 136 // Enable rasterizer discard again. 137 gl.enable(gl.RASTERIZER_DISCARD); 138 139 if (--framesToGo == 0) { 140 finishTest(); 141 } else { 142 requestAnimationFrame(renderReadPixelsTestFrame); 143 } 144 } 145 146 </script> 147 148 </body> 149 </html>