diff options
-rw-r--r-- | progs/tests/Makefile | 1 | ||||
-rw-r--r-- | progs/tests/minmag.c | 198 | ||||
-rw-r--r-- | src/gallium/auxiliary/llvm/Makefile | 2 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 22 |
4 files changed, 219 insertions, 4 deletions
diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 9016efe9e7..00e58a53ce 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -48,6 +48,7 @@ SOURCES = \ invert.c \ jkrahntest.c \ manytex.c \ + minmag.c \ mipmap_limits.c \ multipal.c \ no_s3tc.c \ diff --git a/progs/tests/minmag.c b/progs/tests/minmag.c new file mode 100644 index 0000000000..78ef9db03a --- /dev/null +++ b/progs/tests/minmag.c @@ -0,0 +1,198 @@ +/* + * Test minification vs. magnification filtering. + * Draw two quads with different filtering modes: + * + * +--------------------------+ +--------------------------+ + * | MagFilter = GL_LINEAR | | MagFilter = GL_LINEAR | + * | MinFilter = GL_LINEAR | | MinFilter = GL_NEAREST | + * +--------------------------+ +--------------------------+ + * + * They should look different when the quad is smaller than the level 0 + * texture size (when minifying). + */ + +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <GL/glut.h> + + +static GLint Width = 1000, Height = 500; + + +static GLint TexWidth = 256, TexHeight = 256; +static GLfloat Zpos = 5; +static GLboolean MipMap = 0*GL_TRUE; +static GLboolean LinearFilter = GL_TRUE; + + +static void +redraw(void) +{ + GLfloat w = 1.0; + GLfloat h = 1.0; + + glClear( GL_COLOR_BUFFER_BIT ); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glPushMatrix(); + glTranslatef(-1.5, 0, -Zpos); + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-w, -h); + glTexCoord2f(1, 0); glVertex2f( w, -h); + glTexCoord2f(1, 1); glVertex2f( w, h); + glTexCoord2f(0, 1); glVertex2f(-w, h); + glEnd(); + glPopMatrix(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glPushMatrix(); + glTranslatef(1.5, 0, -Zpos); + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-w, -h); + glTexCoord2f(1, 0); glVertex2f( w, -h); + glTexCoord2f(1, 1); glVertex2f( w, h); + glTexCoord2f(0, 1); glVertex2f(-w, h); + glEnd(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +init(void) +{ + GLubyte color[10][4] = { + { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 1, 1, 0 }, + { 1, 0, 1, 0 }, + { 1, 1, 0, 0 }, + { 1, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 } + }; + GLubyte *texImage; + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("Left quad should be linear filtered and right should be nearest filtered.\n"); + printf("Press z/Z to change quad distance.\n"); + + texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte)); + assert(texImage); + + { + GLint level = 0; + GLint w = TexWidth, h = TexHeight; + while (1) { + int i, j; + + for (i = 0; i < h; i++) { + for (j = 0;j < w; j++) { + if (w==1 || h==1 || (((i / 2) ^ (j / 2)) & 1)) { + /*if (j < i) {*/ + texImage[(i*w+j) * 4 + 0] = 255; + texImage[(i*w+j) * 4 + 1] = 255; + texImage[(i*w+j) * 4 + 2] = 255; + texImage[(i*w+j) * 4 + 3] = 255; + } + else { + texImage[(i*w+j) * 4 + 0] = color[level][0] * 255; + texImage[(i*w+j) * 4 + 1] = color[level][1] * 255; + texImage[(i*w+j) * 4 + 2] = color[level][2] * 255; + texImage[(i*w+j) * 4 + 3] = color[level][3] * 255; + } + } + } + + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texImage); + + printf("Texture level %d: %d x %d\n", level, w, h); + if (!MipMap) + break; + + if (w == 1 && h == 1) + break; + if (w > 1) + w /= 2; + if (h > 1) + h /= 2; + level++; + } + } + + free(texImage); + + glClearColor(0.25, 0.25, 0.25, 1.0); + glEnable(GL_TEXTURE_2D); + + glViewport(0, 0, Width, Height); +} + + + +static void +Reshape(int width, int height) +{ + float ar = (float) width /height; + Width = width; + Height = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1.0, 1.0, 5.0, 2500.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'z': + Zpos--; + break; + case 'Z': + Zpos++; + break; + case 'f': + LinearFilter = !LinearFilter; + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(redraw); + init(); + glutMainLoop(); + return 0; +} diff --git a/src/gallium/auxiliary/llvm/Makefile b/src/gallium/auxiliary/llvm/Makefile index e0abf860c1..39fac6ea4a 100644 --- a/src/gallium/auxiliary/llvm/Makefile +++ b/src/gallium/auxiliary/llvm/Makefile @@ -30,7 +30,7 @@ OBJECTS = $(C_SOURCES:.c=.o) \ ### Include directories INCLUDES = \ -I. \ - -I$(TOP)/src/gallium/drivers + -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/mesa \ diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2f82fd6abe..c54e9d385c 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -474,8 +474,24 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, { if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ - *imgFilter = sampler->state->mag_img_filter; - *level0 = *level1 = (int) sampler->state->min_lod; + *level0 = *level1 = CLAMP((int) sampler->state->min_lod, + 0, (int) sampler->texture->last_level); + + if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { + /* non-mipmapped texture, but still need to determine if doing + * minification or magnification. + */ + float lambda = compute_lambda(sampler, s, t, p, lodbias); + if (lambda <= 0.0) { + *imgFilter = sampler->state->mag_img_filter; + } + else { + *imgFilter = sampler->state->min_img_filter; + } + } + else { + *imgFilter = sampler->state->mag_img_filter; + } } else { float lambda; @@ -487,7 +503,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, /* vertex shader */ lambda = lodbias; /* not really a bias, but absolute LOD */ - if (lambda < 0.0) { /* XXX threshold depends on the filter */ + if (lambda <= 0.0) { /* XXX threshold depends on the filter */ /* magnifying */ *imgFilter = sampler->state->mag_img_filter; *level0 = *level1 = 0; |