add pbobench: a benchmark for pbo functions
[piglit.git] / tests / texturing / lodbias.c
blob8e5c575e9550c027cd538b23f661198b291485f5
1 /*
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
13 * Software.
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.
24 /**
25 * @file
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.
37 * @todo
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"
45 #define SquareSize 50
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];
64 #define NrTests 2
66 /**
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 } }
77 static GLboolean
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,
92 expected, probe,
93 piglit_tolerance, 3)) {
94 fprintf(stderr, "%s: %i,%i failed\n", testname, cellx, celly);
95 free(cell);
96 return GL_FALSE;
101 free(cell);
102 return GL_TRUE;
105 static float scale_for_miplevel(int bias, int level)
107 float base = SquareSize/(4>>level);
108 if (bias >= 0)
109 return base/(float)(1<<bias);
110 else
111 return base*(float)(1<<(-bias));
114 static GLboolean
115 test_simple_texture(int tex, int bias)
117 GLboolean pass = GL_TRUE;
118 int level;
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);
127 glPushMatrix();
128 glScalef(SquareSize, SquareSize, 1.0);
129 glTranslatef(level, tex, 0.0);
130 glBegin(GL_QUADS);
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);
135 glEnd();
136 glPopMatrix();
138 pass = probe_cell("test_simple", level, tex,
139 TextureData[tex][level]) && pass;
142 return pass;
146 * Simple test: Attempt to draw all LOD levels of both textures
147 * at the given LOD bias.
149 static GLboolean
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();
165 return pass;
169 static GLboolean
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);
174 GLfloat expected[3];
175 int i;
177 for(i = 0; i < 3; ++i)
178 expected[i] = TextureData[0][level1][i] + TextureData[1][level2][i];
180 glPushMatrix();
181 glScalef(SquareSize, SquareSize, 1.0);
182 glTranslatef(level1, level2, 0.0);
183 glBegin(GL_QUADS);
184 glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
185 glMultiTexCoord2f(GL_TEXTURE1, 0.0, 0.0);
186 glVertex2f(0, 0);
188 glMultiTexCoord2f(GL_TEXTURE0, scale1, 0.0);
189 glMultiTexCoord2f(GL_TEXTURE1, scale2, 0.0);
190 glVertex2f(1, 0);
192 glMultiTexCoord2f(GL_TEXTURE0, scale1, scale1);
193 glMultiTexCoord2f(GL_TEXTURE1, scale2, scale2);
194 glVertex2f(1, 1);
196 glMultiTexCoord2f(GL_TEXTURE0, 0.0, scale1);
197 glMultiTexCoord2f(GL_TEXTURE1, 0.0, scale2);
198 glVertex2f(0, 1);
199 glEnd();
200 glPopMatrix();
202 return probe_cell("multitex", level1, level2, expected);
207 * Test combinations of LOD bias when multitexturing.
209 static GLboolean
210 test_multitex(int bias1, int bias2)
212 GLboolean pass = GL_TRUE;
213 int x, y;
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();
241 return pass;
244 enum piglit_result
245 piglit_display(void)
247 GLboolean pass = GL_TRUE;
249 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
251 if (piglit_automatic) {
252 int bias1, bias2;
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);
259 } else {
260 if (CurrentTest == 0) {
261 pass = test_simple(CurrentBias, CurrentBias2);
262 } else {
263 pass = test_multitex(CurrentBias, CurrentBias2);
267 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
270 static void Key(unsigned char key, int x, int y)
272 (void) x;
273 (void) y;
274 switch (key) {
275 case 't':
276 CurrentTest++;
277 if (CurrentTest >= NrTests)
278 CurrentTest = 0;
279 printf("Test: %s\n", CurrentTest ? "multitexturing" : "simple");
280 break;
281 case 'b':
282 CurrentBias--;
283 if (CurrentBias < -MaxTextureLodBias)
284 CurrentBias = -MaxTextureLodBias;
285 break;
286 case 'B':
287 CurrentBias++;
288 if (CurrentBias > MaxTextureLodBias)
289 CurrentBias = MaxTextureLodBias;
290 break;
291 case 'n':
292 CurrentBias2--;
293 if (CurrentBias2 < -MaxTextureLodBias)
294 CurrentBias2 = -MaxTextureLodBias;
295 break;
296 case 'N':
297 CurrentBias2++;
298 if (CurrentBias2 > MaxTextureLodBias)
299 CurrentBias2 = MaxTextureLodBias;
300 break;
301 case 27:
302 exit(0);
303 break;
305 printf("Current LOD bias: 1st tex: %i 2nd tex: %i\n", CurrentBias, CurrentBias2);
306 piglit_post_redisplay();
309 void
310 piglit_init(int argc, char **argv)
312 int i;
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) {
323 printf(
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) {
334 int level;
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;
344 int j;
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);