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>WebGL2 texture mipmap level 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=
"2" height=
"2" style=
"width: 2px; height: 2px;"></canvas>
18 <div id=
"description"></div>
19 <div id=
"console"></div>
20 <script id=
"vshader" type=
"x-shader/x-vertex">
22 attribute vec4 vPosition;
23 attribute vec2 texCoord0;
24 varying vec2 texCoord;
27 gl_Position = vPosition * uMult;
32 <script id=
"fshader" type=
"x-shader/x-fragment">
33 precision mediump float;
34 uniform sampler2D tex;
35 varying vec2 texCoord;
38 gl_FragColor = texture2D(tex, texCoord);
42 <script id=
"vshader_texsize" type=
"x-shader/x-vertex">#version
300 es
46 gl_Position = vPosition;
50 <script id=
"fshader_texsize_2d" type=
"x-shader/x-fragment">#version
300 es
52 precision mediump float;
53 uniform sampler2D tex;
55 uniform ivec2 texSize;
59 fragColor = (textureSize(tex, lod) == texSize ? vec4(
255,
0,
0,
255) : vec4(
0,
0,
0,
255));
66 description(document
.title
);
67 var wtu
= WebGLTestUtils
;
68 var gl
= wtu
.create3DContext("example", undefined, 2);
70 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "Should be no errors from setup.");
74 debug("test mipmap level ranges");
75 var tex
= gl
.createTexture();
76 wtu
.setupUnitQuad(gl
, 0, 1);
77 var program
= wtu
.setupProgram(
78 gl
, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
80 gl
.disable(gl
.DEPTH_TEST
);
82 gl
.uniform1i(gl
.getUniformLocation(program
, "tex"), 0);
84 var multLoc
= gl
.getUniformLocation(program
, "uMult");
85 gl
.uniform4f(multLoc
, 1, 1, 1, 1);
87 // Test that filling partial levels is enough for mipmapping.
88 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
89 wtu
.fillTexture(gl
, tex
, 8, 8, [255, 0, 0, 255], 2, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
90 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(8x8, level=2) should succeed");
91 wtu
.fillTexture(gl
, tex
, 4, 4, [0, 255, 0, 255], 3, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
92 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(4x4, level=3) should succeed");
93 wtu
.fillTexture(gl
, tex
, 2, 2, [0, 0, 255, 255], 4, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
94 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(2x2, level=4) should succeed");
95 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_BASE_LEVEL
, 2);
96 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
97 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAX_LEVEL
, 4);
98 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_MAX_LEVEL) should succeed");
99 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAG_FILTER
, gl
.LINEAR
);
100 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_MAG_FILTER) should succeed");
101 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.LINEAR_MIPMAP_LINEAR
);
102 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_MIN_FILTER) should succeed");
103 wtu
.clearAndDrawUnitQuad(gl
);
104 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "clearAndDrawQuad should succeed");
105 wtu
.checkCanvas(gl
, [0, 0, 255, 255], "filling partial levels: should draw with [0, 0, 255, 255]");
107 // Test that generateMipmap works with partial levels.
108 gl
.generateMipmap(gl
.TEXTURE_2D
);
109 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "generateMipmap should succeed");
110 wtu
.clearAndDrawUnitQuad(gl
);
111 wtu
.checkCanvas(gl
, [255, 0, 0, 255], "generateMipmap with partial levels: should draw with [255, 0, 0, 255]");
112 gl
.deleteTexture(tex
);
114 // Test incompleteless for partial levels.
115 tex
= gl
.createTexture();
116 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
117 wtu
.fillTexture(gl
, tex
, 8, 8, [255, 0, 0, 255], 2, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
118 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(8x8, level=2) should succeed");
119 wtu
.fillTexture(gl
, tex
, 4, 4, [255, 0, 0, 255], 3, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
120 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(4x4, level=3) should succeed");
121 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_BASE_LEVEL
, 2);
122 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
123 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAX_LEVEL
, 4);
124 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_MAX_LEVEL) should succeed");
125 wtu
.clearAndDrawUnitQuad(gl
);
126 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "clearAndDrawQuad should succeed");
127 wtu
.checkCanvas(gl
, [0, 0, 0, 255], "incomplete texture should draw with [0, 0, 0, 255]");
128 gl
.deleteTexture(tex
);
130 // Test base level texture isn't specified.
131 tex
= gl
.createTexture();
132 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
133 wtu
.fillTexture(gl
, tex
, 8, 8, [255, 0, 0, 255], 2, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
134 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(8x8, level=2) should succeed");
135 wtu
.fillTexture(gl
, tex
, 4, 4, [255, 0, 0, 255], 3, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
136 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(4x4, level=3) should succeed");
137 wtu
.fillTexture(gl
, tex
, 2, 2, [0, 0, 255, 255], 4, gl
.RGBA
, gl
.UNSIGNED_BYTE
);
138 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "fillTexture(2x2, level=4) should succeed");
139 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_BASE_LEVEL
, 1);
140 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
141 gl
.generateMipmap(gl
.TEXTURE_2D
);
142 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "generateMipmap should fail if base level texture is not specified");
143 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_BASE_LEVEL
, 2);
144 gl
.generateMipmap(gl
.TEXTURE_2D
);
145 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "generateMipmap should succeed");
146 gl
.deleteTexture(tex
);
149 var tex3d
= gl
.createTexture();
150 gl
.bindTexture(gl
.TEXTURE_3D
, tex3d
);
151 gl
.texImage3D( gl
.TEXTURE_3D
, 0, gl
.RGBA
, 8, 8, 8, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, new Uint8Array(8 * 8 * 8 * 4));
152 gl
.generateMipmap(gl
.TEXTURE_3D
);
153 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "generateMipmap should succeed");
154 gl
.texSubImage3D(gl
.TEXTURE_3D
, 1, 0, 0, 0, 4, 4, 4, gl
.RGBA
, gl
.UNSIGNED_BYTE
, new Uint8Array(4 * 4 * 4 * 4));
155 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texSubImage3D should succeed");
156 gl
.deleteTexture(tex3d
);
158 // Test 2D array texture.
159 var tex2dArray
= gl
.createTexture();
160 gl
.bindTexture(gl
.TEXTURE_2D_ARRAY
, tex2dArray
);
161 gl
.texImage3D( gl
.TEXTURE_2D_ARRAY
, 0, gl
.RGBA
, 8, 8, 4, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, new Uint8Array(8 * 8 * 4 * 4));
162 gl
.generateMipmap(gl
.TEXTURE_2D_ARRAY
);
163 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "generateMipmap should succeed");
164 gl
.texSubImage3D(gl
.TEXTURE_2D_ARRAY
, 1, 0, 0, 0, 4, 4, 4, gl
.RGBA
, gl
.UNSIGNED_BYTE
, new Uint8Array(4 * 4 * 4 * 4));
165 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texSubImage3D should succeed");
166 gl
.deleteTexture(tex2dArray
);
168 // Test sized internal format should be both color-renderable and texture-filterable
169 tex
= gl
.createTexture();
170 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
171 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8
, 0, 0, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
172 gl
.generateMipmap(gl
.TEXTURE_2D
);
173 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "generateMipmap should fail for zero-size texture");
174 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8
, 8, 8, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, new Uint8Array(8 * 8 * 4));
175 gl
.generateMipmap(gl
.TEXTURE_2D
);
176 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "generateMipmap should succeed");
177 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8UI
, 8, 8, 0, gl
.RGBA_INTEGER
, gl
.UNSIGNED_BYTE
, new Uint8Array(8 * 8 * 4));
178 gl
.generateMipmap(gl
.TEXTURE_2D
);
179 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "generateMipmap should fail for non-texture-filterable format");
180 if (gl
.getExtension('EXT_color_buffer_float')) {
181 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA32F
, 8, 8, 0, gl
.RGBA
, gl
.FLOAT
, new Float32Array(8 * 8 * 4));
182 gl
.generateMipmap(gl
.TEXTURE_2D
);
183 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "generateMipmap should fail for float texture");
185 if (gl
.getExtension('EXT_color_buffer_float') && gl
.getExtension('OES_texture_float_linear')) {
186 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA32F
, 0, 0, 0, gl
.RGBA
, gl
.FLOAT
, null);
187 gl
.generateMipmap(gl
.TEXTURE_2D
);
188 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
, "generateMipmap should fail for zero-size texture");
189 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA32F
, 8, 8, 0, gl
.RGBA
, gl
.FLOAT
, new Float32Array(8 * 8 * 4));
190 gl
.generateMipmap(gl
.TEXTURE_2D
);
191 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "generateMipmap should succeed");
193 gl
.deleteTexture(tex
);
195 // Test textureSize should work correctly with non-zero base level for texStorage2D
196 var program
= wtu
.setupProgram(
197 gl
, ['vshader_texsize', 'fshader_texsize_2d'], ['vPosition'], [0]);
199 gl
.uniform1i(gl
.getUniformLocation(program
, "tex"), 0);
200 gl
.uniform1i(gl
.getUniformLocation(program
, "lod"), 1);
201 gl
.uniform2i(gl
.getUniformLocation(program
, "texSize"), 7, 4);
202 tex
= gl
.createTexture();
203 gl
.bindTexture(gl
.TEXTURE_2D
, tex
);
204 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MAG_FILTER
, gl
.LINEAR
);
205 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_MAG_FILTER) should succeed");
206 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_MIN_FILTER
, gl
.LINEAR
);
207 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_MIN_FILTER) should succeed");
208 gl
.texParameteri(gl
.TEXTURE_2D
, gl
.TEXTURE_BASE_LEVEL
, 1);
209 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
210 gl
.texStorage2D(gl
.TEXTURE_2D
, 4, gl
.RGBA8
, 31, 17);
211 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texStorage2D should succeed");
212 wtu
.clearAndDrawUnitQuad(gl
);
213 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "clearAndDrawQuad should succeed");
214 wtu
.checkCanvas(gl
, [255, 0, 0, 255], "non-zero base level texStorage2D: should draw with [255, 0, 0, 255]");
215 gl
.deleteTexture(tex
);
219 var successfullyParsed
= true;
222 <script src=
"../../../js/js-test-post.js"></script>