one-large-uniform-buffer.html (5983B)
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 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>WebGL Uniform Buffers Conformance Tests</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 <div id="description"></div> 18 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> 19 <div id="console"></div> 20 <script id="vshader" type="x-shader/x-vertex">#version 300 es 21 in vec4 position; 22 void main() 23 { 24 gl_Position = position; 25 } 26 </script> 27 <script id="fshader" type="x-shader/x-fragment">#version 300 es 28 precision mediump float; 29 uniform uni { 30 vec4 color; 31 }; 32 33 out vec4 fragColor; 34 35 void main() 36 { 37 fragColor = color; 38 } 39 </script> 40 <script> 41 "use strict"; 42 description("This test covers ANGLE bugs when using a large uniform blocks. ANGLE would confuse an internal clipped uniform buffer size and produce an assert or error. Also there were issues with readback of large UBOs. See http://crbug.com/660670."); 43 44 debug(""); 45 46 var wtu = WebGLTestUtils; 47 var canvas = document.getElementById("canvas"); 48 var gl = wtu.create3DContext(canvas, null, 2); 49 var quadVB; 50 51 if (!gl) { 52 testFailed("WebGL context does not exist"); 53 } else { 54 testPassed("WebGL context exists"); 55 56 debug(""); 57 debug("Testing uniform block with large data store"); 58 runTest(); 59 60 debug(""); 61 debug("Testing readback on uniform block with large data store"); 62 runReadbackTest(); 63 } 64 65 function getQuadVerts(depth) { 66 var quadVerts = new Float32Array(3 * 6); 67 quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth; 68 quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth; 69 quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth; 70 quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth; 71 quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth; 72 quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth; 73 return quadVerts; 74 } 75 76 function drawQuad(depth) { 77 if (!quadVB) { 78 quadVB = gl.createBuffer() 79 } 80 81 var quadVerts = getQuadVerts(depth); 82 83 gl.bindBuffer(gl.ARRAY_BUFFER, quadVB); 84 gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW); 85 gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0); 86 gl.enableVertexAttribArray(0); 87 gl.drawArrays(gl.TRIANGLES, 0, 6); 88 } 89 90 function runTest() { 91 92 // Create the program 93 var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"]); 94 if (!program) { 95 testFailed("Failed to set up the program"); 96 return; 97 } 98 99 // Init uniform buffer. To trigger the bug, it's necessary to use the 100 // DYNAMIC_DRAW usage. This makes ANGLE attempt to map the buffer internally 101 // with an incorrect copy size. 102 var ubo = gl.createBuffer(); 103 var big_size = 4096 * 64; 104 var data = new Float32Array([0.5, 0.75, 0.25, 1.0]); 105 gl.bindBuffer(gl.UNIFORM_BUFFER, ubo); 106 gl.bufferData(gl.UNIFORM_BUFFER, big_size, gl.DYNAMIC_DRAW); 107 gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data); 108 109 gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo); 110 var buffer_index = gl.getUniformBlockIndex(program, "uni"); 111 if (buffer_index == -1) { 112 testFailed("Failed to get uniform block index"); 113 return; 114 } 115 gl.uniformBlockBinding(program, buffer_index, 0); 116 117 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up uniform block should succeed"); 118 119 // Draw the quad 120 gl.useProgram(program); 121 drawQuad(0.5); 122 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw with uniform block should succeed"); 123 124 // Verify the output color 125 var color = [127, 191, 64, 255]; 126 wtu.checkCanvas(gl, color, "canvas should be same as input uniform", 1); 127 } 128 129 function runReadbackTest() { 130 131 // Create the program 132 var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"]); 133 if (!program) { 134 testFailed("Failed to set up the program"); 135 return; 136 } 137 138 // Init uniform buffer. To trigger the bug, it's necessary to use the 139 // DYNAMIC_DRAW usage. This makes ANGLE attempt to map the buffer internally 140 // with an incorrect copy size. 141 var ubo = gl.createBuffer(); 142 var num_floats = 4096 * 16; 143 var expected_data = new Float32Array(num_floats); 144 for (var index = 0; index < num_floats; ++index) { 145 expected_data[index] = index; 146 } 147 148 expected_data[0] = 0.5; 149 expected_data[1] = 0.75; 150 expected_data[2] = 0.25; 151 expected_data[3] = 1.0; 152 153 gl.bindBuffer(gl.UNIFORM_BUFFER, ubo); 154 gl.bufferData(gl.UNIFORM_BUFFER, expected_data, gl.DYNAMIC_DRAW); 155 gl.bufferSubData(gl.UNIFORM_BUFFER, 0, expected_data); 156 157 gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo); 158 var buffer_index = gl.getUniformBlockIndex(program, "uni"); 159 if (buffer_index == -1) { 160 testFailed("Failed to get uniform block index"); 161 return; 162 } 163 gl.uniformBlockBinding(program, buffer_index, 0); 164 165 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up uniform block should succeed"); 166 167 // Draw the quad 168 gl.useProgram(program); 169 drawQuad(0.5); 170 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw with uniform block should succeed"); 171 172 // Verify the output color 173 var color = [127, 191, 64, 255]; 174 wtu.checkCanvas(gl, color, "canvas should be same as input uniform", 1); 175 176 // Verify readback 177 var actual_data = new Float32Array(num_floats); 178 gl.getBufferSubData(gl.UNIFORM_BUFFER, 0, actual_data); 179 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Readback from uniform block should succeed"); 180 181 for (var index = 0; index < num_floats; ++index) { 182 if (actual_data[index] != expected_data[index]) { 183 testFailed("Expected and actual buffer data do not match"); 184 return; 185 } 186 } 187 } 188 189 debug(""); 190 var successfullyParsed = true; 191 </script> 192 <script src="../../js/js-test-post.js"></script> 193 194 </body> 195 </html>