Skip to content

Commit 1beafa6

Browse files
authored
Add getAttribLocation and getUniformLocation error tests (#3730)
1 parent 15cb509 commit 1beafa6

File tree

5 files changed

+264
-25
lines changed

5 files changed

+264
-25
lines changed

sdk/tests/conformance/attribs/00_test_list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
--min-version 1.0.2 gl-disabled-vertex-attrib.html
66
--min-version 1.0.4 gl-disabled-vertex-attrib-update.html
77
gl-enable-vertex-attrib.html
8+
--min-version 1.0.4 gl-get-attrib-location-errors.html
89
--min-version 1.0.3 gl-matrix-attributes.html
910
--max-version 1.9.9 gl-vertex-attrib.html
1011
gl-vertexattribpointer.html
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!--
2+
Copyright (c) 2025 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 Get Vertex Attrib Location Errors 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>
15+
</head>
16+
<body>
17+
<canvas id="one" width="50" height="50"></canvas>
18+
<canvas id="two" width="50" height="50"></canvas>
19+
<div id="description"></div>
20+
<div id="console"></div>
21+
<script>
22+
"use strict";
23+
description("Tests error conditions for getAttribLocation");
24+
const wtu = WebGLTestUtils;
25+
26+
const canvas1 = document.getElementById("one");
27+
const canvas2 = document.getElementById("two");
28+
const gl1 = wtu.create3DContext(canvas1);
29+
const gl2 = wtu.create3DContext(canvas2);
30+
31+
const notLinkedProgram = gl1.createProgram();
32+
const deletedProgram = wtu.setupSimpleColorProgram(gl1);
33+
gl1.deleteProgram(deletedProgram);
34+
35+
const validProgram = wtu.setupSimpleColorProgram(gl1);
36+
const validProgramOtherContext = wtu.setupSimpleColorProgram(gl2);
37+
38+
function runTests() {
39+
for (const prefix of ["", "gl_", "webgl_", "_webgl_"]) {
40+
debug("");
41+
debug(`Running tests with ${prefix == '' ? 'no' : prefix} prefix`);
42+
43+
if (!gl1.isContextLost()) {
44+
shouldBe("gl1.getAttribLocation(validProgram, 'vPosition')", "0");
45+
} else {
46+
shouldBe("gl1.getAttribLocation(validProgram, 'vPosition')", "-1");
47+
}
48+
wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Valid attribute");
49+
50+
shouldBe(`gl1.getAttribLocation(validProgram, '${prefix}unknown')`, "-1");
51+
wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Not found attribute");
52+
53+
const length = wtu.getDefault3DContextVersion() > 1 ? 1025 : 257;
54+
shouldBe(`gl1.getAttribLocation(validProgram, '${prefix}${"a".repeat(length)}')`, "-1");
55+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
56+
"Too long attribute name");
57+
58+
shouldBe(`gl1.getAttribLocation(validProgram, '${prefix}à')`, "-1");
59+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
60+
"Attribute name with an unsupported character");
61+
62+
shouldBe(`gl1.getAttribLocation(deletedProgram, '${prefix}vPosition')`, "-1");
63+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
64+
"Deleted program");
65+
66+
shouldBe(`gl1.getAttribLocation(validProgramOtherContext, '${prefix}vPosition')`, "-1");
67+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_OPERATION,
68+
"Program from another context");
69+
70+
shouldBe(`gl1.getAttribLocation(notLinkedProgram, '${prefix}vPosition')`, "-1");
71+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_OPERATION,
72+
"Not linked program");
73+
}
74+
}
75+
76+
runTests();
77+
78+
const ext = gl1.getExtension("WEBGL_lose_context");
79+
if (ext) {
80+
canvas1.addEventListener("webglcontextlost", function (event) {
81+
event.preventDefault();
82+
83+
setTimeout(function() {
84+
debug("");
85+
debug("Retrying all tests with lost context");
86+
wtu.glErrorShouldBe(gl1, gl1.CONTEXT_LOST_WEBGL);
87+
runTests();
88+
ext.restoreContext();
89+
}, 0);
90+
}, false);
91+
92+
canvas1.addEventListener("webglcontextrestored", function (_) {
93+
debug("");
94+
debug("Test an invalidated program with a restored context");
95+
wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "No errors after context restore");
96+
97+
shouldBeFalse("gl1.isProgram(validProgram)");
98+
shouldBe("gl1.getAttribLocation(validProgram, 'vPosition')", "-1");
99+
wtu.glErrorShouldBe(gl1, gl1.INVALID_OPERATION, "Program created before the context lost event");
100+
101+
finishTest();
102+
}, false);
103+
104+
ext.loseContext();
105+
} else {
106+
finishTest();
107+
}
108+
109+
var successfullyParsed = true;
110+
</script>
111+
</body>
112+
</html>

