Commit 1dbc6cef authored by Nicolai Hähnle's avatar Nicolai Hähnle
Browse files

New test: texturing/texdepth

Very basic test of
 - ARB_depth_texture
 - ARB_shadow
 - ARB_shadow_ambient
 - EXT_shadow_funcs
parent eb6359d4
......@@ -70,6 +70,7 @@ bugs['r300-readcache'] = PlainExecTest([testBinDir + 'r300-readcache'])
texturing = Group()
texturing['cubemap'] = PlainExecTest([testBinDir + 'cubemap', '-auto'])
texturing['texdepth'] = PlainExecTest([testBinDir + 'texdepth', '-auto'])
texturing['texrect-many'] = PlainExecTest([testBinDir + 'texrect-many', '-auto'])
profile.tests['bugs'] = bugs
......
......@@ -19,4 +19,5 @@ link_libraries (
)
add_executable (cubemap cubemap.c)
add_executable (texdepth texdepth.c)
add_executable (texrect-many texrect-many.c)
/**
* @file texdepth.c
*
* Basic tests for the following extensions:
* - ARB_depth_texture
* - ARB_shadow
* - ARB_shadow_ambient
* - EXT_shadow_funcs
*/
#define GL_GLEXT_PROTOTYPES
#include "GL/glut.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "piglit-util.h"
#define ROWS 4
#define COLS 8
static int Automatic = 0;
static int Width = COLS*32, Height = ROWS*32;
static int CellWidth, CellHeight;
static int CurrentTest = 0;
static int HaveShadow = 0;
static int HaveShadowAmbient = 0;
static int HaveShadowFuncs = 0;
static GLuint Textures[2]; /* tex0: loaded via TexImage; tex1: loaded via CopyTexImage */
static void CreateRenderedTexture()
{
glViewport(0, 0, COLS*4, ROWS*4);
glClearColor(0.5, 0.5, 0.0, 0.25);
glClearDepth(0.25);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glBegin(GL_QUADS);
glVertex3f(0.25, 0.25, 0.75);
glVertex3f(0.75, 0.25, 0.75);
glVertex3f(0.75, 0.75, 0.75);
glVertex3f(0.25, 0.75, 0.75);
glEnd();
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, Textures[1]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
0, 0, 4, 4, 0);
}
/**
* Verify whether the given cell contains the color that is consistent
* with a depth texture result of \p value in the given depth texture mode.
*/
static int probe_cell_depth_mode(int cellx, int celly, int depth_texture_mode, float value)
{
float expected[4] = { 1.0, 1.0, 1.0, 1.0 };
switch(depth_texture_mode) {
case GL_INTENSITY:
expected[3] = value;
/* fall through */
case GL_LUMINANCE:
expected[0] = value;
expected[1] = value;
expected[2] = value;
break;
case GL_ALPHA:
/* Note: alpha values v are translated into RGBA (0,0,0,v),
* but texture environments ignore the RGB component for alpha
* textures, so in the end we're back to RGB being white */
expected[3] = value;
break;
}
return piglit_probe_pixel_rgba(
cellx*CellWidth + (CellWidth/2), celly*CellHeight + (CellHeight/2),
expected);
}
/**
* Render the depth textures directly, without any texture comparisons.
*/
static int test_RenderTextures(int param)
{
int succ = 1;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, param);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(1,0);
glVertex2f(4,0);
glTexCoord2f(1,1);
glVertex2f(4,4);
glTexCoord2f(0,1);
glVertex2f(0,4);
glEnd();
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glBindTexture(GL_TEXTURE_2D, Textures[1]);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, param);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(4,0);
glTexCoord2f(1,0);
glVertex2f(8,0);
glTexCoord2f(1,1);
glVertex2f(8,4);
glTexCoord2f(0,1);
glVertex2f(4,4);
glEnd();
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glDisable(GL_TEXTURE_2D);
/* Note: Report only the first failed probe */
succ = succ && probe_cell_depth_mode(0, 0, param, 0.0);
succ = succ && probe_cell_depth_mode(2, 0, param, 0.25);
succ = succ && probe_cell_depth_mode(0, 2, param, 0.5);
succ = succ && probe_cell_depth_mode(2, 2, param, 1.0);
succ = succ && probe_cell_depth_mode(4, 0, param, 0.25);
succ = succ && probe_cell_depth_mode(4, 1, param, 0.25);
succ = succ && probe_cell_depth_mode(4, 2, param, 0.25);
succ = succ && probe_cell_depth_mode(4, 3, param, 0.25);
succ = succ && probe_cell_depth_mode(5, 0, param, 0.25);
succ = succ && probe_cell_depth_mode(5, 1, param, 0.75);
succ = succ && probe_cell_depth_mode(5, 2, param, 0.75);
succ = succ && probe_cell_depth_mode(5, 3, param, 0.25);
succ = succ && probe_cell_depth_mode(6, 0, param, 0.25);
succ = succ && probe_cell_depth_mode(6, 1, param, 0.75);
succ = succ && probe_cell_depth_mode(6, 2, param, 0.75);
succ = succ && probe_cell_depth_mode(6, 3, param, 0.25);
succ = succ && probe_cell_depth_mode(7, 0, param, 0.25);
succ = succ && probe_cell_depth_mode(7, 1, param, 0.25);
succ = succ && probe_cell_depth_mode(7, 2, param, 0.25);
succ = succ && probe_cell_depth_mode(7, 3, param, 0.25);
return succ;
}
static float texture_compare(int comparefunc, float r, float texture, float ambient)
{
int test;
switch(comparefunc) {
case GL_NEVER: test = 0; break;
case GL_LESS: test = r < texture; break;
case GL_LEQUAL: test = r <= texture; break;
case GL_EQUAL: test = r == texture; break;
case GL_NOTEQUAL: test = r != texture; break;
case GL_GEQUAL: test = r >= texture; break;
case GL_GREATER: test = r > texture; break;
case GL_ALWAYS: test = 1; break;
}
return test ? 1.0 : ambient;
}
static int test_worker(int comparefunc, float ambient)
{
int succ;
if (!HaveShadow)
return 1;
if (!HaveShadowFuncs && (comparefunc != GL_LEQUAL && comparefunc != GL_GEQUAL))
return 1;
if (!HaveShadowAmbient && ambient > 0.0)
return 1;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, comparefunc);
if (ambient > 0.0)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, ambient);
glBegin(GL_QUADS);
glTexCoord3f(0,0,0.6);
glVertex2f(0,0);
glTexCoord3f(1,0,0.6);
glVertex2f(4,0);
glTexCoord3f(1,1,0.6);
glVertex2f(4,4);
glTexCoord3f(0,1,0.6);
glVertex2f(0,4);
glEnd();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
if (ambient > 0.0)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.0);
glBindTexture(GL_TEXTURE_2D, Textures[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, comparefunc);
if (ambient > 0.0)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, ambient);
glBegin(GL_QUADS);
glTexCoord3f(0.0,0.0,0.2);
glVertex2f(4,0);
glTexCoord3f(0.5,0.0,0.2);
glVertex2f(6,0);
glTexCoord3f(0.5,0.5,0.2);
glVertex2f(6,2);
glTexCoord3f(0.0,0.5,0.2);
glVertex2f(4,2);
glTexCoord3f(0.5,0.0,0.5);
glVertex2f(6,0);
glTexCoord3f(1.0,0.0,0.5);
glVertex2f(8,0);
glTexCoord3f(1.0,0.5,0.5);
glVertex2f(8,2);
glTexCoord3f(0.5,0.5,0.5);
glVertex2f(6,2);
glTexCoord3f(0.0,0.5,0.8);
glVertex2f(4,2);
glTexCoord3f(0.5,0.5,0.8);
glVertex2f(6,2);
glTexCoord3f(0.5,1.0,0.8);
glVertex2f(6,4);
glTexCoord3f(0.0,1.0,0.8);
glVertex2f(4,4);
glEnd();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
if (ambient > 0.0)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.0);
glDisable(GL_TEXTURE_2D);
succ = succ && probe_cell_depth_mode(0, 0, GL_LUMINANCE, texture_compare(comparefunc, 0.6, 0.0, ambient));
succ = succ && probe_cell_depth_mode(2, 0, GL_LUMINANCE, texture_compare(comparefunc, 0.6, 0.25, ambient));
succ = succ && probe_cell_depth_mode(0, 2, GL_LUMINANCE, texture_compare(comparefunc, 0.6, 0.5, ambient));
succ = succ && probe_cell_depth_mode(2, 2, GL_LUMINANCE, texture_compare(comparefunc, 0.6, 1.0, ambient));
succ = succ && probe_cell_depth_mode(4, 0, GL_LUMINANCE, texture_compare(comparefunc, 0.2, 0.25, ambient));
succ = succ && probe_cell_depth_mode(5, 1, GL_LUMINANCE, texture_compare(comparefunc, 0.2, 0.75, ambient));
succ = succ && probe_cell_depth_mode(6, 0, GL_LUMINANCE, texture_compare(comparefunc, 0.5, 0.25, ambient));
succ = succ && probe_cell_depth_mode(6, 1, GL_LUMINANCE, texture_compare(comparefunc, 0.5, 0.75, ambient));
succ = succ && probe_cell_depth_mode(4, 3, GL_LUMINANCE, texture_compare(comparefunc, 0.8, 0.25, ambient));
succ = succ && probe_cell_depth_mode(5, 2, GL_LUMINANCE, texture_compare(comparefunc, 0.8, 0.75, ambient));
return succ;
}
static int test_BasicShadow(int comparefunc)
{
return test_worker(comparefunc, 0.0);
}
static int test_AmbientShadow(int comparefunc)
{
return test_worker(comparefunc, 0.4);
}
struct test_step {
int (*func)(int);
int param;
const char* name;
};
static struct test_step Tests[] = {
{ test_RenderTextures, GL_LUMINANCE, "Render textures GL_LUMINANCE (no shadow functionality)" },
{ test_RenderTextures, GL_INTENSITY, "Render textures GL_INTENSITY (no shadow functionality)" },
{ test_RenderTextures, GL_ALPHA, "Render textures GL_ALPHA (no shadow functionality)" },
{ test_BasicShadow, GL_NEVER, "EXT_shadow_func: GL_NEVER" },
{ test_BasicShadow, GL_LESS, "EXT_shadow_func: GL_LESS" },
{ test_BasicShadow, GL_LEQUAL, "ARB_shadow: GL_LEQUAL" },
/* don't test GL_EQUAL and GL_NOTEQUAL: they're bound to be unreliable due to precision problems */
{ test_BasicShadow, GL_GEQUAL, "ARB_shadow: GL_GEQUAL" },
{ test_BasicShadow, GL_GREATER, "EXT_shadow_func: GL_GREATER" },
{ test_BasicShadow, GL_ALWAYS, "EXT_shadow_func: GL_ALWAYS" },
{ test_AmbientShadow, GL_NEVER, "Ambient + EXT_shadow_func: GL_NEVER" },
{ test_AmbientShadow, GL_LESS, "Ambient + EXT_shadow_func: GL_LESS" },
{ test_AmbientShadow, GL_LEQUAL, "Ambient + ARB_shadow: GL_LEQUAL" },
/* don't test GL_EQUAL and GL_NOTEQUAL: they're bound to be unreliable due to precision problems */
{ test_AmbientShadow, GL_GEQUAL, "Ambient + ARB_shadow: GL_GEQUAL" },
{ test_AmbientShadow, GL_GREATER, "Ambient + EXT_shadow_func: GL_GREATER" },
{ test_AmbientShadow, GL_ALWAYS, "Ambient + EXT_shadow_func: GL_ALWAYS" },
};
#define NumTests (ARRAY_SIZE(Tests))
static void Display(void)
{
glReadBuffer(GL_BACK);
CreateRenderedTexture();
glViewport(0, 0, Width, Height);
if (Automatic) {
int succ = 1;
int i;
for(i = 0; i < NumTests; ++i) {
glClearColor(0.5, 0.5, 0.0, 0.6);
glClearDepth(0.25);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
succ = Tests[i].func(Tests[i].param);
if (!succ) {
printf("Test failed: '%s'\nSee above for details.\n\n", Tests[i].name);
break;
}
}
piglit_report_result(succ ? PIGLIT_SUCCESS : PIGLIT_FAILURE);
}
glClearColor(0.5, 0.5, 0.0, 0.6);
glClearDepth(0.25);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Tests[CurrentTest].func(Tests[CurrentTest].param);
glutSwapBuffers();
}
static void Reshape(int width, int height)
{
CellWidth = width / COLS;
CellHeight = height / ROWS;
Width = CellWidth*COLS;
Height = CellHeight*ROWS;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, COLS, 0.0, ROWS, 0.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
case 't':
CurrentTest++;
if (CurrentTest >= NumTests)
CurrentTest = 0;
printf("Now showing test: %s\n", Tests[CurrentTest].name);
break;
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
static void init()
{
GLfloat texbuf[4];
int i;
piglit_require_extension("GL_ARB_depth_texture");
HaveShadow = glutExtensionSupported("GL_ARB_shadow");
if (!HaveShadow)
printf("GL_ARB_shadow not supported.\n");
HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient");
if (!HaveShadowAmbient)
printf("GL_ARB_shadow_ambient not supported.\n");
HaveShadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
if (!HaveShadowFuncs)
printf("GL_EXT_shadow_funcs not supported.\n");
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glGenTextures(2, Textures);
glBindTexture(GL_TEXTURE_2D, Textures[0]);
texbuf[0] = 0.0;
texbuf[1] = 0.25;
texbuf[2] = 0.5;
texbuf[3] = 1.0;
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 2, 2, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, texbuf);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, Textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 4, 4, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Reshape(Width,Height);
}
int main(int argc, char**argv)
{
glutInit(&argc, argv);
if (argc == 2 && !strcmp(argv[1], "-auto"))
Automatic = 1;
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(Width, Height);
glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Display);
if (!Automatic)
printf("Press 't' to cycle through test images\n");
init();
glutMainLoop();
return 0;
}
......@@ -23,6 +23,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "GL/glut.h"
#include "piglit-util.h"
/** Returns the line in the program string given the character position. */
......@@ -59,3 +63,36 @@ void piglit_require_extension(const char *name)
exit(1);
}
}
/**
* Read a pixel from the given location and compare its RGBA value to the
* given expected values.
*
* Print a log message if the color value deviates from the expected value.
* \return true if the color values match, false otherwise
*/
int piglit_probe_pixel_rgba(int x, int y, const float* expected)
{
GLfloat probe[4];
GLfloat delta[4];
GLfloat deltamax;
int i;
glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, probe);
deltamax = 0.0;
for(i = 0; i < 4; ++i) {
delta[i] = probe[i] - expected[i];
if (fabs(delta[i]) > deltamax)
deltamax = fabs(delta[i]);
}
if (deltamax < 0.01)
return 1;
printf("Probe at (%i,%i)\n", x, y);
printf(" Expected: %f %f %f %f\n", expected[0], expected[1], expected[2], expected[3]);
printf(" Observed: %f %f %f %f\n", probe[0], probe[1], probe[2], probe[3]);
return 0;
}
......@@ -32,4 +32,4 @@ enum piglit_result {
int FindLine(const char *program, int position);
void piglit_report_result(enum piglit_result result);
void piglit_require_extension(const char *name);
int piglit_probe_pixel_rgba(int x, int y, const float* expected);
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