2 * Copyright © 2012 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
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
21 * DEALINGS IN THE SOFTWARE.
26 * Tests linking and drawing with uniform buffer objects of size
27 * MAX_UNIFORM_BLOCK_SIZE and MAX_UNIFORM_BLOCK_SIZE + 4.
29 * We test the max size + 4 because implementations are allowed to
30 * link and draw beyond the exposed limits, but at that point there
31 * are no guarantees it will link. Those tests are the "vsexceed" and
32 * "fsexceed" arguments.
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 config
.supports_gl_compat_version
= 10;
41 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
42 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
44 PIGLIT_GL_TEST_CONFIG_END
54 usage(const char *name
)
56 fprintf(stderr
, "usage: %s <vs | vsexceed | fs | fsexceed>\n",
58 piglit_report_result(PIGLIT_FAIL
);
64 const char *vs_ubo_template
=
65 "#extension GL_ARB_uniform_buffer_object : enable\n"
69 "layout(std140) uniform ubo {\n"
75 " gl_Position = gl_Vertex;\n"
79 const char *fs_template
=
80 "#extension GL_ARB_uniform_buffer_object : enable\n"
85 " gl_FragColor = vary;\n"
88 const char *vs_template
=
89 "#extension GL_ARB_uniform_buffer_object : enable\n"
92 " gl_Position = gl_Vertex;\n"
95 const char *fs_ubo_template
=
96 "#extension GL_ARB_uniform_buffer_object : enable\n"
98 "layout(std140) uniform ubo {\n"
104 " gl_FragColor = v[i];\n"
107 char *vs_source
, *fs_source
;
108 GLint max_size
, vec4s
, i_location
;
109 GLuint vs
, fs
, prog
, bo
;
115 const float green
[4] = { 0, 1, 0, 0 };
118 piglit_require_extension("GL_ARB_uniform_buffer_object");
120 glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE
, &max_size
);
121 printf("Max uniform block size: %d\n", max_size
);
122 vec4s
= max_size
/ 4 / 4;
126 target
= GL_VERTEX_SHADER
;
127 may_link_fail
= false;
128 test_index
= vec4s
- 1;
131 target
= GL_VERTEX_SHADER
;
132 may_link_fail
= true;
134 test_index
= vec4s
- 2;
137 target
= GL_FRAGMENT_SHADER
;
138 may_link_fail
= false;
139 test_index
= vec4s
- 1;
142 target
= GL_FRAGMENT_SHADER
;
143 may_link_fail
= true;
145 test_index
= vec4s
- 2;
150 may_link_fail
= false;
154 case GL_VERTEX_SHADER
:
155 (void)!asprintf(&vs_source
, vs_ubo_template
, vec4s
);
156 (void)!asprintf(&fs_source
, "%s", fs_template
);
157 printf("Testing VS with uniform block vec4 v[%d]\n", vec4s
);
159 case GL_FRAGMENT_SHADER
:
160 (void)!asprintf(&vs_source
, "%s", vs_template
);
161 (void)!asprintf(&fs_source
, fs_ubo_template
, vec4s
);
162 printf("Testing FS with uniform block vec4 v[%d]\n", vec4s
);
165 piglit_report_result(PIGLIT_FAIL
);
168 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vs_source
);
169 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, fs_source
);
171 prog
= glCreateProgram();
172 glAttachShader(prog
, vs
);
173 glAttachShader(prog
, fs
);
177 if (!piglit_link_check_status_quiet(prog
)) {
178 printf("Failed to link with uniform block vec4 "
180 piglit_report_result(PIGLIT_PASS
);
183 if (!piglit_link_check_status_quiet(prog
)) {
185 "Failed to link with uniform block vec4 "
191 size
= vec4s
* 4 * sizeof(float);
192 glGenBuffers(1, &bo
);
193 glBindBuffer(GL_UNIFORM_BUFFER
, bo
);
194 glBufferData(GL_UNIFORM_BUFFER
, size
, NULL
, GL_DYNAMIC_DRAW
);
195 data
= glMapBuffer(GL_UNIFORM_BUFFER
, GL_READ_WRITE
);
196 memset(data
, 0, size
);
198 /* The whole uniform buffer will be zeros, except for the
199 * entry at v[test_index] which will be green.
201 data
[test_index
* 4 + 0] = green
[0];
202 data
[test_index
* 4 + 1] = green
[1];
203 data
[test_index
* 4 + 2] = green
[2];
204 data
[test_index
* 4 + 3] = green
[3];
205 glUnmapBuffer(GL_UNIFORM_BUFFER
);
208 i_location
= glGetUniformLocation(prog
, "i");
209 glUniform1i(i_location
, test_index
);
211 glUniformBlockBinding(prog
, 0, 0);
212 glBindBufferBase(GL_UNIFORM_BUFFER
, 0, bo
);
213 piglit_draw_rect(-1, -1, 2, 2);
215 pass
= piglit_probe_rect_rgba(0, 0, piglit_width
, piglit_height
, green
);
217 glDeleteProgram(prog
);
219 piglit_present_results();
221 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
226 piglit_init(int argc
, char **argv
)
231 if (strcmp(argv
[1], "vs") == 0)
233 else if (strcmp(argv
[1], "vsexceed") == 0)
235 else if (strcmp(argv
[1], "fs") == 0)
237 else if (strcmp(argv
[1], "fsexceed") == 0)