sdk/tests/conformance/uniforms/00_test_list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ gl-uniform-arrays.html
22
# This test is no longer valid with the new packing restrictions
33
#--min-version 1.0.02 gl-uniform-unused-array-elements-get-truncated.html
44
gl-uniform-bool.html
5+
--min-version 1.0.4 gl-get-uniform-location-errors.html
56
--min-version 1.0.4 gl-get-uniform-non-current-program.html
67
gl-uniformmatrix4fv.html
78
gl-unknown-uniform.html
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!--
2+
Copyright (c) 2025 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 Get Uniform Location Errors 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>
15+
</head>
16+
<body>
17+
<canvas id="one" width="50" height="50"></canvas>
18+
<canvas id="two" width="50" height="50"></canvas>
19+
<div id="description"></div>
20+
<div id="console"></div>
21+
<script>
22+
"use strict";
23+
description("Tests error conditions for getUniformLocation");
24+
const wtu = WebGLTestUtils;
25+
26+
const canvas1 = document.getElementById("one");
27+
const canvas2 = document.getElementById("two");
28+
const gl1 = wtu.create3DContext(canvas1);
29+
const gl2 = wtu.create3DContext(canvas2);
30+
31+
const notLinkedProgram = gl1.createProgram();
32+
const deletedProgram = wtu.setupSimpleColorProgram(gl1);
33+
gl1.deleteProgram(deletedProgram);
34+
35+
const validProgram = wtu.setupSimpleColorProgram(gl1);
36+
const validProgramOtherContext = wtu.setupSimpleColorProgram(gl2);
37+
38+
function runTests() {
39+
for (const prefix of ["", "gl_", "webgl_", "_webgl_"]) {
40+
debug("");
41+
debug(`Running tests with ${prefix == '' ? 'no' : prefix} prefix`);
42+
43+
if (!gl1.isContextLost()) {
44+
shouldBeNonNull("gl1.getUniformLocation(validProgram, 'u_color')");
45+
} else {
46+
shouldBeNull("gl1.getUniformLocation(validProgram, 'u_color')");
47+
}
48+
wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Valid uniform");
49+
50+
shouldBeNull(`gl1.getUniformLocation(validProgram, '${prefix}unknown')`);
51+
wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Not found uniform");
52+
53+
const length = wtu.getDefault3DContextVersion() > 1 ? 1025 : 257;
54+
shouldBeNull(`gl1.getUniformLocation(validProgram, '${prefix}${"a".repeat(length)}')`);
55+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
56+
"Too long uniform name");
57+
58+
shouldBeNull(`gl1.getUniformLocation(validProgram, '${prefix}à')`);
59+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
60+
"Uniform name with an unsupported character");
61+
62+
shouldBeNull(`gl1.getUniformLocation(deletedProgram, '${prefix}u_color')`);
63+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_VALUE,
64+
"Deleted program");
65+
66+
shouldBeNull(`gl1.getUniformLocation(validProgramOtherContext, '${prefix}u_color')`);
67+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_OPERATION,
68+
"Program from another context");
69+
70+
shouldBeNull(`gl1.getUniformLocation(notLinkedProgram, '${prefix}u_color')`);
71+
wtu.glErrorShouldBe(gl1, gl1.isContextLost() ? gl1.NO_ERROR : gl1.INVALID_OPERATION,
72+
"Not linked program");
73+
}
74+
}
75+
76+
runTests();
77+
78+
const ext = gl1.getExtension("WEBGL_lose_context");
79+
if (ext) {
80+
canvas1.addEventListener("webglcontextlost", function (event) {
81+
event.preventDefault();
82+
83+
setTimeout(function() {
84+
debug("");
85+
debug("Retrying all tests with lost context");
86+
wtu.glErrorShouldBe(gl1, gl1.CONTEXT_LOST_WEBGL);
87+
runTests();
88+
ext.restoreContext();
89+
}, 0);
90+
}, false);
91+
92+
canvas1.addEventListener("webglcontextrestored", function (_) {
93+
debug("");
94+
debug("Test an invalidated program with a restored context");
95+
wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "No errors after context restore");
96+
97+
shouldBeFalse("gl1.isProgram(validProgram)");
98+
shouldBeNull("gl1.getUniformLocation(validProgram, 'u_color')");
99+
wtu.glErrorShouldBe(gl1, gl1.INVALID_OPERATION, "Program created before the context lost event");
100+
101+
finishTest();
102+
}, false);
103+
104+
ext.loseContext();
105+
} else {
106+
finishTest();
107+
}
108+
109+
var successfullyParsed = true;
110+
</script>
111+
</body>
112+
</html>

