Commit 5ed59893 authored by Nicolai Hähnle's avatar Nicolai Hähnle

New test fp-indirections2

Not only test whether indirections are computed in a reasonable way,
but actually stress the number of indirections and check whether the
rendering results are correct.

This catches a regression introduced in the r300 driver by commit
0723cd1b0a8a76808844a2216d709f56fbad88e2
Signed-off-by: Nicolai Hähnle's avatarNicolai Hähnle <nhaehnle@gmail.com>
parent 246be615
......@@ -102,6 +102,7 @@ shaders['fp-fragment-position'] = PlainExecTest([testBinDir + 'fp-fragment-posit
shaders['fp-kil'] = PlainExecTest([testBinDir + 'fp-kil', '-auto'])
shaders['fp-incomplete-tex'] = PlainExecTest([testBinDir + 'fp-incomplete-tex', '-auto'])
shaders['fp-indirections'] = PlainExecTest([testBinDir + 'fp-indirections', '-auto'])
shaders['fp-indirections2'] = PlainExecTest([testBinDir + 'fp-indirections2', '-auto'])
shaders['glsl-bug-22603'] = PlainExecTest([testBinDir + 'glsl-bug-22603', '-auto'])
shaders['glsl-dlist-getattriblocation'] = PlainExecTest([testBinDir + 'glsl-dlist-getattriblocation', '-auto'])
shaders['glsl-uniform-update'] = PlainExecTest([testBinDir + 'glsl-uniform-update', '-auto'])
......
......@@ -32,6 +32,7 @@ add_executable (fp-generic fp-generic.c)
add_executable (fp-kil fp-kil.c)
add_executable (fp-incomplete-tex fp-incomplete-tex.c)
add_executable (fp-indirections fp-indirections.c)
add_executable (fp-indirections2 fp-indirections2.c)
add_executable (glsl-bug-22603 glsl-bug-22603.c)
add_executable (glsl-dlist-getattriblocation glsl-dlist-getattriblocation.c)
add_executable (glsl-unused-varying glsl-unused-varying.c)
......
/*
* Copyright (c) 2009 Nicolai Hähnle
*
* 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.
*
* Authors:
* Nicolai Hähnle <nhaehnle@gmail.com>
*
*/
/**
* \file
* Whereas fp-indirections tests that the native indirection limits are
* reported essentially correctly, this test actually exercises multiple
* indirection counts up to the reported native limit.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include "piglit-util.h"
#include "piglit-framework.h"
#define TEXTURE_SIZE 32 /* Note: Hardcoded dependencies in texture_init and texture_follow */
int piglit_WindowMode = GLUT_RGBA;
int piglit_Width = TEXTURE_SIZE;
int piglit_Height = TEXTURE_SIZE;
unsigned int max_samples;
unsigned char * texture_data;
unsigned char * texture_data_as_rgba;
GLuint texture_objects[3];
static void texture_init()
{
unsigned int x, y, z;
unsigned char *p;
unsigned char *q;
srand(0x12345678); /* we want repeatable test runs */
texture_data = malloc(TEXTURE_SIZE * TEXTURE_SIZE * TEXTURE_SIZE * 3);
texture_data_as_rgba = malloc(TEXTURE_SIZE * TEXTURE_SIZE * TEXTURE_SIZE * 4);
p = texture_data;
q = texture_data_as_rgba;
for(z = 0; z < TEXTURE_SIZE; ++z) {
for(y = 0; y < TEXTURE_SIZE; ++y) {
for(x = 0; x < TEXTURE_SIZE; ++x) {
unsigned int r = rand();
p[0] = r & 31;
p[1] = (r >> 5) & 31;
p[2] = (r >> 10) & 31;
q[0] = p[0] * 8 + 4;
q[1] = p[1] * 8 + 4;
q[2] = p[2] * 8 + 4;
q[3] = 0xff;
p += 3;
q += 4;
}
}
}
glGenTextures(3, texture_objects);
glBindTexture(GL_TEXTURE_1D, texture_objects[0]);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data_as_rgba);
glBindTexture(GL_TEXTURE_2D, texture_objects[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data_as_rgba);
glBindTexture(GL_TEXTURE_3D, texture_objects[2]);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, TEXTURE_SIZE, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data_as_rgba);
}
static void texture_follow(
unsigned int dim,
unsigned int x, unsigned int y, unsigned int z,
unsigned int hops,
float * expected)
{
unsigned int i;
for(i = 0; i < hops; ++i) {
unsigned char * p;
if (dim < 3)
z = 0;
if (dim < 2)
y = 0;
p = texture_data + z*TEXTURE_SIZE*TEXTURE_SIZE*3 + y*TEXTURE_SIZE*3 + x*3;
x = p[0];
y = p[1];
z = p[2];
}
expected[0] = (x + 0.5) / 32.0;
expected[1] = (y + 0.5) / 32.0;
expected[2] = (z + 0.5) / 32.0;
if (!hops)
expected[2] = 0.0;
}
static const char program_Head[] =
"!!ARBfp1.0\n"
"TEMP r;\n"
;
static const char program_TEX[] =
"TEX %s, %s, texture[0], %iD;\n";
static const char program_MOV[] =
"MOV %s, %s;\n";
static const char program_Tail[] =
"END\n";
static const char program_Input[] = "fragment.texcoord[0]";
static const char program_Output[] = "result.color";
static int test(unsigned int dim, unsigned int samples)
{
char * program_text = malloc(sizeof(program_Head) +
(samples + 1)*sizeof(program_TEX) +
sizeof(program_Tail) +
sizeof(program_Input) + sizeof(program_Output));
char buf[128];
GLuint program_object;
unsigned int draw_height;
unsigned int x, y;
strcpy(program_text, program_Head);
if (!samples) {
snprintf(buf, sizeof(buf), program_MOV, program_Output, program_Input);
strcat(program_text, buf);
} else {
const char * input = program_Input;
unsigned int i;
for(i = 1; i <= samples; ++i) {
const char * output = "r";
if (i == samples)
output = program_Output;
snprintf(buf, sizeof(buf), program_TEX, output, input, dim);
strcat(program_text, buf);
input = output;
}
}
strcat(program_text, program_Tail);
program_object = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB, program_text);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
pglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_object);
draw_height = TEXTURE_SIZE;
piglit_draw_rect_tex(0, 0, TEXTURE_SIZE, draw_height, 0, 0, 1, 1);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
pglDeleteProgramsARB(1, &program_object);
for(y = 0; y < draw_height; ++y) {
for(x = 0; x < TEXTURE_SIZE; ++x) {
float expected[3];
texture_follow(dim, x, y, 0, samples, expected);
if (!piglit_probe_pixel_rgb(x, y, expected)) {
fprintf(stderr, "Failure in dim = %i, samples = %i\n", dim, samples);
return PIGLIT_FAILURE;
}
}
}
return PIGLIT_SUCCESS;
}
int piglit_Display()
{
int result;
unsigned int dim;
unsigned int samples;
piglit_ortho_projection(piglit_Width, piglit_Height, GL_FALSE);
glClear(GL_COLOR_BUFFER_BIT);
for(dim = 1; dim <= 3; ++dim) {
samples = 0;
for(;;) {
result = test(dim, samples);
if (result != PIGLIT_SUCCESS)
return result;
if (samples < 8) {
samples++;
} else if (samples < max_samples) {
samples *= 2;
if (samples > max_samples)
samples = max_samples;
} else {
break;
}
}
}
return PIGLIT_SUCCESS;
}
void piglit_Init(int argc, char ** argv)
{
GLint max_native_tex_instructions;
GLint max_native_tex_indirections;
piglit_require_fragment_program();
pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB,
&max_native_tex_instructions);
pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB,
&max_native_tex_indirections);
printf("Max TEX instructions / TEX indirections: %i / %i\n",
max_native_tex_instructions,
max_native_tex_indirections);
max_samples = max_native_tex_indirections;
if (max_samples > max_native_tex_instructions) {
/* ARB_fragment_program, issue 24:
* For implementations with no restrictions on the number of indirections,
* the maximum indirection count will equal the maximum texture instruction
* count.
*/
fprintf(stderr, "Violation of ARB_fragment_program issue 24: TEX indirections > TEX instructions\n");
max_samples = max_native_tex_instructions;
}
if (max_samples > 1024)
max_samples = 1024;
texture_init();
}
......@@ -464,6 +464,53 @@ piglit_draw_rect(float x, float y, float w, float h)
glDisableClientState(GL_VERTEX_ARRAY);
}
/**
* Convenience function to draw an axis-aligned rectangle
* with texture coordinates.
*/
GLvoid
piglit_draw_rect_tex(float x, float y, float w, float h,
float tx, float ty, float tw, float th)
{
float verts[4][4];
float tex[4][2];
verts[0][0] = x;
verts[0][1] = y;
verts[0][2] = 0.0;
verts[0][3] = 1.0;
tex[0][0] = tx;
tex[0][1] = ty;
verts[1][0] = x + w;
verts[1][1] = y;
verts[1][2] = 0.0;
verts[1][3] = 1.0;
tex[1][0] = tx + tw;
tex[1][1] = ty;
verts[2][0] = x + w;
verts[2][1] = y + h;
verts[2][2] = 0.0;
verts[2][3] = 1.0;
tex[2][0] = tx + tw;
tex[2][1] = ty + th;
verts[3][0] = x;
verts[3][1] = y + h;
verts[3][2] = 0.0;
verts[3][3] = 1.0;
tex[3][0] = tx;
tex[3][1] = ty + th;
glVertexPointer(4, GL_FLOAT, 0, verts);
glTexCoordPointer(2, GL_FLOAT, 0, tex);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
/**
* Convenience function to configure projection matrix for window coordinates
......
......@@ -69,6 +69,8 @@ GLuint piglit_compile_program(GLenum target, const char* text);
GLint piglit_compile_shader(GLenum target, char *filename);
GLint piglit_link_simple_program(GLint vs, GLint fs);
GLvoid piglit_draw_rect(float x, float y, float w, float h);
GLvoid piglit_draw_rect_tex(float x, float y, float w, float h,
float tx, float ty, float tw, float th);
void piglit_escape_exit_key(unsigned char key, int x, int y);
char *piglit_load_text_file(const char *file_name, unsigned *size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment