Backed out changeset b462e7b742d8 (bug 1908261) for causing multiple reftest failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance / extensions / oes-texture-float.html
blob8bec35b9cffd6de2b0b5170b33f91ebaec0387d1
1 <!--
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.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>OES_texture_float/WEBGL_color_buffer_float</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 <script src="../../js/tests/ext-float-blend.js"></script>
16 </head>
17 <body>
18 <div id="description"></div>
19 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
20 <div id="console"></div>
21 <!-- Shaders for testing floating-point textures -->
22 <script id="testFragmentShader" type="x-shader/x-fragment">
23 precision mediump float;
24 uniform sampler2D tex;
25 uniform vec4 subtractor;
26 varying vec2 texCoord;
27 void main()
29 vec4 color = texture2D(tex, texCoord);
30 if (abs(color.r - subtractor.r) +
31 abs(color.g - subtractor.g) +
32 abs(color.b - subtractor.b) +
33 abs(color.a - subtractor.a) < 8.0) {
34 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
35 } else {
36 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
39 </script>
40 <!-- Shaders for testing floating-point render targets -->
41 <script id="positionVertexShader" type="x-shader/x-vertex">
42 attribute vec4 vPosition;
43 void main()
45 gl_Position = vPosition;
47 </script>
48 <script id="floatingPointFragmentShader" type="x-shader/x-fragment">
49 void main()
51 gl_FragColor = vec4(10000.0, 10000.0, 10000.0, 10000.0);
53 </script>
54 <script>
55 "use strict";
56 description("This test verifies the functionality of the OES_texture_float and WEBGL_color_buffer_float extensions, if available.");
58 debug("");
60 var wtu = WebGLTestUtils;
61 var canvas = document.getElementById("canvas");
62 var gl = wtu.create3DContext(canvas);
63 var ext = null;
65 if (!gl) {
66 testFailed("WebGL context does not exist");
67 } else {
68 testPassed("WebGL context exists");
70 var texturedShaders = [
71 wtu.simpleTextureVertexShader,
72 "testFragmentShader"
74 var testProgram =
75 wtu.setupProgram(gl,
76 texturedShaders,
77 ['vPosition', 'texCoord0'],
78 [0, 1]);
79 var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
81 // First verify that allocation of floating-point textures fails if
82 // the extension has not been enabled yet.
83 runTextureCreationTest(testProgram, false);
86 debug("");
87 debug("Testing that component type framebuffer attachment queries are rejected with the extension disabled");
88 const fbo = gl.createFramebuffer();
89 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
91 const rbo = gl.createRenderbuffer();
92 gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
93 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,gl.RENDERBUFFER, rbo);
94 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB565, 8, 8);
95 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup renderbuffer should succeed.");
96 shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8211 /* FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT */)');
97 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Query must fail.");
98 gl.deleteRenderbuffer(rbo);
100 const tex = gl.createTexture();
101 gl.bindTexture(gl.TEXTURE_2D, tex);
102 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
103 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
104 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup texture should succeed.");
105 shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0x8211 /* FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT */)');
106 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Query must fail.");
107 gl.deleteTexture(tex);
109 gl.deleteFramebuffer(fbo);
112 if (!gl.getExtension("OES_texture_float")) {
113 testPassed("No OES_texture_float support -- this is legal");
114 } else {
115 testPassed("Successfully enabled OES_texture_float extension");
116 // If alpha value is missing from a texture it gets filled to 1 when sampling according to GLES2.0 table 3.12
117 runTextureCreationTest(testProgram, true, gl.RGBA, 4, [10000, 10000, 10000, 10000]);
118 runTextureCreationTest(testProgram, true, gl.RGB, 3, [10000, 10000, 10000, 1]);
119 runTextureCreationTest(testProgram, true, gl.LUMINANCE, 1, [10000, 10000, 10000, 1]);
120 runTextureCreationTest(testProgram, true, gl.ALPHA, 1, [0, 0, 0, 10000]);
121 runTextureCreationTest(testProgram, true, gl.LUMINANCE_ALPHA, 2, [10000, 10000, 10000, 10000]);
123 (function() {
124 debug("");
125 var renderable = isRenderable(gl);
126 var renderableExtName = "WEBGL_color_buffer_float";
127 var supported = gl.getSupportedExtensions().includes(renderableExtName);
128 if (renderable && !supported) {
129 testFailed("RGBA/FLOAT is color renderable but " + renderableExtName + " not exposed");
130 } else if (supported && !renderable) {
131 testFailed(renderableExtName + " is exposed but RGBA/FLOAT is not color renderable");
133 if (supported) {
134 runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0, true);
135 runRenderTargetAndReadbackTest(testProgram, gl.RGB, 3, [10000, 10000, 10000, 1], 0, false);
136 runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 1, true);
137 runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0.5, true);
138 runFramebufferTest();
141 debug("");
142 debug("Testing that component type framebuffer attachment queries are accepted with the extension enabled");
143 ext = gl.getExtension("WEBGL_color_buffer_float");
144 shouldBeNonNull('ext');
145 const fbo = gl.createFramebuffer();
146 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
148 const rbo = gl.createRenderbuffer();
149 gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
150 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,gl.RENDERBUFFER, rbo);
151 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB565, 8, 8);
152 shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'ext.UNSIGNED_NORMALIZED_EXT');
153 gl.renderbufferStorage(gl.RENDERBUFFER, ext.RGBA32F_EXT, 8, 8);
154 shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'gl.FLOAT');
155 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after valid renderbuffer attachment queries.");
157 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT,gl.RENDERBUFFER, rbo);
158 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, 8, 8);
159 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after depth-stencil renderbuffer setup.");
160 shouldBeNull('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)');
161 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Component type query is not allowed for combined depth-stencil attachments.");
162 gl.deleteRenderbuffer(rbo);
164 const tex = gl.createTexture();
165 gl.bindTexture(gl.TEXTURE_2D, tex);
166 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
167 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
168 shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'ext.UNSIGNED_NORMALIZED_EXT');
169 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8, 8, 0, gl.RGBA, gl.FLOAT, null);
170 shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)', 'gl.FLOAT');
171 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after valid texture attachment queries.");
172 gl.deleteTexture(tex);
174 gl.deleteFramebuffer(fbo);
177 debug("");
178 debug("Test float32 blending without EXT_float_blend.");
179 testExtFloatBlend(gl.RGBA);
181 debug("");
182 debug("Testing that float32 blending succeeds with EXT_float_blend.");
183 if (!gl.getExtension("EXT_float_blend")) {
184 testPassed("No EXT_float_blend support -- this is legal");
185 return;
187 testExtFloatBlend(gl.RGBA);
189 })();
191 runUniqueObjectTest();
195 function isRenderable(gl) {
196 var tex = gl.createTexture();
197 gl.bindTexture(gl.TEXTURE_2D, tex);
198 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null);
200 var fb = gl.createFramebuffer();
201 gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
202 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
204 var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
205 gl.deleteFramebuffer(fb);
206 gl.deleteTexture(tex);
208 return status == gl.FRAMEBUFFER_COMPLETE;
211 function allocateTexture()
213 var texture = gl.createTexture();
214 gl.bindTexture(gl.TEXTURE_2D, texture);
215 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
216 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
217 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
218 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
219 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed");
220 return texture;
223 function checkRenderingResults()
225 wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
228 function runTextureCreationTest(testProgram, extensionEnabled, opt_format, opt_numChannels, opt_subtractor)
230 var format = opt_format || gl.RGBA;
231 var numberOfChannels = opt_numChannels || 4;
232 var expectFailure = !extensionEnabled;
233 var subtractor = opt_subtractor || [10000, 10000, 10000, 10000];
235 debug("");
236 debug("testing format: " + wtu.glEnumToString(gl, format) +
237 " expect:" + (extensionEnabled ? "success" : "failure"));
239 var texture = allocateTexture();
240 // Generate data.
241 var width = 2;
242 var height = 2;
243 var data = new Float32Array(width * height * numberOfChannels);
244 for (var ii = 0; ii < data.length; ++ii) {
245 data[ii] = 10000;
247 gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, gl.FLOAT, data);
248 if (expectFailure) {
249 wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "floating-point texture allocation must be disallowed if OES_texture_float isn't enabled");
250 return;
251 } else {
252 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed if OES_texture_float is enabled");
254 // Verify that the texture actually works for sampling and contains the expected data.
255 gl.uniform4fv(gl.getUniformLocation(testProgram, "subtractor"), subtractor);
256 wtu.clearAndDrawUnitQuad(gl);
257 checkRenderingResults();
259 // Check that linear fails.
260 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
261 wtu.clearAndDrawUnitQuad(gl);
262 wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
265 function arrayToString(arr, size) {
266 var mySize;
267 if (!size)
268 mySize = arr.length;
269 else
270 mySize = size;
271 var out = "[";
272 for (var ii = 0; ii < mySize; ++ii) {
273 if (ii > 0) {
274 out += ", ";
276 out += arr[ii];
278 return out + "]";
281 function runRenderTargetAndReadbackTest(testProgram, format, numberOfChannels, subtractor, texSubImageCover, requireRenderable)
283 var formatString = wtu.glEnumToString(gl, format);
284 debug("");
285 debug("testing floating-point " + formatString + " render target" + (texSubImageCover > 0 ? " after calling texSubImage" : ""));
287 var texture = allocateTexture();
288 var width = 2;
289 var height = 2;
290 gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, gl.FLOAT, null);
291 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed if OES_texture_float is enabled");
293 // Try to use this texture as a render target.
294 var fbo = gl.createFramebuffer();
295 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
296 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
297 gl.bindTexture(gl.TEXTURE_2D, null);
298 // It is legal for a WebGL implementation exposing the OES_texture_float extension to
299 // support floating-point textures but not as attachments to framebuffer objects.
300 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
301 if (requireRenderable)
302 testFailed("floating-point " + formatString + " render target not supported");
303 else
304 debug("floating-point " + formatString + " render target not supported -- this is legal");
305 return;
308 if (texSubImageCover > 0) {
309 // Ensure that replacing the whole texture or a part of it with texSubImage2D doesn't affect renderability
310 gl.bindTexture(gl.TEXTURE_2D, texture);
311 var data = new Float32Array(width * height * numberOfChannels * texSubImageCover);
312 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height * texSubImageCover, format, gl.FLOAT, data);
313 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed if OES_texture_float is enabled");
314 gl.bindTexture(gl.TEXTURE_2D, null);
315 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
316 testFailed("render target support changed after calling texSubImage2D");
317 return;
321 var renderProgram =
322 wtu.setupProgram(gl,
323 ["positionVertexShader", "floatingPointFragmentShader"],
324 ['vPosition'],
325 [0]);
326 wtu.clearAndDrawUnitQuad(gl);
327 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering to floating-point texture should succeed");
329 // Now sample from the floating-point texture and verify we got the correct values.
330 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
331 gl.bindTexture(gl.TEXTURE_2D, texture);
332 gl.useProgram(testProgram);
333 gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0);
334 gl.uniform4fv(gl.getUniformLocation(testProgram, "subtractor"), subtractor);
335 wtu.clearAndDrawUnitQuad(gl);
336 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering from floating-point texture should succeed");
337 checkRenderingResults();
339 // Finally, if the implementation supports floating-point readback, verify it.
340 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
341 var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
342 var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
343 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter of IMPLEMENTATION_COLOR_READ_{FORMAT|TYPE} should succeed");
344 if ((implFormat == gl.RGBA || implFormat == gl.RGB) && implType == gl.FLOAT) {
345 debug("Checking readback of floating-point values");
346 var arraySize = (implFormat == gl.RGBA) ? 4 : 3
347 var buf = new Float32Array(arraySize);
348 gl.readPixels(0, 0, 1, 1, implFormat, implType , buf);
349 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels from floating-point renderbuffer should succeed");
350 var ok = true;
351 var tolerance = 8.0; // TODO: factor this out from both this test and the subtractor shader above.
352 for (var ii = 0; ii < buf.length; ++ii) {
353 if (Math.abs(buf[ii] - subtractor[ii]) > tolerance) {
354 ok = false;
355 break;
358 if (ok) {
359 testPassed("readPixels of float-type data from floating-point renderbuffer succeeded");
360 } else {
361 testFailed("readPixels of float-type data from floating-point renderbuffer failed: expected "
362 + arrayToString(subtractor, arraySize) + ", got " + arrayToString(buf));
367 function runUniqueObjectTest()
369 debug("");
370 debug("Testing that getExtension() returns the same object each time");
371 gl.getExtension("OES_texture_float").myProperty = 2;
372 webglHarnessCollectGarbage();
373 shouldBe('gl.getExtension("OES_texture_float").myProperty', '2');
376 // Make sure we can call readPixels with the passed in arrayBufferConstructor and that the color
377 // channels are the ones we expect. If there is a mismatch between the glType and arrayBuffer type,
378 // fail the test.
379 function verifyReadPixelsColors(red, green, blue, alpha, alphaRGB, glFormat, glType, arrayBufferConstructor) {
380 var typeName = wtu.glEnumToString(gl, glType);
382 debug(wtu.glEnumToString(gl, glFormat) + " framebuffer with " + typeName + " readback.");
384 var arrayBuffer = new arrayBufferConstructor(4);
385 gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
386 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should return NO_ERROR when reading " + typeName + " data.");
388 assertMsg(arrayBuffer[0] === red, "Red channel should be " + red + " for " + typeName + " readPixels. Received: " + arrayBuffer[0]);
389 assertMsg(arrayBuffer[1] === green, "Green channel should be " + green + " for " + typeName + " readPixels. Received: " + arrayBuffer[1]);
390 assertMsg(arrayBuffer[2] === blue, "Blue channel should be " + blue + " for " + typeName + " readPixels. Received: " + arrayBuffer[2]);
391 if (glFormat === gl.RGBA) {
392 assertMsg(arrayBuffer[3] === alpha, "Alpha channel should be " + alpha + " for " + typeName + " readPixels. Received: " + arrayBuffer[3]);
393 } else if (glFormat === gl.RGB) {
394 assertMsg(arrayBuffer[3] === alphaRGB, "Alpha channel should be " + alphaRGB + " for " + typeName + " readPixels. Received: " + arrayBuffer[3]);
397 // Make sure any arrayBuffer types that are not equal to arrayBufferConstructor fail readPixels.
398 if (arrayBufferConstructor !== Uint8Array) {
399 arrayBuffer = new Uint8Array(4);
400 gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
401 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "readPixels should return INVALID_OPERATION when reading mismatched types. " + Uint8Array.toString());
403 if (arrayBufferConstructor !== Float32Array) {
404 arrayBuffer = new Float32Array(4);
405 gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
406 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "readPixels should return INVALID_OPERATION when reading mismatched types. " + Float32Array.toString());
408 if (arrayBufferConstructor !== Uint16Array) {
409 arrayBuffer = new Uint16Array(4);
410 gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
411 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "readPixels should return INVALID_OPERATION when reading mismatched types. " + Uint16Array.toString());
415 // Verify that float textures attached to frame buffers function correctly with regard to framebuffer
416 // completness, IMPLEMENTATION_COLOR_READ_FORMAT/TYPE and readPixels
417 function runFramebufferTest() {
418 debug("");
419 debug("Framebuffer Tests");
421 var texture = allocateTexture();
422 gl.bindTexture(gl.TEXTURE_2D, texture);
424 var fbo = gl.createFramebuffer();
425 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
426 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
428 debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail.");
429 var arrayBufferFloatOutput = new Float32Array(4); // 4 color channels
430 [gl.LUMINANCE, gl.LUMINANCE_ALPHA, gl.ALPHA].forEach(function(badFormat) {
431 debug(wtu.glEnumToString(gl, badFormat) + " framebuffer");
433 gl.texImage2D(gl.TEXTURE_2D, 0, badFormat, 1, 1, 0, badFormat, gl.FLOAT, null);
434 shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
436 shouldBeNull("gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT)");
437 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "IMPLEMENTATION_COLOR_READ_FORMAT should fail for incomplete framebuffers.");
439 shouldBeNull("gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE)");
440 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "IMPLEMENTATION_COLOR_READ_TYPE should fail for incomplete framebuffers.");
442 gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, arrayBufferFloatOutput);
443 wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION , "readPixels should fail on incomplete framebuffers.");
444 debug("");
447 debug("Ensure color renderable formats [RGBA, RGB] succeed.");
448 var arrayBufferFloatInput = new Float32Array(4); // 4 color channels
449 arrayBufferFloatInput[0] = 0;
450 arrayBufferFloatInput[1] = .25;
451 arrayBufferFloatInput[2] = .50;
452 arrayBufferFloatInput[3] = .75;
454 [gl.RGBA, gl.RGB].forEach(function(goodFormat) {
455 debug("");
456 debug(wtu.glEnumToString(gl, goodFormat) + " framebuffer tests");
458 gl.texImage2D(gl.TEXTURE_2D, 0, goodFormat, 1, 1, 0, goodFormat, gl.FLOAT, arrayBufferFloatInput);
459 if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
460 testPassed("Format is not renderable. This is allowed.");
461 return;
463 verifyReadPixelsColors(
464 0.00, // red
465 0.25, // green
466 0.50, // blue
467 0.75, // alpha
468 1.0, // alphaRGB
469 goodFormat,
470 gl.FLOAT,
471 Float32Array);
473 var implementationColorReadFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
474 assertMsg(implementationColorReadFormat === gl.RGBA || implementationColorReadFormat === gl.RGB,
475 "IMPLEMENTATION_COLOR_READ_FORMAT should be color renderable: RGBA or RGB. Received: " + wtu.glEnumToString(gl, implementationColorReadFormat));
477 var implementationColorReadType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
478 assertMsg(implementationColorReadType === gl.UNSIGNED_BYTE ||
479 implementationColorReadType === gl.FLOAT ||
480 "IMPLEMENTATION_COLOR_READ_TYPE must be one of UNSIGNED_BYTE or FLOAT " +
481 "Received: " + wtu.glEnumToString(gl, implementationColorReadType));
485 debug("");
486 var successfullyParsed = true;
487 </script>
488 <script src="../../js/js-test-post.js"></script>
490 </body>
491 </html>