summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-shader-texture-lod.html
blob: 30176bd59037a6de140e1bbe1d67ccafe905b285 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL EXT_shader_texture_lod Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/desktop-gl-constants.js"></script>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 256px; height: 256px;"> </canvas>
<canvas id="canvas2" style="width: 256px; height: 256px;"> </canvas>
<div id="console"></div>
<!-- Shaders for testing texture LOD functions -->

<!-- Shader omitting the required #extension pragma -->
<script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
precision mediump float;
varying vec2 texCoord0v;
uniform float lod;
uniform sampler2D tex;
void main() {
    vec4 color = texture2DLodEXT(tex, texCoord0v, lod);
    gl_FragColor = color;
}
</script>

<!-- Shader to test macro definition -->
<script id="macroFragmentShader" type="x-shader/x-fragment">
precision mediump float;
void main() {
#ifdef GL_EXT_shader_texture_lod
    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
#else
    // Error expected
    #error no GL_EXT_shader_texture_lod;
#endif
}
</script>

<!-- Shader with required #extension pragma -->
<script id="testFragmentShader" type="x-shader/x-fragment">
#extension GL_EXT_shader_texture_lod : enable
precision mediump float;
varying vec2 texCoord0v;
uniform float lod;
uniform sampler2D tex;
void main() {
    vec4 color = texture2DLodEXT(tex, texCoord0v, lod);
    gl_FragColor = color;
}
</script>

<!-- Shaders to link with test fragment shaders -->
<script id="goodVertexShader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord0v;
void main() {
    texCoord0v = texCoord0;
    gl_Position = vPosition;
}
</script>

<!-- Shaders to test output -->
<script id="outputVertexShader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord0v;
void main() {
    texCoord0v = texCoord0;
    gl_Position = vPosition;
}
</script>
<script id="outputFragmentShader" type="x-shader/x-fragment">
#extension GL_EXT_shader_texture_lod : require
precision mediump float;
varying vec2 texCoord0v;
uniform float lod;
uniform sampler2D tex;
void main() {
    vec4 color = texture2DLodEXT(tex, texCoord0v, lod);
    gl_FragColor = color;
}
</script>

<script>
description("This test verifies the functionality of the EXT_shader_texture_lod extension, if it is available.");

debug("");

var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas);
var ext = null;

// Run all tests once.
runAllTests();

// Run all tests against with a new context to test for any cache issues.
debug("");
debug("Testing new context to catch cache errors");
var canvas2 = document.getElementById("canvas2");
gl = wtu.create3DContext(canvas2);
ext = null;
runAllTests();

function runAllTests() {
    if (!gl) {
        testFailed("WebGL context does not exist");
    } else {
        testPassed("WebGL context exists");

        // Run tests with extension disabled
        runShaderTests(false);

        // Query the extension and store globally so shouldBe can access it
        ext = gl.getExtension("EXT_shader_texture_lod");
        if (!ext) {
            testPassed("No EXT_shader_texture_lod support -- this is legal");

            runSupportedTest(false);
        } else {
            testPassed("Successfully enabled EXT_shader_texture_lod extension");

            runSupportedTest(true);

            runShaderTests(true);
            runOutputTests();
            runUniqueObjectTest();
            runReferenceCycleTest();

            // Run deferred link tests.
            runDeferredLinkTests();
        }
    }

}

function runSupportedTest(extensionEnabled) {
    var supported = gl.getSupportedExtensions();
    if (supported.indexOf("EXT_shader_texture_lod") >= 0) {
        if (extensionEnabled) {
            testPassed("EXT_shader_texture_lod listed as supported and getExtension succeeded");
        } else {
            testFailed("EXT_shader_texture_lod listed as supported but getExtension failed");
        }
    } else {
        if (extensionEnabled) {
            testFailed("EXT_shader_texture_lod not listed as supported but getExtension succeeded");
        } else {
            testPassed("EXT_shader_texture_lod not listed as supported and getExtension failed -- this is legal");
        }
    }
}

function runShaderTests(extensionEnabled) {
    debug("");
    debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));

    // Expect the macro shader to succeed ONLY if enabled
    var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
    if (extensionEnabled) {
        if (macroFragmentProgram) {
            // Expected result
            testPassed("GL_EXT_shader_texture_lod defined in shaders when extension is enabled");
        } else {
            testFailed("GL_EXT_shader_texture_lod not defined in shaders when extension is enabled");
        }
    } else {
        if (macroFragmentProgram) {
            testFailed("GL_EXT_shader_texture_lod defined in shaders when extension is disabled");
        } else {
            testPassed("GL_EXT_shader_texture_lod not defined in shaders when extension disabled");
        }
    }

    // Always expect the shader missing the #pragma to fail (whether enabled or not)
    var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
    if (missingPragmaFragmentProgram) {
        testFailed("Shader built-ins allowed without #extension pragma");
    } else {
        testPassed("Shader built-ins disallowed without #extension pragma");
    }

    // Try to compile a shader using the built-ins that should only succeed if enabled
    var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
    if (extensionEnabled) {
        if (testFragmentProgram) {
            testPassed("Shader built-ins compiled successfully when extension enabled");
        } else {
            testFailed("Shader built-ins failed to compile when extension enabled");
        }
    } else {
        if (testFragmentProgram) {
            testFailed("Shader built-ins compiled successfully when extension disabled");
        } else {
            testPassed("Shader built-ins failed to compile when extension disabled");
        }
    }
}

