/* * Copyright 2010 VMware, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Test building a mipmap in various orders: * From largest to smallest * From smallest to largest * Random order. * * Author: Brian Paul */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_width = 200; config.window_height = 200; config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB; config.khr_no_error_support = PIGLIT_NO_ERRORS; PIGLIT_GL_TEST_CONFIG_END #define MAX_LEVEL 7 enum order { NORMAL, REVERSE, RANDOM }; static GLubyte level_intensity(GLint level) { return 100 + level * 20; } static void setup_tex_image(GLint level) { GLint size = 1 << (MAX_LEVEL - level); GLubyte *img = malloc(size * size * 4); GLubyte val = level_intensity(level); memset(img, val, size * size * 4); glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, img); free(img); } /* * Generate a mipmapped texture. * Define the mipmap levels/images in the order specified by 'ord'. */ static void generate_mipmap(enum order ord) { GLuint tex; GLint level; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); /* hint to the driver that there won't be a mipmap (but that's a lie) */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* Set each mipmap level to a different intensity, starting with the * smallest mipmap level and ending with the largest at level=0. */ if (ord == NORMAL) { for (level = 0; level <= MAX_LEVEL; level++) { setup_tex_image(level); } } else if (ord == REVERSE) { for (level = MAX_LEVEL; level >= 0; level--) { setup_tex_image(level); } } else { static const GLuint rand[MAX_LEVEL + 1] = {3, 1, 2, 4, 7, 0, 6, 5}; assert(ord == RANDOM); for (level = 0; level <= MAX_LEVEL; level++) { setup_tex_image(rand[level]); } } /* use mipmap filtering */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } static GLboolean test(enum order ord, const char *order) { const int px = piglit_width / 2, py = piglit_height / 2; GLboolean pass = GL_TRUE; GLuint level; generate_mipmap(ord); glEnable(GL_TEXTURE_2D); /* render a test polygon for each mipmap level */ for (level = 0; level <= MAX_LEVEL; level++) { float expected[4]; int p; expected[0] = expected[1] = expected[2] = level_intensity(level) / 255.0; /* force sampling from a specific mipmap level */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, level); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, level); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glTexCoord2f(0, 0); glVertex2f(-1, -1); glTexCoord2f(1, 0); glVertex2f(1, -1); glTexCoord2f(1, 1); glVertex2f(1, 1); glTexCoord2f(0, 1); glVertex2f(-1, 1); glEnd(); p = piglit_probe_pixel_rgb(px, py, expected); if (!p) { printf(" At mipmap level %d, order = %s\n", level, order); } pass &= p; piglit_present_results(); } return pass; } void piglit_init(int argc, char **argv) { /* nothing */ } enum piglit_result piglit_display(void) { if (!test(NORMAL, "Normal")) return PIGLIT_FAIL; if (!test(REVERSE, "Reverse")) return PIGLIT_FAIL; if (!test(RANDOM, "Random")) return PIGLIT_FAIL; return PIGLIT_PASS; }