2 * Copyright (c) The Piglit project 2008
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Test the GL_EXT_texture_lod_bias extension.
28 * Only test LOD bias with a granularity of 1.0 with a nearest mip filter.
29 * This leaves room for somewhat inaccurate hardware implementations.
30 * The point of this test is that the implementation has to get the big
31 * picture issues right:
33 * 1. LOD bias is per texture stage, not per texture object.
34 * 2. LOD bias is applied *before* clamping.
35 * 3. The supported bias range must be reported correctly.
38 * Check per-texture object LOD bias (support for this was added in OpenGL 1.4).
39 * In particular, check interaction of per-texture and per-TexUnit bias.
40 * Check clamping behaviour.
43 #include "piglit-util-gl.h"
47 PIGLIT_GL_TEST_CONFIG_BEGIN
49 config
.supports_gl_compat_version
= 10;
51 config
.window_width
= 3*SquareSize
;
52 config
.window_height
= 3*SquareSize
;
53 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
54 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
56 PIGLIT_GL_TEST_CONFIG_END
58 static int CurrentTest
= 0;
59 static int CurrentBias
= 0;
60 static int CurrentBias2
= 0;
61 static int MaxTextureLodBias
;
62 static GLuint Textures
[2];
67 * The test uses two 4x4 clamped, mipmapped textures (i.e. 3 mip levels)
68 * with the following RGB colors on each level.
70 * Note: Black is used as a background color, so don't use black for the textures.
72 static GLfloat TextureData
[2][3][3] = {
73 { { 0.5, 0.5, 0.5 }, { 0.5, 0.0, 0.0 }, { 0.0, 0.5, 0.0 } },
74 { { 0.0, 0.0, 0.5 }, { 0.5, 0.5, 0.0 }, { 0.0, 0.5, 0.5 } }
78 probe_cell(const char* testname
, int cellx
, int celly
, const float* expected
)
80 const int step
= SquareSize
/5;
81 const int extent
= 4*step
;
82 const int x
= SquareSize
*cellx
+step
;
83 const int y
= SquareSize
*celly
+step
;
84 float *cell
= malloc(extent
*extent
*3*sizeof(float));
86 glReadPixels(x
, y
, extent
, extent
, GL_RGB
, GL_FLOAT
, cell
);
88 for(int yoffset
= 0; yoffset
< extent
; yoffset
+= step
) {
89 for(int xoffset
= 0; xoffset
< extent
; xoffset
+= step
) {
90 const float *probe
= cell
+3*(extent
*yoffset
+xoffset
);
91 if (!piglit_compare_pixels(x
+ xoffset
, y
+ yoffset
,
93 piglit_tolerance
, 3)) {
94 fprintf(stderr
, "%s: %i,%i failed\n", testname
, cellx
, celly
);
105 static float scale_for_miplevel(int bias
, int level
)
107 float base
= SquareSize
/(4>>level
);
109 return base
/(float)(1<<bias
);
111 return base
*(float)(1<<(-bias
));
115 test_simple_texture(int tex
, int bias
)
117 GLboolean pass
= GL_TRUE
;
120 glBindTexture(GL_TEXTURE_2D
, Textures
[tex
]);
121 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
122 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, bias
);
124 for(level
= 0; level
< 3; ++level
) {
125 float scale
= scale_for_miplevel(bias
, level
);
128 glScalef(SquareSize
, SquareSize
, 1.0);
129 glTranslatef(level
, tex
, 0.0);
131 glTexCoord2f(0.0, 0.0); glVertex2f(0, 0);
132 glTexCoord2f(scale
, 0.0); glVertex2f(1, 0);
133 glTexCoord2f(scale
, scale
); glVertex2f(1, 1);
134 glTexCoord2f(0.0, scale
); glVertex2f(0, 1);
138 pass
= probe_cell("test_simple", level
, tex
,
139 TextureData
[tex
][level
]) && pass
;
146 * Simple test: Attempt to draw all LOD levels of both textures
147 * at the given LOD bias.
150 test_simple(int bias1
, int bias2
)
152 GLboolean pass
= GL_TRUE
;
154 glClearColor(0.0, 0.0, 0.0, 1.0);
155 glClear(GL_COLOR_BUFFER_BIT
);
157 glEnable(GL_TEXTURE_2D
);
158 pass
= test_simple_texture(0, bias1
) && pass
;
159 pass
= test_simple_texture(1, bias2
) && pass
;
160 glDisable(GL_TEXTURE_2D
);
162 if (!piglit_automatic
)
163 piglit_present_results();
170 test_multitex_combo(int bias1
, int level1
, int bias2
, int level2
)
172 float scale1
= scale_for_miplevel(bias1
, level1
);
173 float scale2
= scale_for_miplevel(bias2
, level2
);
177 for(i
= 0; i
< 3; ++i
)
178 expected
[i
] = TextureData
[0][level1
][i
] + TextureData
[1][level2
][i
];
181 glScalef(SquareSize
, SquareSize
, 1.0);
182 glTranslatef(level1
, level2
, 0.0);
184 glMultiTexCoord2f(GL_TEXTURE0
, 0.0, 0.0);
185 glMultiTexCoord2f(GL_TEXTURE1
, 0.0, 0.0);
188 glMultiTexCoord2f(GL_TEXTURE0
, scale1
, 0.0);
189 glMultiTexCoord2f(GL_TEXTURE1
, scale2
, 0.0);
192 glMultiTexCoord2f(GL_TEXTURE0
, scale1
, scale1
);
193 glMultiTexCoord2f(GL_TEXTURE1
, scale2
, scale2
);
196 glMultiTexCoord2f(GL_TEXTURE0
, 0.0, scale1
);
197 glMultiTexCoord2f(GL_TEXTURE1
, 0.0, scale2
);
202 return probe_cell("multitex", level1
, level2
, expected
);
207 * Test combinations of LOD bias when multitexturing.
210 test_multitex(int bias1
, int bias2
)
212 GLboolean pass
= GL_TRUE
;
215 glClearColor(0.0, 0.0, 0.0, 1.0);
216 glClear(GL_COLOR_BUFFER_BIT
);
218 glEnable(GL_TEXTURE_2D
);
219 glBindTexture(GL_TEXTURE_2D
, Textures
[0]);
220 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
221 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, bias1
);
223 glActiveTexture(GL_TEXTURE1
);
224 glEnable(GL_TEXTURE_2D
);
225 glBindTexture(GL_TEXTURE_2D
, Textures
[1]);
226 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_ADD
);
227 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, bias2
);
229 for(y
= 0; y
< 3; ++y
) {
230 for(x
= 0; x
< 3; ++x
)
231 pass
= test_multitex_combo(bias1
, x
, bias2
, y
) && pass
;
234 glDisable(GL_TEXTURE_2D
);
235 glActiveTexture(GL_TEXTURE0
);
236 glDisable(GL_TEXTURE_2D
);
238 if (!piglit_automatic
)
239 piglit_present_results();
247 GLboolean pass
= GL_TRUE
;
249 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
251 if (piglit_automatic
) {
253 for(bias1
= -MaxTextureLodBias
; bias1
<= MaxTextureLodBias
; bias1
++) {
254 for(bias2
= -MaxTextureLodBias
; bias2
<= MaxTextureLodBias
; bias2
++) {
255 pass
= pass
&& test_simple(bias1
, bias2
);
256 pass
= pass
&& test_multitex(bias1
, bias2
);
260 if (CurrentTest
== 0) {
261 pass
= test_simple(CurrentBias
, CurrentBias2
);
263 pass
= test_multitex(CurrentBias
, CurrentBias2
);
267 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
270 static void Key(unsigned char key
, int x
, int y
)
277 if (CurrentTest
>= NrTests
)
279 printf("Test: %s\n", CurrentTest
? "multitexturing" : "simple");
283 if (CurrentBias
< -MaxTextureLodBias
)
284 CurrentBias
= -MaxTextureLodBias
;
288 if (CurrentBias
> MaxTextureLodBias
)
289 CurrentBias
= MaxTextureLodBias
;
293 if (CurrentBias2
< -MaxTextureLodBias
)
294 CurrentBias2
= -MaxTextureLodBias
;
298 if (CurrentBias2
> MaxTextureLodBias
)
299 CurrentBias2
= MaxTextureLodBias
;
305 printf("Current LOD bias: 1st tex: %i 2nd tex: %i\n", CurrentBias
, CurrentBias2
);
306 piglit_post_redisplay();
310 piglit_init(int argc
, char **argv
)
314 piglit_require_gl_version(13);
316 piglit_require_extension("GL_EXT_texture_lod_bias");
318 glGetIntegerv(GL_MAX_TEXTURE_LOD_BIAS_EXT
, &MaxTextureLodBias
);
319 if (!piglit_automatic
)
320 printf("MAX_TEXTURE_LOD_BIAS_EXT = %i\n", MaxTextureLodBias
);
322 if (!piglit_automatic
) {
324 "Press 't' to switch tests\n"
325 "Press 'b'/'B' to change primary LOD bias\n"
326 "Press 'n'/'N' to change secondary LOD bias\n"
327 "Press 'Escape' to quit\n");
328 piglit_set_keyboard_func(Key
);
331 glGenTextures(2, Textures
);
333 for(i
= 0; i
< 2; ++i
) {
336 glBindTexture(GL_TEXTURE_2D
, Textures
[i
]);
338 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST_MIPMAP_NEAREST
);
339 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
341 for(level
= 0; level
< 3; ++level
) {
342 GLfloat texdata
[16][3];
343 int dim
= 4 >> level
;
346 for(j
= 0; j
< dim
*dim
; ++j
) {
347 texdata
[j
][0] = TextureData
[i
][level
][0];
348 texdata
[j
][1] = TextureData
[i
][level
][1];
349 texdata
[j
][2] = TextureData
[i
][level
][2];
352 glTexImage2D(GL_TEXTURE_2D
, level
, GL_RGB
, dim
, dim
, 0, GL_RGB
, GL_FLOAT
, texdata
);
356 glReadBuffer(GL_BACK
);