function runOutputTests() {
    debug("");
    debug("Testing various draws for valid built-in function behavior");
    gl.viewport(0, 0, canvas.width, canvas.height);

    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition', 'texCoord0'], [0, 1]);
    var quadParameters = wtu.setupUnitQuad(gl, 0, 1);

    var colors = [
        {name: 'red', color:[255, 0, 0, 255]},
        {name: 'green', color:[0, 255, 0, 255]},
        {name: 'blue', color:[0, 0, 255, 255]},
        {name: 'yellow', color:[255, 255, 0, 255]},
        {name: 'magenta', color:[255, 0, 255, 255]},
        {name: 'cyan', color:[0, 255, 255, 255]},
        {name: 'pink', color:[255, 128, 128, 255]},
        {name: 'gray', color:[128, 128, 128, 255]},
        {name: 'light green', color:[128, 255, 128, 255]},
    ];

    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);

    for (var ii = 0; ii < colors.length; ++ii) {
        var color = colors[ii];
        var size = Math.pow(2, colors.length - ii - 1);
        wtu.fillTexture(gl, tex, size, size, color.color, ii);
    }

    var loc = gl.getUniformLocation(program, "lod");

    for (var ii = 0; ii < colors.length; ++ii) {
        gl.uniform1f(loc, ii);
        var color = colors[ii];
        wtu.drawUnitQuad(gl);
        wtu.checkCanvas(
            gl, color.color,
            "256x256 texture drawn to 256x256 dest with lod = " + ii +
            " should be " + color.name);
    }

    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
}

function runUniqueObjectTest()
{
    debug("");
    debug("Testing that getExtension() returns the same object each time");
    ext = null;
    gl.getExtension("EXT_shader_texture_lod").myProperty = 2;
    webglHarnessCollectGarbage();
    shouldBe('gl.getExtension("EXT_shader_texture_lod").myProperty', '2');
}

function runReferenceCycleTest()
{
    // create some reference cycles. The goal is to see if they cause leaks. The point is that
    // some browser test runners have instrumentation to detect leaked refcounted objects.
    debug("");
    debug("Testing reference cycles between context and extension objects");
    var ext = gl.getExtension("EXT_shader_texture_lod");

    // create cycle between extension and context, since the context has to hold a reference to the extension
    ext.context = gl;

    // create a self-cycle on the extension object
    ext.ext = ext;
}

function runDeferredLinkTests() {
    debug("");
    debug("Testing deferred shader compilation tests.");

    // Test for compilation failures that are caused by missing extensions
    // do not succeed if extensions are enabled during linking. This would
    // only happen for deferred shader compilations.

    // First test if link succeeds with extension enabled.
    var glEnabled = wtu.create3DContext();
    var extEnabled = glEnabled.getExtension("EXT_shader_texture_lod");
    if (!extEnabled) {
        testFailed("Deferred link test expects the extension to be supported");
    }

    var vertexShader = wtu.loadShaderFromScript(glEnabled, "goodVertexShader");
    var fragmentShader = wtu.loadShaderFromScript(glEnabled, "macroFragmentShader");

    if (!vertexShader || !fragmentShader) {
        testFailed("Could not create good shaders.");
        return;
    }

    var program = wtu.setupProgram(glEnabled, [vertexShader, fragmentShader]);

    if (!program) {
        testFailed("Compilation with extension enabled failed.");
        return;
    }

    // Create new context to test link failure without extension enabled.
    var glDeferred = wtu.create3DContext();

    var vertexShader = wtu.loadShaderFromScript(glDeferred, "goodVertexShader", glDeferred.VERTEX_SHADER, undefined, undefined, true);
    var fragmentShader = wtu.loadShaderFromScript(glDeferred, "macroFragmentShader", glDeferred.FRAGMENT_SHADER, undefined, undefined, true);

    if (vertexShader == null || fragmentShader == null) {
        testFailed("Could not create shaders.");
        return;
    }

    // Shader compilations should have failed due to extensions not enabled.
    glDeferred.getExtension("EXT_shader_texture_lod");
    var program = wtu.setupProgram(glDeferred, [vertexShader, fragmentShader]);
    if (program) {
        testFailed("Compilation with extension disabled then linking with extension enabled should have failed.");
        return;
    }

    testPassed("Compilation with extension disabled then linking with extension enabled.");
}

debug("");
successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>

</body>
</html>