2 * Permission is hereby granted, free of charge, to any person obtaining a
3 * copy of this software and associated documentation files (the "Software"),
4 * to deal in the Software without restriction, including without limitation
5 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
6 * and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
9 * The above copyright notice and this permission notice (including the next
10 * paragraph) shall be included in all copies or substantial portions of the
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * Marek Olšák <maraeo@gmail.com>
26 * Tests that binding the maximum number of textures in both the vertex and
27 * fragment shader works.
31 #include "piglit-util-gl.h"
33 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config
.supports_gl_compat_version
= 20;
37 config
.window_width
= 300;
38 config
.window_height
= 300;
39 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
40 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
42 PIGLIT_GL_TEST_CONFIG_END
44 static const char *vs_source
=
46 "uniform sampler2D vertex_tex[NUM]; \n"
47 "uniform int vertex_index;"
48 "varying vec3 vertex_tex_color; \n"
52 " gl_Position = gl_Vertex; \n"
53 " vertex_tex_color = vec3(0.0); \n"
54 " for (i = 0; i < NUM; i++) \n"
55 " if (i == vertex_index) \n"
56 " vertex_tex_color = texture2DLod(vertex_tex[i], vec2(%f), 0.0).xyz; \n"
59 static const char *vs_source_no_textures
=
60 "varying vec3 vertex_tex_color; \n"
63 " gl_Position = gl_Vertex; \n"
64 " vertex_tex_color = vec3(0.0); \n"
67 static const char *fs_source
=
69 "uniform sampler2D fragment_tex[NUM]; \n"
70 "uniform int fragment_index;"
71 "varying vec3 vertex_tex_color; \n"
75 " vec3 fragment_tex_color = vec3(0.0); \n"
76 " for (i = 0; i < NUM; i++) \n"
77 " if (i == fragment_index) \n"
78 " fragment_tex_color = texture2D(fragment_tex[i], vec2(%f), 0.0).xyz; \n"
79 " gl_FragColor = vec4(fragment_tex_color + vertex_tex_color, 1.0); \n"
83 static int max_vs_textures
, max_fs_textures
;
86 get_texture_color(int unit
, float out
[4])
88 out
[0] = (unit
% 16) / 15.0;
89 out
[1] = (unit
/ 16) / 15.0;
95 set_uniform(GLuint prog
, const char *name
, int value
)
97 GLuint loc
= glGetUniformLocation(prog
, name
);
99 glUniform1i(loc
, value
);
103 draw_rect_core(int ix
, int iy
, int iw
, int ih
)
105 float x
= -1 + 2.0*ix
/piglit_width
;
106 float y
= -1 + 2.0*iy
/piglit_height
;
107 float w
= 2.0*iw
/piglit_width
;
108 float h
= 2.0*ih
/piglit_height
;
129 glGenBuffers(1, &vbo
);
130 glBindBuffer(GL_ARRAY_BUFFER
, vbo
);
131 glBufferData(GL_ARRAY_BUFFER
, sizeof(verts
), verts
, GL_STATIC_DRAW
);
133 glEnableVertexAttribArray(0);
134 glVertexAttribPointer(0, 4, GL_FLOAT
, GL_FALSE
, 0, NULL
);
136 glDrawArrays(GL_TRIANGLE_FAN
, 0, 4);
138 glDisableVertexAttribArray(0);
139 glDeleteBuffers(1, &vbo
);
143 probe_pixel(int unit
, int x
, int y
)
147 get_texture_color(unit
, expected
);
149 if (piglit_probe_pixel_rgb(x
, y
, expected
))
152 printf(" When testing texture unit %i\n", unit
);
159 GLboolean pass
= GL_TRUE
;
162 glClear(GL_COLOR_BUFFER_BIT
);
168 set_uniform(prog
, "fragment_index", max_fs_textures
);
169 for (i
= 0; i
< max_vs_textures
; i
++) {
170 set_uniform(prog
, "vertex_index", i
);
171 draw_rect_core(x
, y
, 20, 20);
172 pass
= probe_pixel(unit
, x
+10, y
+10) && pass
;
176 if (x
+20 > piglit_width
) {
182 set_uniform(prog
, "vertex_index", max_vs_textures
);
183 for (i
= 0; i
< max_fs_textures
; i
++) {
184 set_uniform(prog
, "fragment_index", i
);
185 draw_rect_core(x
, y
, 20, 20);
186 pass
= probe_pixel(unit
, x
+10, y
+10) && pass
;
190 if (x
+20 > piglit_width
) {
196 piglit_check_gl_error(GL_NO_ERROR
);
197 piglit_present_results();
199 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
203 set_texture(int unit
)
208 get_texture_color(unit
, color
);
210 glGenTextures(1, &tex
);
211 glActiveTexture(GL_TEXTURE0
+ unit
);
212 glBindTexture(GL_TEXTURE_2D
, tex
);
213 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB8
, 1, 1, 0,
214 GL_RGB
, GL_FLOAT
, color
);
215 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
216 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
217 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_BORDER
);
218 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_BORDER
);
219 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_BORDER_COLOR
, color
);
221 piglit_check_gl_error(GL_NO_ERROR
);
225 piglit_init(int argc
, char **argv
)
228 int max_combined_textures
, i
, unit
;
230 float texcoord
= 0.5;
232 if (argc
== 2 && strcmp(argv
[1], "border") == 0) {
233 /* Sample outside of the texture, testing border color. */
235 } else if (argc
!= 1) {
236 printf("Usage: max-samples [border]\n");
237 piglit_report_result(PIGLIT_SKIP
);
241 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, &max_fs_textures
);
242 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, &max_vs_textures
);
243 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, &max_combined_textures
);
244 printf("GL_MAX_TEXTURE_IMAGE_UNITS = %d\n", max_fs_textures
);
245 printf("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = %d\n", max_vs_textures
);
246 printf("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = %d\n", max_combined_textures
);
248 assert(max_fs_textures
<= max_combined_textures
);
250 max_vs_textures
= MIN2(max_vs_textures
, max_combined_textures
- max_fs_textures
);
252 /* compile shaders */
253 if (max_vs_textures
) {
254 sprintf(str
, vs_source
, max_vs_textures
, texcoord
);
255 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, str
);
258 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vs_source_no_textures
);
261 sprintf(str
, fs_source
, max_fs_textures
, texcoord
);
262 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, str
);
264 prog
= piglit_link_simple_program(vs
, fs
);
267 piglit_check_gl_error(GL_NO_ERROR
);
269 /* initialize textures */
271 for (i
= 0; i
< max_vs_textures
; i
++) {
273 sprintf(name
, "vertex_tex[%i]", i
);
274 set_uniform(prog
, name
, unit
);
279 for (i
= 0; i
< max_fs_textures
; i
++) {
281 sprintf(name
, "fragment_tex[%i]", i
);
282 set_uniform(prog
, name
, unit
);
287 glClearColor(0.0, 0.0, 1.0, 1.0);
289 if (piglit_get_gl_version() >= 30) {
290 glGenVertexArrays(1, &vao
);
291 glBindVertexArray(vao
);
294 piglit_check_gl_error(GL_NO_ERROR
);