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>WebGL texture mipmap 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>
17 <canvas id=
"example" width=
"4" height=
"4" style=
"width: 16px; height: 16px;"></canvas>
18 <div id=
"description"></div>
19 <div id=
"console"></div>
20 <script id=
"vshader" type=
"x-shader/x-vertex">
21 attribute vec4 vPosition;
22 attribute vec2 texCoord0;
23 varying vec2 texCoord;
26 gl_Position = vPosition;
31 <script id=
"fshader" type=
"x-shader/x-fragment">
32 precision mediump float;
33 uniform sampler2D tex;
34 varying vec2 texCoord;
37 gl_FragColor = texture2D(tex, texCoord);
42 var wtu
= WebGLTestUtils
;
43 var canvas
= document
.getElementById("example");
44 var gl
= wtu
.create3DContext(canvas
, undefined, 2);
46 description("Test srgb emulation for generateMipmap.");
47 function generateMipmap()
49 debug("Generate mipmaps for sRGB texture");
51 wtu
.setupUnitQuad(gl
, 0, 1);
52 var program
= wtu
.setupProgram(
53 gl
, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
55 gl
.disable(gl
.DEPTH_TEST
);
60 srgba
: [0, 63, 127, 255],
63 var texLoc
= gl
.getUniformLocation(program
, "tex");
64 gl
.uniform1i(texLoc
, 0);
69 canvas
.height
= height
;
70 gl
.viewport(0, 0, width
, height
);
72 var srgbTex
= gl
.createTexture();
73 gl
.bindTexture(gl
.TEXTURE_2D
, srgbTex
);
74 // Set full texture as srgba color first.
75 wtu
.fillTexture(gl
, srgbTex
, width
, height
, colors
['srgba'], 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, gl
.SRGB8_ALPHA8
);
76 // Set up-left region of the texture as red color.
77 // In order to make sure bi-linear interpolation operates on different colors, red region
78 // is 1 pixel smaller than a quarter of the full texture on each side.
79 var redWidth
= width
/ 2 - 1;
80 var redHeight
= height
/ 2 - 1;
81 var buf
= new Uint8Array(redWidth
* redHeight
* 4);
82 for (var i
= 0; i
< redWidth
* redHeight
; i
++) {
88 gl
.texSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, redWidth
, redHeight
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, buf
);
89 gl
.generateMipmap(gl
.TEXTURE_2D
);
90 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.NEAREST_MIPMAP_NEAREST
);
92 // Decode the srgba texture to a linear texture which will be used as reference.
93 var linearTex
= gl
.createTexture();
94 gl
.bindTexture(gl
.TEXTURE_2D
, linearTex
);
95 wtu
.fillTexture(gl
, linearTex
, width
, height
, wtu
.sRGBToLinear(colors
['srgba']), 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
96 // Set up-left region of the texture as red color.
97 // In order to make sure bi-linear interpolation operates on different colors, red region
98 // is 1 pixel smaller than a quarter of the full texture on each side.
99 for (var i
= 0; i
< redWidth
* redHeight
; i
++) {
100 buf
[4 * i
+ 0] = 255;
103 buf
[4 * i
+ 3] = 255;
105 gl
.texSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, redWidth
, redHeight
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, buf
);
106 gl
.generateMipmap(gl
.TEXTURE_2D
);
107 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.NEAREST_MIPMAP_NEAREST
);
109 // Change canvas to a small size.
112 canvas
.width
= width
;
113 canvas
.height
= height
;
114 gl
.viewport(0, 0, width
, height
);
116 // Draw with srgb texture and linear texture respectively.
117 gl
.bindTexture(gl
.TEXTURE_2D
, srgbTex
);
118 wtu
.clearAndDrawUnitQuad(gl
);
119 var result
= new Uint8Array(width
* height
* 4);
120 gl
.readPixels(0, 0, width
, height
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, result
);
121 gl
.bindTexture(gl
.TEXTURE_2D
, linearTex
);
122 wtu
.clearAndDrawUnitQuad(gl
);
123 var reference
= new Uint8Array(width
* height
* 4);
124 gl
.readPixels(0, 0, width
, height
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, reference
);
126 gl
.deleteTexture(srgbTex
);
127 gl
.deleteTexture(linearTex
);
130 var diff
= new Uint8Array(width
* height
* 4);
131 var failed
= wtu
.comparePixels(result
, reference
, tolerance
, diff
);
133 testFailed("Generate wrong mipmaps for sRGB texture.");
134 wtu
.displayImageDiff(result
, reference
, diff
, width
, height
);
136 testPassed("Generate correct mipmaps for sRGB texture.");
140 function generateMipmap_immutableTexture()
142 debug("Generate mipmaps for immutable texture.");
143 var tex
= gl
.createTexture();
144 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
145 gl
.texStorage2D(gl
.TEXTURE_2D
, Math
.log2(canvas
.width
), gl
.SRGB8_ALPHA8
, canvas
.width
, canvas
.height
);
146 gl
.generateMipmap(gl
.TEXTURE_2D
);
147 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "GenerateMipmap should succeed.");
149 gl
.deleteTexture(tex
);
152 function generateMipmap_widthHeightNotEqual()
154 debug("Generate mipmaps when width and height are not equal.");
155 var tex
= gl
.createTexture();
156 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
157 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.SRGB8_ALPHA8
, 64, 32, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
158 gl
.generateMipmap(gl
.TEXTURE_2D
);
159 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "GenerateMipmap should succeed.");
161 gl
.deleteTexture(tex
);
164 function generateMipmap_maxLevelLessThanFullMipmapLevel()
166 debug("Generate mipmaps when maxLevel is less than full mipmap level.");
168 wtu
.setupUnitQuad(gl
, 0, 1);
169 var program
= wtu
.setupProgram(
170 gl
, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
172 var colors
= [0, 63, 127, 255];
174 var texLoc
= gl
.getUniformLocation(program
, "tex");
175 gl
.uniform1i(texLoc
, 0);
179 canvas
.width
= width
;
180 canvas
.height
= height
;
181 gl
.viewport(0, 0, width
, height
);
183 var srgbTex
= gl
.createTexture();
184 gl
.bindTexture(gl
.TEXTURE_2D
, srgbTex
);
185 wtu
.fillTexture(gl
, srgbTex
, width
, height
, colors
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, gl
.SRGB8_ALPHA8
);
187 // Set max level, check if the max level mipmap is generated.
189 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAX_LEVEL
, max_level
);
190 gl
.generateMipmap(gl
.TEXTURE_2D
);
191 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.NEAREST_MIPMAP_NEAREST
);
194 height
>>= max_level
;
195 canvas
.width
= width
;
196 canvas
.height
= height
;
197 gl
.viewport(0, 0, width
, height
);
199 gl
.bindTexture(gl
.TEXTURE_2D
, srgbTex
);
200 wtu
.clearAndDrawUnitQuad(gl
);
202 var reference
= wtu
.sRGBToLinear(colors
);
204 wtu
.checkCanvasRect(gl
, 0, 0, width
, height
, reference
, msg
, [1,1,1,1]);
206 gl
.deleteTexture(srgbTex
);
210 generateMipmap_immutableTexture();
211 generateMipmap_widthHeightNotEqual();
212 generateMipmap_maxLevelLessThanFullMipmapLevel();
214 var successfullyParsed
= true;
216 <script src=
"../../../js/js-test-post.js"></script>