Skip to content

Commit 4169a3b

Browse files
authored
Add tests for late extension enabling and disabling. (#3776)
These tests apply only to WebGL 1.0, which for historical reasons, allowed extensions to be enabled after non-preprocessor tokens. It was infeasible to allow extensions to be disabled late in shader parsing, so the spec has been revised to forbid this behavior. This does not seem to impact any WebGL applications in production. Follow-up to #3774.
1 parent 109abd5 commit 4169a3b

2 files changed

Lines changed: 155 additions & 0 deletions

File tree

sdk/tests/conformance/glsl/misc/00_test_list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ embedded-struct-definitions-forbidden.html
55
--min-version 1.0.4 empty-declaration.html
66
empty_main.vert.html
77
--min-version 1.0.3 expression-list-in-declarator-initializer.html
8+
--min-version 1.0.4 --max-version 1.9.9 extension-enable-and-disable.html
89
--min-version 1.0.4 fragcolor-fragdata-invariant.html
910
gl_position_unset.vert.html
1011
--min-version 1.0.4 global-variable-init.html
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<!--
2+
Copyright (c) 2026 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 GLSL extension enable and disable late conformance 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="example" width="4" height="4"></canvas>
18+
<div id="description"></div>
19+
<div id="console"></div>
20+
<script>
21+
"use strict";
22+
description(document.title);
23+
var wtu = WebGLTestUtils;
24+
25+
var gl;
26+
27+
// This test runs only under WebGL 1.0. WebGL 2.0 follows GLSL ES
28+
// 300's extension enabling and disabling rules.
29+
let contextVersion = wtu.getDefault3DContextVersion();
30+
if (contextVersion != 1) {
31+
debug("Test only applies to WebGL 1.0.");
32+
} else {
33+
gl = wtu.create3DContext("example");
34+
if (!gl) {
35+
testFailed("WebGL context creation failed");
36+
} else {
37+
// Check for the extension.
38+
var ext = gl.getExtension("EXT_frag_depth");
39+
if (!ext) {
40+
debug("EXT_frag_depth not supported, skipping test.");
41+
} else {
42+
runTests();
43+
}
44+
}
45+
}
46+
47+
function runTests() {
48+
var vsSource = `
49+
attribute vec4 position;
50+
void main() {
51+
gl_Position = position;
52+
}
53+
`;
54+
55+
// Case 1: LateEnableExtension (Should Succeed)
56+
// Test that in WebGL1, extensions can be enabled late in the shader.
57+
var fsSourceSuccess = `
58+
precision mediump float;
59+
void main()
60+
{
61+
#extension GL_EXT_frag_depth : enable
62+
gl_FragDepthEXT = 1.0;
63+
}
64+
`;
65+
66+
// Case 2: LateDisableExtension - Case A (Should Fail)
67+
// Test that in WebGL1, even though an extension can be enabled late in the shader, it cannot be disabled late.
68+
var fsSourceFailA = `
69+
#extension GL_EXT_frag_depth : enable
70+
precision mediump float;
71+
void main()
72+
{
73+
gl_FragDepthEXT = 1.0;
74+
#extension GL_EXT_frag_depth : disable
75+
}
76+
`;
77+
78+
// Case 3: LateDisableExtension - Case B (Should Fail)
79+
// Test that in WebGL1, even though an extension can be enabled late in the shader, it cannot be disabled late.
80+
var fsSourceFailB = `
81+
#extension GL_EXT_frag_depth : enable
82+
precision mediump float;
83+
void main()
84+
{
85+
gl_FragDepthEXT = 1.0;
86+
}
87+
#extension all : disable
88+
`;
89+
90+
runShaderTest(vsSource, fsSourceSuccess, true, "LateEnableExtension (Should Succeed)");
91+
runShaderTest(vsSource, fsSourceFailA, false, "LateDisableExtension Case A (Should Fail)");
92+
runShaderTest(vsSource, fsSourceFailB, false, "LateDisableExtension Case B (Should Fail)");
93+
}
94+
95+
function runShaderTest(vsSource, fsSource, shouldSucceed, desc) {
96+
debug("");
97+
debug("Testing: " + desc);
98+
var vs = gl.createShader(gl.VERTEX_SHADER);
99+
gl.shaderSource(vs, vsSource);
100+
gl.compileShader(vs);
101+
var vsCompileStatus = gl.getShaderParameter(vs, gl.COMPILE_STATUS);
102+
103+
var fs = gl.createShader(gl.FRAGMENT_SHADER);
104+
gl.shaderSource(fs, fsSource);
105+
gl.compileShader(fs);
106+
var fsCompileStatus = gl.getShaderParameter(fs, gl.COMPILE_STATUS);
107+
108+
var programLinked = false;
109+
var program = null;
110+
111+
if (vsCompileStatus && fsCompileStatus) {
112+
program = gl.createProgram();
113+
gl.attachShader(program, vs);
114+
gl.attachShader(program, fs);
115+
gl.linkProgram(program);
116+
programLinked = gl.getProgramParameter(program, gl.LINK_STATUS);
117+
}
118+
119+
var overallSuccess = vsCompileStatus && fsCompileStatus && programLinked;
120+
121+
if (shouldSucceed) {
122+
if (overallSuccess) {
123+
testPassed("Shader compiled and linked successfully as expected.");
124+
} else {
125+
testFailed("Shader failed to compile or link. VS compile: " + vsCompileStatus +
126+
", FS compile: " + fsCompileStatus + ", Link: " + programLinked);
127+
if (!vsCompileStatus) debug("VS info log: " + gl.getShaderInfoLog(vs));
128+
if (!fsCompileStatus) debug("FS info log: " + gl.getShaderInfoLog(fs));
129+
if (program && !programLinked) debug("Program info log: " + gl.getProgramInfoLog(program));
130+
}
131+
} else {
132+
if (!overallSuccess) {
133+
testPassed("Shader compilation or linking failed as expected. VS compile: " + vsCompileStatus +
134+
", FS compile: " + fsCompileStatus + ", Link: " + programLinked);
135+
} else {
136+
testFailed("Shader compiled and linked successfully, but it should have failed.");
137+
}
138+
}
139+
140+
// Cleanup
141+
if (program) {
142+
gl.detachShader(program, vs);
143+
gl.detachShader(program, fs);
144+
gl.deleteProgram(program);
145+
}
146+
gl.deleteShader(vs);
147+
gl.deleteShader(fs);
148+
}
149+
150+
var successfullyParsed = true;
151+
</script>
152+
<script src="../../../js/js-test-post.js"></script>
153+
</body>
154+
</html>

0 commit comments

Comments
 (0)