2 * Copyright © 2020, 2021, 2022 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 DEALINGS
24 #include "piglit-util-gl.h"
27 * @file texture-buffer-size-clamp.c
29 * Tests that texture buffer's size cannot exceed
30 * GL_MAX_TEXTURE_BUFFER_SIZE_ARB even if underlying buffer allows it
31 * to be bigger. In other words the size of texture buffer must be clamped
32 * to the GL_MAX_TEXTURE_BUFFER_SIZE_ARB by the driver.
35 static struct piglit_gl_test_config
*piglit_config
= NULL
;
37 static enum piglit_result
test_buffer(void *param
);
41 int32_t texel_byte_size
;
42 GLuint program
, texel_format
;
43 GLuint buffer_id
, texture_id
;
45 enum piglit_result (*test_func
)(struct test_parameter
*self
,
46 GLsizeiptr texel_count
);
49 static const struct texture_format
57 } texture_formats
[] = {
58 {sizeof(uint8_t), GL_R8UI
},
59 {sizeof(uint8_t) * 2, GL_RG8UI
},
60 {sizeof(uint8_t) * 4, GL_RGBA8UI
}
63 static struct test_parameter test_parameters
[2 * ARRAY_SIZE(texture_formats
)];
65 static struct piglit_subtest
66 subtests_config
[1 + ARRAY_SIZE(test_parameters
)] = {
67 {"r8ui_texture_buffer_size_via_sampler",
70 {"r8ui_texture_buffer_size_via_image",
73 {"rg8ui_texture_buffer_size_via_sampler",
76 {"rg8ui_texture_buffer_size_via_image",
79 {"rgba8ui_texture_buffer_size_via_sampler",
82 {"rgba8ui_texture_buffer_size_via_image",
87 PIGLIT_GL_TEST_CONFIG_BEGIN
88 config
.supports_gl_core_version
= 31;
89 config
.window_visual
=
90 PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
91 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
92 config
.subtests
= subtests_config
;
93 piglit_config
= &config
;
94 PIGLIT_GL_TEST_CONFIG_END
97 get_max_texture_buffer_size()
99 static GLint max_size
= 0;
101 glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE_ARB
, &max_size
);
108 return PIGLIT_FAIL
; /* UNREACHED */
111 static enum piglit_result
112 test_sampler_buffer_internal(struct test_parameter
*parameters
,
113 GLsizeiptr texel_count
)
115 glUseProgram(parameters
->program
);
117 glTexBuffer(GL_TEXTURE_BUFFER
, parameters
->texel_format
,
118 parameters
->buffer_id
);
119 glBufferData(GL_TEXTURE_BUFFER
,
120 texel_count
* parameters
->texel_byte_size
,
121 NULL
, GL_STREAM_COPY
);
123 GLuint error
= glGetError();
124 if (error
== GL_OUT_OF_MEMORY
)
127 glUniform1i(glGetUniformLocation(parameters
->program
, "size"),
129 glUniform1i(glGetUniformLocation(parameters
->program
, "maxSize"),
130 get_max_texture_buffer_size());
132 glClearColor(0.2, 0.2, 0.2, 0.2);
133 glClear(GL_COLOR_BUFFER_BIT
);
135 piglit_draw_rect(-1, -1, 2, 2);
137 static const float green
[4] = {0, 1, 0, 1};
139 pass
= piglit_probe_rect_rgba(0, 0, piglit_width
,
140 piglit_height
, green
);
142 piglit_present_results();
143 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
146 static enum piglit_result
147 test_image_buffer_internal(struct test_parameter
*parameters
,
148 GLsizeiptr texel_count
)
150 if (!piglit_is_extension_supported("GL_ARB_compute_shader")) {
154 glUseProgram(parameters
->program
);
156 glTexBuffer(GL_TEXTURE_BUFFER
, parameters
->texel_format
,
157 parameters
->buffer_id
);
158 glBufferData(GL_TEXTURE_BUFFER
,
159 texel_count
* parameters
->texel_byte_size
,
160 NULL
, GL_STREAM_COPY
);
161 GLuint error
= glGetError();
162 if (error
== GL_OUT_OF_MEMORY
)
165 glBindImageTexture(0, parameters
->texture_id
, 0, GL_FALSE
,
166 0, GL_READ_ONLY
, parameters
->texel_format
);
169 glGenBuffers(1, &ssbo
);
170 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
);
171 glBufferData(GL_SHADER_STORAGE_BUFFER
, sizeof(uint32_t),
172 NULL
, GL_STREAM_READ
);
173 glBindBuffer(GL_SHADER_STORAGE_BUFFER
, ssbo
);
175 glDispatchCompute(1,1,1);
177 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT
);
179 int32_t *result
= (int32_t *) glMapBuffer(GL_SHADER_STORAGE_BUFFER
,
181 int32_t result_value
= *result
;
183 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
184 glDeleteBuffers(1, &ssbo
);
186 size_t expected_value
= MIN2(texel_count
,
187 get_max_texture_buffer_size());
188 return (result_value
== expected_value
) ? PIGLIT_PASS
: PIGLIT_FAIL
;
191 static enum piglit_result
192 test_buffer(void *param
)
194 struct test_parameter
*parameter
= param
;
196 int32_t offsets
[] = {-1, 0, 1};
197 int32_t max_size
= get_max_texture_buffer_size();
198 enum piglit_result pass
= PIGLIT_PASS
;
200 for (size_t i
= 0; i
< ARRAY_SIZE(offsets
); i
++) {
201 GLsizeiptr texel_count
= (int64_t)max_size
+ offsets
[i
];
203 enum piglit_result ret
= parameter
->test_func(parameter
,
206 if (ret
== PIGLIT_FAIL
) {
207 piglit_loge("Wrong shader texel count result, "
208 "max buffer texture size %d, "
209 "texture buffer size: %ld",
210 max_size
, texel_count
);
212 } else if (ret
== PIGLIT_SKIP
) {
221 generate_parameters_data(GLuint prog_sampler
, GLuint prog_image
,
222 GLuint buf_id
, GLuint tex_id
)
224 size_t subtests_count
= ARRAY_SIZE(test_parameters
);
225 for (size_t i
= 0; i
< subtests_count
; i
++) {
226 const size_t format_idx
= i
/ 2;
227 const bool is_image
= i
% 2;
229 struct test_parameter
*parameter
= &test_parameters
[i
];
230 struct piglit_subtest
*subtest
= &subtests_config
[i
];
232 parameter
->buffer_id
= buf_id
;
233 parameter
->texture_id
= tex_id
;
234 parameter
->program
= is_image
? prog_image
: prog_sampler
;
235 parameter
->texel_format
= texture_formats
[format_idx
].format
;
236 parameter
->texel_byte_size
= texture_formats
[format_idx
].size
;
237 parameter
->test_func
= is_image
? test_image_buffer_internal
:
238 test_sampler_buffer_internal
;
240 subtest
->data
= parameter
;
245 piglit_init(int argc
, char **argv
)
247 static const char vert
[] = "#version 140\n"
248 "in vec4 piglit_vertex;\n"
249 "void main() {gl_Position = piglit_vertex;}";
251 static const char frag
[] = "#version 140\n"
252 "uniform samplerBuffer s;\n"
253 "uniform int size, maxSize;\n"
256 " if (textureSize(s) != min(size, maxSize))\n"
257 " gl_FragColor = vec4(1, 0, 0, 1);\n"
259 " gl_FragColor = vec4(0, 1, 0, 1);\n"
262 static const char comp
[] = "#version 420\n"
263 "#extension GL_ARB_compute_shader: enable\n"
264 "#extension GL_ARB_shader_storage_buffer_object: require\n"
265 "#extension GL_ARB_shader_image_size: require\n"
266 "layout(local_size_x = 1) in;\n"
267 "writeonly readonly uniform imageBuffer s;\n"
268 "layout(std430, binding=0) writeonly buffer SZ\n"
274 " size = imageSize(s);\n"
277 GLuint prog_sampler
= piglit_build_simple_program(vert
, frag
);
279 GLuint prog_image
= 0;
280 if (piglit_is_extension_supported("GL_ARB_compute_shader")) {
282 piglit_compile_shader_text(GL_COMPUTE_SHADER
, comp
);
284 /* Creating the openGL program */
285 prog_image
= glCreateProgram();
286 if (prog_image
== 0) {
288 "Couldn't create the shader program.\n");
289 glDeleteShader(shader
);
290 piglit_report_result(PIGLIT_FAIL
);
293 /* Attaching the shaders to the program */
294 glAttachShader(prog_image
, shader
);
296 /* Linking the program */
297 glLinkProgram(prog_image
);
299 glDeleteShader(shader
);
301 if (!piglit_link_check_status(prog_image
)) {
302 /* Details of the error have already been printed. */
303 glDeleteProgram(prog_image
);
304 piglit_report_result(PIGLIT_FAIL
);
308 GLuint buf_id
, tex_id
;
310 glGenBuffers(1, &buf_id
);
311 glBindBuffer(GL_TEXTURE_BUFFER
, buf_id
);
313 glGenTextures(1, &tex_id
);
314 glBindTexture(GL_TEXTURE_BUFFER
, tex_id
);
316 generate_parameters_data(prog_sampler
, prog_image
, buf_id
, tex_id
);
318 enum piglit_result result
= piglit_run_selected_subtests(
319 piglit_config
->subtests
,
320 piglit_config
->selected_subtests
,
321 piglit_config
->num_selected_subtests
,
324 glDeleteBuffers(1, &buf_id
);
325 glDeleteTextures(1, &tex_id
);
326 glDeleteProgram(prog_sampler
);
327 glDeleteProgram(prog_image
);
329 piglit_report_result(result
);