specs/latest/1.0/index.html

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3266,25 +3266,33 @@ <h4>Uniforms and attributes</h4>
32663266
<dt class="idl-code">[WebGLHandlesContextLoss] GLint getAttribLocation(WebGLProgram program, DOMString name)
32673267
<span class="gl-spec">(<a href="http://registry.khronos.org/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf#nameddest=section-2.10.4">OpenGL ES 2.0 &sect;2.10.4</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGetAttribLocation.xml">man page</a>)</span>
32683268
<dd>
3269+
If the context's <a href="#webgl-context-lost-flag">webgl context lost flag</a> is set,
3270+
generates no error and returns -1 regardless of the passed parameters.<br><br>
3271+
3272+
If the <a href="#webgl-object-invalidated-flag">invalidated flag</a> of the passed
3273+
<code>program</code> is set, generates an <code>INVALID_OPERATION</code> error and
3274+
returns -1.<br><br>
3275+
32693276
If <code>program</code> was generated by a different <code>WebGLRenderingContext</code>
3270-
than this one, generates an <code>INVALID_OPERATION</code> error and returns -1. <br><br>
3277+
than this one, generates an <code>INVALID_OPERATION</code> error and returns -1.<br><br>
32713278

3272-
If the passed name is longer than the restriction defined
3273-
in <a href="#MAX_LOCATION_LENGTHS">Maximum Uniform and Attribute Location Lengths</a>,
3274-
generates an <code>INVALID_VALUE</code> error and returns -1. <br><br>
3279+
If <code>program</code> was deleted,
3280+
generates an <code>INVALID_VALUE</code> error and returns -1.<br><br>
32753281

3276-
Returns -1 if <code>name</code> starts with one of the reserved WebGL prefixes
3277-
per <a href="#GLSL_CONSTRUCTS">GLSL Constructs</a>. <br><br>
3282+
If <code>program</code> is not linked,
3283+
generates an <code>INVALID_OPERATION</code> error and returns -1.<br><br>
32783284

3279-
Returns -1 if the context's <a href="#webgl-context-lost-flag">webgl context lost
3280-
flag</a> is set. <br><br>
3285+
If the passed <code>name</code> is longer than the restriction defined
3286+
in <a href="#MAX_LOCATION_LENGTHS">Maximum Uniform and Attribute Location Lengths</a>,
3287+
generates an <code>INVALID_VALUE</code> error and returns -1.<br><br>
32813288

3282-
If the <a href="#webgl-object-invalidated-flag">invalidated flag</a> of the passed
3283-
program is set, generates an <code>INVALID_OPERATION</code> error and returns
3284-
-1. <br><br>
3289+
If the passed <code>name</code> contains
3290+
<a href="#CHARACTERS_OUTSIDE_VALID_SET">Characters Outside the GLSL Source Character Set</a>,
3291+
generates an <code>INVALID_VALUE</code> error and returns -1.<br><br>
32853292

3286-
See <a href="#CHARACTERS_OUTSIDE_VALID_SET">Characters Outside the GLSL Source Character
3287-
Set</a> for additional validation performed by WebGL implementations.
3293+
If the passed <code>name</code> starts with one of the reserved WebGL prefixes
3294+
per <a href="#GLSL_CONSTRUCTS">GLSL Constructs</a> and none of the error conditions
3295+
described above apply, generates no error and returns -1.
32883296
<dt class="idl-code">any getUniform(WebGLProgram program, WebGLUniformLocation location)
32893297
<span class="gl-spec">(<a href="http://registry.khronos.org/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf#nameddest=section-6.1.8">OpenGL ES 2.0 &sect;6.1.8</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGetUniform.xml">man page</a>)</span>
32903298
<dd>
@@ -3321,24 +3329,29 @@ <h4>Uniforms and attributes</h4>
33213329
<span class="gl-spec">(<a href="http://registry.khronos.org/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf#nameddest=section-2.10.4">OpenGL ES 2.0 &sect;2.10.4</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGetUniformLocation.xml">man page</a>)</span>
33223330
<dd>
33233331
If <code>program</code> was generated by a different <code>WebGLRenderingContext</code>
3324-
than this one, generates an <code>INVALID_OPERATION</code> error. <br><br>
3332+
than this one, generates an <code>INVALID_OPERATION</code> error and returns null.<br><br>
33253333

3326-
<p>Return a new <code>WebGLUniformLocation</code> that represents the location of a
3327-
specific uniform variable within a program object. The return value is null if name does
3328-
not correspond to an active uniform variable in the passed program.</p>
3334+
If <code>program</code> was deleted,
3335+
generates an <code>INVALID_VALUE</code> error and returns null.<br><br>
3336+
3337+
If <code>program</code> is not linked,
3338+
generates an <code>INVALID_OPERATION</code> error and returns null.<br><br>
33293339

3330-
<p>If the passed name is longer than the restriction defined
3340+
If the passed <code>name</code> is longer than the restriction defined
33313341
in <a href="#MAX_LOCATION_LENGTHS">Maximum Uniform and Attribute Location Lengths</a>,
3332-
generates an <code>INVALID_VALUE</code> error and returns null.</p>
3342+
generates an <code>INVALID_VALUE</code> error and returns null.<br><br>
33333343

3334-
<p>Returns null if <code>name</code> starts with one of the reserved WebGL prefixes
3335-
per <a href="#GLSL_CONSTRUCTS">GLSL Constructs</a>.</p>
3344+
If the passed <code>name</code> contains
3345+
<a href="#CHARACTERS_OUTSIDE_VALID_SET">Characters Outside the GLSL Source Character Set</a>,
3346+
generates an <code>INVALID_VALUE</code> error and returns null.<br><br>
33363347

3337-
<p>See <a href="#CHARACTERS_OUTSIDE_VALID_SET">Characters Outside the GLSL Source
3338-
Character Set</a> for additional validation performed by WebGL implementations.</p>
3348+
If the passed <code>name</code> starts with one of the reserved WebGL prefixes
3349+
per <a href="#GLSL_CONSTRUCTS">GLSL Constructs</a> and none of the error conditions
3350+
described above apply, generates no error and returns null.<br><br>
33393351

3340-
<p>Returns null if any OpenGL errors are generated during the execution of this
3341-
function.</p>
3352+
Returns a new <code>WebGLUniformLocation</code> that represents the location of a
3353+
specific uniform variable within a program object. The return value is null if name does
3354+
not correspond to an active uniform variable in the passed <code>program</code>.
33423355
<dt class="idl-code">any getVertexAttrib(GLuint index, GLenum pname)
33433356
<span class="gl-spec">(<a href="http://registry.khronos.org/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf#nameddest=section-6.1.8">OpenGL ES 2.0 &sect;6.1.8</a>, <a class="nonnormative" href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGetVertexAttrib.xml">man page</a>)</span>
33443357
<dd>

0 commit comments

Comments
 (0)