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 out of bounds uniform array access.
</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 <div id=
"description"></div>
18 <canvas id=
"example" width=
"128" height=
"128" style=
"background: black;">
20 <div id=
"console"></div>
21 <script id=
"vshader" type=
"x-shader/x-vertex">
22 attribute vec4 vPosition;
24 uniform float lineWidth;
26 uniform vec4 colorArray[
6];
29 vec2 texcoord = vec2(vPosition.xy *
0.5 + vec2(
0.5,
0.5));
30 int index = int(texcoord.x + texcoord.y * lineWidth) * elemMult;
31 v_color = colorArray[index];
32 gl_Position = vPosition;
37 <script id=
"fshader" type=
"x-shader/x-fragment">
38 precision mediump float;
42 gl_FragColor = v_color;
47 debug("Tests a WebGL program that accesses out of bounds uniform array elements");
55 var pixels
= new Uint8Array(width
* height
* 4);
61 1.0, 0.0, 0.0, 1.0, // Red
62 0.0, 1.0, 0.0, 1.0, // Green
63 0.0, 0.0, 1.0, 1.0, // Blue
64 0.0, 1.0, 1.0, 1.0, // Cyan
65 1.0, 0.0, 1.0, 1.0, // Magenta
66 1.0, 1.0, 0.0, 1.0 // Yellow
70 var wtu
= WebGLTestUtils
;
71 gl
= wtu
.create3DContext("example");
72 var program
= wtu
.setupProgram(
74 ['vshader', 'fshader'],
77 // setupQuad produces the geometry we want for a gridRes x gridRes grid
78 // of points. No interpolation will be performed across the points, so
79 // according to the WebGL specification for out-of-bounds array accesses,
80 // we will get exactly the input colors from the uniform colorArray, or
81 // zero, for each pixel on the canvas.
82 wtu
.setupIndexedQuad(gl
, gridRes
, 0);
83 var colorArrayLoc
= gl
.getUniformLocation(program
, "colorArray[0]");
84 assertMsg(colorArrayLoc
!= null, "color array uniform should be found");
85 var colors
= new Float32Array(knownColors
);
86 gl
.uniform4fv(colorArrayLoc
, colors
);
87 lineWidthLoc
= gl
.getUniformLocation(program
, "lineWidth");
88 elemMultLoc
= gl
.getUniformLocation(program
, "elemMult");
89 assertMsg(gl
.getError() == gl
.NO_ERROR
, "Should be no errors from setup.");
93 function withinEpsilon(val1
, val2
) {
94 return Math
.abs(val1
- val2
) < 0.0001;
97 function isKnownColor(r
, g
, b
) {
98 if (r
== 0 && g
== 0 && b
== 0)
100 for (var ii
= 0; ii
< knownColors
.length
; ii
+= 4) {
101 if (withinEpsilon(r
/ 255.0, knownColors
[ii
+ 0]) &&
102 withinEpsilon(g
/ 255.0, knownColors
[ii
+ 1]) &&
103 withinEpsilon(b
/ 255.0, knownColors
[ii
+ 2]))
109 function runOneIteration() {
110 if (elemMult
< 2048) {
112 var startingLineWidth
= lineWidth
;
113 var firstFailingPixel
= null;
114 var firstFailingValue
= null;
115 for (; lineWidth
< 2540; lineWidth
+= 31) {
117 gl
.clear(gl
.COLOR_BUFFER_BIT
| gl
.DEPTH_BUFFER_BIT
);
118 gl
.uniform1f(lineWidthLoc
, lineWidth
);
119 gl
.uniform1i(elemMultLoc
, elemMult
);
120 gl
.drawArrays(gl
.POINTS
, 0, gridRes
* gridRes
);
123 gl
.readPixels(0, 0, width
, height
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, pixels
);
126 for (var y
= 0; y
< height
; ++y
) {
127 for (var x
= 0; x
< width
; ++x
) {
128 if (!isKnownColor(pixels
[4 * (width
* y
+ x
) + 0],
129 pixels
[4 * (width
* y
+ x
) + 1],
130 pixels
[4 * (width
* y
+ x
) + 2])) {
132 if (firstFailingPixel
== null) {
133 firstFailingPixel
= [x
, y
];
134 firstFailingValue
= [pixels
[4 * (width
* y
+ x
) + 0],
135 pixels
[4 * (width
* y
+ x
) + 1],
136 pixels
[4 * (width
* y
+ x
) + 2]];
142 var endingLineWidth
= lineWidth
- 31;
145 testPassed("Good rendering results for lineWidths " +
146 startingLineWidth
+ "..." + endingLineWidth
+
147 " at elemMult=" + elemMult
);
149 testFailed("for lineWidth=" + lineWidth
+ ", elemMult=" + elemMult
+
150 ": first failing pixel (" + firstFailingPixel
[0] + ", " + firstFailingPixel
[1] + ") was (" +
151 firstFailingValue
[0] + ", " +
152 firstFailingValue
[1] + ", " +
153 firstFailingValue
[2] + "), should be (0, 0, 0) or one of known colors");
156 setTimeout(runOneIteration
, 0);
164 var successfullyParsed
= true;