Commit fd4dbea9 authored by Ian Romanick's avatar Ian Romanick

fp-rfl: Test RFL instruction from GL_NV_fragment_program_option.

parent f849d2d6
......@@ -103,6 +103,7 @@ 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['fp-rfl'] = PlainExecTest([testBinDir + 'fp-rfl', '-auto'])
shaders['fp-set-01'] = PlainExecTest([testBinDir + 'fp-set-01', '-auto'])
shaders['fp-unpack-01'] = PlainExecTest([testBinDir + 'fp-unpack-01', '-auto'])
shaders['glsl-bug-22603'] = PlainExecTest([testBinDir + 'glsl-bug-22603', '-auto'])
......
......@@ -33,6 +33,7 @@ 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 (fp-rfl fp-rfl.c)
add_executable (fp-set-01 fp-set-01.c)
add_executable (fp-unpack-01 fp-unpack-01.c)
add_executable (glsl-bug-22603 glsl-bug-22603.c)
......
/*
* Copyright © 2009 Intel Corporation
*
* 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.
*/
/**
* \file fp-rfl.c
* Validate the RFL instruction in GL_NV_fragment_program_option.
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <assert.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 BOX_SIZE 8
/* As many columns as will fit in 640.
*/
#define TEST_COLS ((640 - 1) / (BOX_SIZE + 1))
/* As many rows as will fit in 400.
*/
#define TEST_ROWS ((400 - 1) / (BOX_SIZE + 1))
int piglit_WindowMode = GLUT_DOUBLE;
int piglit_Width = (((BOX_SIZE + 1) * TEST_COLS)+1);
int piglit_Height = (((BOX_SIZE + 1) * TEST_ROWS)+1);
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
static const char vert_shader_source[] =
"!!ARBvp1.0\n"
"ATTRIB iPos = vertex.position;\n"
"OUTPUT oPos = result.position;\n"
"PARAM mvp[4] = { state.matrix.mvp };\n"
"DP4 oPos.x, mvp[0], iPos;\n"
"DP4 oPos.y, mvp[1], iPos;\n"
"DP4 oPos.z, mvp[2], iPos;\n"
"DP4 oPos.w, mvp[3], iPos;\n"
"MOV result.texcoord[0], vertex.attrib[1];\n"
"MOV result.texcoord[1], vertex.attrib[2];\n"
"END"
;
static const char frag_shader_source[] =
"!!ARBfp1.0\n"
#if 1
"OPTION NV_fragment_program;\n"
"TEMP tmp, axis, direction;\n"
"\n"
"# Since we're calcuating per-fragment and the parameters are\n"
"# interpolated, the parameters must be normalized.\n"
"DP3 tmp.x, fragment.texcoord[0], fragment.texcoord[0];\n"
"DP3 tmp.y, fragment.texcoord[1], fragment.texcoord[1];\n"
"RCP tmp.x, tmp.x;\n"
"RCP tmp.y, tmp.y;\n"
"MUL axis, tmp.x, fragment.texcoord[0];\n"
"MUL direction, tmp.y, fragment.texcoord[1];\n"
"RFL result.color, fragment.texcoord[0], fragment.texcoord[1];\n"
#else
"TEMP tmp, axis, direction;\n"
"DP3 tmp.x, fragment.texcoord[0], fragment.texcoord[0];\n"
"DP3 tmp.y, fragment.texcoord[1], fragment.texcoord[1];\n"
"RCP tmp.x, tmp.x;\n"
"RCP tmp.y, tmp.y;\n"
"MUL axis, tmp.x, fragment.texcoord[0];\n"
"MUL direction, tmp.y, fragment.texcoord[1];\n"
/* This is the open-coded version of the RFL instruction. It was used
* during the development of the test. Since it maybe useful in future
* debugging, I am leaving it in.
*/
"DP3 tmp.w, axis, axis;\n"
"DP3 tmp.x, axis, direction;\n"
"MUL tmp.x, 2.0.x, tmp.x;\n"
"RCP tmp.w, tmp.w;\n"
"MUL tmp.x, tmp.x, tmp.w;\n"
"MAD result.color.xyz, tmp.xxxx, axis, -direction;\n"
"MOV result.color.w, {0.0};\n"
#endif
"END"
;
/**
* \name Handles to programs.
*/
/*@{*/
static GLint vert_prog;
static GLint frag_prog;
/*@}*/
static GLfloat direction[4 * TEST_ROWS * TEST_COLS];
static GLfloat axis[4 * TEST_ROWS * TEST_COLS];
static GLfloat position[4 * TEST_ROWS * TEST_COLS];
static const float green[4] = { 0.0, 1.0, 0.0, 0.0 };
int
piglit_Display(void)
{
int result = PIGLIT_SUCCESS;
unsigned r;
unsigned c;
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glEnable(GL_VERTEX_PROGRAM_ARB);
glVertexAttribPointerARB(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat),
position);
glVertexAttribPointerARB(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat),
axis);
glVertexAttribPointerARB(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat),
direction);
glEnableVertexAttribArrayARB(0);
glEnableVertexAttribArrayARB(1);
glEnableVertexAttribArrayARB(2);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vert_prog);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_prog);
glPointSize((float) BOX_SIZE);
glDrawArrays(GL_POINTS, 0, TEST_ROWS * TEST_COLS);
for (r = 0; r < TEST_ROWS; r++) {
for (c = 0; c < TEST_COLS; c++) {
const int idx = 4 * ((r * TEST_COLS) + c);
if (!piglit_probe_pixel_rgb(position[idx + 0],
position[idx + 1],
green)) {
printf("direction = { %.2f %.2f %.2f }\n"
"axis = { %.2f %.2f %.2f }\n",
direction[idx + 0],
direction[idx + 1],
direction[idx + 2],
axis[idx + 0],
axis[idx + 1],
axis[idx + 2]);
}
}
}
glutSwapBuffers();
return result;
}
double
random_float(void)
{
return (double) random() / (double) random();
}
void
piglit_Init(int argc, char **argv)
{
unsigned r;
unsigned c;
unsigned i;
(void) argc;
(void) argv;
piglit_require_vertex_program();
piglit_require_fragment_program();
piglit_require_extension("GL_NV_fragment_program_option");
piglit_ortho_projection(piglit_Width, piglit_Height, GL_FALSE);
vert_prog = piglit_compile_program(GL_VERTEX_PROGRAM_ARB,
vert_shader_source);
frag_prog = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB,
frag_shader_source);
glClearColor(0.5, 0.5, 0.5, 1.0);
i = 0;
for (r = 0; r < TEST_ROWS; r++) {
for (c = 0; c < TEST_COLS; c++) {
position[i + 0] = (float)((BOX_SIZE / 2) + c *
(BOX_SIZE + 1) + 1);
position[i + 1] = (float)((BOX_SIZE / 2) + r *
(BOX_SIZE + 1) + 1);
position[i + 2] = 0.0f;
position[i + 3] = 1.0f;
i += 4;
}
}
/* Generate a bunch of random direction vectors. Based on the random
* direction vector, generate an axis such that the reflection of the
* random vector across the axis is { 0, 1, 0 }.
*/
srandom(time(NULL));
for (i = 0; i < (ELEMENTS(direction) / 4); i++) {
const double d[3] = {
random_float(),
random_float(),
random_float()
};
const double inv_mag_d = 1.0 /
sqrt((d[0] * d[0]) + (d[1] * d[1]) + (d[2] * d[2]));
double a[3];
double mag_a;
direction[(i * 4) + 0] = d[0] * inv_mag_d;
direction[(i * 4) + 1] = d[1] * inv_mag_d;
direction[(i * 4) + 2] = d[2] * inv_mag_d;
direction[(i * 4) + 3] = 0.0;
a[0] = direction[(i * 4) + 0] + 0.0;
a[1] = direction[(i * 4) + 1] + 1.0;
a[2] = direction[(i * 4) + 2] + 0.0;
mag_a = sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2]));
axis[(i * 4) + 0] = a[0] / mag_a;
axis[(i * 4) + 1] = a[1] / mag_a;
axis[(i * 4) + 2] = a[2] / mag_a;
axis[(i * 4) + 3] = 0.0;
}
}
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