Commit 1cec2f48 authored by Ian Romanick's avatar Ian Romanick

Execerise conditional write masks in NV_fragment_program_option

parent 2f36c321
......@@ -95,6 +95,7 @@ general['sync_api'] = PlainExecTest([testBinDir + 'sync_api', '-auto'])
shaders = Group()
shaders['trinity-fp1'] = PlainExecTest([testBinDir + 'trinity-fp1', '-auto'])
shaders['fp-condition_codes-01'] = PlainExecTest([testBinDir + 'fp-condition_codes-01', '-auto'])
shaders['fp-fog'] = PlainExecTest([testBinDir + 'fp-fog', '-auto'])
shaders['fp-lit-mask'] = PlainExecTest([testBinDir + 'fp-lit-mask', '-auto'])
shaders['fp-fragment-position'] = PlainExecTest([testBinDir + 'fp-fragment-position', '-auto'])
......
......@@ -24,6 +24,7 @@ link_libraries (
add_definitions ( -DSOURCE_DIR="\\\"${piglit_SOURCE_DIR}/\\\"" )
add_executable (trinity-fp1 trinity-fp1.c)
add_executable (fp-condition_codes-01 fp-condition_codes-01.c)
add_executable (fp-lit-mask fp-lit-mask.c)
add_executable (fp-fog fp-fog.c)
add_executable (fp-fragment-position fp-fragment-position.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-condition_codes-01.c
* Validate that the correct components of the condition code register are
* set to the desired value.
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.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"
/* One for the reference square and one for each possible condition code.
*/
#define TEST_ROWS (1 + 6)
/* One for each possible non-empty write mask.
*/
#define TEST_COLS (15)
#define BOX_SIZE 16
int piglit_WindowMode = GLUT_DOUBLE;
int piglit_Width = (((BOX_SIZE+1)*TEST_ROWS)+1);
int piglit_Height = (((BOX_SIZE+1)*TEST_COLS)+1);
#define INVERT_MASK(x) (~(x) & 0x0f)
static char shader_source[64 * 1024];
/**
* Strings for binary write-masks.
*
* Bit 0 corresponds to X, bit 1 to y, etc.
*/
static const char *const mask_strings[16] = {
"<empty>",
"x",
"y",
"xy",
"z",
"xz",
"yz",
"xyz",
"w",
"xw",
"yw",
"xyw",
"zw",
"xzw",
"yzw",
"xyzw",
};
/**
* Strings for condition codes.
*/
static const char *const cc_strings[6] = {
"EQ",
"GE",
"GT",
"LE",
"LT",
"NE",
};
/**
* Constant values that will set required condition codes
*
* The even values set the parallel condition code in \c cc_strings, and the
* odd values set something else. For example, element 4 sets GT, and element
* 5 does not (it sets LT).
*/
static const GLfloat cc_values[12] = {
0.5, 1.0,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
0.0, 0.5
};
/**
* Source for the fragment program to render the reference box.
*/
static const char reference_shader_source[] =
"!!ARBfp1.0\n"
"MOV result.color, program.env[0];\n"
"END"
;
/**
* \name Handles to fragment programs.
*/
/*@{*/
static GLint reference_prog;
static GLint progs[TEST_ROWS * TEST_COLS];
/*@}*/
void
generate_shader(unsigned cc, unsigned good_mask)
{
unsigned len;
static const char *const swiz[16] = {
"yyyy", "xyyy", "yxyy", "xxyy",
"yyxy", "xyxy", "yxxy", "xxxy",
"yyyx", "xyyx", "yxyx", "xxyx",
"yyxx", "xyxx", "yxxx", "xxxx",
};
len = sprintf(& shader_source[0],
"!!ARBfp1.0\n"
"OPTION NV_fragment_program;\n"
"PARAM good = program.env[0];\n"
"PARAM junk = program.env[1];\n"
"TEMP R0, R1, R2;\n"
"\n"
"# Create a combination of good and bad data in R0.\n"
"MOV R0, junk;\n");
if (good_mask != 0) {
len += sprintf(& shader_source[len],
"MOV R0.%s, good;\n",
mask_strings[good_mask]);
}
len += sprintf(& shader_source[len],
"\n"
"# Set the condition codes. Inputs are on the range\n"
"# [0, 1], so the range must be expanded to [-1, 1].\n"
"MADC R2, fragment.color.%s, 2.0, -1.0;\n"
"\n"
"# Create a combination of good and bad data in R1.\n"
"# The components in R0 that already have good data\n"
"# should have bad data in R1.\n"
"MOV R1, good;\n",
swiz[INVERT_MASK(good_mask)]);
if (good_mask != 0) {
len += sprintf(& shader_source[len],
"MOV R1.%s, junk;\n",
mask_strings[good_mask]);
}
len += sprintf(& shader_source[len],
"\n"
"# Fill remaining bits of R0 with good data from R1.\n"
"# Write that data to the shader output.\n"
"MOV R0 (%s.xyzw), R1;\n"
"MOV result.color, R0;\n"
"END\n",
cc_strings[cc]);
}
int
piglit_Display(void)
{
static const GLfloat good_color[4] = { 0.9, 0.5, 0.7, 1.0 };
static const GLfloat junk_color[4] = { 0.2, 0.2, 0.2, 1.0 };
unsigned i = 0;
unsigned cc;
unsigned mask;
int pass = 1;
glClear(GL_COLOR_BUFFER_BIT);
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
0, good_color);
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
1, junk_color);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, reference_prog);
piglit_draw_rect(1, 1, BOX_SIZE, BOX_SIZE);
for (cc = 0; cc < 6; cc++) {
glColor4f(cc_values[(cc * 2) + 0], cc_values[(cc * 2) + 1],
0.0, 1.0);
for (mask = 0; mask < 0x0f; mask++) {
const int x = ((cc + 1) * (BOX_SIZE + 1)) + 1;
const int y = (mask * (BOX_SIZE + 1)) + 1;
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, progs[i]);
piglit_draw_rect(x, y, BOX_SIZE, BOX_SIZE);
i++;
if (!piglit_probe_pixel_rgb(x + (BOX_SIZE / 2),
y + (BOX_SIZE / 2),
good_color)) {
if (!piglit_Automatic)
printf("CC %s with mask %s failed.\n",
cc_strings[cc],
mask_strings[mask]);
pass = 0;
}
}
}
glutSwapBuffers();
return pass;
}
void
piglit_Init(int argc, char **argv)
{
unsigned cc;
unsigned mask;
unsigned i;
(void) argc;
(void) argv;
piglit_require_fragment_program();
piglit_require_extension("GL_NV_fragment_program_option");
piglit_ortho_projection(piglit_Width, piglit_Height, GL_FALSE);
reference_prog = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB,
reference_shader_source);
i = 0;
for (cc = 0; cc < 6; cc++) {
for (mask = 0; mask < 0x0f; mask++) {
generate_shader(cc, mask);
progs[i] =
piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB,
shader_source);
i++;
}
}
}
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