instanced-rendering-large-divisor.html (4440B)
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 Instanced Arrays Conformance Tests - large vertex attrib divisors</title> 12 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 13 <script src="../../js/desktop-gl-constants.js"></script> 14 <script src="../../js/js-test-pre.js"></script> 15 <script src="../../js/webgl-test-utils.js"></script> 16 </head> 17 <body> 18 <div id="description"></div> 19 <canvas id="canvas"> </canvas> 20 <div id="console"></div> 21 <script id="outputVertexShader" type="x-shader/x-vertex">#version 300 es 22 layout(location = 0) in vec2 a_position; 23 layout(location = 1) in float a_positionOffset; 24 layout(location = 2) in vec4 a_color; 25 out vec4 v_color; 26 void main() 27 { 28 gl_Position = vec4(a_position.x * 0.05 + a_positionOffset, a_position.y * 0.05, 0.0, 1.0); 29 v_color = a_color; 30 } 31 </script> 32 33 <script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es 34 precision highp float; 35 in vec4 v_color; 36 out vec4 my_FragColor; 37 void main() 38 { 39 my_FragColor = v_color; 40 } 41 </script> 42 43 <script> 44 "use strict"; 45 description("Test switching vertex attrib divisor of one attribute between different large values"); 46 // This is a regression test for http://anglebug.com/2832 47 48 debug(""); 49 50 var wtu = WebGLTestUtils; 51 var canvas = document.getElementById("canvas"); 52 canvas.width = 256; 53 canvas.height = 256; 54 var gl = wtu.create3DContext(canvas, null, 2); 55 56 var colorDivisor = 65536 * 2; 57 58 if (!gl) { 59 testFailed("WebGL context does not exist"); 60 } else { 61 testPassed("WebGL context exists"); 62 63 runTest(); 64 } 65 66 function runTest() { 67 var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]); 68 69 gl.clearColor(0.0, 0.0, 1.0, 1.0); 70 71 wtu.setupIndexedQuadWithOptions(gl, {positionLocation: 0}); 72 73 var offsetBuf = gl.createBuffer(); 74 gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuf); 75 // Note that only the first two offsets below should be used for rendering. 76 // We add some extra ones to the buffer since it can reveal if a too small divisor is used on the WebGL backend. 77 var offsetData = []; 78 for (var i = 0; i < 4; ++i) { 79 offsetData.push(0.0 + i * 0.25); 80 } 81 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(offsetData), gl.DYNAMIC_DRAW); 82 83 gl.enableVertexAttribArray(1); 84 gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0); 85 86 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up vertex buffer should succeed"); 87 88 var colorBuf = gl.createBuffer(); 89 gl.bindBuffer(gl.ARRAY_BUFFER, colorBuf); 90 // Red and green colors. 91 var colorData = new Float32Array([1.0, 0.0, 0.0, 1.0, 92 0.0, 1.0, 0.0, 1.0]); 93 gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW); 94 95 gl.enableVertexAttribArray(2); 96 gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0); 97 gl.vertexAttribDivisor(2, colorDivisor); 98 99 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up color buffer should succeed"); 100 101 var divisorsToTry = [ 102 256, 103 65536, 104 65536 * 2 105 ]; 106 107 for (var i = 0; i < divisorsToTry.length; ++i) { 108 runDrawElementsTest(divisorsToTry[i]); 109 } 110 } 111 112 function runDrawElementsTest(divisor) { 113 debug("Using divisor " + divisor); 114 gl.clear(gl.COLOR_BUFFER_BIT); 115 gl.vertexAttribDivisor(1, divisor); 116 117 var instanceCount = divisor + 1; 118 var quadsRendered = Math.floor((instanceCount - 1) / divisor) + 1; 119 120 gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount); 121 122 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Instanced draw should succeed"); 123 124 for (var quadIndex = 0; quadIndex < quadsRendered + 1; ++quadIndex) { 125 var quadX = Math.floor((quadIndex / 8) * 256 + 128); 126 var quadY = 128; 127 if (quadIndex < quadsRendered) { 128 var quadColorIndex = Math.floor((quadIndex * divisor) / colorDivisor); 129 if (quadColorIndex == 0) { 130 wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [255, 0, 0, 255]); 131 } else { 132 wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [0, 255, 0, 255]); 133 } 134 } else { 135 wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [0, 0, 255, 255]); 136 } 137 } 138 } 139 140 debug(""); 141 var successfullyParsed = true; 142 </script> 143 <script src="../../js/js-test-post.js"></script> 144 </body> 145 </html>