132001f49Smrg/* 232001f49Smrg * Copyright (C) 2000 Brian Paul All Rights Reserved. 332001f49Smrg * 432001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a 532001f49Smrg * copy of this software and associated documentation files (the "Software"), 632001f49Smrg * to deal in the Software without restriction, including without limitation 732001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 832001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the 932001f49Smrg * Software is furnished to do so, subject to the following conditions: 1032001f49Smrg * 1132001f49Smrg * The above copyright notice and this permission notice shall be included 1232001f49Smrg * in all copies or substantial portions of the Software. 1332001f49Smrg * 1432001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1532001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1632001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1732001f49Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1832001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1932001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2032001f49Smrg */ 2132001f49Smrg 2232001f49Smrg/** 2332001f49Smrg * \file bug_3195.c 2432001f49Smrg * 2532001f49Smrg * Simple regression test for bug #3195. A bug in the i180 driver caused 2632001f49Smrg * a segfault (inside the driver) when the LOD bias is adjusted and no texture 2732001f49Smrg * is enabled. This test, which is based on progs/demos/lodbias.c, sets up 2832001f49Smrg * all the texturing, disables all textures, adjusts the LOD bias, then 2932001f49Smrg * re-enables \c GL_TEXTURE_2D. 3032001f49Smrg * 3132001f49Smrg * \author Brian Paul 3232001f49Smrg * \author Ian Romanick <idr@us.ibm.com> 3332001f49Smrg */ 3432001f49Smrg 3532001f49Smrg#include <assert.h> 3632001f49Smrg#include <stdlib.h> 3732001f49Smrg#include <stdio.h> 3832001f49Smrg#include <math.h> 3932001f49Smrg#include <GL/glew.h> 4032001f49Smrg#include "glut_wrap.h" 4132001f49Smrg 4232001f49Smrg#include "readtex.h" 4332001f49Smrg 4432001f49Smrg#define TEXTURE_FILE DEMOS_DATA_DIR "girl.rgb" 4532001f49Smrg 4632001f49Smrgstatic GLfloat Xrot = 0, Yrot = -30, Zrot = 0; 4732001f49Smrgstatic GLint Bias = 0, BiasStepSign = +1; /* ints avoid fp precision problem */ 4832001f49Smrgstatic GLint BiasMin = -400, BiasMax = 400; 4932001f49Smrg 5032001f49Smrg 5132001f49Smrg 5232001f49Smrgstatic void 5332001f49SmrgPrintString(const char *s) 5432001f49Smrg{ 5532001f49Smrg while (*s) { 5632001f49Smrg glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 5732001f49Smrg s++; 5832001f49Smrg } 5932001f49Smrg} 6032001f49Smrg 6132001f49Smrgstatic void Idle( void ) 6232001f49Smrg{ 6332001f49Smrg static int lastTime = 0; 6432001f49Smrg int time = glutGet(GLUT_ELAPSED_TIME); 6532001f49Smrg int step; 6632001f49Smrg 6732001f49Smrg if (lastTime == 0) 6832001f49Smrg lastTime = time; 6932001f49Smrg else if (time - lastTime < 10) 7032001f49Smrg return; 7132001f49Smrg 7232001f49Smrg step = (time - lastTime) / 10 * BiasStepSign; 7332001f49Smrg lastTime = time; 7432001f49Smrg 7532001f49Smrg Bias += step; 7632001f49Smrg if (Bias < BiasMin) { 7732001f49Smrg exit(0); 7832001f49Smrg } 7932001f49Smrg else if (Bias > BiasMax) { 8032001f49Smrg Bias = BiasMax; 8132001f49Smrg BiasStepSign = -1; 8232001f49Smrg } 8332001f49Smrg 8432001f49Smrg glutPostRedisplay(); 8532001f49Smrg} 8632001f49Smrg 8732001f49Smrg 8832001f49Smrgstatic void Display( void ) 8932001f49Smrg{ 9032001f49Smrg char str[100]; 9132001f49Smrg 9232001f49Smrg glClear( GL_COLOR_BUFFER_BIT ); 9332001f49Smrg 9432001f49Smrg glMatrixMode( GL_PROJECTION ); 9532001f49Smrg glLoadIdentity(); 9632001f49Smrg glOrtho(-1, 1, -1, 1, -1, 1); 9732001f49Smrg glMatrixMode( GL_MODELVIEW ); 9832001f49Smrg glLoadIdentity(); 9932001f49Smrg 10032001f49Smrg glDisable(GL_TEXTURE_2D); 10132001f49Smrg glColor3f(1,1,1); 10232001f49Smrg glRasterPos3f(-0.9, -0.9, 0.0); 10332001f49Smrg sprintf(str, "Texture LOD Bias = %4.1f", Bias * 0.01); 10432001f49Smrg PrintString(str); 10532001f49Smrg 10632001f49Smrg glMatrixMode( GL_PROJECTION ); 10732001f49Smrg glLoadIdentity(); 10832001f49Smrg glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); 10932001f49Smrg glMatrixMode( GL_MODELVIEW ); 11032001f49Smrg glLoadIdentity(); 11132001f49Smrg glTranslatef( 0.0, 0.0, -8.0 ); 11232001f49Smrg 11332001f49Smrg glPushMatrix(); 11432001f49Smrg glRotatef(Xrot, 1, 0, 0); 11532001f49Smrg glRotatef(Yrot, 0, 1, 0); 11632001f49Smrg glRotatef(Zrot, 0, 0, 1); 11732001f49Smrg 11832001f49Smrg glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.01 * Bias); 11932001f49Smrg glEnable(GL_TEXTURE_2D); 12032001f49Smrg 12132001f49Smrg glBegin(GL_POLYGON); 12232001f49Smrg glTexCoord2f(0, 0); glVertex2f(-1, -1); 12332001f49Smrg glTexCoord2f(2, 0); glVertex2f( 1, -1); 12432001f49Smrg glTexCoord2f(2, 2); glVertex2f( 1, 1); 12532001f49Smrg glTexCoord2f(0, 2); glVertex2f(-1, 1); 12632001f49Smrg glEnd(); 12732001f49Smrg 12832001f49Smrg glPopMatrix(); 12932001f49Smrg 13032001f49Smrg glutSwapBuffers(); 13132001f49Smrg} 13232001f49Smrg 13332001f49Smrg 13432001f49Smrgstatic void Reshape( int width, int height ) 13532001f49Smrg{ 13632001f49Smrg glViewport( 0, 0, width, height ); 13732001f49Smrg} 13832001f49Smrg 13932001f49Smrg 14032001f49Smrgstatic void Key( unsigned char key, int x, int y ) 14132001f49Smrg{ 14232001f49Smrg (void) x; 14332001f49Smrg (void) y; 14432001f49Smrg switch (key) { 14532001f49Smrg case 27: 14632001f49Smrg exit(0); 14732001f49Smrg break; 14832001f49Smrg } 14932001f49Smrg glutPostRedisplay(); 15032001f49Smrg} 15132001f49Smrg 15232001f49Smrg 15332001f49Smrgstatic void SpecialKey( int key, int x, int y ) 15432001f49Smrg{ 15532001f49Smrg const GLfloat step = 3.0; 15632001f49Smrg (void) x; 15732001f49Smrg (void) y; 15832001f49Smrg switch (key) { 15932001f49Smrg case GLUT_KEY_UP: 16032001f49Smrg Xrot -= step; 16132001f49Smrg break; 16232001f49Smrg case GLUT_KEY_DOWN: 16332001f49Smrg Xrot += step; 16432001f49Smrg break; 16532001f49Smrg case GLUT_KEY_LEFT: 16632001f49Smrg Yrot -= step; 16732001f49Smrg break; 16832001f49Smrg case GLUT_KEY_RIGHT: 16932001f49Smrg Yrot += step; 17032001f49Smrg break; 17132001f49Smrg } 17232001f49Smrg glutPostRedisplay(); 17332001f49Smrg} 17432001f49Smrg 17532001f49Smrg 17632001f49Smrgstatic void Init( void ) 17732001f49Smrg{ 17832001f49Smrg GLfloat maxBias; 17932001f49Smrg const char * const ver_string = (const char *) 18032001f49Smrg glGetString( GL_VERSION ); 18132001f49Smrg 18232001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 18332001f49Smrg printf("GL_VERSION = %s\n", ver_string); 18432001f49Smrg 18532001f49Smrg printf("\nThis program should function nearly identically to Mesa's lodbias demo.\n" 18632001f49Smrg "It should cycle through the complet LOD bias range once and exit. If bug\n" 18732001f49Smrg "#3195 still exists, the demo should crash almost immediatly.\n"); 18832001f49Smrg printf("This is a regression test for bug #3195.\n"); 18932001f49Smrg printf("https://bugs.freedesktop.org/show_bug.cgi?id=3195\n"); 19032001f49Smrg 19132001f49Smrg if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) { 19232001f49Smrg printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n"); 19332001f49Smrg exit(1); 19432001f49Smrg } 19532001f49Smrg 19632001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 19732001f49Smrg 19832001f49Smrg if (glutExtensionSupported("GL_SGIS_generate_mipmap")) { 19932001f49Smrg /* test auto mipmap generation */ 20032001f49Smrg GLint width, height, i; 20132001f49Smrg GLenum format; 20232001f49Smrg GLubyte *image = LoadRGBImage(TEXTURE_FILE, &width, &height, &format); 20332001f49Smrg if (!image) { 20432001f49Smrg printf("Error: could not load texture image %s\n", TEXTURE_FILE); 20532001f49Smrg exit(1); 20632001f49Smrg } 20732001f49Smrg /* resize to 256 x 256 */ 20832001f49Smrg if (width != 256 || height != 256) { 20932001f49Smrg GLubyte *newImage = malloc(256 * 256 * 4); 21032001f49Smrg gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image, 21132001f49Smrg 256, 256, GL_UNSIGNED_BYTE, newImage); 21232001f49Smrg free(image); 21332001f49Smrg image = newImage; 21432001f49Smrg } 21532001f49Smrg printf("Using GL_SGIS_generate_mipmap\n"); 21632001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); 21732001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, format, 256, 256, 0, 21832001f49Smrg format, GL_UNSIGNED_BYTE, image); 21932001f49Smrg free(image); 22032001f49Smrg 22132001f49Smrg /* make sure mipmap was really generated correctly */ 22232001f49Smrg width = height = 256; 22332001f49Smrg for (i = 0; i < 9; i++) { 22432001f49Smrg GLint w, h; 22532001f49Smrg glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w); 22632001f49Smrg glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h); 22732001f49Smrg printf("Level %d size: %d x %d\n", i, w, h); 22832001f49Smrg assert(w == width); 22932001f49Smrg assert(h == height); 23032001f49Smrg width /= 2; 23132001f49Smrg height /= 2; 23232001f49Smrg } 23332001f49Smrg 23432001f49Smrg } 23532001f49Smrg else if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { 23632001f49Smrg printf("Error: could not load texture image %s\n", TEXTURE_FILE); 23732001f49Smrg exit(1); 23832001f49Smrg } 23932001f49Smrg 24032001f49Smrg /* mipmapping required for this extension */ 24132001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 24232001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 24332001f49Smrg glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 24432001f49Smrg 24532001f49Smrg glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &maxBias); 24632001f49Smrg printf("LOD bias range: [%g, %g]\n", -maxBias, maxBias); 24732001f49Smrg BiasMin = -100 * maxBias; 24832001f49Smrg BiasMax = 100 * maxBias; 24932001f49Smrg 25032001f49Smrg /* Since we have (about) 8 mipmap levels, no need to bias beyond 25132001f49Smrg * the range [-1, +8]. 25232001f49Smrg */ 25332001f49Smrg if (BiasMin < -100) 25432001f49Smrg BiasMin = -100; 25532001f49Smrg if (BiasMax > 800) 25632001f49Smrg BiasMax = 800; 25732001f49Smrg} 25832001f49Smrg 25932001f49Smrg 26032001f49Smrgint main( int argc, char *argv[] ) 26132001f49Smrg{ 26232001f49Smrg glutInit( &argc, argv ); 26332001f49Smrg glutInitWindowPosition( 0, 0 ); 26432001f49Smrg glutInitWindowSize( 350, 350 ); 26532001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); 26632001f49Smrg glutCreateWindow( "Bug #3195 Test" ); 26732001f49Smrg glewInit(); 26832001f49Smrg glutReshapeFunc( Reshape ); 26932001f49Smrg glutKeyboardFunc( Key ); 27032001f49Smrg glutSpecialFunc( SpecialKey ); 27132001f49Smrg glutDisplayFunc( Display ); 27232001f49Smrg glutIdleFunc(Idle); 27332001f49Smrg Init(); 27432001f49Smrg glutMainLoop(); 27532001f49Smrg return 0; 27632001f49Smrg} 277