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.
10 <meta charset=
"utf-8">
11 <title>Test Format R11F_G11F_B10F
</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>
17 <div id=
"description"></div>
18 <div id=
"console"></div>
19 <canvas id=
"canvas" width=
"20" height=
"20"> </canvas>
20 <script id=
"vshader" type=
"x-shader/x-vertex">
22 attribute vec2 texCoord0;
23 varying vec2 texCoord;
26 gl_Position = vec4(pos,
0.0,
1.0);
31 <script id=
"fshader" type=
"x-shader/x-fragment">
32 precision mediump float;
35 uniform sampler2D u_tex;
36 varying vec2 texCoord;
39 vec4 sample = texture2D(u_tex, texCoord);
40 vec3 rgb = sample.xyz;
41 if (abs(rgb[
0] - u_color[
0])
> u_tol[
0] ||
42 abs(rgb[
1] - u_color[
1])
> u_tol[
1] ||
43 abs(rgb[
2] - u_color[
2])
> u_tol[
2]) {
44 gl_FragColor = vec4(
1,
0,
0,
1);
46 gl_FragColor = vec4(
0,
1,
0,
1);
52 description("This tests format R11F_G11F_B10F works as expected");
53 debug("MacOSX driver bug. See https://github.com/KhronosGroup/WebGL/issues/1832");
55 var wtu
= WebGLTestUtils
;
56 var canvas
= document
.getElementById("canvas");
57 var gl
= wtu
.create3DContext(canvas
, undefined, 2);
59 var testValues
= [100, 1000, 2047, 2500, 4095, 5000,
60 8191, 8192, 10000, 16383, 16384];
63 testFailed("context does not exist");
65 testPassed("context exists");
66 if (gl
.getExtension("EXT_color_buffer_float")) {
67 testPassed("Extension EXT_color_buffer_float is available");
69 testRenderbufferReadback(4, 4);
70 testTextureReadback(4, 4);
71 testTextureSampling(4, 4);
73 testPassed("Extension EXT_color_buffer_float is unavailable - this is legal");
77 function setupColor(testR
, testG
, testB
, value
) {
78 var data
= new Float32Array(4);
79 data
[0] = testR
? value
: 0;
80 data
[1] = testG
? value
: 0;
81 data
[2] = testB
? value
: 0;
82 data
[3] = 1; // Doesn't really matter for RGB formats.
86 // The definition of <Unsinged 11-Bit Floating-Point Number> in GLES 3.0.4:
87 // https://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.4.pdf#nameddest=section-2.1.3
88 // The definition of <Unsinged 10-Bit Floating-Point Number> in GLES 3.0.4:
89 // https://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.4.pdf#nameddest=section-2.1.4
90 function setTolerance (testR
, testG
, testB
, value
) {
91 var tol
= new Float32Array(3);
93 if (value
< Math
.pow(2, -14)) {
96 exponent
= Math
.floor(Math
.log(value
) / Math
.LN2
);
98 var tol11F
= Math
.pow(2, exponent
) / 64;
99 var tol10F
= Math
.pow(2, exponent
) / 32;
100 tol
[0] = testR
? tol11F
: 0;
101 tol
[1] = testG
? tol11F
: 0;
102 tol
[2] = testB
? tol10F
: 0;
106 function clearAndVerifyColor(width
, height
, testR
, testG
, testB
, value
) {
107 var data
= setupColor(testR
, testG
, testB
, value
);
108 var tol
= setTolerance(testR
, testG
, testB
, value
);
109 gl
.clearBufferfv(gl
.COLOR
, 0, data
);
110 var buffer
= new Float32Array(width
* height
* 4);
111 gl
.readPixels(0, 0, width
, height
, gl
.RGBA
, gl
.FLOAT
, buffer
);
112 for (var ii
= 0; ii
< width
* height
; ++ii
) {
113 var pixel
= [buffer
[ii
* 4], buffer
[ii
* 4 + 1], buffer
[ii
* 4 + 2], buffer
[ii
* 4 + 3]];
114 if (isNaN(pixel
[0]) || isNaN(pixel
[1]) || isNaN(pixel
[2]) ||
115 Math
.abs(pixel
[0] - data
[0]) > tol
[0] ||
116 Math
.abs(pixel
[1] - data
[1]) > tol
[1] ||
117 Math
.abs(pixel
[2] - data
[2]) > tol
[2]) {
118 testFailed("ReadPixels " + ii
+ " : got [" + pixel
+ "], expected [" + data
+ "], tol [" + tol
+ "]");
122 testPassed("ReadPixels success : [" + data
+ "]");
125 function clearDrawAndVerifyColor(fbo
, program
, testR
, testG
, testB
, value
) {
126 var data
= setupColor(testR
, testG
, testB
, value
);
127 var tol
= setTolerance(testR
, testG
, testB
, value
);
128 debug("Testing : [" + data
+ "] with tolerance = [" + tol
+ "]");
130 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
131 gl
.clearBufferfv(gl
.COLOR
, 0, data
);
133 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
134 gl
.clearColor(0, 0, 0,1);
135 gl
.clear(gl
.COLOR_BUFFER_BIT
);
137 gl
.uniform3fv(program
.colorPos
, data
.slice(0, 3));
138 gl
.uniform3fv(program
.tolPos
, tol
);
140 wtu
.drawUnitQuad(gl
);
141 wtu
.checkCanvas(gl
, [0, 255, 0, 255], "Should pass (green color instead of red)");
145 function testReadPixelsFromColorChannelsWithVariousValues(width
, height
) {
146 debug("Testing R channel");
147 for (var ii
= 0; ii
< testValues
.length
; ++ii
) {
148 clearAndVerifyColor(width
, height
, true, false, false, testValues
[ii
]);
150 debug("Testing G channel");
151 for (var ii
= 0; ii
< testValues
.length
; ++ii
) {
152 clearAndVerifyColor(width
, height
, false, true, false, testValues
[ii
]);
154 debug("Testing B channel");
155 for (var ii
= 0; ii
< testValues
.length
; ++ii
) {
156 clearAndVerifyColor(width
, height
, false, false, true, testValues
[ii
]);
160 function testSampleTextureFromColorChannelsWithVariousValues(fbo
, program
) {
161 debug("Testing R channel");
162 for (var ii
= 0; ii
< testValues
.length
; ++ii
) {
163 clearDrawAndVerifyColor(fbo
, program
, true, false, false, testValues
[ii
]);
165 debug("Testing G channel");
166 for (var ii
= 0; ii
< testValues
.length
; ++ii
) {
167 clearDrawAndVerifyColor(fbo
, program
, false, true, false, testValues
[ii
]);
169 debug("Testing B channel");
170 for (var ii
= 0; ii
< testValues
.length
; ++ii
) {
171 clearDrawAndVerifyColor(fbo
, program
, false, false, true, testValues
[ii
]);
175 function testRenderbufferReadback(width
, height
) {
177 debug("Checking clearing and readback of a color image of renderbuffer with R11F_G11F_B10F format.");
179 var fbo
= gl
.createFramebuffer();
180 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
181 var renderbuffer
= gl
.createRenderbuffer();
182 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, renderbuffer
);
183 gl
.renderbufferStorage(gl
.RENDERBUFFER
, gl
.R11F_G11F_B10F
, width
, height
);
184 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, renderbuffer
);
185 shouldBe("gl.FRAMEBUFFER_COMPLETE", "gl.checkFramebufferStatus(gl.FRAMEBUFFER)");
186 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Setup framebuffer with renderbuffer should succeed.");
188 testReadPixelsFromColorChannelsWithVariousValues(width
, height
);
190 gl
.deleteFramebuffer(fbo
);
191 gl
.deleteRenderbuffer(renderbuffer
);
194 function testTextureReadback(width
, height
) {
196 debug("Checking clearing and readback of a color image of texture with R11F_G11F_B10F format.");
198 var fbo
= gl
.createFramebuffer();
199 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
200 var tex
= gl
.createTexture();
201 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
202 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.R11F_G11F_B10F
, width
, height
, 0, gl
.RGB
, gl
.FLOAT
, null);
203 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex
, 0);
204 shouldBe("gl.FRAMEBUFFER_COMPLETE", "gl.checkFramebufferStatus(gl.FRAMEBUFFER)");
205 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Setup framebuffer with texture should succeed.");
207 testReadPixelsFromColorChannelsWithVariousValues(width
, height
);
209 gl
.deleteFramebuffer(fbo
);
210 gl
.deleteTexture(tex
);
213 function setupProgram() {
214 var program
= wtu
.setupProgram(gl
, ["vshader", "fshader"], ["pos", "texCoord0"]);
217 program
.colorPos
= gl
.getUniformLocation(program
, "u_color");
218 program
.tolPos
= gl
.getUniformLocation(program
, "u_tol");
219 var texPos
= gl
.getUniformLocation(program
, "u_tex");
220 program
.buffers
= wtu
.setupUnitQuad(gl
, 0, 1);
221 if (!program
.colorPos
|| !program
.tolPos
|| !texPos
|| program
.buffers
.length
== 0) {
222 gl
.deleteProgram(program
);
225 gl
.useProgram(program
);
226 gl
.uniform1i(texPos
, 0);
227 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Setup program should succeed.");
231 function testTextureSampling(width
, height
) {
233 debug("Checking sampling of a texture with R11_G11F_B10F format");
235 var program
= setupProgram();
237 testFailed("Failed to setup program");
241 var fbo
= gl
.createFramebuffer();
242 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fbo
);
243 var tex
= gl
.createTexture();
244 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
245 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.R11F_G11F_B10F
, width
, height
, 0, gl
.RGB
, gl
.FLOAT
, null);
246 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.LINEAR
);
247 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex
, 0);
248 shouldBe("gl.FRAMEBUFFER_COMPLETE", "gl.checkFramebufferStatus(gl.FRAMEBUFFER)");
249 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Setup framebuffer with texture should succeed.");
251 testSampleTextureFromColorChannelsWithVariousValues(fbo
, program
);
253 gl
.deleteTexture(tex
);
254 gl
.deleteFramebuffer(fbo
);
255 gl
.deleteProgram(program
);
259 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "No GL error from tests.");
260 var successfullyParsed
= true;
263 <script src=
"../../js/js-test-post.js"></script>