fbo-mrt-alphatest: Actually require MRTs to be available.
[piglit.git] / tests / spec / arb_shader_storage_buffer_object / max-ssbo-size.c
blobc243dd3426a114ced6912c3e0ae84e0d2a688e47
1 /*
2 * Copyright © 2015 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 max-ssbo-size.c
26 * Tests linking and drawing with shader storage buffer objects of size
27 * MAX_SHADER_STORAGE_BLOCK_SIZE.
29 * Based on ARB_uniform_buffer_object's maxuniformblocksize.c
32 #include "piglit-util-gl.h"
34 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config.supports_gl_compat_version = 32;
37 config.supports_gl_core_version = 32;
38 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
39 config.khr_no_error_support = PIGLIT_NO_ERRORS;
41 PIGLIT_GL_TEST_CONFIG_END
43 static enum {
44 VS,
45 VS_EXCEED,
46 FS,
47 FS_EXCEED,
48 } mode;
50 static void
51 usage(const char *name)
53 fprintf(stderr, "usage: %s <vs | vsexceed | fs | fsexceed>\n",
54 name);
55 piglit_report_result(PIGLIT_FAIL);
58 enum piglit_result
59 piglit_display(void)
61 const char *vs_ssbo_template =
62 "#version 130\n"
63 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
64 "#extension GL_ARB_uniform_buffer_object : enable\n"
65 "\n"
66 "varying vec4 vary;"
67 "in vec4 piglit_vertex;\n"
68 "\n"
69 "layout(std140) buffer ssbo {\n"
70 " vec4 v[%d];\n"
71 "};\n"
72 "uniform int i;\n"
73 "\n"
74 "void main() {\n"
75 " gl_Position = piglit_vertex;\n"
76 " vary = v[i];\n"
77 "}\n";
79 const char *fs_template =
80 "#version 130\n"
81 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
82 "\n"
83 "varying vec4 vary;"
84 "\n"
85 "void main() {\n"
86 " gl_FragColor = vary;\n"
87 "}\n";
89 const char *vs_template =
90 "#version 130\n"
91 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
92 "in vec4 piglit_vertex;\n"
93 "\n"
94 "void main() {\n"
95 " gl_Position = piglit_vertex;\n"
96 "}\n";
98 const char *fs_ssbo_template =
99 "#version 130\n"
100 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
101 "#extension GL_ARB_uniform_buffer_object : enable\n"
102 "\n"
103 "layout(std140) buffer ssbo {\n"
104 " vec4 v[%d];\n"
105 "};\n"
106 "uniform int i;\n"
107 "\n"
108 "void main() {\n"
109 " gl_FragColor = v[i];\n"
110 "}\n";
112 GLint max_size, vec4s, i_location;
113 GLuint vs, fs, prog, bo;
114 GLenum target;
115 float *data;
116 size_t size;
117 bool pass = true;
118 bool link_should_fail;
119 GLint num_vertex_ssbo;
120 const float green[4] = { 0, 1, 0, 0 };
121 int test_index;
123 piglit_require_extension("GL_ARB_shader_storage_buffer_object");
124 piglit_require_extension("GL_ARB_uniform_buffer_object");
126 glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
127 printf("Max shader storage block size: %d\n", max_size);
128 vec4s = max_size / 4 / 4;
130 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &num_vertex_ssbo);
132 switch (mode) {
133 case VS:
134 target = GL_VERTEX_SHADER;
135 link_should_fail = false;
136 test_index = vec4s - 1;
137 if (num_vertex_ssbo == 0)
138 piglit_report_result(PIGLIT_SKIP);
139 break;
140 case VS_EXCEED:
141 target = GL_VERTEX_SHADER;
142 link_should_fail = true;
143 vec4s++;
144 test_index = vec4s - 2;
145 if (num_vertex_ssbo == 0)
146 piglit_report_result(PIGLIT_SKIP);
147 break;
148 case FS:
149 target = GL_FRAGMENT_SHADER;
150 link_should_fail = false;
151 test_index = vec4s - 1;
152 break;
153 case FS_EXCEED:
154 target = GL_FRAGMENT_SHADER;
155 link_should_fail = true;
156 vec4s++;
157 test_index = vec4s - 2;
158 break;
159 default:
160 assert(false);
161 target = GL_NONE;
162 link_should_fail = false;
165 switch (target) {
166 case GL_VERTEX_SHADER:
167 vs = piglit_compile_shader_formatted(GL_VERTEX_SHADER,
168 vs_ssbo_template, vec4s);
169 fs = piglit_compile_shader_formatted(GL_FRAGMENT_SHADER,
170 "%s", fs_template);
171 printf("Testing VS with shader storage block vec4 v[%d]\n", vec4s);
172 break;
173 case GL_FRAGMENT_SHADER:
174 vs = piglit_compile_shader_formatted(GL_VERTEX_SHADER,
175 "%s", vs_template);
176 fs = piglit_compile_shader_formatted(GL_FRAGMENT_SHADER,
177 fs_ssbo_template, vec4s);
178 printf("Testing FS with shader storage block vec4 v[%d]\n", vec4s);
179 break;
180 default:
181 piglit_report_result(PIGLIT_FAIL);
184 prog = glCreateProgram();
185 glAttachShader(prog, vs);
186 glAttachShader(prog, fs);
187 glLinkProgram(prog);
189 if (link_should_fail) {
190 if (!piglit_link_check_status_quiet(prog)) {
191 printf("Failed to link with shader storage block vec4 "
192 "v[%d]\n", vec4s);
193 piglit_report_result(PIGLIT_PASS);
195 } else {
196 if (!piglit_link_check_status_quiet(prog)) {
197 fprintf(stderr,
198 "Failed to link with shader storage block vec4 "
199 "v[%d]\n", vec4s);
200 return PIGLIT_FAIL;
204 size = vec4s * 4 * sizeof(float);
205 glGenBuffers(1, &bo);
206 glBindBuffer(GL_SHADER_STORAGE_BUFFER, bo);
207 glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
208 data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE);
209 memset(data, 0, size);
211 /* The whole shader storage buffer will be zeros, except for the
212 * entry at v[test_index] which will be green.
214 data[test_index * 4 + 0] = green[0];
215 data[test_index * 4 + 1] = green[1];
216 data[test_index * 4 + 2] = green[2];
217 data[test_index * 4 + 3] = green[3];
218 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
220 glUseProgram(prog);
221 i_location = glGetUniformLocation(prog, "i");
222 glUniform1i(i_location, test_index);
224 glShaderStorageBlockBinding(prog, 0, 0);
225 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bo);
226 piglit_draw_rect(-1, -1, 2, 2);
228 pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green);
230 glDeleteProgram(prog);
232 piglit_present_results();
234 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
238 void
239 piglit_init(int argc, char **argv)
241 if (argc < 2)
242 usage(argv[0]);
244 if (strcmp(argv[1], "vs") == 0)
245 mode = VS;
246 else if (strcmp(argv[1], "vsexceed") == 0)
247 mode = VS_EXCEED;
248 else if (strcmp(argv[1], "fs") == 0)
249 mode = FS;
250 else if (strcmp(argv[1], "fsexceed") == 0)
251 mode = FS_EXCEED;
252 else
253 usage(argv[0]);