Add more structure constructor tests.
[piglit/hramrach.git] / tests / shaders / fp-indirections2.c
blob0c56fb15ed5def51f7967ce2804e6c0830136e06
1 /*
2 * Copyright (c) 2009 Nicolai Hähnle
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.
23 * Authors:
24 * Nicolai Hähnle <nhaehnle@gmail.com>
28 /**
29 * \file
30 * Whereas fp-indirections tests that the native indirection limits are
31 * reported essentially correctly, this test actually exercises multiple
32 * indirection counts up to the reported native limit.
35 #include "piglit-util.h"
36 #include "piglit-framework.h"
38 #define TEXTURE_SIZE 32 /* Note: Hardcoded dependencies in texture_init and texture_follow */
40 int piglit_window_mode = GLUT_RGBA;
41 int piglit_width = TEXTURE_SIZE;
42 int piglit_height = TEXTURE_SIZE;
44 unsigned int max_samples;
45 unsigned char * texture_data;
46 unsigned char * texture_data_as_rgba;
47 GLuint texture_objects[3];
50 static void texture_init(void)
52 unsigned int x, y, z;
53 unsigned char *p;
54 unsigned char *q;
56 srand(0x12345678); /* we want repeatable test runs */
58 texture_data = malloc(TEXTURE_SIZE * TEXTURE_SIZE * TEXTURE_SIZE * 3);
59 texture_data_as_rgba = malloc(TEXTURE_SIZE * TEXTURE_SIZE * TEXTURE_SIZE * 4);
61 p = texture_data;
62 q = texture_data_as_rgba;
63 for(z = 0; z < TEXTURE_SIZE; ++z) {
64 for(y = 0; y < TEXTURE_SIZE; ++y) {
65 for(x = 0; x < TEXTURE_SIZE; ++x) {
66 unsigned int r = rand();
67 p[0] = r & 31;
68 p[1] = (r >> 5) & 31;
69 p[2] = (r >> 10) & 31;
71 q[0] = p[0] * 8 + 4;
72 q[1] = p[1] * 8 + 4;
73 q[2] = p[2] * 8 + 4;
74 q[3] = 0xff;
76 p += 3;
77 q += 4;
82 glGenTextures(3, texture_objects);
84 glBindTexture(GL_TEXTURE_1D, texture_objects[0]);
85 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
86 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
87 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data_as_rgba);
89 glBindTexture(GL_TEXTURE_2D, texture_objects[1]);
90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
91 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
92 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data_as_rgba);
94 glBindTexture(GL_TEXTURE_3D, texture_objects[2]);
95 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
96 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
97 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, TEXTURE_SIZE, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data_as_rgba);
100 static void texture_follow(
101 unsigned int dim,
102 unsigned int x, unsigned int y, unsigned int z,
103 unsigned int hops,
104 float * expected)
106 unsigned int i;
108 for(i = 0; i < hops; ++i) {
109 unsigned char * p;
111 if (dim < 3)
112 z = 0;
113 if (dim < 2)
114 y = 0;
116 p = texture_data + z*TEXTURE_SIZE*TEXTURE_SIZE*3 + y*TEXTURE_SIZE*3 + x*3;
117 x = p[0];
118 y = p[1];
119 z = p[2];
122 expected[0] = (x + 0.5) / 32.0;
123 expected[1] = (y + 0.5) / 32.0;
124 expected[2] = (z + 0.5) / 32.0;
126 if (!hops)
127 expected[2] = 0.0;
130 static const char program_Head[] =
131 "!!ARBfp1.0\n"
132 "TEMP r;\n"
135 static const char program_TEX[] =
136 "TEX %s, %s, texture[0], %iD;\n";
138 static const char program_MOV[] =
139 "MOV %s, %s;\n";
141 static const char program_Tail[] =
142 "END\n";
144 static const char program_Input[] = "fragment.texcoord[0]";
145 static const char program_Output[] = "result.color";
147 static enum piglit_result test(unsigned int dim, unsigned int samples)
149 char * program_text = malloc(sizeof(program_Head) +
150 (samples + 1)*sizeof(program_TEX) +
151 sizeof(program_Tail) +
152 sizeof(program_Input) + sizeof(program_Output));
153 char buf[128];
154 GLuint program_object;
155 unsigned int draw_height;
156 unsigned int x, y;
158 strcpy(program_text, program_Head);
159 if (!samples) {
160 snprintf(buf, sizeof(buf), program_MOV, program_Output, program_Input);
161 strcat(program_text, buf);
162 } else {
163 const char * input = program_Input;
164 unsigned int i;
165 for(i = 1; i <= samples; ++i) {
166 const char * output = "r";
167 if (i == samples)
168 output = program_Output;
169 snprintf(buf, sizeof(buf), program_TEX, output, input, dim);
170 strcat(program_text, buf);
171 input = output;
174 strcat(program_text, program_Tail);
176 program_object = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB, program_text);
178 glEnable(GL_FRAGMENT_PROGRAM_ARB);
179 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_object);
181 draw_height = TEXTURE_SIZE;
182 piglit_draw_rect_tex(0, 0, TEXTURE_SIZE, draw_height, 0, 0, 1, 1);
184 glDisable(GL_FRAGMENT_PROGRAM_ARB);
185 glDeleteProgramsARB(1, &program_object);
187 for(y = 0; y < draw_height; ++y) {
188 for(x = 0; x < TEXTURE_SIZE; ++x) {
189 float expected[3];
190 texture_follow(dim, x, y, 0, samples, expected);
191 if (!piglit_probe_pixel_rgb(x, y, expected)) {
192 fprintf(stderr, "Failure in dim = %i, samples = %i\n", dim, samples);
193 return PIGLIT_FAILURE;
198 return PIGLIT_SUCCESS;
201 enum piglit_result
202 piglit_display(void)
204 enum piglit_result result;
205 unsigned int dim;
206 unsigned int samples;
208 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
209 glClear(GL_COLOR_BUFFER_BIT);
211 for(dim = 1; dim <= 3; ++dim) {
212 samples = 0;
213 for(;;) {
214 result = test(dim, samples);
215 if (result != PIGLIT_SUCCESS)
216 return result;
218 if (samples < 8) {
219 samples++;
220 } else if (samples < max_samples) {
221 samples *= 2;
222 if (samples > max_samples)
223 samples = max_samples;
224 } else {
225 break;
230 return PIGLIT_SUCCESS;
234 void piglit_init(int argc, char ** argv)
236 GLint max_native_tex_instructions;
237 GLint max_native_tex_indirections;
239 piglit_require_fragment_program();
241 glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
242 GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB,
243 &max_native_tex_instructions);
244 glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
245 GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB,
246 &max_native_tex_indirections);
248 printf("Max TEX instructions / TEX indirections: %i / %i\n",
249 max_native_tex_instructions,
250 max_native_tex_indirections);
252 max_samples = max_native_tex_indirections;
253 if (max_samples > max_native_tex_instructions) {
254 /* ARB_fragment_program, issue 24:
255 * For implementations with no restrictions on the number of indirections,
256 * the maximum indirection count will equal the maximum texture instruction
257 * count.
259 fprintf(stderr, "Violation of ARB_fragment_program issue 24: TEX indirections > TEX instructions\n");
260 max_samples = max_native_tex_instructions;
263 if (max_samples > 1024)
264 max_samples = 1024;
266 texture_init();