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 <link rel=
"stylesheet" href=
"../../resources/js-test-style.css"/>
11 <script src=
"../../js/js-test-pre.js"></script>
12 <script src=
"../../js/webgl-test-utils.js"></script>
13 <title>WebGL Out-of-Bounds Array Buffer Conformance Test
</title>
16 <canvas id=
"canvas" width=
"8" height=
"8" style=
"width: 100px; height: 100px;"></canvas>
17 <div id=
"description"></div>
18 <div id=
"console"></div>
19 <script id=
"vsCheckOutOfBounds" type=
"x-shader/x-vertex">
20 precision mediump float;
21 attribute vec2 position;
22 attribute vec4 vecRandom;
25 // Per the spec, each component can either contain existing contents
26 // of the buffer or
0.
27 bool testFloatComponent(float component) {
28 return (component ==
0.2 || component ==
0.0);
30 // The last component is additionally allowed to be
1.0.
31 bool testLastFloatComponent(float component) {
32 return testFloatComponent(component) || component ==
1.0;
36 if (testFloatComponent(vecRandom.x) &&
37 testFloatComponent(vecRandom.y) &&
38 testFloatComponent(vecRandom.z) &&
39 testLastFloatComponent(vecRandom.w)) {
40 v_color = vec4(
0.0,
1.0,
0.0,
1.0); // green -- We're good
42 v_color = vec4(
1.0,
0.0,
0.0,
1.0); // red -- Unexpected value
44 gl_Position = vec4(position,
0.0,
1.0);
49 description("This test verifies that out-of-bounds array buffers behave according to spec.");
51 var wtu
= WebGLTestUtils
;
52 var canvas
= document
.getElementById("canvas");
53 var gl
= wtu
.create3DContext(canvas
, {antialias
: false});
55 var numberOfQuads
= 200;
57 // Draw out-of-bounds beginning with the start offset passed in.
58 // Ensure that drawArrays flags either no error or INVALID_OPERATION. In the case of INVALID_OPERATION,
59 // no canvas pixels can be touched. In the case of NO_ERROR, all written values must either be the
60 // zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
61 function drawAndVerifyOutOfBoundsArrays(gl
, first
, count
) {
62 gl
.clearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
63 gl
.clear(gl
.COLOR_BUFFER_BIT
| gl
.DEPTH_BUFFER_BIT
);
65 gl
.drawArrays(gl
.TRIANGLES
, first
, count
);
66 var error
= gl
.getError();
67 if (error
=== gl
.INVALID_OPERATION
) {
68 testPassed("drawArrays flagged INVALID_OPERATION, which is valid so long as all canvas pixels were not touched.");
69 wtu
.checkCanvas(gl
, [0, 0, 255, 255]);
70 } else if (error
=== gl
.NO_ERROR
) {
71 testPassed("drawArrays flagged NO_ERROR, which is valid so long as all canvas pixels are green.");
72 wtu
.checkCanvas(gl
, [0, 255, 0, 255]);
74 testFailed("Invalid error flagged by drawArrays. Should be INVALID_OPERATION or NO_ERROR");
78 // Create a vertex buffer with 200 properly formed triangle quads. These quads will cover the
79 // canvas texture such that every single pixel is touched by the fragment shader.
80 var glQuadBuffer
= gl
.createBuffer();
81 gl
.bindBuffer(gl
.ARRAY_BUFFER
, glQuadBuffer
);
82 var quadPositions
= new Float32Array(numberOfQuads
* /*ComponentsPerQuad*/2 * /*VerticesPerQuad*/6);
83 for (var i
= 0; i
< quadPositions
.length
; i
+= /*ComponentsPerQuad*/2 * /*VerticesPerQuad*/6) {
84 quadPositions
[i
+0] = -1.0; // upper left
85 quadPositions
[i
+1] = 1.0;
86 quadPositions
[i
+2] = 1.0; // upper right
87 quadPositions
[i
+3] = 1.0;
88 quadPositions
[i
+4] = -1.0; // lower left
89 quadPositions
[i
+5] = -1.0;
90 quadPositions
[i
+6] = 1.0; // upper right
91 quadPositions
[i
+7] = 1.0;
92 quadPositions
[i
+8] = 1.0; // lower right
93 quadPositions
[i
+9] = -1.0;
94 quadPositions
[i
+10] = -1.0; // lower left
95 quadPositions
[i
+11] = -1.0;
97 gl
.bufferData(gl
.ARRAY_BUFFER
, quadPositions
, gl
.STATIC_DRAW
);
98 gl
.enableVertexAttribArray(0);
99 gl
.vertexAttribPointer(0, 2, gl
.FLOAT
, false, 0, 0);
102 // Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer will be
103 // the one read past the end.
104 var glVertexBuffer
= gl
.createBuffer();
105 gl
.bindBuffer(gl
.ARRAY_BUFFER
, glVertexBuffer
);
106 gl
.bufferData(gl
.ARRAY_BUFFER
, new Float32Array([0.2, 0.2, 0.2, 0.2, 0.2, 0.2]), gl
.STATIC_DRAW
);
107 gl
.enableVertexAttribArray(1);
108 gl
.vertexAttribPointer(1, 4, gl
.FLOAT
, false, 0, 0);
110 // Setup the verification program.
111 var glProgram
= wtu
.setupProgram(gl
, ["vsCheckOutOfBounds", wtu
.simpleVertexColorFragmentShader
], ["position", "vecRandom"]);
112 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Shader and buffer setup should not generate errors");
114 debug("Test -- Draw off the end of the vertex buffer near the beginning of the out of bounds area.");
115 drawAndVerifyOutOfBoundsArrays(gl
, /*first*/6, /*count*/6);
119 debug("Test -- Draw off the end of the vertex buffer near the end of the out of bounds area.")
120 drawAndVerifyOutOfBoundsArrays(gl
, /*first*/(numberOfQuads
- 1) * 6, /*count*/6);
122 var successfullyParsed
= true;
124 <script src=
"../../js/js-test-post.js"></script>