Add more structure constructor tests.
[piglit/hramrach.git] / tests / shaders / vp-address-04.c
blob93787d3d84d097ac7f76d5818d504732a5ef72dc
1 /*
2 * Copyright © 2009 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 /**
25 * \file vp-address-04.c
26 * Validate vectored address registers with various constant offsets.
28 * This is something of a combination of vp-address-02 and vp-address-03.
29 * GL_NV_vertex_program2_option requires at least two address registers. Base
30 * GL_ARB_vertex_program implementations can also support more than one, but
31 * only one is required.
33 * \author Ian Romanick <ian.d.romanick@intel.com>
36 #include "piglit-util.h"
37 #include "piglit-framework.h"
39 static const GLfloat attrib[] = {
40 0.0, 0.0,
41 0.0, 1.0,
42 0.0, 2.0,
43 0.0, -1.0,
44 0.0, -2.0,
46 1.0, 0.0,
47 1.0, 1.0,
48 1.0, 2.0,
49 1.0, -1.0,
50 1.0, -2.0,
52 2.0, 0.0,
53 2.0, 1.0,
54 2.0, 2.0,
55 2.0, -1.0,
56 2.0, -2.0,
58 -1.0, 0.0,
59 -1.0, 1.0,
60 -1.0, 2.0,
61 -1.0, -1.0,
62 -1.0, -2.0,
64 -2.0, 0.0,
65 -2.0, 1.0,
66 -2.0, 2.0,
67 -2.0, -1.0,
68 -2.0, -2.0,
71 #define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
73 #define TEST_ROWS 16
74 #define TEST_COLS (ELEMENTS(attrib) / 2)
75 #define BOX_SIZE 16
78 int piglit_window_mode = GLUT_DOUBLE;
79 int piglit_width = (((BOX_SIZE+1)*TEST_COLS)+1);
80 int piglit_height = (((BOX_SIZE+1)*TEST_ROWS)+1);
83 static const char vertex_source_template[] =
84 "!!ARBvp1.0\n"
85 "OPTION NV_vertex_program2;\n"
86 "PARAM colors[] = { program.env[0..3] };\n"
87 "ADDRESS A0, A1;\n"
88 "\n"
89 "ARL A0, vertex.attrib[1];\n"
90 "ARL A1, vertex.attrib[2];\n"
91 "ADD result.color, colors[A0.%c %c %u], colors[A1.%c %c %u];\n"
92 PIGLIT_VERTEX_PROGRAM_MVP_TRANSFORM
93 "END\n"
97 /**
98 * \name Handles to programs.
100 /*@{*/
101 static GLint progs[TEST_COLS * TEST_ROWS];
102 /*@}*/
105 static void generate_shader_source(char *source, size_t source_len,
106 unsigned component_mask, const GLfloat *attr);
109 static void
110 set_attribute(unsigned component, GLuint index, GLfloat value)
112 GLfloat v[4];
114 /* Set all of the components to something invalid. Then set one
115 * component to the desried, valid value.
117 v[0] = -value;
118 v[1] = -value;
119 v[2] = -value;
120 v[3] = -value;
121 v[component] = value;
123 glVertexAttrib4fvARB(index, v);
127 enum piglit_result
128 piglit_display(void)
130 static const GLfloat color[4] = { 0.0, 0.5, 0.0, 0.5 };
131 static const GLfloat good_color[4] = { 0.0, 1.0, 0.0, 1.0 };
132 static const GLfloat bad_color[4] = { 1.0, 0.0, 0.0, 1.0 };
133 enum piglit_result result = PIGLIT_SUCCESS;
134 unsigned i;
135 unsigned j;
137 glClear(GL_COLOR_BUFFER_BIT);
139 glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 0, bad_color);
140 glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 1, color);
141 glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 2, bad_color);
142 glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 3, bad_color);
144 for (i = 0; i < TEST_ROWS; i++) {
145 const int y = 1 + (i * (BOX_SIZE + 1));
147 for (j = 0; j < TEST_COLS; j++) {
148 const int x = 1 + (j * (BOX_SIZE + 1));
149 const unsigned idx = (i * TEST_COLS) + j;
151 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, progs[idx]);
153 set_attribute( i & 0x03, 1, attrib[(j * 2) + 0]);
154 set_attribute((i >> 2) & 0x03, 2, attrib[(j * 2) + 1]);
156 piglit_draw_rect(x, y, BOX_SIZE, BOX_SIZE);
158 if (!piglit_probe_pixel_rgb(x + (BOX_SIZE / 2),
159 y + (BOX_SIZE / 2),
160 good_color)) {
161 if (! piglit_automatic) {
162 char src[1024];
163 generate_shader_source(src,
164 sizeof(src),
166 & attrib[j * 2]);
168 printf("shader %u failed with "
169 "attributes %.1f, %.1f:\n%s\n",
170 idx,
171 attrib[(j * 2) + 0],
172 attrib[(j * 2) + 1],
173 src);
176 result = PIGLIT_FAILURE;
181 glutSwapBuffers();
182 return result;
186 void
187 generate_shader_source(char *source, size_t source_len, unsigned component_mask,
188 const GLfloat *attr)
190 static const char components[] = "xyzw";
191 char comp[2];
192 int offset[2];
193 char direction[2];
195 comp[0] = components[component_mask & 0x03];
196 comp[1] = components[(component_mask >> 2) & 0x03];
198 /* We want the constant offset in the instruction plus
199 * the value read from the attribute to be 1.
201 offset[0] = 1 - (int) attr[0];
202 offset[1] = 1 - (int) attr[1];
204 if (offset[0] < 0) {
205 direction[0] = '-';
206 offset[0] = -offset[0];
207 } else {
208 direction[0] = '+';
211 if (offset[1] < 0) {
212 direction[1] = '-';
213 offset[1] = -offset[1];
214 } else {
215 direction[1] = '+';
218 snprintf(source, source_len, vertex_source_template,
219 comp[0], direction[0], offset[0],
220 comp[1], direction[1], offset[1]);
224 void
225 piglit_init(int argc, char **argv)
227 GLint max_address_registers;
228 unsigned i;
229 unsigned j;
231 (void) argc;
232 (void) argv;
234 piglit_require_vertex_program();
235 piglit_require_fragment_program();
236 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
238 glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
239 GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB,
240 & max_address_registers);
241 if (max_address_registers == 0) {
242 /* we have to have at least one address register */
243 if (! piglit_automatic)
244 printf("GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB == 0\n");
246 piglit_report_result(PIGLIT_FAILURE);
247 } else if (max_address_registers == 1) {
248 if (glutExtensionSupported("GL_NV_vertex_program2_option")) {
249 /* this extension requires two address regs */
250 if (! piglit_automatic)
251 printf("GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB "
252 "== 1\n");
254 piglit_report_result(PIGLIT_FAILURE);
255 } else {
256 piglit_report_result(PIGLIT_SKIP);
260 for (i = 0; i < TEST_ROWS; i++) {
261 for (j = 0; j < TEST_COLS; j++) {
262 char shader_source[1024];
263 const unsigned idx = (i * TEST_COLS) + j;
266 generate_shader_source(shader_source,
267 sizeof(shader_source),
269 &attrib[2 * j]);
270 progs[idx] =
271 piglit_compile_program(GL_VERTEX_PROGRAM_ARB,
272 shader_source);
276 glEnable(GL_FRAGMENT_PROGRAM_ARB);
277 glEnable(GL_VERTEX_PROGRAM_ARB);
278 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, piglit_ARBfp_pass_through);
280 glClearColor(0.5, 0.5, 0.5, 1.0);