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.
10 <meta charset=
"utf-8">
11 <title>WebGL Unconsumed Vertex Attributes Out of Bounds Test
</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>
17 <canvas id=
"example" width=
"50" height=
"50">
19 <div id=
"description"></div>
20 <div id=
"console"></div>
21 <script id=
"vshader" type=
"x-shader/x-vertex">
25 <script id=
"vshader_attrib" type=
"x-shader/x-vertex">
26 attribute vec4 vPosition;
28 gl_Position = vPosition;
32 <script id=
"fshader" type=
"x-shader/x-fragment">
34 gl_FragColor = vec4(
1);
40 description("Test that unconsumed vertex attributes are not read out of bounds");
41 // Tests for http://crbug.com/756293 (driver crash on macOS)
42 // and a class of similar bugs that could exist on other systems.
44 var wtu
= WebGLTestUtils
;
45 var contextVersion
= wtu
.getDefault3DContextVersion();
46 var gl
= wtu
.create3DContext("example");
50 var numAttribs
= gl
.getParameter(gl
.MAX_VERTEX_ATTRIBS
);
54 function setupBuffers(numVerts
) {
55 var vertices
= new Float32Array(numVerts
* 3);
56 allocatedBuffer
= gl
.createBuffer();
57 gl
.bindBuffer(gl
.ARRAY_BUFFER
, allocatedBuffer
);
58 gl
.bufferData(gl
.ARRAY_BUFFER
, vertices
, gl
.STATIC_DRAW
);
60 var indices
= new Uint16Array(numVerts
);
61 for (var ii
= 0; ii
< numVerts
; ++ii
) {
65 indexBuffer
= gl
.createBuffer();
66 gl
.bindBuffer(gl
.ELEMENT_ARRAY_BUFFER
, indexBuffer
);
67 gl
.bufferData(gl
.ELEMENT_ARRAY_BUFFER
, indices
, gl
.STATIC_DRAW
);
70 var progNoAttribs
= wtu
.setupProgram(gl
, ['vshader', 'fshader'], [], []);
71 var progAttrib1
= wtu
.setupProgram(gl
, ['vshader_attrib', 'fshader'], ['vPosition'], [1]);
72 var progAttrib2
= wtu
.setupProgram(gl
, ['vshader_attrib', 'fshader'], ['vPosition'], [2]);
75 var unallocatedBuffer
= gl
.createBuffer();
79 debug("<u>Tests with one unconsumed attribute<u>");
84 draw: function() { gl
.drawArrays(gl
.TRIANGLES
, 0, 3); }
89 draw: function() { gl
.drawElements(gl
.TRIANGLES
, 60000, gl
.UNSIGNED_SHORT
, 0); }
92 if (contextVersion
>= 2) {
94 name
: "drawArraysInstanced",
96 draw: function() { gl
.drawArraysInstanced(gl
.TRIANGLES
, 0, 3, 1); }
99 name
: "drawElementsInstanced",
101 draw: function() { gl
.drawElementsInstanced(gl
.TRIANGLES
, 60000, gl
.UNSIGNED_SHORT
, 0, 1); }
104 name
: "drawRangeElements",
106 draw: function() { gl
.drawRangeElements(gl
.TRIANGLES
, 0, 60000, 60000, gl
.UNSIGNED_SHORT
, 0, 1); }
113 gl
.bindBuffer(gl
.ELEMENT_ARRAY_BUFFER
, indexBuffer
);
115 for (var attrib
= 0; attrib
< numAttribs
; ++attrib
) {
116 debug("Attrib " + attrib
+ " unconsumed");
117 for (var i
= 0; i
< tests
.length
; ++i
) {
119 gl
.useProgram(progNoAttribs
);
121 gl
.enableVertexAttribArray(attrib
);
122 gl
.bindBuffer(gl
.ARRAY_BUFFER
, unallocatedBuffer
);
123 gl
.vertexAttribPointer(attrib
, 3, gl
.FLOAT
, false, 0, 0);
127 gl
.disableVertexAttribArray(attrib
);
128 wtu
.glErrorShouldBe(gl
, test
.errors
, test
.name
);
133 debug("<u>Tests with one consumed attribute and one unconsumed attribute<u>");
135 var ext
= gl
.getExtension("ANGLE_instanced_arrays");
137 debug("ANGLE_instanced_arrays not available - skipped");
140 name
: "drawArraysInstancedANGLE",
143 ext
.drawArraysInstancedANGLE(gl
.TRIANGLES
, 0, 3, 1);
147 name
: "drawElementsInstancedANGLE",
150 ext
.drawElementsInstancedANGLE(gl
.TRIANGLES
, 3, gl
.UNSIGNED_SHORT
, 0, 1);
155 // Note these don't trigger the macOS driver crash (http://crbug.com/756293)
156 // but they still add potentially useful coverage.
157 for (var attrib
= 0; attrib
< numAttribs
; ++attrib
) {
158 var consumedAttrib
= attrib
== 1 ? 2 : 1;
159 var prog
= consumedAttrib
== 1 ? progAttrib1
: progAttrib2
;
160 debug("Attrib " + attrib
+
161 " unconsumed (attrib " + consumedAttrib
+ " consumed)");
163 for (var i
= 0; i
< tests
.length
; ++i
) {
167 gl
.enableVertexAttribArray(attrib
);
168 gl
.bindBuffer(gl
.ARRAY_BUFFER
, unallocatedBuffer
);
169 gl
.vertexAttribPointer(attrib
, 3, gl
.FLOAT
, false, 0, 0);
171 // Needed because ANGLE_instanced_arrays requires at least one consumed
172 // attribute to have divisor=0 (which is the default, so we don't need to
173 // call vertexAttribDivisorANGLE here).
174 gl
.enableVertexAttribArray(consumedAttrib
);
175 gl
.bindBuffer(gl
.ARRAY_BUFFER
, allocatedBuffer
);
176 gl
.vertexAttribPointer(consumedAttrib
, 3, gl
.FLOAT
, false, 0, 0);
180 gl
.disableVertexAttribArray(attrib
);
181 gl
.disableVertexAttribArray(consumedAttrib
);
182 wtu
.glErrorShouldBe(gl
, test
.errors
, test
.name
);
186 var successfullyParsed
= true;
188 <script src=
"../../js/js-test-post.js"></script>