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
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
51 usage(const char *name
)
53 fprintf(stderr
, "usage: %s <vs | vsexceed | fs | fsexceed>\n",
55 piglit_report_result(PIGLIT_FAIL
);
61 const char *vs_ssbo_template
=
63 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
64 "#extension GL_ARB_uniform_buffer_object : enable\n"
67 "in vec4 piglit_vertex;\n"
69 "layout(std140) buffer ssbo {\n"
75 " gl_Position = piglit_vertex;\n"
79 const char *fs_template
=
81 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
86 " gl_FragColor = vary;\n"
89 const char *vs_template
=
91 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
92 "in vec4 piglit_vertex;\n"
95 " gl_Position = piglit_vertex;\n"
98 const char *fs_ssbo_template
=
100 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
101 "#extension GL_ARB_uniform_buffer_object : enable\n"
103 "layout(std140) buffer ssbo {\n"
109 " gl_FragColor = v[i];\n"
112 char *vs_source
, *fs_source
;
113 GLint max_size
, vec4s
, i_location
;
114 GLuint vs
, fs
, prog
, bo
;
119 bool link_should_fail
;
120 GLint num_vertex_ssbo
;
121 const float green
[4] = { 0, 1, 0, 0 };
124 piglit_require_extension("GL_ARB_shader_storage_buffer_object");
125 piglit_require_extension("GL_ARB_uniform_buffer_object");
127 glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE
, &max_size
);
128 printf("Max shader storage block size: %d\n", max_size
);
129 vec4s
= max_size
/ 4 / 4;
131 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS
, &num_vertex_ssbo
);
135 target
= GL_VERTEX_SHADER
;
136 link_should_fail
= false;
137 test_index
= vec4s
- 1;
138 if (num_vertex_ssbo
== 0)
139 piglit_report_result(PIGLIT_SKIP
);
142 target
= GL_VERTEX_SHADER
;
143 link_should_fail
= true;
145 test_index
= vec4s
- 2;
146 if (num_vertex_ssbo
== 0)
147 piglit_report_result(PIGLIT_SKIP
);
150 target
= GL_FRAGMENT_SHADER
;
151 link_should_fail
= false;
152 test_index
= vec4s
- 1;
155 target
= GL_FRAGMENT_SHADER
;
156 link_should_fail
= true;
158 test_index
= vec4s
- 2;
163 link_should_fail
= false;
167 case GL_VERTEX_SHADER
:
168 (void)!asprintf(&vs_source
, vs_ssbo_template
, vec4s
);
169 (void)!asprintf(&fs_source
, "%s", fs_template
);
170 printf("Testing VS with shader storage block vec4 v[%d]\n", vec4s
);
172 case GL_FRAGMENT_SHADER
:
173 (void)!asprintf(&vs_source
, "%s", vs_template
);
174 (void)!asprintf(&fs_source
, fs_ssbo_template
, vec4s
);
175 printf("Testing FS with shader storage block vec4 v[%d]\n", vec4s
);
178 piglit_report_result(PIGLIT_FAIL
);
181 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vs_source
);
182 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, fs_source
);
184 prog
= glCreateProgram();
185 glAttachShader(prog
, vs
);
186 glAttachShader(prog
, fs
);
189 if (link_should_fail
) {
190 if (!piglit_link_check_status_quiet(prog
)) {
191 printf("Failed to link with shader storage block vec4 "
193 piglit_report_result(PIGLIT_PASS
);
196 if (!piglit_link_check_status_quiet(prog
)) {
198 "Failed to link with shader storage block vec4 "
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
);
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
;
239 piglit_init(int argc
, char **argv
)
244 if (strcmp(argv
[1], "vs") == 0)
246 else if (strcmp(argv
[1], "vsexceed") == 0)
248 else if (strcmp(argv
[1], "fs") == 0)
250 else if (strcmp(argv
[1], "fsexceed") == 0)