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
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
24 * Nicolai Hähnle <nhaehnle@gmail.com>
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)
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);
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();
69 p
[2] = (r
>> 10) & 31;
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(
102 unsigned int x
, unsigned int y
, unsigned int z
,
108 for(i
= 0; i
< hops
; ++i
) {
116 p
= texture_data
+ z
*TEXTURE_SIZE
*TEXTURE_SIZE
*3 + y
*TEXTURE_SIZE
*3 + x
*3;
122 expected
[0] = (x
+ 0.5) / 32.0;
123 expected
[1] = (y
+ 0.5) / 32.0;
124 expected
[2] = (z
+ 0.5) / 32.0;
130 static const char program_Head
[] =
135 static const char program_TEX
[] =
136 "TEX %s, %s, texture[0], %iD;\n";
138 static const char program_MOV
[] =
141 static const char program_Tail
[] =
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
));
154 GLuint program_object
;
155 unsigned int draw_height
;
158 strcpy(program_text
, program_Head
);
160 snprintf(buf
, sizeof(buf
), program_MOV
, program_Output
, program_Input
);
161 strcat(program_text
, buf
);
163 const char * input
= program_Input
;
165 for(i
= 1; i
<= samples
; ++i
) {
166 const char * output
= "r";
168 output
= program_Output
;
169 snprintf(buf
, sizeof(buf
), program_TEX
, output
, input
, dim
);
170 strcat(program_text
, buf
);
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
) {
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
;
204 enum piglit_result result
;
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
) {
214 result
= test(dim
, samples
);
215 if (result
!= PIGLIT_SUCCESS
)
220 } else if (samples
< max_samples
) {
222 if (samples
> max_samples
)
223 samples
= max_samples
;
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
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)