c4e51feb47a1b8198b0e4b0edd6b57a8b331e551
[WebKit-https.git] / LayoutTests / fast / canvas / webgl / oes-texture-half-float.html
1 <!--
2
3 /*
4 ** Copyright (c) 2013 The Khronos Group Inc.
5 **
6 ** Permission is hereby granted, free of charge, to any person obtaining a
7 ** copy of this software and/or associated documentation files (the
8 ** "Materials"), to deal in the Materials without restriction, including
9 ** without limitation the rights to use, copy, modify, merge, publish,
10 ** distribute, sublicense, and/or sell copies of the Materials, and to
11 ** permit persons to whom the Materials are furnished to do so, subject to
12 ** the following conditions:
13 **
14 ** The above copyright notice and this permission notice shall be included
15 ** in all copies or substantial portions of the Materials.
16 **
17 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
24 */
25
26 -->
27
28 <!DOCTYPE html>
29 <html>
30 <head>
31 <meta charset="utf-8">
32 <title>WebGL OES_texture_half_float Conformance Tests</title>
33 <script src="resources/desktop-gl-constants.js" type="text/javascript"></script>
34 <script src="../../../resources/js-test.js"></script>
35 <script src="resources/webgl-test.js"></script>
36 <script src="resources/webgl-test-utils.js"></script>
37 </head>
38 <body>
39 <div id="description"></div>
40 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
41 <div id="console"></div>
42 <script id="testFragmentShader" type="x-shader/x-fragment">
43 precision mediump float;
44 uniform sampler2D tex;
45 uniform vec4 subtractor;
46 varying vec2 texCoord;
47 void main()
48 {
49     vec4 color = texture2D(tex, texCoord);
50     if (abs(color.r - subtractor.r) +
51         abs(color.g - subtractor.g) +
52         abs(color.b - subtractor.b) +
53         abs(color.a - subtractor.a) < 8.0) {
54         gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
55     } else {
56         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
57     }
58 }
59 </script>
60 <!-- Shaders for testing half-floating-point render targets -->
61 <script id="positionVertexShader" type="x-shader/x-vertex">
62 attribute vec4 vPosition;
63 void main()
64 {
65     gl_Position = vPosition;
66 }
67 </script>
68 <script id="floatingPointFragmentShader" type="x-shader/x-fragment">
69 void main()
70 {
71     gl_FragColor = vec4(10000.0, 10000.0, 10000.0, 10000.0);
72 }
73 </script>
74 <script>
75 "use strict"
76 description("This test verifies the functionality of OES_texture_half_float with null/non-null ArrayBufferView");
77
78 debug("");
79 var wtu = WebGLTestUtils;
80 var canvas = document.getElementById("canvas");
81 var gl = wtu.create3DContext(canvas);
82 // This constant must be defined in order to run the texture creation test without the extension enabled.
83 var halfFloatOESEnum = 0x8D61;
84 var ext = null;
85
86 if (!gl) {
87     testFailed("WebGL context does not exists");
88 } else {
89     testPassed("WebGL context exists");
90
91     // Verify that allocation of texture fails if extension is not enabled
92     runTextureCreationTest(false);
93
94     if (!(ext = gl.getExtension("OES_texture_half_float"))) {
95         testPassed("No OES_texture_half_float support. This is legal");
96     } else {
97         testPassed("Successfully enabled OES_texture_half_float extension");
98
99         // Check if creation of texture succeed's with various formats and null ArrayBufferView
100         var formats = [gl.RGBA, gl.RGB, gl.LUMINANCE, gl.ALPHA, gl.LUMINANCE_ALPHA];
101         for (var i = 0; i < formats.length; i++) {
102             runTextureCreationTest(true, formats[i], null);
103         }
104
105         // Texture creation should fail when passed with non-null ArrayBufferView
106         for (var i = 0; i < formats.length; i++) {
107             var width = 2;
108             var height = 2;
109
110             // Float32Array
111             var float32Data = new Float32Array(width * height * getNumberOfChannels(formats[i]));
112             for (var ii = 0; ii < float32Data.length; ii++) {
113                 float32Data[ii] = 1000;
114             }
115             runTextureCreationTest(true, formats[i], float32Data);
116
117             // Int16Array
118             var int16Data = new Int16Array(width * height * getNumberOfChannels(formats[i]));
119             for (var ii = 0; ii <  int16Data.length; ii++) {
120                 int16Data[ii] = 1000;
121             }
122             runTextureCreationTest(true, formats[i], int16Data);
123
124             // Uint16Array
125             var uint16Data = new Uint16Array(width * height * getNumberOfChannels(formats[i]));
126             for (var ii = 0; ii <  uint16Data.length; ii++) {
127                 uint16Data[ii] = 1000;
128             }
129             runTextureCreationTest(true, formats[i], uint16Data);
130         }
131
132         // Check if attaching texture as FBO target succeeds (Not mandatory)
133         runRenderTargetTest();
134         // Check of getExtension() returns same object
135         runUniqueObjectTest();
136     }
137 }
138
139 function getNumberOfChannels(format)
140 {
141     if (format == gl.RGBA)
142         return 4;
143     else if (format == gl.RGB)
144         return 3;
145     else if (format == gl.LUMINANCE || format == gl.ALPHA)
146         return 1;
147     else if (format == gl.LUMINANCE_ALPHA)
148         return 2;
149 }
150
151 function getFormatName(format)
152 {
153     if (format == gl.RGBA)
154         return "RGBA";
155     else if (format == gl.RGB)
156         return "RGB";
157     else if (format == gl.LUMINANCE)
158         return "LUMINANCE";
159     else if (format == gl.ALPHA)
160         return "ALPHA";
161     else if (format == gl.LUMINANCE_ALPHA)
162         return "LUMINANCE_ALPHA";
163 }
164
165 function allocateTexture()
166 {
167     var texture = gl.createTexture();
168     gl.bindTexture(gl.TEXTURE_2D, texture);
169     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
170     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
171     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
172     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
173     glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed");
174     return texture;
175 }
176
177 function runTextureCreationTest(extensionEnabled, opt_format, opt_data)
178 {
179     var format = opt_format || gl.RGBA;
180     var data = opt_data || null;
181     var expectSuccess = true;
182
183     if (!extensionEnabled || data)
184         expectSuccess = false;
185     debug("Testing texture creation with extension " + (extensionEnabled ? "enabled" : "disabled") +
186           ", format " + getFormatName(format) + ", and data " + (data ? "non-null" : "null") +
187           ". Expect " + (expectSuccess ? "Success" : "Failure"));
188
189     var texture = allocateTexture();
190     var width = 2;
191     var height = 2;
192     gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, halfFloatOESEnum, data);
193     if(!extensionEnabled) {
194         glErrorShouldBe(gl, gl.INVALID_ENUM, "Half floating point texture must be disallowed if OES_texture_half_float isn't enabled");
195         return;
196     } else if (data) {
197         glErrorShouldBe(gl, gl.INVALID_OPERATION, "Half floating point texture allocation must be disallowed when ArrayBufferView is not-null");
198         return;
199     } else {
200         glErrorShouldBe(gl, gl.NO_ERROR, "Half floating point texture allocation should succeed if OES_texture_half_float is enabled");
201     }
202 }
203
204 function checkRenderingResults()
205 {
206     wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
207 }
208
209 function runRenderTargetTest(testProgram)
210 {
211     debug("");
212     debug("Testing half floating point render target");
213
214     var texture = allocateTexture();
215     var width = 2;
216     var height = 2;
217
218     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, ext.HALF_FLOAT_OES, null);
219     glErrorShouldBe(gl, gl.NO_ERROR, "Half floating point texture allocation should succeed if OES_texture_half_float is enabled");
220
221     // Try to use this texture as render target
222     var fbo = gl.createFramebuffer();
223     gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
224     gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
225     gl.bindTexture(gl.TEXTURE_2D, null);
226
227     // It is legal for a WebGL implementation exposing the OES_texture_half_float extension to
228     // support half floating point textures but not as attachments to framebuffer objects.
229     if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
230         debug("Half floating point render targets not supported -- this is legal");
231         return;
232     }
233
234     var renderProgram =
235         wtu.setupProgram(gl,
236                          ["positionVertexShader", "floatingPointFragmentShader"],
237                          ['vPosition'],
238                          [0]);
239     wtu.drawQuad(gl);
240     glErrorShouldBe(gl, gl.NO_ERROR, "Rendering to half floating point texture should succeed");
241
242     // Now sample from the half floating-point texture and verify we got the correct values.
243     var texturedShaders = [
244       wtu.setupSimpleTextureVertexShader(gl),
245           "testFragmentShader"
246       ];
247     var testProgram =
248         wtu.setupProgram(gl,
249                         [wtu.setupSimpleTextureVertexShader(gl), "testFragmentShader"],
250                         ['vPosition', 'texCoord0'],
251                         [0, 1]);
252     var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
253     gl.bindFramebuffer(gl.FRAMEBUFFER, null);
254     gl.bindTexture(gl.TEXTURE_2D, texture);
255     gl.useProgram(testProgram);
256     gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0);
257     wtu.drawQuad(gl);
258     glErrorShouldBe(gl, gl.NO_ERROR, "rendering from half floating point texture should succeed");
259     checkRenderingResults();
260 }
261
262 function runUniqueObjectTest()
263 {
264     debug("Testing that getExtension() returns the same object each time");
265     gl.getExtension("OES_texture_half_float").myProperty = 2;
266     gc();
267     shouldBe('gl.getExtension("OES_texture_half_float").myProperty', '2');
268 }
269
270 debug("");
271 </script>
272 </body>
273 </html>