ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_uniform_buffer_object / maxuniformblocksize.c
blobce7126f0f09e4885685ed09c021f465a2d6acc39
1 /*
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
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
21 * DEALINGS IN THE SOFTWARE.
24 /** @file maxblocks.c
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
46 static enum {
47 VS,
48 VS_EXCEED,
49 FS,
50 FS_EXCEED,
51 } mode;
53 static void
54 usage(const char *name)
56 fprintf(stderr, "usage: %s <vs | vsexceed | fs | fsexceed>\n",
57 name);
58 piglit_report_result(PIGLIT_FAIL);
61 enum piglit_result
62 piglit_display(void)
64 const char *vs_ubo_template =
65 "#extension GL_ARB_uniform_buffer_object : enable\n"
66 "\n"
67 "varying vec4 vary;"
68 "\n"
69 "layout(std140) uniform ubo {\n"
70 " vec4 v[%d];\n"
71 "};\n"
72 "uniform int i;\n"
73 "\n"
74 "void main() {\n"
75 " gl_Position = gl_Vertex;\n"
76 " vary = v[i];\n"
77 "}\n";
79 const char *fs_template =
80 "#extension GL_ARB_uniform_buffer_object : enable\n"
81 "\n"
82 "varying vec4 vary;"
83 "\n"
84 "void main() {\n"
85 " gl_FragColor = vary;\n"
86 "}\n";
88 const char *vs_template =
89 "#extension GL_ARB_uniform_buffer_object : enable\n"
90 "\n"
91 "void main() {\n"
92 " gl_Position = gl_Vertex;\n"
93 "}\n";
95 const char *fs_ubo_template =
96 "#extension GL_ARB_uniform_buffer_object : enable\n"
97 "\n"
98 "layout(std140) uniform ubo {\n"
99 " vec4 v[%d];\n"
100 "};\n"
101 "uniform int i;\n"
102 "\n"
103 "void main() {\n"
104 " gl_FragColor = v[i];\n"
105 "}\n";
107 char *vs_source, *fs_source;
108 GLint max_size, vec4s, i_location;
109 GLuint vs, fs, prog, bo;
110 GLenum target;
111 float *data;
112 size_t size;
113 bool pass = true;
114 bool may_link_fail;
115 const float green[4] = { 0, 1, 0, 0 };
116 int test_index;
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;
124 switch (mode) {
125 case VS:
126 target = GL_VERTEX_SHADER;
127 may_link_fail = false;
128 test_index = vec4s - 1;
129 break;
130 case VS_EXCEED:
131 target = GL_VERTEX_SHADER;
132 may_link_fail = true;
133 vec4s++;
134 test_index = vec4s - 2;
135 break;
136 case FS:
137 target = GL_FRAGMENT_SHADER;
138 may_link_fail = false;
139 test_index = vec4s - 1;
140 break;
141 case FS_EXCEED:
142 target = GL_FRAGMENT_SHADER;
143 may_link_fail = true;
144 vec4s++;
145 test_index = vec4s - 2;
146 break;
147 default:
148 assert(false);
149 target = GL_NONE;
150 may_link_fail = false;
153 switch (target) {
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);
158 break;
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);
163 break;
164 default:
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);
174 glLinkProgram(prog);
176 if (may_link_fail) {
177 if (!piglit_link_check_status_quiet(prog)) {
178 printf("Failed to link with uniform block vec4 "
179 "v[%d]\n", vec4s);
180 piglit_report_result(PIGLIT_PASS);
182 } else {
183 if (!piglit_link_check_status_quiet(prog)) {
184 fprintf(stderr,
185 "Failed to link with uniform block vec4 "
186 "v[%d]\n", vec4s);
187 return PIGLIT_FAIL;
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);
207 glUseProgram(prog);
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;
225 void
226 piglit_init(int argc, char **argv)
228 if (argc < 2)
229 usage(argv[0]);
231 if (strcmp(argv[1], "vs") == 0)
232 mode = VS;
233 else if (strcmp(argv[1], "vsexceed") == 0)
234 mode = VS_EXCEED;
235 else if (strcmp(argv[1], "fs") == 0)
236 mode = FS;
237 else if (strcmp(argv[1], "fsexceed") == 0)
238 mode = FS_EXCEED;
239 else
240 usage(argv[0]);