2 * Copyright © 2010 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.
29 #include "piglit-util.h"
30 #include "piglit-util-gl.h"
31 #include "piglit-vbo.h"
32 #include "piglit-framework-gl/piglit_gl_framework.h"
33 #include "piglit-subprocess.h"
35 #include "shader_runner_gles_workarounds.h"
36 #include "parser_utils.h"
38 #include "shader_runner_vs_passthrough_spv.h"
40 #define DEFAULT_WINDOW_WIDTH 250
41 #define DEFAULT_WINDOW_HEIGHT 250
43 static bool spirv_replaces_glsl
= false;
44 static struct piglit_gl_test_config current_config
;
47 get_required_config(const char *script_name
, bool spirv
,
48 struct piglit_gl_test_config
*config
);
50 decode_drawing_mode(const char *mode_str
);
52 PIGLIT_GL_TEST_CONFIG_BEGIN
54 if (!piglit_gl_test_config_override_size(&config
)) {
55 config
.window_width
= DEFAULT_WINDOW_WIDTH
;
56 config
.window_height
= DEFAULT_WINDOW_HEIGHT
;
58 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
59 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
61 /* By default SPIR-V mode is false. It will not be enabled
62 * unless the script includes SPIRV YES or SPIRV ONLY lines at
63 * [require] section, so it will be handled later.
66 get_required_config(argv
[1], spirv_replaces_glsl
, &config
);
68 config
.supports_gl_compat_version
= 10;
71 current_config
= config
;
73 PIGLIT_GL_TEST_CONFIG_END
75 static const char passthrough_vertex_shader_source
[] =
76 "#if __VERSION__ >= 130\n"
77 "in vec4 piglit_vertex;\n"
79 "attribute vec4 piglit_vertex;\n"
81 "void main() { gl_Position = piglit_vertex; }\n"
84 struct component_version
{
102 int row_major
; /* int as we don't have a parse_bool */
105 #define ENUM_STRING(e) { #e, e }
107 extern float piglit_tolerance
[4];
109 static int test_num
= 1;
110 static struct component_version gl_version
;
111 static struct component_version glsl_version
;
112 static struct component_version glsl_req_version
;
113 static int gl_max_vertex_output_components
;
114 static int gl_max_fragment_uniform_components
;
115 static int gl_max_vertex_uniform_components
;
116 static int gl_max_vertex_attribs
;
117 static int gl_max_varying_components
;
118 static int gl_max_clip_planes
;
119 static int gl_num_program_binary_formats
= 0;
121 static const char *test_start
= NULL
;
122 static unsigned test_start_line_num
= 0;
124 static GLuint vertex_shaders
[256];
125 static unsigned num_vertex_shaders
= 0;
126 static GLuint tess_ctrl_shaders
[256];
127 static unsigned num_tess_ctrl_shaders
= 0;
128 static GLuint tess_eval_shaders
[256];
129 static unsigned num_tess_eval_shaders
= 0;
130 static GLuint geometry_shaders
[256];
131 static unsigned num_geometry_shaders
= 0;
132 static GLuint fragment_shaders
[256];
133 static unsigned num_fragment_shaders
= 0;
134 static GLuint compute_shaders
[256];
135 static unsigned num_compute_shaders
= 0;
136 static int num_uniform_blocks
;
137 static GLuint
*uniform_block_bos
;
138 static int *uniform_block_indexes
; /* ubo block index, indexed by ubo binding */
139 static GLenum geometry_layout_input_type
= GL_TRIANGLES
;
140 static GLenum geometry_layout_output_type
= GL_TRIANGLE_STRIP
;
141 static GLint geometry_layout_vertices_out
= 0;
142 static GLuint atomics_bos
[8];
143 static GLuint ssbo
[32];
144 static unsigned num_shader_include_paths
= 0;
145 static char **shader_include_path
;
146 static char *shader_include_names
[256];
147 static unsigned num_shader_includes
= 0;
149 #define MAX_XFB_BUFFERS 4 /* Same value used at nir_xfb_info */
150 static GLuint xfb
[MAX_XFB_BUFFERS
];
152 #define MAX_QUERIES 2
153 static GLuint queries
[MAX_QUERIES
];
155 #define SHADER_TYPES 6
156 static GLuint
*subuniform_locations
[SHADER_TYPES
];
157 static int num_subuniform_locations
[SHADER_TYPES
];
158 static char *shader_string
;
159 static GLint shader_string_size
;
160 static const char *vertex_data_start
= NULL
;
161 static const char *vertex_data_end
= NULL
;
163 static GLuint sso_vertex_prog
;
164 static GLuint sso_tess_control_prog
;
165 static GLuint sso_tess_eval_prog
;
166 static GLuint sso_geometry_prog
;
167 static GLuint sso_fragment_prog
;
168 static GLuint sso_compute_prog
;
169 static GLuint pipeline
= 0;
170 static size_t num_vbo_rows
= 0;
171 static bool vbo_present
= false;
172 static bool link_ok
= false;
173 static bool prog_in_use
= false;
174 static bool sso_in_use
= false;
175 static bool separable_program
= false;
176 static bool glsl_in_use
= false;
177 static bool force_glsl
= false;
178 static bool spirv_in_use
= false;
179 static bool force_no_names
= false;
180 static GLchar
*prog_err_info
= NULL
;
181 static GLuint vao
= 0;
182 static GLuint draw_fbo
, read_fbo
;
183 static GLint render_width
, render_height
;
184 static GLint read_width
, read_height
;
186 static bool use_get_program_binary
= false;
188 static bool ignore_missing_uniforms
= false;
190 static bool report_subtests
= false;
192 struct specialization_list
{
196 union { GLuint u
; GLfloat f
; } *values
;
199 static struct specialization_list
200 specializations
[SHADER_TYPES
];
202 static struct texture_binding
{
207 } texture_bindings
[32];
209 static struct resident_handle
{
212 } resident_handles
[32];
215 clear_texture_binding(unsigned idx
)
217 REQUIRE(idx
< ARRAY_SIZE(texture_bindings
),
218 "Invalid texture index %d\n", idx
);
220 if (texture_bindings
[idx
].obj
) {
221 glDeleteTextures(1, &texture_bindings
[idx
].obj
);
222 texture_bindings
[idx
].obj
= 0;
227 set_texture_binding(unsigned idx
, GLuint obj
, unsigned w
, unsigned h
, unsigned l
)
229 clear_texture_binding(idx
);
231 REQUIRE(idx
< ARRAY_SIZE(texture_bindings
),
232 "Invalid texture index %d\n", idx
);
233 texture_bindings
[idx
].obj
= obj
;
234 texture_bindings
[idx
].width
= w
;
235 texture_bindings
[idx
].height
= h
;
236 texture_bindings
[idx
].layers
= l
;
239 static const struct texture_binding
*
240 get_texture_binding(unsigned idx
)
242 REQUIRE(idx
< ARRAY_SIZE(texture_bindings
),
243 "Invalid texture index %d\n", idx
);
244 REQUIRE(texture_bindings
[idx
].obj
,
245 "No texture bound at %d\n", idx
);
246 return &texture_bindings
[idx
];
250 clear_resident_handle(unsigned idx
)
252 REQUIRE(idx
< ARRAY_SIZE(resident_handles
),
253 "Invalid resident handle index %d\n", idx
);
255 if (resident_handles
[idx
].handle
) {
256 GLuint64 handle
= resident_handles
[idx
].handle
;
257 if (resident_handles
[idx
].is_tex
) {
258 if (glIsTextureHandleResidentARB(handle
))
259 glMakeTextureHandleNonResidentARB(handle
);
261 if (glIsImageHandleResidentARB(handle
))
262 glMakeImageHandleNonResidentARB(handle
);
264 resident_handles
[idx
].handle
= 0;
269 set_resident_handle(unsigned idx
, GLuint64 handle
, bool is_tex
)
271 clear_resident_handle(idx
);
273 REQUIRE(idx
< ARRAY_SIZE(resident_handles
),
274 "Invalid resident handle index %d\n", idx
);
275 resident_handles
[idx
].handle
= handle
;
276 resident_handles
[idx
].is_tex
= is_tex
;
279 static const struct resident_handle
*
280 get_resident_handle(unsigned idx
)
282 REQUIRE(idx
< ARRAY_SIZE(resident_handles
),
283 "Invalid resident handle index %d\n", idx
);
284 REQUIRE(resident_handles
[idx
].handle
,
285 "No resident handle at %d\n", idx
);
286 return &resident_handles
[idx
];
293 vertex_shader_passthrough
,
295 vertex_shader_specializations
,
298 tess_ctrl_shader_spirv
,
299 tess_ctrl_shader_specializations
,
301 tess_eval_shader_spirv
,
302 tess_eval_shader_specializations
,
304 geometry_shader_spirv
,
305 geometry_shader_specializations
,
308 fragment_shader_spirv
,
309 fragment_shader_specializations
,
312 compute_shader_spirv
,
313 compute_shader_specializations
,
316 shader_include_paths
,
320 static const struct string_to_enum all_types
[] = {
321 ENUM_STRING(GL_FLOAT
),
322 ENUM_STRING(GL_FLOAT_VEC2
),
323 ENUM_STRING(GL_FLOAT_VEC3
),
324 ENUM_STRING(GL_FLOAT_VEC4
),
325 ENUM_STRING(GL_DOUBLE
),
326 ENUM_STRING(GL_DOUBLE_VEC2
),
327 ENUM_STRING(GL_DOUBLE_VEC3
),
328 ENUM_STRING(GL_DOUBLE_VEC4
),
330 ENUM_STRING(GL_INT_VEC2
),
331 ENUM_STRING(GL_INT_VEC3
),
332 ENUM_STRING(GL_INT_VEC4
),
333 ENUM_STRING(GL_UNSIGNED_INT
),
334 ENUM_STRING(GL_UNSIGNED_INT_VEC2
),
335 ENUM_STRING(GL_UNSIGNED_INT_VEC3
),
336 ENUM_STRING(GL_UNSIGNED_INT_VEC4
),
337 ENUM_STRING(GL_INT64_ARB
),
338 ENUM_STRING(GL_INT64_VEC2_ARB
),
339 ENUM_STRING(GL_INT64_VEC3_ARB
),
340 ENUM_STRING(GL_INT64_VEC4_ARB
),
341 ENUM_STRING(GL_UNSIGNED_INT64_ARB
),
342 ENUM_STRING(GL_UNSIGNED_INT64_VEC2_ARB
),
343 ENUM_STRING(GL_UNSIGNED_INT64_VEC3_ARB
),
344 ENUM_STRING(GL_UNSIGNED_INT64_VEC4_ARB
),
345 ENUM_STRING(GL_BOOL
),
346 ENUM_STRING(GL_BOOL_VEC2
),
347 ENUM_STRING(GL_BOOL_VEC3
),
348 ENUM_STRING(GL_BOOL_VEC4
),
349 ENUM_STRING(GL_FLOAT_MAT2
),
350 ENUM_STRING(GL_FLOAT_MAT3
),
351 ENUM_STRING(GL_FLOAT_MAT4
),
352 ENUM_STRING(GL_FLOAT_MAT2x3
),
353 ENUM_STRING(GL_FLOAT_MAT2x4
),
354 ENUM_STRING(GL_FLOAT_MAT3x2
),
355 ENUM_STRING(GL_FLOAT_MAT3x4
),
356 ENUM_STRING(GL_FLOAT_MAT4x2
),
357 ENUM_STRING(GL_FLOAT_MAT4x3
),
358 ENUM_STRING(GL_DOUBLE_MAT2
),
359 ENUM_STRING(GL_DOUBLE_MAT3
),
360 ENUM_STRING(GL_DOUBLE_MAT4
),
361 ENUM_STRING(GL_DOUBLE_MAT2x3
),
362 ENUM_STRING(GL_DOUBLE_MAT2x4
),
363 ENUM_STRING(GL_DOUBLE_MAT3x2
),
364 ENUM_STRING(GL_DOUBLE_MAT3x4
),
365 ENUM_STRING(GL_DOUBLE_MAT4x2
),
366 ENUM_STRING(GL_DOUBLE_MAT4x3
),
367 ENUM_STRING(GL_SAMPLER_1D
),
368 ENUM_STRING(GL_SAMPLER_2D
),
369 ENUM_STRING(GL_SAMPLER_3D
),
370 ENUM_STRING(GL_SAMPLER_CUBE
),
371 ENUM_STRING(GL_SAMPLER_1D_SHADOW
),
372 ENUM_STRING(GL_SAMPLER_2D_SHADOW
),
373 ENUM_STRING(GL_SAMPLER_1D_ARRAY
),
374 ENUM_STRING(GL_SAMPLER_2D_ARRAY
),
375 ENUM_STRING(GL_SAMPLER_1D_ARRAY_SHADOW
),
376 ENUM_STRING(GL_SAMPLER_2D_ARRAY_SHADOW
),
377 ENUM_STRING(GL_SAMPLER_2D_MULTISAMPLE
),
378 ENUM_STRING(GL_SAMPLER_2D_MULTISAMPLE_ARRAY
),
379 ENUM_STRING(GL_SAMPLER_CUBE_SHADOW
),
380 ENUM_STRING(GL_SAMPLER_BUFFER
),
381 ENUM_STRING(GL_SAMPLER_2D_RECT
),
382 ENUM_STRING(GL_SAMPLER_2D_RECT_SHADOW
),
383 ENUM_STRING(GL_INT_SAMPLER_1D
),
384 ENUM_STRING(GL_INT_SAMPLER_2D
),
385 ENUM_STRING(GL_INT_SAMPLER_3D
),
386 ENUM_STRING(GL_INT_SAMPLER_CUBE
),
387 ENUM_STRING(GL_INT_SAMPLER_1D_ARRAY
),
388 ENUM_STRING(GL_INT_SAMPLER_2D_ARRAY
),
389 ENUM_STRING(GL_INT_SAMPLER_2D_MULTISAMPLE
),
390 ENUM_STRING(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
),
391 ENUM_STRING(GL_INT_SAMPLER_BUFFER
),
392 ENUM_STRING(GL_INT_SAMPLER_2D_RECT
),
393 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_1D
),
394 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D
),
395 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_3D
),
396 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_CUBE
),
397 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY
),
398 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY
),
399 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE
),
400 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
),
401 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_BUFFER
),
402 ENUM_STRING(GL_UNSIGNED_INT_SAMPLER_2D_RECT
),
407 compare(float ref
, float value
, enum comparison cmp
);
410 compare_uint(GLuint ref
, GLuint value
, enum comparison cmp
);
413 compare_int(GLint ref
, GLint value
, enum comparison cmp
);
416 version_init(struct component_version
*v
, enum version_tag tag
, bool core
, bool compat
, bool es
, unsigned num
)
418 assert(tag
== VERSION_GL
|| tag
== VERSION_GLSL
);
429 version_copy(struct component_version
*dest
, struct component_version
*src
)
431 memcpy(dest
, src
, sizeof(*dest
));
435 version_compare(struct component_version
*a
, struct component_version
*b
, enum comparison cmp
)
437 assert(a
->_tag
== b
->_tag
);
442 return compare(a
->num
, b
->num
, cmp
);
446 * Get the version string.
449 version_string(struct component_version
*v
)
456 snprintf(v
->_string
, sizeof(v
->_string
) - 1, "GL%s %d.%d",
458 v
->num
/ 10, v
->num
% 10);
461 snprintf(v
->_string
, sizeof(v
->_string
) - 1, "GLSL%s %d.%d",
463 v
->num
/ 100, v
->num
% 100);
475 target_to_short_name(GLenum target
)
478 case GL_VERTEX_SHADER
:
480 case GL_FRAGMENT_SHADER
:
482 case GL_TESS_CONTROL_SHADER
:
484 case GL_TESS_EVALUATION_SHADER
:
486 case GL_GEOMETRY_SHADER
:
488 case GL_COMPUTE_SHADER
:
496 static enum piglit_result
497 compile_glsl(GLenum target
)
499 GLuint shader
= glCreateShader(target
);
503 printf("Cannot mix SPIRV and non-SPIRV shaders\n");
510 case GL_VERTEX_SHADER
:
511 if (piglit_get_gl_version() < 20 &&
512 !(piglit_is_extension_supported("GL_ARB_shader_objects") &&
513 piglit_is_extension_supported("GL_ARB_vertex_shader")))
516 case GL_FRAGMENT_SHADER
:
517 if (piglit_get_gl_version() < 20 &&
518 !(piglit_is_extension_supported("GL_ARB_shader_objects") &&
519 piglit_is_extension_supported("GL_ARB_fragment_shader")))
522 case GL_TESS_CONTROL_SHADER
:
523 case GL_TESS_EVALUATION_SHADER
:
524 if (gl_version
.num
< (gl_version
.es
? 32 : 40))
525 if (!piglit_is_extension_supported(gl_version
.es
?
526 "GL_OES_tessellation_shader" :
527 "GL_ARB_tessellation_shader"))
530 case GL_GEOMETRY_SHADER
:
531 if (gl_version
.num
< 32)
532 if (!piglit_is_extension_supported(gl_version
.es
?
533 "GL_OES_geometry_shader" :
534 "GL_ARB_geometry_shader4"))
537 case GL_COMPUTE_SHADER
:
538 if (gl_version
.num
< (gl_version
.es
? 31 : 43))
539 if (!piglit_is_extension_supported("GL_ARB_compute_shader"))
544 if (!glsl_req_version
.num
) {
545 printf("GLSL version requirement missing\n");
549 if (!strstr(shader_string
, "#version ")) {
550 char *shader_strings
[2];
551 char version_string
[100];
552 GLint shader_string_sizes
[2];
554 /* Add a #version directive based on the GLSL requirement. */
555 sprintf(version_string
, "#version %d", glsl_req_version
.num
);
556 if (glsl_req_version
.es
&& glsl_req_version
.num
!= 100) {
557 strcat(version_string
, " es");
559 strcat(version_string
, "\n");
560 shader_strings
[0] = version_string
;
561 shader_string_sizes
[0] = strlen(version_string
);
562 shader_strings
[1] = shader_string
;
563 shader_string_sizes
[1] = shader_string_size
;
565 glShaderSource(shader
, 2,
566 (const GLchar
**) shader_strings
,
567 shader_string_sizes
);
570 glShaderSource(shader
, 1,
571 (const GLchar
**) &shader_string
,
572 &shader_string_size
);
575 if (num_shader_include_paths
) {
576 glCompileShaderIncludeARB(shader
, num_shader_include_paths
,
577 (const char **) shader_include_path
, NULL
);
579 glCompileShader(shader
);
581 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &ok
);
587 glGetShaderiv(shader
, GL_INFO_LOG_LENGTH
, &size
);
590 glGetShaderInfoLog(shader
, size
, NULL
, info
);
592 fprintf(stderr
, "Failed to compile %s: %s\n",
593 target_to_short_name(target
),
601 case GL_VERTEX_SHADER
:
602 vertex_shaders
[num_vertex_shaders
] = shader
;
603 num_vertex_shaders
++;
605 case GL_TESS_CONTROL_SHADER
:
606 tess_ctrl_shaders
[num_tess_ctrl_shaders
] = shader
;
607 num_tess_ctrl_shaders
++;
609 case GL_TESS_EVALUATION_SHADER
:
610 tess_eval_shaders
[num_tess_eval_shaders
] = shader
;
611 num_tess_eval_shaders
++;
613 case GL_GEOMETRY_SHADER
:
614 geometry_shaders
[num_geometry_shaders
] = shader
;
615 num_geometry_shaders
++;
617 case GL_FRAGMENT_SHADER
:
618 fragment_shaders
[num_fragment_shaders
] = shader
;
619 num_fragment_shaders
++;
621 case GL_COMPUTE_SHADER
:
622 compute_shaders
[num_compute_shaders
] = shader
;
623 num_compute_shaders
++;
630 static enum piglit_result
631 compile_and_bind_program(GLenum target
, const char *start
, int len
)
637 case GL_VERTEX_PROGRAM_ARB
:
638 if (!piglit_is_extension_supported("GL_ARB_vertex_program"))
641 case GL_FRAGMENT_PROGRAM_ARB
:
642 if (!piglit_is_extension_supported("GL_ARB_fragment_program"))
647 source
= malloc(len
+ 1);
648 memcpy(source
, start
, len
);
650 prog
= piglit_compile_program(target
, source
);
653 glBindProgramARB(target
, prog
);
661 program_binary_save_restore(bool script_command
)
665 GLenum binary_format
;
669 if (!script_command
&& !use_get_program_binary
)
672 if (script_command
&& gl_num_program_binary_formats
== 0)
673 piglit_report_result(PIGLIT_SKIP
);
675 glGetProgramiv(prog
, GL_LINK_STATUS
, &ok
);
677 if (script_command
) {
678 fprintf(stderr
, "Can't save/restore program that is "
680 piglit_report_result(PIGLIT_FAIL
);
686 #ifdef PIGLIT_USE_OPENGL
687 glGetProgramiv(prog
, GL_PROGRAM_BINARY_LENGTH
, &binary_length
);
689 glGetProgramiv(prog
, GL_PROGRAM_BINARY_LENGTH_OES
, &binary_length
);
691 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
692 fprintf(stderr
, "glGetProgramiv GL_PROGRAM_BINARY_LENGTH "
694 piglit_report_result(PIGLIT_FAIL
);
697 binary
= malloc(binary_length
);
699 fprintf(stderr
, "Failed to allocate buffer for "
700 "GetProgramBinary\n");
701 piglit_report_result(PIGLIT_FAIL
);
704 #ifdef PIGLIT_USE_OPENGL
705 glGetProgramBinary(prog
, binary_length
, &binary_length
, &binary_format
,
708 glGetProgramBinaryOES(prog
, binary_length
, &binary_length
,
709 &binary_format
, binary
);
711 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
712 fprintf(stderr
, "glGetProgramBinary error\n");
714 piglit_report_result(PIGLIT_FAIL
);
717 new_prog
= glCreateProgram();
718 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
720 piglit_report_result(PIGLIT_FAIL
);
723 #ifdef PIGLIT_USE_OPENGL
724 glProgramBinary(new_prog
, binary_format
, binary
, binary_length
);
726 glProgramBinaryOES(new_prog
, binary_format
, binary
, binary_length
);
729 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
730 fprintf(stderr
, "glProgramBinary error "
731 "(should not happen according to spec.)\n");
732 piglit_report_result(PIGLIT_FAIL
);
735 glGetProgramiv(prog
, GL_LINK_STATUS
, &ok
);
737 fprintf(stderr
, "link failure after glProgramBinary\n");
738 piglit_report_result(PIGLIT_FAIL
);
742 glUseProgram(new_prog
);
743 if (!piglit_check_gl_error(GL_NO_ERROR
))
744 piglit_report_result(PIGLIT_FAIL
);
747 glDeleteProgram(prog
);
748 if (!piglit_check_gl_error(GL_NO_ERROR
))
749 piglit_report_result(PIGLIT_FAIL
);
755 static enum piglit_result
756 specialize_spirv(GLenum target
,
760 printf("Cannot mix SPIR-V and non-SPIR-V shaders\n");
766 const struct specialization_list
*specs
;
769 case GL_VERTEX_SHADER
:
770 specs
= specializations
+ 0;
772 case GL_TESS_CONTROL_SHADER
:
773 specs
= specializations
+ 1;
775 case GL_TESS_EVALUATION_SHADER
:
776 specs
= specializations
+ 2;
778 case GL_GEOMETRY_SHADER
:
779 specs
= specializations
+ 3;
781 case GL_FRAGMENT_SHADER
:
782 specs
= specializations
+ 4;
784 case GL_COMPUTE_SHADER
:
785 specs
= specializations
+ 5;
788 assert(!"Should not get here.");
791 glSpecializeShaderARB(shader
,
795 &specs
->values
[0].u
);
798 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &ok
);
804 glGetShaderiv(shader
, GL_INFO_LOG_LENGTH
, &size
);
805 info
= malloc(MAX2(size
, 1));
808 glGetShaderInfoLog(shader
, size
, NULL
, info
);
810 printf("Failed to specialize %s: %s\n",
811 target_to_short_name(target
), info
);
818 case GL_VERTEX_SHADER
:
819 vertex_shaders
[num_vertex_shaders
] = shader
;
820 num_vertex_shaders
++;
822 case GL_TESS_CONTROL_SHADER
:
823 tess_ctrl_shaders
[num_tess_ctrl_shaders
] = shader
;
824 num_tess_ctrl_shaders
++;
826 case GL_TESS_EVALUATION_SHADER
:
827 tess_eval_shaders
[num_tess_eval_shaders
] = shader
;
828 num_tess_eval_shaders
++;
830 case GL_GEOMETRY_SHADER
:
831 geometry_shaders
[num_geometry_shaders
] = shader
;
832 num_geometry_shaders
++;
834 case GL_FRAGMENT_SHADER
:
835 fragment_shaders
[num_fragment_shaders
] = shader
;
836 num_fragment_shaders
++;
838 case GL_COMPUTE_SHADER
:
839 compute_shaders
[num_compute_shaders
] = shader
;
840 num_compute_shaders
++;
847 static enum piglit_result
848 assemble_spirv(GLenum target
)
850 if (!piglit_is_extension_supported("GL_ARB_gl_spirv")) {
854 /* Strip comments from the source */
855 char *stripped_source
= malloc(shader_string_size
);
856 char *p
= stripped_source
;
857 bool at_start_of_line
= true;
859 for (const char *in
= shader_string
;
860 in
< shader_string
+ shader_string_size
;
862 if (*in
== '#' && at_start_of_line
) {
866 shader_string
+ shader_string_size
- in
);
871 at_start_of_line
= *in
== '\n';
876 GLuint shader
= piglit_assemble_spirv(target
,
880 free(stripped_source
);
882 return specialize_spirv(target
, shader
);
885 static enum piglit_result
886 link_sso(GLenum target
)
892 glGetProgramiv(prog
, GL_LINK_STATUS
, &ok
);
898 glGetProgramiv(prog
, GL_INFO_LOG_LENGTH
, &size
);
899 prog_err_info
= malloc(MAX2(size
, 1));
900 prog_err_info
[0] = 0;
902 glGetProgramInfoLog(prog
, size
, NULL
, prog_err_info
);
904 fprintf(stderr
, "SSO glLinkProgram(%s) failed: %s\n",
905 target_to_short_name(target
),
912 if (!program_binary_save_restore(false))
916 case GL_VERTEX_SHADER
:
917 sso_vertex_prog
= prog
;
918 glUseProgramStages(pipeline
, GL_VERTEX_SHADER_BIT
, prog
);
920 case GL_TESS_CONTROL_SHADER
:
921 sso_tess_control_prog
= prog
;
922 glUseProgramStages(pipeline
, GL_TESS_CONTROL_SHADER_BIT
, prog
);
924 case GL_TESS_EVALUATION_SHADER
:
925 sso_tess_eval_prog
= prog
;
926 glUseProgramStages(pipeline
, GL_TESS_EVALUATION_SHADER_BIT
, prog
);
928 case GL_GEOMETRY_SHADER
:
929 sso_geometry_prog
= prog
;
930 glUseProgramStages(pipeline
, GL_GEOMETRY_SHADER_BIT
, prog
);
932 case GL_FRAGMENT_SHADER
:
933 sso_fragment_prog
= prog
;
934 glUseProgramStages(pipeline
, GL_FRAGMENT_SHADER_BIT
, prog
);
936 case GL_COMPUTE_SHADER
:
937 sso_compute_prog
= prog
;
938 glUseProgramStages(pipeline
, GL_COMPUTE_SHADER_BIT
, prog
);
945 * Compare two values given a specified comparison operator
948 compare(float ref
, float value
, enum comparison cmp
)
951 case equal
: return value
== ref
;
952 case not_equal
: return value
!= ref
;
953 case less
: return value
< ref
;
954 case greater_equal
: return value
>= ref
;
955 case greater
: return value
> ref
;
956 case less_equal
: return value
<= ref
;
959 assert(!"Should not get here.");
964 compare_double(double ref
, double value
, enum comparison cmp
)
967 case equal
: return fabs(value
- ref
) < DBL_EPSILON
;
968 case not_equal
: return fabs(value
- ref
) >= DBL_EPSILON
;
969 case less
: return value
< ref
;
970 case greater_equal
: return value
>= ref
;
971 case greater
: return value
> ref
;
972 case less_equal
: return value
<= ref
;
975 assert(!"Should not get here.");
980 compare_uint(GLuint ref
, GLuint value
, enum comparison cmp
)
983 case equal
: return value
== ref
;
984 case not_equal
: return value
!= ref
;
985 case less
: return value
< ref
;
986 case greater_equal
: return value
>= ref
;
987 case greater
: return value
> ref
;
988 case less_equal
: return value
<= ref
;
991 assert(!"Should not get here.");
996 compare_int(GLint ref
, GLint value
, enum comparison cmp
)
999 case equal
: return value
== ref
;
1000 case not_equal
: return value
!= ref
;
1001 case less
: return value
< ref
;
1002 case greater_equal
: return value
>= ref
;
1003 case greater
: return value
> ref
;
1004 case less_equal
: return value
<= ref
;
1007 assert(!"Should not get here.");
1012 compare_uint64(GLuint64 ref
, GLuint64 value
, enum comparison cmp
)
1015 case equal
: return value
== ref
;
1016 case not_equal
: return value
!= ref
;
1017 case less
: return value
< ref
;
1018 case greater_equal
: return value
>= ref
;
1019 case greater
: return value
> ref
;
1020 case less_equal
: return value
<= ref
;
1023 assert(!"Should not get here.");
1028 compare_int64(GLint64 ref
, GLint64 value
, enum comparison cmp
)
1031 case equal
: return value
== ref
;
1032 case not_equal
: return value
!= ref
;
1033 case less
: return value
< ref
;
1034 case greater_equal
: return value
>= ref
;
1035 case greater
: return value
> ref
;
1036 case less_equal
: return value
<= ref
;
1039 assert(!"Should not get here.");
1044 * Get the string representation of a comparison operator
1047 comparison_string(enum comparison cmp
)
1050 case equal
: return "==";
1051 case not_equal
: return "!=";
1052 case less
: return "<";
1053 case greater_equal
: return ">=";
1054 case greater
: return ">";
1055 case less_equal
: return "<=";
1058 assert(!"Should not get here.");
1063 * " ES" before the comparison operator indicates the version
1064 * pertains to GL ES.
1067 parse_version_comparison(const char *line
, enum comparison
*cmp
,
1068 struct component_version
*v
, enum version_tag tag
)
1073 const bool core
= parse_str(line
, "CORE", &line
);
1074 const bool compat
= parse_str(line
, "COMPAT", &line
);
1075 const bool es
= parse_str(line
, "ES", &line
);
1077 REQUIRE(parse_comparison_op(line
, cmp
, &line
),
1078 "Invalid comparison operation at: %s\n", line
);
1080 REQUIRE(parse_uint(line
, &major
, &line
) &&
1081 parse_str(line
, ".", &line
) &&
1082 parse_uint(line
, &minor
, &line
),
1083 "Invalid version string: %s\n", line
);
1085 parse_whitespace(line
, &line
);
1086 if (*line
!= '\n') {
1087 printf("Unexpected characters following version comparison\n");
1088 piglit_report_result(PIGLIT_FAIL
);
1091 /* This hack is so that we can tell the difference between GL versions
1092 * and GLSL versions. All GL versions look like 3.2, and we want the
1093 * integer to be 32. All GLSL versions look like 1.40, and we want
1094 * the integer to be 140.
1096 if (tag
== VERSION_GLSL
) {
1097 full_num
= (major
* 100) + minor
;
1099 full_num
= (major
* 10) + minor
;
1102 version_init(v
, tag
, core
, compat
, es
, full_num
);
1106 * Parse and check a line from the requirement section of the test
1108 static enum piglit_result
1109 process_requirement(const char *line
)
1112 static const struct {
1116 } getint_limits
[] = {
1118 "GL_MAX_VERTEX_OUTPUT_COMPONENTS",
1119 &gl_max_vertex_output_components
,
1120 "vertex output components",
1123 "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS",
1124 &gl_max_fragment_uniform_components
,
1125 "fragment uniform components",
1128 "GL_MAX_VERTEX_UNIFORM_COMPONENTS",
1129 &gl_max_vertex_uniform_components
,
1130 "vertex uniform components",
1133 "GL_MAX_VERTEX_ATTRIBS",
1134 &gl_max_vertex_attribs
,
1138 "GL_MAX_VARYING_COMPONENTS",
1139 &gl_max_varying_components
,
1140 "varying components",
1143 "GL_NUM_PROGRAM_BINARY_FORMATS",
1144 &gl_num_program_binary_formats
,
1145 "num program binary formats",
1150 /* The INT keyword in the requirements section causes
1151 * shader_runner to read the specified integer value and
1152 * processes the given requirement.
1154 if (parse_str(line
, "INT ", &line
)) {
1155 enum comparison cmp
;
1156 int comparison_value
, gl_int_value
;
1159 REQUIRE(parse_enum_gl(line
, &int_enum
, &line
),
1160 "Invalid comparison enum at: %s\n", line
);
1161 REQUIRE(parse_comparison_op(line
, &cmp
, &line
),
1162 "Invalid comparison operation at: %s\n", line
);
1163 REQUIRE(parse_int(line
, &comparison_value
, &line
),
1164 "Invalid comparison value at: %s\n", line
);
1166 glGetIntegerv(int_enum
, &gl_int_value
);
1167 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
1168 fprintf(stderr
, "Error reading %s\n",
1169 piglit_get_gl_enum_name(int_enum
));
1173 if (!compare(comparison_value
, gl_int_value
, cmp
)) {
1174 printf("Test requires %s %s %i. "
1175 "The driver supports %i.\n",
1176 piglit_get_gl_enum_name(int_enum
),
1177 comparison_string(cmp
),
1186 /* There are five types of requirements that a test can currently
1189 * * Require that some GL extension be supported
1190 * * Require some particular versions of GL
1191 * * Require some particular versions of GLSL
1192 * * Require some particular number of uniform components
1193 * * Require shaders be built as separate shader objects
1195 * The tests for GL and GLSL versions can be equal, not equal,
1196 * less, less-or-equal, greater, or greater-or-equal. Extension tests
1197 * can also require that a particular extension not be supported by
1198 * prepending ! to the extension name.
1200 for (i
= 0; i
< ARRAY_SIZE(getint_limits
); i
++) {
1201 enum comparison cmp
;
1204 if (!parse_str(line
, getint_limits
[i
].name
, &line
))
1207 REQUIRE(parse_comparison_op(line
, &cmp
, &line
),
1208 "Invalid comparison operation at: %s\n", line
);
1210 maxcomp
= atoi(line
);
1211 if (!compare(maxcomp
, *getint_limits
[i
].val
, cmp
)) {
1212 printf("Test requires %s %s %i. "
1213 "The driver supports %i.\n",
1214 getint_limits
[i
].desc
,
1215 comparison_string(cmp
),
1217 *getint_limits
[i
].val
);
1223 if (parse_str(line
, "GL_", NULL
) &&
1224 parse_word_copy(line
, buffer
, sizeof(buffer
), &line
)) {
1225 if (!piglit_is_extension_supported(buffer
)) {
1226 printf("Test requires unsupported extension %s\n", buffer
);
1229 } else if (parse_str(line
, "!", &line
) &&
1230 parse_str(line
, "GL_", NULL
) &&
1231 parse_word_copy(line
, buffer
, sizeof(buffer
), &line
)) {
1232 if (piglit_is_extension_supported(buffer
)) {
1233 printf("Test requires unsupported extension %s\n", buffer
);
1236 } else if (parse_str(line
, "GLSL", &line
)) {
1237 enum comparison cmp
;
1239 parse_version_comparison(line
, &cmp
, &glsl_req_version
,
1242 /* We only allow >= because we potentially use the
1243 * version number to insert a #version directive. */
1244 if (cmp
!= greater_equal
) {
1245 printf("Unsupported GLSL version comparison\n");
1249 if (!version_compare(&glsl_req_version
, &glsl_version
, cmp
)) {
1250 printf("Test requires %s %s. "
1251 "Actual version %s.\n",
1252 comparison_string(cmp
),
1253 version_string(&glsl_req_version
),
1254 version_string(&glsl_version
));
1257 } else if (parse_str(line
, "GL", &line
)) {
1258 enum comparison cmp
;
1259 struct component_version gl_req_version
;
1261 parse_version_comparison(line
, &cmp
, &gl_req_version
,
1264 if (!version_compare(&gl_req_version
, &gl_version
, cmp
)) {
1265 printf("Test requires %s %s. "
1266 "Actual version is %s.\n",
1267 comparison_string(cmp
),
1268 version_string(&gl_req_version
),
1269 version_string(&gl_version
));
1272 } else if (parse_str(line
, "rlimit", &line
)) {
1275 REQUIRE(parse_uint(line
, &lim
, &line
),
1276 "Invalid rlimit argument at: %s\n", line
);
1278 piglit_set_rlimit(lim
);
1279 } else if (parse_str(line
, "SSO", &line
) &&
1280 parse_str(line
, "ENABLED", NULL
)) {
1281 if (separable_program
) {
1282 printf("SSO and SEPARABLE PROGRAM directives are incompatible.\n");
1286 const char *const ext_name
= gl_version
.es
1287 ? "GL_EXT_separate_shader_objects"
1288 : "GL_ARB_separate_shader_objects";
1289 const unsigned min_version
= gl_version
.es
1292 if (gl_version
.num
< min_version
)
1293 piglit_require_extension(ext_name
);
1296 glGenProgramPipelines(1, &pipeline
);
1297 } else if (parse_str(line
, "SEPARABLE PROGRAM", &line
) &&
1298 parse_str(line
, "ENABLED", NULL
)) {
1300 printf("SSO and SEPARABLE PROGRAM directives are incompatible.\n");
1304 const char *const ext_name
= gl_version
.es
1305 ? "GL_EXT_separate_shader_objects"
1306 : "GL_ARB_separate_shader_objects";
1307 const unsigned min_version
= gl_version
.es
1310 if (gl_version
.num
< min_version
)
1311 piglit_require_extension(ext_name
);
1313 separable_program
= true;
1314 } else if (parse_str(line
, "SPIRV", &line
)) {
1315 spirv_replaces_glsl
= !force_glsl
;
1317 if (parse_str(line
, "ONLY", NULL
)) {
1319 printf("This shader is not compatible with GLSL\n");
1322 } else if (parse_str(line
, "YES", NULL
)) {
1323 /* Empty. Everything already set. Just parsing
1327 printf("Unknown SPIRV line in [require]\n");
1331 if (spirv_replaces_glsl
)
1332 force_no_names
= true;
1333 } else if (parse_str(line
, "ignore_missing_uniforms", &line
)) {
1334 ignore_missing_uniforms
= true;
1341 * Process a line from the [geometry layout] section of a test
1344 process_geometry_layout(const char *line
)
1349 parse_whitespace(line
, &line
);
1351 if (line
[0] == '\0' || line
[0] == '\n') {
1353 } else if (sscanf(line
, "input type %31s", s
) == 1) {
1354 geometry_layout_input_type
= decode_drawing_mode(s
);
1355 } else if (sscanf(line
, "output type %31s", s
) == 1) {
1356 geometry_layout_output_type
= decode_drawing_mode(s
);
1357 } else if (sscanf(line
, "vertices out %d", &x
) == 1) {
1358 geometry_layout_vertices_out
= x
;
1360 printf("Could not parse geometry layout line: %s\n", line
);
1361 piglit_report_result(PIGLIT_FAIL
);
1365 static enum piglit_result
1366 leave_state(enum states state
, const char *line
, const char *script_name
)
1373 if (spirv_replaces_glsl
) {
1374 printf("Running on SPIR-V mode\n");
1376 if (force_no_names
&& !spirv_replaces_glsl
) {
1377 printf("Running on GLSL mode, forcing not using "
1378 "uniform/uniform block names\n");
1383 if (spirv_replaces_glsl
)
1385 shader_string_size
= line
- shader_string
;
1386 return compile_glsl(GL_VERTEX_SHADER
);
1388 case vertex_shader_passthrough
:
1389 if (spirv_replaces_glsl
) {
1390 shader_string
= (char *) passthrough_vertex_shader_source_spv
;
1391 shader_string_size
= strlen(passthrough_vertex_shader_source_spv
);
1393 return assemble_spirv(GL_VERTEX_SHADER
);
1395 return compile_glsl(GL_VERTEX_SHADER
);
1397 case vertex_program
:
1398 return compile_and_bind_program(GL_VERTEX_PROGRAM_ARB
,
1400 line
- shader_string
);
1402 case vertex_shader_spirv
:
1403 if (!spirv_replaces_glsl
)
1405 shader_string_size
= line
- shader_string
;
1406 return assemble_spirv(GL_VERTEX_SHADER
);
1408 case vertex_shader_specializations
:
1411 case tess_ctrl_shader
:
1412 if (spirv_replaces_glsl
)
1414 shader_string_size
= line
- shader_string
;
1415 return compile_glsl(GL_TESS_CONTROL_SHADER
);
1417 case tess_ctrl_shader_spirv
:
1418 if (!spirv_replaces_glsl
)
1420 shader_string_size
= line
- shader_string
;
1421 return assemble_spirv(GL_TESS_CONTROL_SHADER
);
1423 case tess_ctrl_shader_specializations
:
1426 case tess_eval_shader
:
1427 if (spirv_replaces_glsl
)
1429 shader_string_size
= line
- shader_string
;
1430 return compile_glsl(GL_TESS_EVALUATION_SHADER
);
1432 case tess_eval_shader_spirv
:
1433 if (!spirv_replaces_glsl
)
1435 shader_string_size
= line
- shader_string
;
1436 return assemble_spirv(GL_TESS_EVALUATION_SHADER
);
1438 case tess_eval_shader_specializations
:
1441 case geometry_shader
:
1442 if (spirv_replaces_glsl
)
1444 shader_string_size
= line
- shader_string
;
1445 return compile_glsl(GL_GEOMETRY_SHADER
);
1447 case geometry_shader_spirv
:
1448 if (!spirv_replaces_glsl
)
1450 shader_string_size
= line
- shader_string
;
1451 return assemble_spirv(GL_GEOMETRY_SHADER
);
1453 case geometry_shader_specializations
:
1456 case geometry_layout
:
1459 case fragment_shader
:
1460 if (spirv_replaces_glsl
)
1462 shader_string_size
= line
- shader_string
;
1463 return compile_glsl(GL_FRAGMENT_SHADER
);
1465 case fragment_program
:
1466 return compile_and_bind_program(GL_FRAGMENT_PROGRAM_ARB
,
1468 line
- shader_string
);
1471 case fragment_shader_spirv
:
1472 if (!spirv_replaces_glsl
)
1474 shader_string_size
= line
- shader_string
;
1475 return assemble_spirv(GL_FRAGMENT_SHADER
);
1477 case fragment_shader_specializations
:
1480 case compute_shader
:
1481 if (spirv_replaces_glsl
)
1483 shader_string_size
= line
- shader_string
;
1484 return compile_glsl(GL_COMPUTE_SHADER
);
1486 case compute_shader_spirv
:
1487 if (!spirv_replaces_glsl
)
1489 shader_string_size
= line
- shader_string
;
1490 return assemble_spirv(GL_COMPUTE_SHADER
);
1492 case compute_shader_specializations
:
1496 vertex_data_end
= line
;
1499 case shader_include
: {
1500 const char *path_end
= strchrnul(shader_string
, '\n');
1502 if (shader_string
== path_end
) {
1503 fprintf(stderr
, "No shader include path provided\n");
1507 if (!piglit_is_extension_supported("GL_ARB_shading_language_include"))
1510 int path_name_len
= path_end
- shader_string
;
1511 glNamedStringARB(GL_SHADER_INCLUDE_ARB
, path_name_len
, shader_string
,
1512 line
- shader_string
- path_name_len
, shader_string
+ path_name_len
);
1514 shader_include_names
[num_shader_includes
] = strndup(shader_string
, path_name_len
);
1515 num_shader_includes
++;
1516 assert(num_shader_includes
<= 256);
1518 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
1519 fprintf(stderr
, "glNamedStringARB error\n");
1526 case shader_include_paths
: {
1527 num_shader_include_paths
= 0;
1528 const char *cursor
= shader_string
;
1530 const char *line_start
= cursor
;
1531 cursor
= strchr(cursor
, '\n');
1533 if (cursor
== line_start
) {
1539 num_shader_include_paths
++;
1540 } while (cursor
&& cursor
< line
);
1542 shader_include_path
= calloc(num_shader_include_paths
, sizeof(char *));
1544 cursor
= shader_string
;
1545 for (unsigned i
= 0; i
< num_shader_include_paths
; i
++) {
1546 char *line_end
= strchr(cursor
, '\n');
1547 unsigned path_len
= line_end
- cursor
- 1;
1548 char *path
= malloc(path_len
+ 1);
1549 path
[path_len
] = '\0';
1551 memcpy(path
, cursor
, path_len
);
1552 shader_include_path
[i
] = path
;
1553 cursor
= line_end
+ 1;
1563 assert(!"Not yet supported.");
1569 static enum piglit_result
1570 process_shader(GLenum target
, unsigned num_shaders
, GLuint
*shaders
)
1572 if (num_shaders
== 0)
1576 prog
= glCreateProgram();
1577 glProgramParameteri(prog
, GL_PROGRAM_SEPARABLE
, GL_TRUE
);
1580 for (unsigned i
= 0; i
< num_shaders
; i
++) {
1581 glAttachShader(prog
, shaders
[i
]);
1584 #ifdef PIGLIT_USE_OPENGL
1585 if (geometry_layout_input_type
!= GL_TRIANGLES
) {
1586 glProgramParameteriARB(prog
, GL_GEOMETRY_INPUT_TYPE_ARB
,
1587 geometry_layout_input_type
);
1589 if (geometry_layout_output_type
!= GL_TRIANGLE_STRIP
) {
1590 glProgramParameteriARB(prog
, GL_GEOMETRY_OUTPUT_TYPE_ARB
,
1591 geometry_layout_output_type
);
1593 if (geometry_layout_vertices_out
!= 0) {
1594 glProgramParameteriARB(prog
, GL_GEOMETRY_VERTICES_OUT_ARB
,
1595 geometry_layout_vertices_out
);
1599 /* If the shaders reference piglit_vertex or piglit_tex, bind
1600 * them to some fixed attribute locations so they can be used
1601 * with piglit_draw_rect_tex() in GLES.
1603 glBindAttribLocation(prog
, PIGLIT_ATTRIB_POS
, "piglit_vertex");
1604 glBindAttribLocation(prog
, PIGLIT_ATTRIB_TEX
, "piglit_texcoord");
1607 return link_sso(target
);
1613 static enum piglit_result
1614 link_and_use_shaders(void)
1616 enum piglit_result result
;
1621 if ((num_vertex_shaders
== 0)
1622 && (num_fragment_shaders
== 0)
1623 && (num_tess_ctrl_shaders
== 0)
1624 && (num_tess_eval_shaders
== 0)
1625 && (num_geometry_shaders
== 0)
1626 && (num_compute_shaders
== 0))
1630 prog
= glCreateProgram();
1632 result
= process_shader(GL_VERTEX_SHADER
, num_vertex_shaders
, vertex_shaders
);
1633 if (result
!= PIGLIT_PASS
)
1635 result
= process_shader(GL_TESS_CONTROL_SHADER
, num_tess_ctrl_shaders
, tess_ctrl_shaders
);
1636 if (result
!= PIGLIT_PASS
)
1638 result
= process_shader(GL_TESS_EVALUATION_SHADER
, num_tess_eval_shaders
, tess_eval_shaders
);
1639 if (result
!= PIGLIT_PASS
)
1641 result
= process_shader(GL_GEOMETRY_SHADER
, num_geometry_shaders
, geometry_shaders
);
1642 if (result
!= PIGLIT_PASS
)
1644 result
= process_shader(GL_FRAGMENT_SHADER
, num_fragment_shaders
, fragment_shaders
);
1645 if (result
!= PIGLIT_PASS
)
1647 result
= process_shader(GL_COMPUTE_SHADER
, num_compute_shaders
, compute_shaders
);
1648 if (result
!= PIGLIT_PASS
)
1652 if (separable_program
)
1653 glProgramParameteri(prog
, GL_PROGRAM_SEPARABLE
, GL_TRUE
);
1655 glLinkProgram(prog
);
1659 if (!program_binary_save_restore(false))
1661 glGetProgramiv(prog
, GL_LINK_STATUS
, &ok
);
1667 glGetProgramiv(prog
, GL_INFO_LOG_LENGTH
, &size
);
1668 prog_err_info
= malloc(MAX2(size
, 1));
1669 prog_err_info
[0] = 0;
1671 glGetProgramInfoLog(prog
, size
, NULL
, prog_err_info
);
1673 result
= PIGLIT_PASS
;
1686 glGetProgramiv(prog
, GL_INFO_LOG_LENGTH
, &size
);
1687 prog_err_info
= malloc(MAX2(size
, 1));
1688 prog_err_info
[0] = 0;
1690 glGetProgramInfoLog(prog
, size
, NULL
, prog_err_info
);
1694 for (i
= 0; i
< num_vertex_shaders
; i
++) {
1695 glDeleteShader(vertex_shaders
[i
]);
1697 num_vertex_shaders
= 0;
1699 for (i
= 0; i
< num_tess_ctrl_shaders
; i
++) {
1700 glDeleteShader(tess_ctrl_shaders
[i
]);
1702 num_tess_ctrl_shaders
= 0;
1704 for (i
= 0; i
< num_tess_eval_shaders
; i
++) {
1705 glDeleteShader(tess_eval_shaders
[i
]);
1707 num_tess_eval_shaders
= 0;
1709 for (i
= 0; i
< num_geometry_shaders
; i
++) {
1710 glDeleteShader(geometry_shaders
[i
]);
1712 num_geometry_shaders
= 0;
1714 for (i
= 0; i
< num_fragment_shaders
; i
++) {
1715 glDeleteShader(fragment_shaders
[i
]);
1717 num_fragment_shaders
= 0;
1719 for (i
= 0; i
< num_compute_shaders
; i
++) {
1720 glDeleteShader(compute_shaders
[i
]);
1722 num_compute_shaders
= 0;
1727 static enum piglit_result
1728 process_specialization(enum states state
, const char *line
)
1730 const char *end
= strchrnul(line
, '\n');
1732 enum { TYPE_FLOAT
, TYPE_UINT
} type
;
1734 while (line
< end
&& isspace(*line
))
1737 if (line
>= end
|| *line
== '#')
1740 if (parse_str(line
, "uint", &next
))
1742 else if (parse_str(line
, "float", &next
))
1747 struct specialization_list
*list
;
1750 case vertex_shader_specializations
:
1751 list
= specializations
+ 0;
1753 case tess_ctrl_shader_specializations
:
1754 list
= specializations
+ 1;
1756 case tess_eval_shader_specializations
:
1757 list
= specializations
+ 2;
1759 case geometry_shader_specializations
:
1760 list
= specializations
+ 3;
1762 case fragment_shader_specializations
:
1763 list
= specializations
+ 4;
1765 case compute_shader_specializations
:
1766 list
= specializations
+ 5;
1769 assert(!"Should not get here.");
1772 if (list
->n_entries
>= list
->buffer_size
) {
1773 if (list
->buffer_size
== 0)
1774 list
->buffer_size
= 1;
1776 list
->buffer_size
*= 2;
1777 list
->indices
= realloc(list
->indices
,
1778 (sizeof list
->indices
[0]) *
1780 list
->values
= realloc(list
->values
,
1781 (sizeof list
->values
[0]) *
1785 if (parse_uints(next
, list
->indices
+ list
->n_entries
, 1, &next
) != 1)
1790 if (parse_uints(next
,
1791 &list
->values
[list
->n_entries
].u
,
1797 if (parse_floats(next
,
1798 &list
->values
[list
->n_entries
].f
,
1810 fprintf(stderr
, "Invalid specialization line\n");
1814 static enum piglit_result
1815 process_test_script(const char *script_name
)
1819 char *text
= piglit_load_text_file(script_name
, &text_size
);
1820 enum states state
= none
;
1821 const char *line
= text
;
1822 enum piglit_result result
;
1825 printf("could not read file \"%s\"\n", script_name
);
1831 while (line
[0] != '\0') {
1832 if (line
[0] == '[') {
1833 result
= leave_state(state
, line
, script_name
);
1834 if (result
!= PIGLIT_PASS
)
1837 if (parse_str(line
, "[require]", NULL
)) {
1838 state
= requirements
;
1839 } else if (parse_str(line
, "[vertex shader]", NULL
)) {
1840 state
= vertex_shader
;
1841 shader_string
= NULL
;
1842 } else if (parse_str(line
, "[vertex program]", NULL
)) {
1843 state
= vertex_program
;
1844 shader_string
= NULL
;
1845 } else if (parse_str(line
, "[vertex shader passthrough]", NULL
)) {
1846 state
= vertex_shader_passthrough
;
1848 (char *) passthrough_vertex_shader_source
;
1849 shader_string_size
= strlen(shader_string
);
1850 } else if (parse_str(line
, "[vertex shader spirv]", NULL
)) {
1851 state
= vertex_shader_spirv
;
1852 shader_string
= NULL
;
1853 } else if (parse_str(line
, "[vertex shader specializations]", NULL
)) {
1854 state
= vertex_shader_specializations
;
1855 } else if (parse_str(line
, "[tessellation control shader]", NULL
)) {
1856 state
= tess_ctrl_shader
;
1857 shader_string
= NULL
;
1858 } else if (parse_str(line
, "[tessellation control shader spirv]", NULL
)) {
1859 state
= tess_ctrl_shader_spirv
;
1860 shader_string
= NULL
;
1861 } else if (parse_str(line
, "[tessellation control shader specializations]", NULL
)) {
1862 state
= tess_ctrl_shader_specializations
;
1863 } else if (parse_str(line
, "[tessellation evaluation shader]", NULL
)) {
1864 state
= tess_eval_shader
;
1865 shader_string
= NULL
;
1866 } else if (parse_str(line
, "[tessellation evaluation shader spirv]", NULL
)) {
1867 state
= tess_eval_shader_spirv
;
1868 shader_string
= NULL
;
1869 } else if (parse_str(line
, "[tessellation evaluation shader specializations]", NULL
)) {
1870 state
= tess_eval_shader_specializations
;
1871 } else if (parse_str(line
, "[geometry shader]", NULL
)) {
1872 state
= geometry_shader
;
1873 shader_string
= NULL
;
1874 } else if (parse_str(line
, "[geometry shader specializations]", NULL
)) {
1875 state
= geometry_shader_specializations
;
1876 } else if (parse_str(line
, "[geometry shader spirv]", NULL
)) {
1877 state
= geometry_shader_spirv
;
1878 shader_string
= NULL
;
1879 } else if (parse_str(line
, "[geometry shader specializations]", NULL
)) {
1880 state
= geometry_shader_specializations
;
1881 } else if (parse_str(line
, "[geometry layout]", NULL
)) {
1882 state
= geometry_layout
;
1883 shader_string
= NULL
;
1884 } else if (parse_str(line
, "[fragment shader]", NULL
)) {
1885 state
= fragment_shader
;
1886 shader_string
= NULL
;
1887 } else if (parse_str(line
, "[fragment program]", NULL
)) {
1888 state
= fragment_program
;
1889 shader_string
= NULL
;
1890 } else if (parse_str(line
, "[fragment shader specializations]", NULL
)) {
1891 state
= fragment_shader_specializations
;
1892 } else if (parse_str(line
, "[fragment shader spirv]", NULL
)) {
1893 state
= fragment_shader_spirv
;
1894 shader_string
= NULL
;
1895 } else if (parse_str(line
, "[fragment shader specializations]", NULL
)) {
1896 state
= fragment_shader_specializations
;
1897 } else if (parse_str(line
, "[compute shader]", NULL
)) {
1898 state
= compute_shader
;
1899 shader_string
= NULL
;
1900 } else if (parse_str(line
, "[compute shader spirv]", NULL
)) {
1901 state
= compute_shader_spirv
;
1902 shader_string
= NULL
;
1903 } else if (parse_str(line
, "[compute shader specializations]", NULL
)) {
1904 state
= compute_shader_specializations
;
1905 } else if (parse_str(line
, "[vertex data]", NULL
)) {
1906 state
= vertex_data
;
1907 vertex_data_start
= NULL
;
1908 } else if (parse_str(line
, "[shader include]", NULL
)) {
1909 state
= shader_include
;
1910 shader_string
= NULL
;
1911 } else if (parse_str(line
, "[shader include paths]", NULL
)) {
1912 state
= shader_include_paths
;
1913 shader_string
= NULL
;
1914 } else if (parse_str(line
, "[test]", NULL
)) {
1915 test_start
= strchrnul(line
, '\n');
1916 test_start_line_num
= line_num
+ 1;
1917 if (test_start
[0] != '\0')
1922 "Unknown section in test script. "
1923 "Perhaps missing closing ']'?\n");
1929 case vertex_shader_passthrough
:
1933 result
= process_requirement(line
);
1934 if (result
!= PIGLIT_PASS
)
1938 case geometry_layout
:
1939 process_geometry_layout(line
);
1943 case vertex_program
:
1944 case tess_ctrl_shader
:
1945 case tess_eval_shader
:
1946 case geometry_shader
:
1947 case fragment_shader
:
1948 case fragment_program
:
1949 case compute_shader
:
1950 case vertex_shader_spirv
:
1951 case tess_ctrl_shader_spirv
:
1952 case tess_eval_shader_spirv
:
1953 case geometry_shader_spirv
:
1954 case fragment_shader_spirv
:
1955 case compute_shader_spirv
:
1956 case shader_include
:
1957 case shader_include_paths
:
1958 if (shader_string
== NULL
)
1959 shader_string
= (char *) line
;
1962 case vertex_shader_specializations
:
1963 case tess_ctrl_shader_specializations
:
1964 case tess_eval_shader_specializations
:
1965 case geometry_shader_specializations
:
1966 case fragment_shader_specializations
:
1967 case compute_shader_specializations
: {
1968 enum piglit_result result
=
1969 process_specialization(state
, line
);
1970 if (result
!= PIGLIT_PASS
)
1976 if (vertex_data_start
== NULL
)
1977 vertex_data_start
= line
;
1985 line
= strchrnul(line
, '\n');
1986 if (line
[0] != '\0')
1992 return leave_state(state
, line
, script_name
);
1995 struct requirement_parse_results
{
1999 bool found_depthbuffer
;
2000 struct component_version gl_version
;
2001 struct component_version glsl_version
;
2006 parse_required_config(struct requirement_parse_results
*results
,
2007 const char *script_name
)
2010 char *text
= piglit_load_text_file(script_name
, &text_size
);
2011 const char *line
= text
;
2012 bool in_requirement_section
= false;
2014 results
->found_gl
= false;
2015 results
->found_glsl
= false;
2016 results
->found_size
= false;
2017 results
->found_depthbuffer
= false;
2020 printf("could not read file \"%s\"\n", script_name
);
2021 piglit_report_result(PIGLIT_FAIL
);
2024 while (line
[0] != '\0') {
2025 if (line
[0] == '[') {
2026 if (in_requirement_section
)
2029 in_requirement_section
= false;
2032 if (!in_requirement_section
) {
2033 if (parse_str(line
, "[require]", NULL
)) {
2034 in_requirement_section
= true;
2037 if (parse_str(line
, "GL_", NULL
)
2038 || parse_str(line
, "!GL_", NULL
)) {
2040 } else if (parse_str(line
, "GLSL", &line
)) {
2041 enum comparison cmp
;
2042 struct component_version version
;
2044 parse_version_comparison(line
, &cmp
,
2045 &version
, VERSION_GLSL
);
2046 if (cmp
== greater_equal
) {
2047 results
->found_glsl
= true;
2048 version_copy(&results
->glsl_version
, &version
);
2050 } else if (parse_str(line
, "GL", &line
)) {
2051 enum comparison cmp
;
2052 struct component_version version
;
2054 parse_version_comparison(line
, &cmp
,
2055 &version
, VERSION_GL
);
2056 if (cmp
== greater_equal
2059 results
->found_gl
= true;
2060 version_copy(&results
->gl_version
, &version
);
2062 } else if (parse_str(line
, "SIZE", &line
)) {
2063 results
->found_size
= true;
2064 parse_uints(line
, results
->size
, 2, NULL
);
2065 } else if (parse_str(line
, "depthbuffer", NULL
)) {
2066 results
->found_depthbuffer
= true;
2070 line
= strchrnul(line
, '\n');
2071 if (line
[0] != '\0')
2077 if (!in_requirement_section
) {
2078 printf("[require] section missing\n");
2079 piglit_report_result(PIGLIT_FAIL
);
2082 if (results
->found_glsl
&& results
->glsl_version
.es
&& !results
->found_gl
) {
2083 printf("%s", "The test specifies a requirement for GLSL ES, "
2084 "but specifies no GL requirement\n.");
2085 piglit_report_result(PIGLIT_FAIL
);
2091 choose_required_gl_version(struct requirement_parse_results
*parse_results
,
2092 struct component_version
*gl_version
)
2094 if (parse_results
->found_gl
) {
2095 version_copy(gl_version
, &parse_results
->gl_version
);
2097 assert(!parse_results
->found_glsl
|| !parse_results
->glsl_version
.es
);
2098 version_init(gl_version
, VERSION_GL
, false, false, false, 10);
2104 /* Possibly promote the GL version. */
2105 if (parse_results
->found_glsl
2106 && gl_version
->num
< required_gl_version_from_glsl_version(
2107 parse_results
->glsl_version
.num
)) {
2108 gl_version
->num
= required_gl_version_from_glsl_version(
2109 parse_results
->glsl_version
.num
);
2114 * Just determine the GLSL version required by the shader script.
2116 * This function is a bit of a hack that is, unfortunately necessary. A test
2117 * script can require a specific GLSL version or a specific GL version. To
2118 * satisfy this requirement, the piglit framework code needs to know about the
2119 * requirement before creating the context. However, the requirements section
2120 * can contain other requirements, such as minimum number of uniforms.
2122 * The requirements section can't be fully processed until after the context
2123 * is created, but the context can't be created until after the requirements
2124 * section is processed. Do a quick scan over the requirements section to find
2125 * the GL and GLSL version requirements. Use these to guide context creation.
2128 get_required_config(const char *script_name
, bool spirv
,
2129 struct piglit_gl_test_config
*config
)
2131 struct requirement_parse_results parse_results
;
2132 struct component_version required_gl_version
;
2134 parse_required_config(&parse_results
, script_name
);
2135 choose_required_gl_version(&parse_results
, &required_gl_version
);
2138 required_gl_version
.es
= false;
2139 required_gl_version
.core
= true;
2140 required_gl_version
.num
= MAX2(required_gl_version
.num
, 33);
2143 if (parse_results
.found_size
) {
2144 config
->window_width
= parse_results
.size
[0];
2145 config
->window_height
= parse_results
.size
[1];
2148 if (required_gl_version
.es
) {
2149 config
->supports_gl_es_version
= required_gl_version
.num
;
2150 } else if (required_gl_version
.num
>= 31) {
2151 if (!required_gl_version
.compat
)
2152 config
->supports_gl_core_version
= required_gl_version
.num
;
2153 if (!required_gl_version
.core
)
2154 config
->supports_gl_compat_version
= required_gl_version
.num
;
2156 config
->supports_gl_compat_version
= 10;
2159 if (parse_results
.found_depthbuffer
) {
2160 config
->window_visual
|= PIGLIT_GL_VISUAL_DEPTH
;
2165 * Check that the GL implementation supports unsigned uniforms
2166 * (e.g. through glUniform1ui). If not, terminate the test with a
2170 check_unsigned_support(void)
2172 if (gl_version
.num
< 30 && !piglit_is_extension_supported("GL_EXT_gpu_shader4"))
2173 piglit_report_result(PIGLIT_SKIP
);
2177 * Check that the GL implementation supports double uniforms
2178 * (e.g. through glUniform1d). If not, terminate the test with a
2182 check_double_support(void)
2184 if (gl_version
.num
< 40 && !piglit_is_extension_supported("GL_ARB_gpu_shader_fp64"))
2185 piglit_report_result(PIGLIT_SKIP
);
2189 * Check that the GL implementation supports double uniforms
2190 * (e.g. through glUniform1d). If not, terminate the test with a
2194 check_int64_support(void)
2196 if (!piglit_is_extension_supported("GL_ARB_gpu_shader_int64"))
2197 piglit_report_result(PIGLIT_SKIP
);
2201 * Check that the GL implementation supports shader subroutines
2202 * If not, terminate the test with a SKIP.
2205 check_shader_subroutine_support(void)
2207 if (gl_version
.num
< 40 && !piglit_is_extension_supported("GL_ARB_shader_subroutine"))
2208 piglit_report_result(PIGLIT_SKIP
);
2212 * Check that the GL implementation supports texture handles.
2213 * If not, terminate the test with a SKIP.
2216 check_texture_handle_support(void)
2218 if (!piglit_is_extension_supported("GL_ARB_bindless_texture"))
2219 piglit_report_result(PIGLIT_SKIP
);
2223 get_indexes_and_offset_from_ubo(char *name
, struct block_info block_data
,
2224 GLuint
*uniform_index_out
,
2225 GLint
*block_index_out
,
2229 * Handles uploads of UBO uniforms by mapping the buffer and storing
2230 * the data. If the uniform is not in a uniform block, returns false.
2233 set_ubo_uniform(char *name
, const char *type
,
2235 struct block_info block_data
)
2237 /* Note: on SPIR-V we can't access to uniform_index as we
2238 * could lack the name. We force that with force_no_names on
2241 GLuint uniform_index
;
2249 uint64_t uint64s
[16];
2252 if (!get_indexes_and_offset_from_ubo(name
, block_data
, &uniform_index
,
2253 &block_index
, &offset
)) {
2257 glBindBuffer(GL_UNIFORM_BUFFER
,
2258 uniform_block_bos
[block_index
]);
2259 data
= glMapBuffer(GL_UNIFORM_BUFFER
, GL_WRITE_ONLY
);
2262 if (parse_str(type
, "float", NULL
)) {
2263 parse_floats(line
, f
, 1, NULL
);
2264 memcpy(data
, f
, sizeof(float));
2265 } else if (parse_str(type
, "int64_t", NULL
)) {
2266 parse_int64s(line
, int64s
, 1, NULL
);
2267 memcpy(data
, int64s
, sizeof(int64_t));
2268 } else if (parse_str(type
, "uint64_t", NULL
)) {
2269 parse_uint64s(line
, uint64s
, 1, NULL
);
2270 memcpy(data
, uint64s
, sizeof(uint64_t));
2271 } else if (parse_str(type
, "int", NULL
)) {
2272 parse_ints(line
, ints
, 1, NULL
);
2273 memcpy(data
, ints
, sizeof(int));
2274 } else if (parse_str(type
, "uint", NULL
)) {
2275 parse_uints(line
, uints
, 1, NULL
);
2276 memcpy(data
, uints
, sizeof(int));
2277 } else if (parse_str(type
, "double", NULL
)) {
2278 parse_doubles(line
, d
, 1, NULL
);
2279 memcpy(data
, d
, sizeof(double));
2280 } else if (parse_str(type
, "vec", NULL
)) {
2281 int elements
= type
[3] - '0';
2282 parse_floats(line
, f
, elements
, NULL
);
2283 memcpy(data
, f
, elements
* sizeof(float));
2284 } else if (parse_str(type
, "ivec", NULL
)) {
2285 int elements
= type
[4] - '0';
2286 parse_ints(line
, ints
, elements
, NULL
);
2287 memcpy(data
, ints
, elements
* sizeof(int));
2288 } else if (parse_str(type
, "uvec", NULL
)) {
2289 int elements
= type
[4] - '0';
2290 parse_uints(line
, uints
, elements
, NULL
);
2291 memcpy(data
, uints
, elements
* sizeof(unsigned));
2292 } else if (parse_str(type
, "i64vec", NULL
)) {
2293 int elements
= type
[6] - '0';
2294 parse_int64s(line
, int64s
, elements
, NULL
);
2295 memcpy(data
, int64s
, elements
* sizeof(int64_t));
2296 } else if (parse_str(type
, "u64vec", NULL
)) {
2297 int elements
= type
[6] - '0';
2298 parse_uint64s(line
, uint64s
, elements
, NULL
);
2299 memcpy(data
, uint64s
, elements
* sizeof(uint64_t));
2300 } else if (parse_str(type
, "dvec", NULL
)) {
2301 int elements
= type
[4] - '0';
2302 parse_doubles(line
, d
, elements
, NULL
);
2303 memcpy(data
, d
, elements
* sizeof(double));
2304 } else if (parse_str(type
, "mat", NULL
)) {
2305 GLint matrix_stride
, row_major
;
2306 int cols
= type
[3] - '0';
2307 int rows
= type
[4] == 'x' ? type
[5] - '0' : cols
;
2309 float *matrixdata
= (float *)data
;
2311 assert(cols
>= 2 && cols
<= 4);
2312 assert(rows
>= 2 && rows
<= 4);
2314 parse_floats(line
, f
, rows
* cols
, NULL
);
2316 if (!force_no_names
) {
2317 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2318 GL_UNIFORM_MATRIX_STRIDE
,
2320 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2321 GL_UNIFORM_IS_ROW_MAJOR
,
2324 matrix_stride
= block_data
.matrix_stride
;
2325 row_major
= block_data
.row_major
;
2328 matrix_stride
/= sizeof(float);
2330 /* Expect the data in the .shader_test file to be listed in
2331 * column-major order no matter what the layout of the data in
2334 for (c
= 0; c
< cols
; c
++) {
2335 for (r
= 0; r
< rows
; r
++) {
2337 matrixdata
[matrix_stride
* r
+ c
] =
2340 matrixdata
[matrix_stride
* c
+ r
] =
2345 } else if (parse_str(type
, "dmat", NULL
)) {
2346 GLint matrix_stride
, row_major
;
2347 int cols
= type
[4] - '0';
2348 int rows
= type
[5] == 'x' ? type
[6] - '0' : cols
;
2350 double *matrixdata
= (double *)data
;
2352 assert(cols
>= 2 && cols
<= 4);
2353 assert(rows
>= 2 && rows
<= 4);
2355 parse_doubles(line
, d
, rows
* cols
, NULL
);
2357 if (!force_no_names
) {
2358 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2359 GL_UNIFORM_MATRIX_STRIDE
,
2361 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2362 GL_UNIFORM_IS_ROW_MAJOR
,
2365 matrix_stride
= block_data
.matrix_stride
;
2366 row_major
= block_data
.row_major
;
2369 matrix_stride
/= sizeof(double);
2371 /* Expect the data in the .shader_test file to be listed in
2372 * column-major order no matter what the layout of the data in
2375 for (c
= 0; c
< cols
; c
++) {
2376 for (r
= 0; r
< rows
; r
++) {
2378 matrixdata
[matrix_stride
* r
+ c
] =
2381 matrixdata
[matrix_stride
* c
+ r
] =
2386 } else if (parse_str(type
, "handle", NULL
)) {
2387 check_unsigned_support();
2388 check_texture_handle_support();
2389 parse_uints(line
, uints
, 1, NULL
);
2390 GLuint64 handle
= get_resident_handle(uints
[0])->handle
;
2391 memcpy(data
, &handle
, sizeof(uint64_t));
2393 printf("unknown uniform type \"%s\" for \"%s\"\n", type
, name
);
2394 piglit_report_result(PIGLIT_FAIL
);
2397 glUnmapBuffer(GL_UNIFORM_BUFFER
);
2403 * Get the uniform_index, block_index and offset of a given
2404 * uniform. By default it gets those values using the uniform name. If
2405 * force_no_names mode is active, it uses the current values stored at
2406 * @block_data. On the latter, uniform index is not filled up.
2409 get_indexes_and_offset_from_ubo(char *name
, struct block_info block_data
,
2410 GLuint
*uniform_index_out
,
2411 GLint
*block_index_out
,
2414 GLuint uniform_index
= 0;
2417 int name_len
= strlen(name
);
2418 GLint array_index
= 0;
2420 if (!num_uniform_blocks
)
2423 if (!force_no_names
) {
2424 /* if the uniform is an array, strip the index, as GL
2425 prevents non-zero indexes from matching a name */
2426 if (name
[name_len
- 1] == ']') {
2429 for (i
= name_len
- 1; (i
> 0) && isdigit(name
[i
-1]); --i
)
2432 array_index
= strtol(&name
[i
], NULL
, 0);
2436 if (name
[i
] != '[') {
2437 printf("cannot parse uniform \"%s\"\n", name
);
2438 piglit_report_result(PIGLIT_FAIL
);
2445 glGetUniformIndices(prog
, 1, (const char **)&name
, &uniform_index
);
2446 if (uniform_index
== GL_INVALID_INDEX
) {
2447 printf("cannot get index of uniform \"%s\"\n", name
);
2448 piglit_report_result(PIGLIT_FAIL
);
2451 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2452 GL_UNIFORM_BLOCK_INDEX
, &block_index
);
2454 if (block_index
== -1)
2458 glGetActiveUniformsiv(prog
, 1, &uniform_index
, GL_UNIFORM_SIZE
, &array_size
);
2460 if (array_index
> array_size
) {
2461 printf("attempt to access beyond uniform \"%s\" array size (%d)\n",
2466 /* if the uniform block is an array, then GetActiveUniformsiv with
2467 * UNIFORM_BLOCK_INDEX will have given us the index of the first
2468 * element in the array.
2470 block_index
+= block_data
.array_index
;
2472 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2473 GL_UNIFORM_OFFSET
, &offset
);
2475 if (name
[name_len
- 1] == ']') {
2478 glGetActiveUniformsiv(prog
, 1, &uniform_index
,
2479 GL_UNIFORM_ARRAY_STRIDE
, &stride
);
2480 offset
+= stride
* array_index
;
2483 if (block_data
.binding
< 0) {
2484 printf("if you force to use a explicit ubo binding, you "
2485 "need to provide it when filling the data with "
2486 "\"ubo binding\"\n");
2487 piglit_report_result(PIGLIT_FAIL
);
2490 /* The mapping could be improved using a hash
2491 * table. For now, this is enough.
2493 block_index
= uniform_block_indexes
[block_data
.binding
];
2495 /* if the uniform block is an array, then GetActiveUniformsiv with
2496 * UNIFORM_BLOCK_INDEX will have given us the index of the first
2497 * element in the array.
2499 block_index
+= block_data
.array_index
;
2501 if (block_data
.offset
< 0) {
2502 printf("if you force to use a explicit ubo binding, you "
2503 "need to provide offset when filling the data with "
2504 "\"ubo offset\"\n");
2505 piglit_report_result(PIGLIT_FAIL
);
2507 offset
= block_data
.offset
;
2510 *offset_out
= offset
;
2511 *block_index_out
= block_index
;
2512 *uniform_index_out
= uniform_index
;
2518 set_uniform(const char *line
, struct block_info block_data
)
2520 char name
[512], type
[512];
2526 uint64_t uint64s
[16];
2529 REQUIRE(parse_word_copy(line
, type
, sizeof(type
), &line
) &&
2530 parse_word_copy(line
, name
, sizeof(name
), &line
),
2531 "Invalid set uniform command at: %s\n", line
);
2533 if (isdigit(name
[0])) {
2534 loc
= strtol(name
, NULL
, 0);
2538 if (set_ubo_uniform(name
, type
, line
, block_data
))
2541 glGetIntegerv(GL_CURRENT_PROGRAM
, (GLint
*) &prog
);
2542 loc
= glGetUniformLocation(prog
, name
);
2544 if (ignore_missing_uniforms
)
2546 printf("cannot get location of uniform \"%s\"\n",
2548 piglit_report_result(PIGLIT_FAIL
);
2552 if (parse_str(type
, "float", NULL
)) {
2553 parse_floats(line
, f
, 1, NULL
);
2554 glUniform1fv(loc
, 1, f
);
2556 } else if (parse_str(type
, "int64_t", NULL
)) {
2557 check_int64_support();
2558 parse_int64s(line
, int64s
, 1, NULL
);
2559 glUniform1i64vARB(loc
, 1, int64s
);
2561 } else if (parse_str(type
, "uint64_t", NULL
)) {
2562 check_int64_support();
2563 parse_uint64s(line
, uint64s
, 1, NULL
);
2564 glUniform1ui64vARB(loc
, 1, uint64s
);
2566 } else if (parse_str(type
, "int", NULL
)) {
2567 parse_ints(line
, ints
, 1, NULL
);
2568 glUniform1iv(loc
, 1, ints
);
2570 } else if (parse_str(type
, "uint", NULL
)) {
2571 check_unsigned_support();
2572 parse_uints(line
, uints
, 1, NULL
);
2573 glUniform1uiv(loc
, 1, uints
);
2575 } else if (parse_str(type
, "double", NULL
)) {
2576 check_double_support();
2577 parse_doubles(line
, d
, 1, NULL
);
2578 glUniform1dv(loc
, 1, d
);
2580 } else if (parse_str(type
, "vec", NULL
)) {
2583 parse_floats(line
, f
, 2, NULL
);
2584 glUniform2fv(loc
, 1, f
);
2587 parse_floats(line
, f
, 3, NULL
);
2588 glUniform3fv(loc
, 1, f
);
2591 parse_floats(line
, f
, 4, NULL
);
2592 glUniform4fv(loc
, 1, f
);
2595 } else if (parse_str(type
, "ivec", NULL
)) {
2598 parse_ints(line
, ints
, 2, NULL
);
2599 glUniform2iv(loc
, 1, ints
);
2602 parse_ints(line
, ints
, 3, NULL
);
2603 glUniform3iv(loc
, 1, ints
);
2606 parse_ints(line
, ints
, 4, NULL
);
2607 glUniform4iv(loc
, 1, ints
);
2610 } else if (parse_str(type
, "uvec", NULL
)) {
2611 check_unsigned_support();
2614 parse_uints(line
, uints
, 2, NULL
);
2615 glUniform2uiv(loc
, 1, uints
);
2618 parse_uints(line
, uints
, 3, NULL
);
2619 glUniform3uiv(loc
, 1, uints
);
2622 parse_uints(line
, uints
, 4, NULL
);
2623 glUniform4uiv(loc
, 1, uints
);
2626 } else if (parse_str(type
, "dvec", NULL
)) {
2627 check_double_support();
2630 parse_doubles(line
, d
, 2, NULL
);
2631 glUniform2dv(loc
, 1, d
);
2634 parse_doubles(line
, d
, 3, NULL
);
2635 glUniform3dv(loc
, 1, d
);
2638 parse_doubles(line
, d
, 4, NULL
);
2639 glUniform4dv(loc
, 1, d
);
2642 } else if (parse_str(type
, "i64vec", NULL
)) {
2643 check_int64_support();
2646 parse_int64s(line
, int64s
, 2, NULL
);
2647 glUniform2i64vARB(loc
, 1, int64s
);
2650 parse_int64s(line
, int64s
, 3, NULL
);
2651 glUniform3i64vARB(loc
, 1, int64s
);
2654 parse_int64s(line
, int64s
, 4, NULL
);
2655 glUniform4i64vARB(loc
, 1, int64s
);
2658 } else if (parse_str(type
, "u64vec", NULL
)) {
2659 check_int64_support();
2662 parse_uint64s(line
, uint64s
, 2, NULL
);
2663 glUniform2ui64vARB(loc
, 1, uint64s
);
2666 parse_uint64s(line
, uint64s
, 3, NULL
);
2667 glUniform3ui64vARB(loc
, 1, uint64s
);
2670 parse_uint64s(line
, uint64s
, 4, NULL
);
2671 glUniform4ui64vARB(loc
, 1, uint64s
);
2674 } else if (parse_str(type
, "mat", NULL
) && type
[3] != '\0') {
2675 char cols
= type
[3];
2676 char rows
= type
[4] == 'x' ? type
[5] : cols
;
2681 parse_floats(line
, f
, 4, NULL
);
2682 glUniformMatrix2fv(loc
, 1, GL_FALSE
, f
);
2685 parse_floats(line
, f
, 6, NULL
);
2686 glUniformMatrix2x3fv(loc
, 1, GL_FALSE
, f
);
2689 parse_floats(line
, f
, 8, NULL
);
2690 glUniformMatrix2x4fv(loc
, 1, GL_FALSE
, f
);
2696 parse_floats(line
, f
, 6, NULL
);
2697 glUniformMatrix3x2fv(loc
, 1, GL_FALSE
, f
);
2700 parse_floats(line
, f
, 9, NULL
);
2701 glUniformMatrix3fv(loc
, 1, GL_FALSE
, f
);
2704 parse_floats(line
, f
, 12, NULL
);
2705 glUniformMatrix3x4fv(loc
, 1, GL_FALSE
, f
);
2711 parse_floats(line
, f
, 8, NULL
);
2712 glUniformMatrix4x2fv(loc
, 1, GL_FALSE
, f
);
2715 parse_floats(line
, f
, 12, NULL
);
2716 glUniformMatrix4x3fv(loc
, 1, GL_FALSE
, f
);
2719 parse_floats(line
, f
, 16, NULL
);
2720 glUniformMatrix4fv(loc
, 1, GL_FALSE
, f
);
2724 } else if (parse_str(type
, "dmat", NULL
) && type
[4] != '\0') {
2725 char cols
= type
[4];
2726 char rows
= type
[5] == 'x' ? type
[6] : cols
;
2731 parse_doubles(line
, d
, 4, NULL
);
2732 glUniformMatrix2dv(loc
, 1, GL_FALSE
, d
);
2735 parse_doubles(line
, d
, 6, NULL
);
2736 glUniformMatrix2x3dv(loc
, 1, GL_FALSE
, d
);
2739 parse_doubles(line
, d
, 8, NULL
);
2740 glUniformMatrix2x4dv(loc
, 1, GL_FALSE
, d
);
2746 parse_doubles(line
, d
, 6, NULL
);
2747 glUniformMatrix3x2dv(loc
, 1, GL_FALSE
, d
);
2750 parse_doubles(line
, d
, 9, NULL
);
2751 glUniformMatrix3dv(loc
, 1, GL_FALSE
, d
);
2754 parse_doubles(line
, d
, 12, NULL
);
2755 glUniformMatrix3x4dv(loc
, 1, GL_FALSE
, d
);
2761 parse_doubles(line
, d
, 8, NULL
);
2762 glUniformMatrix4x2dv(loc
, 1, GL_FALSE
, d
);
2765 parse_doubles(line
, d
, 12, NULL
);
2766 glUniformMatrix4x3dv(loc
, 1, GL_FALSE
, d
);
2769 parse_doubles(line
, d
, 16, NULL
);
2770 glUniformMatrix4dv(loc
, 1, GL_FALSE
, d
);
2774 } else if (parse_str(type
, "handle", NULL
)) {
2775 check_unsigned_support();
2776 check_texture_handle_support();
2777 parse_uints(line
, uints
, 1, NULL
);
2778 glUniformHandleui64ARB(loc
, get_resident_handle(uints
[0])->handle
);
2782 printf("unknown uniform type \"%s\"\n", type
);
2783 piglit_report_result(PIGLIT_FAIL
);
2789 set_vertex_attrib(const char *line
)
2791 char name
[512], type
[512];
2795 REQUIRE(parse_word_copy(line
, type
, sizeof(type
), &line
) &&
2796 parse_word_copy(line
, name
, sizeof(name
), &line
),
2797 "Invalid set vertex attrib command at: %s\n", line
);
2799 if (isdigit(name
[0])) {
2800 loc
= strtol(name
, NULL
, 0);
2804 glGetIntegerv(GL_CURRENT_PROGRAM
, (GLint
*) &prog
);
2805 loc
= glGetAttribLocation(prog
, name
);
2807 if (ignore_missing_uniforms
)
2809 printf("cannot get location of vertex attrib \"%s\"\n",
2811 piglit_report_result(PIGLIT_FAIL
);
2815 if (parse_str(type
, "handle", NULL
)) {
2816 check_unsigned_support();
2817 check_texture_handle_support();
2818 parse_uints(line
, uints
, 1, NULL
);
2819 glVertexAttribL1ui64ARB(loc
, get_resident_handle(uints
[0])->handle
);
2823 printf("unknown vertex attrib type \"%s\"\n", type
);
2824 printf("use [vertex data] instead if possible\n");
2825 piglit_report_result(PIGLIT_FAIL
);
2830 static GLenum
lookup_shader_type(GLuint idx
)
2834 return GL_VERTEX_SHADER
;
2836 return GL_FRAGMENT_SHADER
;
2838 return GL_GEOMETRY_SHADER
;
2840 return GL_TESS_CONTROL_SHADER
;
2842 return GL_TESS_EVALUATION_SHADER
;
2844 return GL_COMPUTE_SHADER
;
2850 static GLenum
get_shader_from_string(const char *name
, int *idx
)
2852 if (parse_str(name
, "GL_VERTEX_SHADER", NULL
)) {
2854 return GL_VERTEX_SHADER
;
2856 if (parse_str(name
, "GL_FRAGMENT_SHADER", NULL
)) {
2858 return GL_FRAGMENT_SHADER
;
2860 if (parse_str(name
, "GL_GEOMETRY_SHADER", NULL
)) {
2862 return GL_GEOMETRY_SHADER
;
2864 if (parse_str(name
, "GL_TESS_CONTROL_SHADER", NULL
)) {
2866 return GL_TESS_CONTROL_SHADER
;
2868 if (parse_str(name
, "GL_TESS_EVALUATION_SHADER", NULL
)) {
2870 return GL_TESS_EVALUATION_SHADER
;
2872 if (parse_str(name
, "GL_COMPUTE_SHADER", NULL
)) {
2874 return GL_COMPUTE_SHADER
;
2880 free_subroutine_uniforms(void)
2883 for (sidx
= 0; sidx
< 4; sidx
++) {
2884 free(subuniform_locations
[sidx
]);
2885 subuniform_locations
[sidx
] = NULL
;
2890 program_subroutine_uniforms(void)
2895 for (sidx
= 0; sidx
< 4; sidx
++) {
2897 if (num_subuniform_locations
[sidx
] == 0)
2900 stype
= lookup_shader_type(sidx
);
2904 glUniformSubroutinesuiv(stype
, num_subuniform_locations
[sidx
], subuniform_locations
[sidx
]);
2909 set_subroutine_uniform(const char *line
)
2920 REQUIRE(parse_word_copy(line
, type
, sizeof(type
), &line
) &&
2921 parse_word_copy(line
, name
, sizeof(name
), &line
) &&
2922 parse_word_copy(line
, subname
, sizeof(subname
), &line
),
2923 "Invalid set subroutine uniform command at: %s\n", line
);
2925 ptype
= get_shader_from_string(type
, &sidx
);
2927 printf("illegal type in subroutine uniform\n");
2928 piglit_report_result(PIGLIT_FAIL
);
2931 glGetIntegerv(GL_CURRENT_PROGRAM
, (GLint
*) &prog
);
2933 if (num_subuniform_locations
[sidx
] == 0) {
2934 glGetProgramStageiv(prog
, ptype
, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
,
2935 &num_subuniform_locations
[sidx
]);
2937 if (num_subuniform_locations
[sidx
] == 0) {
2938 printf("illegal subroutine uniform specified\n");
2939 piglit_report_result(PIGLIT_FAIL
);
2942 subuniform_locations
[sidx
] = calloc(num_subuniform_locations
[sidx
], sizeof(GLuint
));
2943 if (!subuniform_locations
[sidx
])
2944 piglit_report_result(PIGLIT_FAIL
);
2947 loc
= glGetSubroutineUniformLocation(prog
, ptype
, name
);
2949 if (ignore_missing_uniforms
)
2951 printf("cannot get location of subroutine uniform \"%s\"\n",
2953 piglit_report_result(PIGLIT_FAIL
);
2956 idx
= glGetSubroutineIndex(prog
, ptype
, subname
);
2957 if (idx
== GL_INVALID_INDEX
) {
2958 printf("cannot get index of subroutine uniform \"%s\"\n",
2960 piglit_report_result(PIGLIT_FAIL
);
2963 subuniform_locations
[sidx
][loc
] = idx
;
2968 * Query values from current program using glGetProgram.
2970 * Format of the command:
2971 * verify program_query GL_PNAME_ENUM integer
2975 * verify program_query GL_PNAME_ENUM <enum>
2977 * Note: GL_COMPUTE_WORK_GROUP_SIZE is not supported, as is the only
2978 * query that requires a params with more than one component, and we
2979 * want to keep things simple.
2983 verify_program_query(const char *line
)
2985 static const struct string_to_enum all_pnames
[] = {
2986 ENUM_STRING(GL_DELETE_STATUS
),
2987 ENUM_STRING(GL_LINK_STATUS
),
2988 ENUM_STRING(GL_VALIDATE_STATUS
),
2989 ENUM_STRING(GL_INFO_LOG_LENGTH
),
2990 ENUM_STRING(GL_ATTACHED_SHADERS
),
2991 ENUM_STRING(GL_ACTIVE_ATOMIC_COUNTER_BUFFERS
),
2992 ENUM_STRING(GL_ACTIVE_ATTRIBUTES
),
2993 ENUM_STRING(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
),
2994 ENUM_STRING(GL_ACTIVE_UNIFORMS
),
2995 ENUM_STRING(GL_ACTIVE_UNIFORM_BLOCKS
),
2996 ENUM_STRING(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH
),
2997 ENUM_STRING(GL_ACTIVE_UNIFORM_MAX_LENGTH
),
2998 ENUM_STRING(GL_COMPUTE_WORK_GROUP_SIZE
),
2999 ENUM_STRING(GL_PROGRAM_BINARY_LENGTH
),
3000 ENUM_STRING(GL_TRANSFORM_FEEDBACK_BUFFER_MODE
),
3001 ENUM_STRING(GL_TRANSFORM_FEEDBACK_VARYINGS
),
3002 ENUM_STRING(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
),
3003 ENUM_STRING(GL_GEOMETRY_VERTICES_OUT
),
3004 ENUM_STRING(GL_GEOMETRY_INPUT_TYPE
),
3005 ENUM_STRING(GL_GEOMETRY_OUTPUT_TYPE
),
3009 static const struct string_to_enum all_possible_param_enums
[] = {
3010 ENUM_STRING(GL_TRUE
),
3011 ENUM_STRING(GL_FALSE
),
3012 ENUM_STRING(GL_SEPARATE_ATTRIBS
),
3013 ENUM_STRING(GL_INTERLEAVED_ATTRIBS
),
3014 ENUM_STRING(GL_POINTS
),
3015 ENUM_STRING(GL_LINES
),
3016 ENUM_STRING(GL_LINES_ADJACENCY
),
3017 ENUM_STRING(GL_TRIANGLES
),
3018 ENUM_STRING(GL_TRIANGLES_ADJACENCY
),
3019 ENUM_STRING(GL_LINE_STRIP
),
3020 ENUM_STRING(GL_TRIANGLE_STRIP
),
3021 ENUM_STRING(GL_COMPUTE_WORK_GROUP_SIZE
),
3029 REQUIRE(parse_enum_tab(all_pnames
, line
,
3031 "Bad glGetProgram pname at: %s\n", line
);
3033 REQUIRE(parse_enum_tab(all_possible_param_enums
, line
, (unsigned *)&expected
, &line
) ||
3034 parse_int(line
, &expected
, &line
),
3035 "Bad expected value at: %s\n", line
);
3037 if (pname
== GL_COMPUTE_WORK_GROUP_SIZE
) {
3038 /* TODO: eventually it would be good to add support for
3039 * this parameter. What it makes different to the rest is
3040 * that it requires a param with more than one component
3042 fprintf(stderr
, "glGetProgram queries with GL_COMPUTE_WORK_GROUP_SIZE "
3043 "not supported yet\n");
3044 piglit_report_result(PIGLIT_FAIL
);
3047 glGetProgramiv(prog
, pname
, &value
);
3049 if (expected
!= value
) {
3050 fprintf(stderr
, "glGetProgram(%s): expected %d, got %d\n",
3051 piglit_get_gl_enum_name(pname
), expected
, value
);
3052 piglit_report_result(PIGLIT_FAIL
);
3057 * Query a uniform using glGetActiveUniformsiv
3059 * Format of the command:
3061 * active uniform uniform_name GL_PNAME_ENUM integer
3065 * active uniform uniform_name GL_PNAME_ENUM GL_TYPE_ENUM
3068 active_uniform(const char *line
)
3070 static const struct string_to_enum all_pnames
[] = {
3071 ENUM_STRING(GL_UNIFORM_TYPE
),
3072 ENUM_STRING(GL_UNIFORM_SIZE
),
3073 ENUM_STRING(GL_UNIFORM_NAME_LENGTH
),
3074 ENUM_STRING(GL_UNIFORM_BLOCK_INDEX
),
3075 ENUM_STRING(GL_UNIFORM_OFFSET
),
3076 ENUM_STRING(GL_UNIFORM_ARRAY_STRIDE
),
3077 ENUM_STRING(GL_UNIFORM_MATRIX_STRIDE
),
3078 ENUM_STRING(GL_UNIFORM_IS_ROW_MAJOR
),
3079 ENUM_STRING(GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX
),
3083 const char *rest
= line
;
3089 int num_active_uniforms
;
3091 REQUIRE(parse_word_copy(rest
, name
, sizeof(name
), &rest
),
3092 "Bad uniform name at: %s\n", line
);
3094 REQUIRE(parse_enum_tab(all_pnames
, rest
, &pname
, &rest
),
3095 "Bad glGetUniformsiv pname at: %s\n", line
);
3097 REQUIRE(parse_enum_tab(all_types
, rest
, (unsigned *)&expected
, &rest
) ||
3098 parse_int(rest
, &expected
, &rest
),
3099 "Bad expected value at: %s\n", line
);
3101 glGetProgramiv(prog
, GL_ACTIVE_UNIFORMS
, &num_active_uniforms
);
3102 for (i
= 0; i
< num_active_uniforms
; i
++) {
3109 glGetActiveUniform(prog
, i
, sizeof(name_buf
), &name_len
,
3110 &size
, &type
, name_buf
);
3112 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
3113 fprintf(stderr
, "glGetActiveUniform error\n");
3114 piglit_report_result(PIGLIT_FAIL
);
3117 if (strcmp(name
, name_buf
) != 0)
3120 /* If the requested pname is one of the values that
3121 * glGetActiveUniform happens to return, check the value
3122 * returned by that function too.
3125 case GL_UNIFORM_TYPE
:
3129 case GL_UNIFORM_SIZE
:
3133 case GL_UNIFORM_NAME_LENGTH
:
3138 /* This ensures the check below will pass when the
3139 * requested enum is not one of the values already
3140 * returned by glGetActiveUniform.
3146 if (got
!= expected
) {
3148 "glGetActiveUniform(%s, %s): "
3149 "expected %d (0x%04x), got %d (0x%04x)\n",
3150 name
, piglit_get_gl_enum_name(pname
),
3151 expected
, expected
, got
, got
);
3155 /* Set 'got' to some value in case glGetActiveUniformsiv
3156 * doesn't write to it. That should only be able to occur
3157 * when the function raises a GL error, but "should" is kind
3161 glGetActiveUniformsiv(prog
, 1, (GLuint
*) &i
, pname
, &got
);
3163 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
3164 fprintf(stderr
, "glGetActiveUniformsiv error\n");
3165 piglit_report_result(PIGLIT_FAIL
);
3168 if (got
!= expected
) {
3170 "glGetActiveUniformsiv(%s, %s): "
3171 "expected %d, got %d\n",
3172 name
, piglit_get_gl_enum_name(pname
),
3178 piglit_report_result(PIGLIT_FAIL
);
3183 fprintf(stderr
, "No active uniform named \"%s\"\n", name
);
3184 piglit_report_result(PIGLIT_FAIL
);
3190 * Confirms if @resource_index is a given resource, within @interface_type.
3192 * In order to identify it, it uses by default @resource_name. If
3193 * force_no_names mode is activated it uses the binding contained at
3194 * @block_data. Note that for the latter, only ubos or ssbos are
3195 * supported as @interface_type.
3197 * @resource_name_buf, @prop and @value_expected are only used for
3198 * some extra checks.
3200 * Return true if @resource_index is the resource within
3201 * @interface_type we search for. false otherwise.
3204 confirm_program_resource(GLenum interface_type
, GLuint resource_index
,
3205 const char *resource_name
, char *resource_name_buf
,
3206 struct block_info block_data
, unsigned prop
,
3209 if (!force_no_names
) {
3210 GLsizei resource_name_len
;
3212 glGetProgramResourceName(prog
, interface_type
, resource_index
,
3213 512, &resource_name_len
,
3216 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
3217 fprintf(stderr
, "glGetProgramResourceName error\n");
3218 piglit_report_result(PIGLIT_FAIL
);
3221 if (strcmp(resource_name
, resource_name_buf
) != 0)
3224 /* glGetProgramResourceName does not consider the NULL
3225 * terminator when returning the name length, however,
3226 * glGetProgramResourceiv does. We take that into account
3227 * when doing the comparison.
3229 if (prop
== GL_NAME_LENGTH
&&
3230 resource_name_len
!= (value_expected
- 1)) {
3232 "glGetProgramResourceName(%s, %s, %s): "
3233 "expected length: %d (0x%04x), "
3234 "got length: %d (0x%04x)\n",
3235 piglit_get_gl_enum_name(interface_type
),
3236 resource_name
, piglit_get_gl_enum_name(prop
),
3237 value_expected
- 1, value_expected
- 1,
3238 resource_name_len
, resource_name_len
);
3239 piglit_report_result(PIGLIT_FAIL
);
3242 unsigned binding_prop
= GL_BUFFER_BINDING
;
3243 int current_binding
= 0;
3246 if (interface_type
!= GL_SHADER_STORAGE_BLOCK
&&
3247 interface_type
!= GL_UNIFORM_BLOCK
) {
3249 "active_program_interface queries under force_no_names "
3250 "mode are only supported for GL_SHADER_STORAGE_BLOCK "
3251 "or GL_UNIFORM_BLOCK interfaces\n");
3252 piglit_report_result(PIGLIT_FAIL
);
3255 glGetProgramResourceiv(prog
, interface_type
,
3256 resource_index
, 1, &binding_prop
, 1,
3257 &length
, ¤t_binding
);
3258 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
3259 fprintf(stderr
, "glGetProgramResourceiv error\n");
3260 piglit_report_result(PIGLIT_FAIL
);
3263 if (block_data
.binding
!= current_binding
)
3271 * Query an active resource using ARB_program_interface_query functions
3273 * Format of the command:
3275 * verify program_interface_query GL_INTERFACE_TYPE_ENUM name GL_PNAME_ENUM integer
3279 * verify program_interface_query GL_INTERFACE_TYPE_ENUM name GL_PNAME_ENUM GL_TYPE_ENUM
3282 active_program_interface(const char *line
, struct block_info block_data
)
3284 static const struct string_to_enum all_props
[] = {
3285 ENUM_STRING(GL_TYPE
),
3286 ENUM_STRING(GL_ARRAY_SIZE
),
3287 ENUM_STRING(GL_NAME_LENGTH
),
3288 ENUM_STRING(GL_BLOCK_INDEX
),
3289 ENUM_STRING(GL_OFFSET
),
3290 ENUM_STRING(GL_ARRAY_STRIDE
),
3291 ENUM_STRING(GL_MATRIX_STRIDE
),
3292 ENUM_STRING(GL_IS_ROW_MAJOR
),
3293 ENUM_STRING(GL_ATOMIC_COUNTER_BUFFER_INDEX
),
3294 ENUM_STRING(GL_BUFFER_BINDING
),
3295 ENUM_STRING(GL_BUFFER_DATA_SIZE
),
3296 ENUM_STRING(GL_NUM_ACTIVE_VARIABLES
),
3297 ENUM_STRING(GL_REFERENCED_BY_VERTEX_SHADER
),
3298 ENUM_STRING(GL_REFERENCED_BY_TESS_CONTROL_SHADER
),
3299 ENUM_STRING(GL_REFERENCED_BY_TESS_EVALUATION_SHADER
),
3300 ENUM_STRING(GL_REFERENCED_BY_GEOMETRY_SHADER
),
3301 ENUM_STRING(GL_REFERENCED_BY_FRAGMENT_SHADER
),
3302 ENUM_STRING(GL_REFERENCED_BY_COMPUTE_SHADER
),
3303 ENUM_STRING(GL_TOP_LEVEL_ARRAY_SIZE
),
3304 ENUM_STRING(GL_TOP_LEVEL_ARRAY_STRIDE
),
3305 ENUM_STRING(GL_LOCATION
),
3306 ENUM_STRING(GL_LOCATION_INDEX
),
3307 ENUM_STRING(GL_LOCATION_COMPONENT
),
3308 ENUM_STRING(GL_IS_PER_PATCH
),
3309 ENUM_STRING(GL_NUM_COMPATIBLE_SUBROUTINES
),
3310 ENUM_STRING(GL_COMPATIBLE_SUBROUTINES
),
3314 static const struct string_to_enum all_program_interface
[] = {
3315 ENUM_STRING(GL_UNIFORM
),
3316 ENUM_STRING(GL_UNIFORM_BLOCK
),
3317 ENUM_STRING(GL_PROGRAM_INPUT
),
3318 ENUM_STRING(GL_PROGRAM_OUTPUT
),
3319 ENUM_STRING(GL_BUFFER_VARIABLE
),
3320 ENUM_STRING(GL_SHADER_STORAGE_BLOCK
),
3321 ENUM_STRING(GL_ATOMIC_COUNTER_BUFFER
),
3322 ENUM_STRING(GL_VERTEX_SUBROUTINE
),
3323 ENUM_STRING(GL_TESS_CONTROL_SUBROUTINE
),
3324 ENUM_STRING(GL_TESS_EVALUATION_SUBROUTINE
),
3325 ENUM_STRING(GL_GEOMETRY_SUBROUTINE
),
3326 ENUM_STRING(GL_FRAGMENT_SUBROUTINE
),
3327 ENUM_STRING(GL_COMPUTE_SUBROUTINE
),
3328 ENUM_STRING(GL_VERTEX_SUBROUTINE_UNIFORM
),
3329 ENUM_STRING(GL_TESS_CONTROL_SUBROUTINE_UNIFORM
),
3330 ENUM_STRING(GL_TESS_EVALUATION_SUBROUTINE_UNIFORM
),
3331 ENUM_STRING(GL_GEOMETRY_SUBROUTINE_UNIFORM
),
3332 ENUM_STRING(GL_FRAGMENT_SUBROUTINE_UNIFORM
),
3333 ENUM_STRING(GL_COMPUTE_SUBROUTINE_UNIFORM
),
3334 ENUM_STRING(GL_TRANSFORM_FEEDBACK_VARYING
),
3340 unsigned prop
, interface_type
;
3343 int num_active_buffers
;
3345 if (!piglit_is_extension_supported("GL_ARB_program_interface_query") &&
3346 piglit_get_gl_version() < 43) {
3348 "GL_ARB_program_interface_query not supported or "
3349 "OpenGL version < 4.3\n");
3353 REQUIRE(parse_enum_tab(all_program_interface
, line
,
3354 &interface_type
, &line
),
3355 "Bad program interface at: %s\n", line
);
3356 REQUIRE(parse_word_copy(line
, name
, sizeof(name
), &line
),
3357 "Bad program resource name at: %s\n", line
);
3358 REQUIRE(parse_enum_tab(all_props
, line
, &prop
, &line
),
3359 "Bad glGetProgramResourceiv pname at: %s\n", line
);
3360 REQUIRE(parse_enum_tab(all_types
, line
, (unsigned *)&expected
, &line
) ||
3361 parse_int(line
, &expected
, &line
),
3362 "Bad expected value at: %s\n", line
);
3364 glGetProgramInterfaceiv(prog
, interface_type
,
3365 GL_ACTIVE_RESOURCES
, &num_active_buffers
);
3366 for (i
= 0; i
< num_active_buffers
; i
++) {
3371 if (!confirm_program_resource(interface_type
, i
, name
, name_buf
,
3372 block_data
, prop
, expected
))
3375 /* Set 'got' to some value in case glGetActiveUniformsiv
3376 * doesn't write to it. That should only be able to occur
3377 * when the function raises a GL error, but "should" is kind
3381 glGetProgramResourceiv(prog
, interface_type
,
3385 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
3386 fprintf(stderr
, "glGetProgramResourceiv error\n");
3387 piglit_report_result(PIGLIT_FAIL
);
3390 if (got
!= expected
) {
3392 "glGetProgramResourceiv(%s, %s): "
3393 "expected %d, got %d\n",
3394 name
, piglit_get_gl_enum_name(prop
),
3400 piglit_report_result(PIGLIT_FAIL
);
3405 if (!force_no_names
)
3406 fprintf(stderr
, "No active resource named \"%s\"\n", name
);
3408 fprintf(stderr
, "No active resource with binding %i\n", block_data
.binding
);
3410 piglit_report_result(PIGLIT_FAIL
);
3416 query_index(GLenum query
)
3419 case GL_PRIMITIVES_GENERATED
:
3421 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
:
3428 * Checks if the GL_QUERY_RESULT of a given query object has the
3431 * Note that right now it only supports the following two queries:
3432 * * GL_PRIMITIVES_GENERATED
3433 * * GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
3435 * As right now we are only creating those query objects with xfb
3438 * Format of the command:
3440 * verify query_object GL_PRIMITIVES_GENERATED integer
3444 * verify query_object GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN integer
3446 static enum piglit_result
3447 verify_query_object_result(const char *line
)
3449 static const struct string_to_enum all_targets
[] = {
3450 ENUM_STRING(GL_PRIMITIVES_GENERATED
),
3451 ENUM_STRING(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
),
3460 REQUIRE(parse_enum_tab(all_targets
, line
,
3462 "Bad query object target at: %s\n", line
);
3464 REQUIRE(parse_uint(line
, &expected
, &line
),
3465 "Bad expected value at: %s\n", line
);
3467 /* Previous require already checks if the target is one of the
3470 index
= query_index(target
);
3472 if (queries
[index
]) {
3473 glGetQueryObjectuiv(queries
[index
], GL_QUERY_RESULT
, &value
);
3475 fprintf(stderr
, "query object for target %s is not initialized. "
3476 "Did you forget to call \"xfb draw arrays\"?\n",
3477 piglit_get_gl_enum_name(target
));
3481 if (expected
!= value
) {
3482 fprintf(stderr
, "glGetQueryObjectuiv(GL_QUERY_RESULT) for a %s "
3483 "query object: expected %d, got %d\n",
3484 piglit_get_gl_enum_name(target
), expected
, value
);
3491 set_parameter(const char *line
)
3497 count
= sscanf(line
, "%s %d (%f , %f , %f , %f)",
3498 type
, &index
, &f
[0], &f
[1], &f
[2], &f
[3]);
3500 fprintf(stderr
, "Couldn't parse parameter command:\n%s\n", line
);
3501 piglit_report_result(PIGLIT_FAIL
);
3504 if (parse_str(type
, "env_vp", NULL
)) {
3505 glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB
, index
, f
);
3506 } else if (parse_str(type
, "local_vp", NULL
)) {
3507 glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB
, index
, f
);
3508 } else if (parse_str(type
, "env_fp", NULL
)) {
3509 glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB
, index
, f
);
3510 } else if (parse_str(type
, "local_fp", NULL
)) {
3511 glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB
, index
, f
);
3513 fprintf(stderr
, "Unknown parameter type `%s'\n", type
);
3514 piglit_report_result(PIGLIT_FAIL
);
3519 set_patch_parameter(const char *line
)
3521 #ifdef PIGLIT_USE_OPENGL
3524 const char *const line0
= line
;
3526 if (gl_version
.num
< 40)
3527 piglit_require_extension("GL_ARB_tessellation_shader");
3529 if (parse_str(line
, "vertices ", &line
)) {
3530 count
= sscanf(line
, "%d", &i
);
3532 fprintf(stderr
, "Couldn't parse patch parameter command:\n%s\n", line0
);
3533 piglit_report_result(PIGLIT_FAIL
);
3535 glPatchParameteri(GL_PATCH_VERTICES
, i
);
3536 } else if (parse_str(line
, "default level outer ", &line
)) {
3537 count
= sscanf(line
, "%f %f %f %f", &f
[0], &f
[1], &f
[2], &f
[3]);
3539 fprintf(stderr
, "Couldn't parse patch parameter command:\n%s\n", line0
);
3540 piglit_report_result(PIGLIT_FAIL
);
3542 glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL
, f
);
3543 } else if (parse_str(line
, "default level inner ", &line
)) {
3544 count
= sscanf(line
, "%f %f", &f
[0], &f
[1]);
3546 fprintf(stderr
, "Couldn't parse patch parameter command:\n%s\n", line0
);
3547 piglit_report_result(PIGLIT_FAIL
);
3549 glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL
, f
);
3551 fprintf(stderr
, "Couldn't parse patch parameter command:\n%s\n", line
);
3552 piglit_report_result(PIGLIT_FAIL
);
3555 printf("patch parameters are only available in desktop GL\n");
3556 piglit_report_result(PIGLIT_SKIP
);
3561 set_provoking_vertex(const char *line
)
3563 if (parse_str(line
, "first", NULL
)) {
3564 glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT
);
3565 } else if (parse_str(line
, "last", NULL
)) {
3566 glProvokingVertexEXT(GL_LAST_VERTEX_CONVENTION_EXT
);
3568 fprintf(stderr
, "Unknown provoking vertex parameter `%s'\n", line
);
3569 piglit_report_result(PIGLIT_FAIL
);
3573 static const struct string_to_enum enable_table
[] = {
3574 { "GL_CLIP_PLANE0", GL_CLIP_PLANE0
},
3575 { "GL_CLIP_PLANE1", GL_CLIP_PLANE1
},
3576 { "GL_CLIP_PLANE2", GL_CLIP_PLANE2
},
3577 { "GL_CLIP_PLANE3", GL_CLIP_PLANE3
},
3578 { "GL_CLIP_PLANE4", GL_CLIP_PLANE4
},
3579 { "GL_CLIP_PLANE5", GL_CLIP_PLANE5
},
3580 { "GL_CLIP_PLANE6", GL_CLIP_PLANE0
+6 },
3581 { "GL_CLIP_PLANE7", GL_CLIP_PLANE0
+7 },
3582 { "GL_CLIP_DISTANCE0", GL_CLIP_DISTANCE0
},
3583 { "GL_CLIP_DISTANCE1", GL_CLIP_DISTANCE1
},
3584 { "GL_CLIP_DISTANCE2", GL_CLIP_DISTANCE2
},
3585 { "GL_CLIP_DISTANCE3", GL_CLIP_DISTANCE3
},
3586 { "GL_CLIP_DISTANCE4", GL_CLIP_DISTANCE4
},
3587 { "GL_CLIP_DISTANCE5", GL_CLIP_DISTANCE5
},
3588 { "GL_CLIP_DISTANCE6", GL_CLIP_DISTANCE6
},
3589 { "GL_CLIP_DISTANCE7", GL_CLIP_DISTANCE7
},
3590 { "GL_VERTEX_PROGRAM_TWO_SIDE", GL_VERTEX_PROGRAM_TWO_SIDE
},
3591 { "GL_PROGRAM_POINT_SIZE", GL_PROGRAM_POINT_SIZE
},
3592 { "GL_DEPTH_TEST", GL_DEPTH_TEST
},
3593 { "GL_DEPTH_CLAMP", GL_DEPTH_CLAMP
},
3598 do_enable_disable(const char *line
, bool enable_flag
)
3601 REQUIRE(parse_enum_tab(enable_table
, line
, &value
, NULL
),
3602 "Bad enable/disable enum at: %s\n", line
);
3610 static const struct string_to_enum hint_target_table
[] = {
3611 ENUM_STRING(GL_LINE_SMOOTH_HINT
),
3612 ENUM_STRING(GL_POLYGON_SMOOTH_HINT
),
3613 ENUM_STRING(GL_TEXTURE_COMPRESSION_HINT
),
3614 ENUM_STRING(GL_FRAGMENT_SHADER_DERIVATIVE_HINT
),
3618 static const struct string_to_enum hint_param_table
[] = {
3619 ENUM_STRING(GL_FASTEST
),
3620 ENUM_STRING(GL_NICEST
),
3621 ENUM_STRING(GL_DONT_CARE
),
3625 static void do_hint(const char *line
)
3627 unsigned target
, param
;
3628 REQUIRE(parse_enum_tab(hint_target_table
, line
, &target
, &line
),
3629 "Bad hint target at: %s\n", line
);
3630 REQUIRE(parse_enum_tab(hint_param_table
, line
, ¶m
, &line
),
3631 "Bad hint param at: %s\n", line
);
3633 glHint(target
, param
);
3637 draw_instanced_rect(int primcount
, float x
, float y
, float w
, float h
)
3641 piglit_require_extension("GL_ARB_draw_instanced");
3647 verts
[1][0] = x
+ w
;
3652 verts
[2][1] = y
+ h
;
3655 verts
[3][0] = x
+ w
;
3656 verts
[3][1] = y
+ h
;
3660 glVertexPointer(4, GL_FLOAT
, 0, verts
);
3661 glEnableClientState(GL_VERTEX_ARRAY
);
3663 glDrawArraysInstanced(GL_TRIANGLE_STRIP
, 0, 4, primcount
);
3665 glDisableClientState(GL_VERTEX_ARRAY
);
3670 decode_drawing_mode(const char *mode_str
)
3674 for (i
= GL_POINTS
; i
<= GL_PATCHES
; ++i
) {
3675 const char *name
= piglit_get_prim_name(i
);
3676 if (0 == strcmp(mode_str
, name
))
3680 printf("unknown drawing mode \"%s\"\n", mode_str
);
3681 piglit_report_result(PIGLIT_FAIL
);
3683 /* Should not be reached, but return 0 to avoid compiler warning */
3688 handle_texparameter(const char *line
)
3690 static const struct string_to_enum compare_funcs
[] = {
3691 { "greater", GL_GREATER
},
3692 { "gequal", GL_GEQUAL
},
3693 { "less", GL_LESS
},
3694 { "lequal", GL_LEQUAL
},
3695 { "equal", GL_EQUAL
},
3696 { "notequal", GL_NOTEQUAL
},
3697 { "never", GL_NEVER
},
3698 { "always", GL_ALWAYS
},
3701 static const struct string_to_enum depth_modes
[] = {
3702 { "intensity", GL_INTENSITY
},
3703 { "luminance", GL_LUMINANCE
},
3704 { "alpha", GL_ALPHA
},
3705 { "red", GL_RED
}, /* Requires GL 3.0 or GL_ARB_texture_rg */
3708 static const struct string_to_enum min_filter_modes
[] = {
3709 { "nearest_mipmap_nearest", GL_NEAREST_MIPMAP_NEAREST
},
3710 { "linear_mipmap_nearest", GL_LINEAR_MIPMAP_NEAREST
},
3711 { "nearest_mipmap_linear", GL_NEAREST_MIPMAP_LINEAR
},
3712 { "linear_mipmap_linear", GL_LINEAR_MIPMAP_LINEAR
},
3713 { "nearest", GL_NEAREST
},
3714 { "linear", GL_LINEAR
},
3717 static const struct string_to_enum mag_filter_modes
[] = {
3718 { "nearest", GL_NEAREST
},
3719 { "linear", GL_LINEAR
},
3722 static const struct string_to_enum wrap_modes
[] = {
3723 { "repeat", GL_REPEAT
},
3724 { "clamp_to_edge", GL_CLAMP_TO_EDGE
},
3725 { "clamp_to_border", GL_CLAMP_TO_BORDER
},
3728 static const struct string_to_enum swizzle_modes
[] = {
3730 { "green", GL_GREEN
},
3731 { "blue", GL_BLUE
},
3732 { "alpha", GL_ALPHA
},
3735 unsigned target
= 0;
3736 GLenum parameter
= GL_NONE
;
3737 const char *parameter_name
= NULL
;
3738 const struct string_to_enum
*strings
= NULL
;
3741 REQUIRE(parse_tex_target(line
, &target
, &line
),
3742 "Bad texture target at: %s\n", line
);
3744 if (parse_str(line
, "compare_func ", &line
)) {
3745 parameter
= GL_TEXTURE_COMPARE_FUNC
;
3746 parameter_name
= "compare_func";
3747 strings
= compare_funcs
;
3748 } else if (parse_str(line
, "depth_mode ", &line
)) {
3749 parameter
= GL_DEPTH_TEXTURE_MODE
;
3750 parameter_name
= "depth_mode";
3751 strings
= depth_modes
;
3752 } else if (parse_str(line
, "min ", &line
)) {
3753 parameter
= GL_TEXTURE_MIN_FILTER
;
3754 parameter_name
= "min";
3755 strings
= min_filter_modes
;
3756 } else if (parse_str(line
, "mag ", &line
)) {
3757 parameter
= GL_TEXTURE_MAG_FILTER
;
3758 parameter_name
= "mag";
3759 strings
= mag_filter_modes
;
3760 } else if (parse_str(line
, "wrap_s ", &line
)) {
3761 parameter
= GL_TEXTURE_WRAP_S
;
3762 parameter_name
= "wrap_s";
3763 strings
= wrap_modes
;
3764 } else if (parse_str(line
, "wrap_t ", &line
)) {
3765 parameter
= GL_TEXTURE_WRAP_T
;
3766 parameter_name
= "wrap_t";
3767 strings
= wrap_modes
;
3768 } else if (parse_str(line
, "wrap_r ", &line
)) {
3769 parameter
= GL_TEXTURE_WRAP_R
;
3770 parameter_name
= "wrap_r";
3771 strings
= wrap_modes
;
3772 } else if (parse_str(line
, "lod_bias ", &line
)) {
3773 #ifdef PIGLIT_USE_OPENGL
3774 glTexParameterf(target
, GL_TEXTURE_LOD_BIAS
,
3775 strtod(line
, NULL
));
3778 printf("lod_bias feature is only available in desktop GL\n");
3779 piglit_report_result(PIGLIT_SKIP
);
3781 } else if (parse_str(line
, "max_level ", &line
)) {
3782 glTexParameteri(target
, GL_TEXTURE_MAX_LEVEL
,
3783 strtol(line
, NULL
, 10));
3785 } else if (parse_str(line
, "base_level ", &line
)) {
3786 glTexParameteri(target
, GL_TEXTURE_BASE_LEVEL
,
3787 strtol(line
, NULL
, 10));
3789 } else if (parse_str(line
, "border_color ", &line
)) {
3792 count
= sscanf(line
, "%f %f %f %f", &bc
[0], &bc
[1], &bc
[2], &bc
[3]);
3794 fprintf(stderr
, "Could not parse border_color texture parameter.\n");
3795 piglit_report_result(PIGLIT_FAIL
);
3797 glTexParameterfv(target
, GL_TEXTURE_BORDER_COLOR
, bc
);
3799 } else if (parse_str(line
, "swizzle_r ", &line
)) {
3800 parameter
= GL_TEXTURE_SWIZZLE_R
;
3801 parameter_name
= "swizzle_r";
3802 strings
= swizzle_modes
;
3804 fprintf(stderr
, "unknown texture parameter in `%s'\n", line
);
3805 piglit_report_result(PIGLIT_FAIL
);
3808 REQUIRE(parse_enum_tab(strings
, line
, &value
, &line
),
3809 "Bad %s at: %s\n", parameter_name
, line
);
3811 glTexParameteri(target
, parameter
, value
);
3814 static const struct string_to_enum viewport_swizzle_table
[] = {
3815 { "POSITIVE_X", GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV
},
3816 { "NEGATIVE_X", GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV
},
3817 { "POSITIVE_Y", GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV
},
3818 { "NEGATIVE_Y", GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV
},
3819 { "POSITIVE_Z", GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV
},
3820 { "NEGATIVE_Z", GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV
},
3821 { "POSITIVE_W", GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV
},
3822 { "NEGATIVE_W", GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV
},
3827 handle_viewport_swizzle(const char *line
)
3832 viewport
= strtol(line
, (char **)&line
, 0);
3833 REQUIRE(parse_enum_tab(viewport_swizzle_table
, line
, &x
, &line
),
3834 "Bad ViewportSwizzle swizzle at: %s\n", line
);
3835 REQUIRE(parse_enum_tab(viewport_swizzle_table
, line
, &y
, &line
),
3836 "Bad ViewportSwizzle swizzle at: %s\n", line
);
3837 REQUIRE(parse_enum_tab(viewport_swizzle_table
, line
, &z
, &line
),
3838 "Bad ViewportSwizzle swizzle at: %s\n", line
);
3839 REQUIRE(parse_enum_tab(viewport_swizzle_table
, line
, &w
, &line
),
3840 "Bad ViewportSwizzle swizzle at: %s\n", line
);
3842 glViewportSwizzleNV(viewport
, x
, y
, z
, w
);
3850 if (!piglit_is_extension_supported("GL_ARB_uniform_buffer_object") &&
3851 piglit_get_gl_version() < 31) {
3856 /* probably running an ARB_vertex/fragment_program test */
3860 glGetProgramiv(prog
, GL_ACTIVE_UNIFORM_BLOCKS
, &num_uniform_blocks
);
3861 if (num_uniform_blocks
== 0)
3864 uniform_block_bos
= calloc(num_uniform_blocks
, sizeof(GLuint
));
3865 glGenBuffers(num_uniform_blocks
, uniform_block_bos
);
3868 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS
, &max_ubos
);
3869 uniform_block_indexes
= calloc(max_ubos
, sizeof(int));
3871 for (i
= 0; i
< num_uniform_blocks
; i
++) {
3875 glGetActiveUniformBlockiv(prog
, i
, GL_UNIFORM_BLOCK_DATA_SIZE
,
3878 glBindBuffer(GL_UNIFORM_BUFFER
, uniform_block_bos
[i
]);
3879 glBufferData(GL_UNIFORM_BUFFER
, size
, NULL
, GL_STATIC_DRAW
);
3881 if (!force_no_names
) {
3882 glUniformBlockBinding(prog
, i
, i
);
3883 uniform_block_indexes
[i
] = i
;
3886 glGetActiveUniformBlockiv(prog
, i
, GL_UNIFORM_BLOCK_BINDING
,
3888 uniform_block_indexes
[binding
] = i
;
3891 glBindBufferBase(GL_UNIFORM_BUFFER
, binding
, uniform_block_bos
[i
]);
3898 if (draw_fbo
!= 0 &&
3899 draw_fbo
!= piglit_winsys_fbo
)
3900 glDeleteFramebuffers(1, &draw_fbo
);
3902 if (read_fbo
!= 0 &&
3903 read_fbo
!= piglit_winsys_fbo
&&
3904 read_fbo
!= draw_fbo
)
3905 glDeleteFramebuffers(1, &read_fbo
);
3914 if (num_uniform_blocks
== 0) {
3918 glDeleteBuffers(num_uniform_blocks
, uniform_block_bos
);
3919 free(uniform_block_bos
);
3920 uniform_block_bos
= NULL
;
3921 free(uniform_block_indexes
);
3922 uniform_block_indexes
= NULL
;
3923 num_uniform_blocks
= 0;
3927 teardown_atomics(void)
3929 for (unsigned i
= 0; i
< ARRAY_SIZE(atomics_bos
); ++i
) {
3931 glDeleteBuffers(1, &atomics_bos
[i
]);
3936 teardown_shader_include_paths(void)
3938 for (unsigned i
= 0; i
< num_shader_include_paths
; i
++)
3939 free(shader_include_path
[i
]);
3941 for (unsigned i
= 0; i
< num_shader_includes
; i
++) {
3942 glDeleteNamedStringARB(-1, shader_include_names
[i
]);
3943 free(shader_include_names
[i
]);
3946 num_shader_includes
= 0;
3947 num_shader_include_paths
= 0;
3948 free(shader_include_path
);
3949 shader_include_path
= NULL
;
3955 glDeleteBuffers(MAX_XFB_BUFFERS
, xfb
);
3957 glDeleteQueries(1, &queries
[query_index(GL_PRIMITIVES_GENERATED
)]);
3958 glDeleteQueries(1, &queries
[query_index(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
)]);
3959 queries
[query_index(GL_PRIMITIVES_GENERATED
)] = 0;
3960 queries
[query_index(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
)] = 0;
3963 static enum piglit_result
3964 program_must_be_in_use(void)
3967 fprintf(stderr
, "Failed to link:\n%s\n", prog_err_info
);
3969 } else if (!prog_in_use
) {
3970 fprintf(stderr
, "Failed to use program: %s\n", prog_err_info
);
3977 bind_vao_if_supported()
3979 if (vao
== 0 && piglit_is_core_profile
) {
3980 glGenVertexArrays(1, &vao
);
3981 glBindVertexArray(vao
);
3985 static enum piglit_result
3986 draw_arrays_common(int first
, size_t count
)
3988 enum piglit_result result
= program_must_be_in_use();
3990 printf("draw arrays 'first' must be >= 0\n");
3991 piglit_report_result(PIGLIT_FAIL
);
3992 } else if (vbo_present
&&
3993 (size_t) first
>= num_vbo_rows
) {
3994 printf("draw arrays 'first' must be < %lu\n",
3995 (unsigned long) num_vbo_rows
);
3996 piglit_report_result(PIGLIT_FAIL
);
3999 printf("draw arrays 'count' must be > 0\n");
4000 piglit_report_result(PIGLIT_FAIL
);
4001 } else if (vbo_present
&&
4002 count
> num_vbo_rows
- (size_t) first
) {
4003 printf("draw arrays cannot draw beyond %lu\n",
4004 (unsigned long) num_vbo_rows
);
4005 piglit_report_result(PIGLIT_FAIL
);
4007 bind_vao_if_supported();
4011 static const struct string_to_enum light_table
[] = {
4012 ENUM_STRING(GL_AMBIENT
),
4013 ENUM_STRING(GL_DIFFUSE
),
4014 ENUM_STRING(GL_SPECULAR
),
4015 ENUM_STRING(GL_POSITION
),
4016 ENUM_STRING(GL_SPOT_DIRECTION
),
4017 ENUM_STRING(GL_SPOT_EXPONENT
),
4018 ENUM_STRING(GL_SPOT_CUTOFF
),
4019 ENUM_STRING(GL_CONSTANT_ATTENUATION
),
4020 ENUM_STRING(GL_LINEAR_ATTENUATION
),
4021 ENUM_STRING(GL_QUADRATIC_ATTENUATION
),
4026 set_light(const char *line
)
4031 REQUIRE(parse_int(line
, &index
, &line
),
4032 "Bad light index at: %s\n", line
);
4034 REQUIRE(parse_enum_tab(light_table
, line
, &attrib
, &line
),
4035 "Bad light enum at: %s\n", line
);
4037 if (parse_str(line
, "float", &line
)) {
4041 REQUIRE((n
= parse_floats(line
, f
, 16, NULL
)) > 0,
4042 "No float found for light %s\n", line
);
4045 glLightf(GL_LIGHT0
+ index
, attrib
, f
[0]);
4047 glLightfv(GL_LIGHT0
+ index
, attrib
, f
);
4048 } else if (parse_str(line
, "int", &line
)) {
4052 REQUIRE((n
= parse_ints(line
, i
, 16, NULL
)) > 0,
4053 "No int found for light %s\n", line
);
4056 glLighti(GL_LIGHT0
+ index
, attrib
, i
[0]);
4058 glLightiv(GL_LIGHT0
+ index
, attrib
, i
);
4060 printf("Invalid light value type \"%s\"\n", line
);
4061 piglit_report_result(PIGLIT_FAIL
);
4066 probe_atomic_counter(unsigned buffer_num
, GLint counter_num
, const char *op
,
4067 uint32_t value
, bool uses_layout_qualifiers
)
4071 enum comparison cmp
;
4074 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4075 "Invalid comparison operation at: %s\n", op
);
4077 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER
, atomics_bos
[buffer_num
]);
4078 p
= glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER
,
4079 uses_layout_qualifiers
? counter_num
: counter_num
* sizeof(uint32_t),
4080 sizeof(uint32_t), GL_MAP_READ_BIT
);
4083 printf("Couldn't map atomic counter to verify expected value.\n");
4088 result
= compare_uint(value
, observed
, cmp
);
4091 if (uses_layout_qualifiers
)
4092 printf("Atomic counter (binding = %d, offset = %d) test failed: "
4093 "Reference %s Observed\n",
4094 buffer_num
, counter_num
, comparison_string(cmp
));
4096 printf("Atomic counter %d test failed: Reference %s Observed\n",
4097 counter_num
, comparison_string(cmp
));
4098 printf(" Reference: %u\n", value
);
4099 printf(" Observed: %u\n", observed
);
4100 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER
);
4104 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER
);
4109 probe_ssbo_uint(GLint ssbo_index
, GLint ssbo_offset
, const char *op
, uint32_t value
)
4113 enum comparison cmp
;
4116 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4117 "Invalid comparison operation at: %s\n", op
);
4119 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
[ssbo_index
]);
4120 p
= glMapBufferRange(GL_SHADER_STORAGE_BUFFER
, ssbo_offset
,
4121 sizeof(uint32_t), GL_MAP_READ_BIT
);
4124 printf("Couldn't map ssbo to verify expected value.\n");
4129 result
= compare_uint(value
, observed
, cmp
);
4132 printf("SSBO %d test failed: Reference %s Observed\n",
4133 ssbo_offset
, comparison_string(cmp
));
4134 printf(" Reference: %u\n", value
);
4135 printf(" Observed: %u\n", observed
);
4136 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4140 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4145 probe_ssbo_uint64(GLint ssbo_index
, GLint ssbo_offset
, const char *op
, uint64_t value
)
4149 enum comparison cmp
;
4152 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4153 "Invalid comparison operation at: %s\n", op
);
4155 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
[ssbo_index
]);
4156 p
= glMapBufferRange(GL_SHADER_STORAGE_BUFFER
, ssbo_offset
,
4157 sizeof(uint64_t), GL_MAP_READ_BIT
);
4160 printf("Couldn't map ssbo to verify expected value.\n");
4165 result
= compare_uint64(value
, observed
, cmp
);
4168 printf("SSBO %d test failed: Reference %s Observed\n",
4169 ssbo_offset
, comparison_string(cmp
));
4170 printf(" Reference: %"PRIu64
"\n", value
);
4171 printf(" Observed: %"PRIu64
"\n", observed
);
4172 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4176 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4181 probe_ssbo_int(GLint ssbo_index
, GLint ssbo_offset
, const char *op
, int32_t value
)
4185 enum comparison cmp
;
4188 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4189 "Invalid comparison operation at: %s\n", op
);
4191 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
[ssbo_index
]);
4192 p
= glMapBufferRange(GL_SHADER_STORAGE_BUFFER
, ssbo_offset
,
4193 sizeof(uint32_t), GL_MAP_READ_BIT
);
4196 printf("Couldn't map ssbo to verify expected value.\n");
4201 result
= compare_int(value
, observed
, cmp
);
4204 printf("SSBO %d test failed: Reference %s Observed\n",
4205 ssbo_offset
, comparison_string(cmp
));
4206 printf(" Reference: %d\n", value
);
4207 printf(" Observed: %d\n", observed
);
4208 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4212 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4217 probe_ssbo_int64(GLint ssbo_index
, GLint ssbo_offset
, const char *op
, int64_t value
)
4221 enum comparison cmp
;
4224 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4225 "Invalid comparison operation at: %s\n", op
);
4227 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
[ssbo_index
]);
4228 p
= glMapBufferRange(GL_SHADER_STORAGE_BUFFER
, ssbo_offset
,
4229 sizeof(uint64_t), GL_MAP_READ_BIT
);
4232 printf("Couldn't map ssbo to verify expected value.\n");
4237 result
= compare_int64(value
, observed
, cmp
);
4240 printf("SSBO %d test failed: Reference %s Observed\n",
4241 ssbo_offset
, comparison_string(cmp
));
4242 printf(" Reference: %"PRId64
"\n", value
);
4243 printf(" Observed: %"PRId64
"\n", observed
);
4244 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4248 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4253 probe_ssbo_double(GLint ssbo_index
, GLint ssbo_offset
, const char *op
, double value
)
4257 enum comparison cmp
;
4260 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4261 "Invalid comparison operation at: %s\n", op
);
4263 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
[ssbo_index
]);
4264 p
= glMapBufferRange(GL_SHADER_STORAGE_BUFFER
, ssbo_offset
,
4265 sizeof(double), GL_MAP_READ_BIT
);
4268 printf("Couldn't map ssbo to verify expected value.\n");
4273 result
= compare_double(value
, observed
, cmp
);
4276 printf("SSBO %d test failed: Reference %s Observed\n",
4277 ssbo_offset
, comparison_string(cmp
));
4278 printf(" Reference: %g\n", value
);
4279 printf(" Observed: %g\n", observed
);
4280 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4284 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4289 probe_ssbo_float(GLint ssbo_index
, GLint ssbo_offset
, const char *op
, float value
)
4293 enum comparison cmp
;
4296 REQUIRE(parse_comparison_op(op
, &cmp
, NULL
),
4297 "Invalid comparison operation at: %s\n", op
);
4299 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, 0, ssbo
[ssbo_index
]);
4300 p
= glMapBufferRange(GL_SHADER_STORAGE_BUFFER
, ssbo_offset
,
4301 sizeof(float), GL_MAP_READ_BIT
);
4304 printf("Couldn't map ssbo to verify expected value.\n");
4309 result
= compare_double(value
, observed
, cmp
);
4312 printf("SSBO %d test failed: Reference %s Observed\n",
4313 ssbo_offset
, comparison_string(cmp
));
4314 printf(" Reference: %g\n", value
);
4315 printf(" Observed: %g\n", observed
);
4316 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4320 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER
);
4324 GLenum
piglit_xfb_primitive_mode(GLenum draw_arrays_mode
)
4326 switch (draw_arrays_mode
) {
4332 case GL_LINES_ADJACENCY
:
4333 case GL_LINE_STRIP_ADJACENCY
:
4336 case GL_TRIANGLE_STRIP
:
4337 case GL_TRIANGLE_FAN
:
4338 case GL_TRIANGLES_ADJACENCY
:
4339 case GL_TRIANGLE_STRIP_ADJACENCY
:
4340 return GL_TRIANGLES
;
4343 printf("glDrawArrays mode %s not supported for a transform feedback operation\n",
4344 piglit_get_gl_enum_name(draw_arrays_mode
));
4345 piglit_report_result(PIGLIT_FAIL
);
4349 begin_query(GLenum query_type
)
4351 unsigned idx
= query_index(query_type
);
4352 if (queries
[idx
] == 0)
4353 glGenQueries(1, &queries
[idx
]);
4354 glBeginQuery(query_type
, queries
[idx
]);
4358 piglit_xfb_draw_arrays(GLenum mode
, int first
, size_t count
)
4360 GLenum primitive_mode
= piglit_xfb_primitive_mode(mode
);
4362 begin_query(GL_PRIMITIVES_GENERATED
);
4363 begin_query(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
);
4365 glEnable(GL_RASTERIZER_DISCARD
);
4367 /* We don't need to call glBindBufferBase here, it is done on
4368 * the "xfb buffer object" command
4371 glBeginTransformFeedback(primitive_mode
);
4372 glDrawArrays(mode
, first
, count
);
4373 glEndTransformFeedback();
4375 glDisable(GL_RASTERIZER_DISCARD
);
4379 glEndQuery(GL_PRIMITIVES_GENERATED
);
4380 glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
);
4384 probe_xfb_float(GLuint buf
, unsigned n
, float expected
)
4388 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, buf
);
4389 p
= glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER
, n
* sizeof(float),
4390 sizeof(float), GL_MAP_READ_BIT
);
4392 printf("Couldn't map xfb buffer %u\n", buf
);
4395 result
= fabsf(expected
- *p
) < piglit_tolerance
[0];
4397 printf("xfb buffer %i[%i]: %f, Expected: %f\n",
4398 buf
, n
, *p
, expected
);
4401 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
);
4406 probe_xfb_double(GLuint buf
, unsigned n
, double expected
)
4411 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
, buf
);
4412 p
= glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER
, n
* sizeof(double),
4413 sizeof(double), GL_MAP_READ_BIT
);
4415 printf("Couldn't map xfb buffer %u\n", buf
);
4418 result
= fabs(expected
- *p
) < piglit_tolerance
[0];
4420 printf("xfb buffer %i[%i]: %lf, Expected: %lf\n",
4421 buf
, n
, *p
, expected
);
4424 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER
);
4429 piglit_display(void)
4431 const char *line
, *next_line
, *rest
;
4433 enum piglit_result full_result
= PIGLIT_PASS
;
4434 GLbitfield clear_bits
= 0;
4435 bool link_error_expected
= false;
4437 struct block_info block_data
= {0, -1, -1, -1, -1};
4439 if (test_start
== NULL
)
4442 next_line
= test_start
;
4443 line_num
= test_start_line_num
;
4444 while (next_line
[0] != '\0') {
4447 int x
, y
, z
, w
, h
, l
, tex
, level
;
4448 unsigned ux
, uy
, uz
;
4451 char s
[300]; // 300 for safety
4452 enum piglit_result result
= PIGLIT_PASS
;
4454 parse_whitespace(next_line
, &line
);
4456 next_line
= strchrnul(next_line
, '\n');
4458 /* Duplicate the line to make it null terminated */
4459 line
= strndup(line
, next_line
- line
);
4461 /* If strchrnul found a newline, then skip it */
4462 if (next_line
[0] != '\0')
4465 if (line
[0] == '\0') {
4466 } else if (sscanf(line
, "active shader program %s", s
) == 1) {
4467 switch (get_shader_from_string(s
, &x
)) {
4468 case GL_VERTEX_SHADER
:
4469 glActiveShaderProgram(pipeline
, sso_vertex_prog
);
4471 case GL_TESS_CONTROL_SHADER
:
4472 glActiveShaderProgram(pipeline
, sso_tess_control_prog
);
4474 case GL_TESS_EVALUATION_SHADER
:
4475 glActiveShaderProgram(pipeline
, sso_tess_eval_prog
);
4477 case GL_GEOMETRY_SHADER
:
4478 glActiveShaderProgram(pipeline
, sso_geometry_prog
);
4480 case GL_FRAGMENT_SHADER
:
4481 glActiveShaderProgram(pipeline
, sso_fragment_prog
);
4483 case GL_COMPUTE_SHADER
:
4484 glActiveShaderProgram(pipeline
, sso_compute_prog
);
4487 } else if (sscanf(line
, "atomic counter buffer %u %u", &x
, &y
) == 2) {
4488 GLuint
*atomics_buf
= calloc(y
, sizeof(GLuint
));
4489 glGenBuffers(1, &atomics_bos
[x
]);
4490 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, x
, atomics_bos
[x
]);
4491 glBufferData(GL_ATOMIC_COUNTER_BUFFER
,
4492 sizeof(GLuint
) * y
, atomics_buf
,
4495 } else if (sscanf(line
, "atomic counters %d", &x
) == 1) {
4496 GLuint
*atomics_buf
= calloc(x
, sizeof(GLuint
));
4497 glGenBuffers(1, &atomics_bos
[0]);
4498 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, 0, atomics_bos
[0]);
4499 glBufferData(GL_ATOMIC_COUNTER_BUFFER
,
4501 atomics_buf
, GL_STATIC_DRAW
);
4503 } else if (sscanf(line
, "atomic counter %u %u %u", &x
, &y
, &z
) == 3) {
4504 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, x
, atomics_bos
[x
]);
4505 glBufferSubData(GL_ATOMIC_COUNTER_BUFFER
,
4506 sizeof(GLuint
) * y
, sizeof(GLuint
),
4508 } else if (parse_str(line
, "clear color ", &rest
)) {
4509 parse_floats(rest
, c
, 4, NULL
);
4510 glClearColor(c
[0], c
[1], c
[2], c
[3]);
4511 clear_bits
|= GL_COLOR_BUFFER_BIT
;
4512 } else if (parse_str(line
, "clear depth ", &rest
)) {
4513 parse_floats(rest
, c
, 1, NULL
);
4515 clear_bits
|= GL_DEPTH_BUFFER_BIT
;
4516 } else if (parse_str(line
, "clear", NULL
)) {
4517 glClear(clear_bits
);
4518 } else if (sscanf(line
,
4519 "clip plane %d %lf %lf %lf %lf",
4520 &x
, &d
[0], &d
[1], &d
[2], &d
[3]) == 5) {
4521 if (x
< 0 || x
>= gl_max_clip_planes
) {
4522 printf("clip plane id %d out of range\n", x
);
4523 piglit_report_result(PIGLIT_FAIL
);
4525 glClipPlane(GL_CLIP_PLANE0
+ x
, d
);
4526 #ifdef PIGLIT_USE_OPENGL
4527 } else if (parse_str(line
, "color ", &rest
)) {
4528 parse_floats(rest
, c
, 4, NULL
);
4529 assert(!piglit_is_core_profile
);
4532 } else if (sscanf(line
,
4535 result
= program_must_be_in_use();
4536 glMemoryBarrier(GL_ALL_BARRIER_BITS
);
4537 glDispatchCompute(x
, y
, z
);
4538 glMemoryBarrier(GL_ALL_BARRIER_BITS
);
4539 } else if (sscanf(line
,
4540 "compute group size %d %d %d %d %d %d",
4541 &x
, &y
, &z
, &w
, &h
, &l
) == 6) {
4542 result
= program_must_be_in_use();
4543 glMemoryBarrier(GL_ALL_BARRIER_BITS
);
4544 glDispatchComputeGroupSizeARB(x
, y
, z
, w
, h
, l
);
4545 glMemoryBarrier(GL_ALL_BARRIER_BITS
);
4546 } else if (parse_str(line
, "draw rect tex ", &rest
)) {
4547 result
= program_must_be_in_use();
4548 program_subroutine_uniforms();
4549 parse_floats(rest
, c
, 8, NULL
);
4550 piglit_draw_rect_tex(c
[0], c
[1], c
[2], c
[3],
4551 c
[4], c
[5], c
[6], c
[7]);
4552 } else if (parse_str(line
, "draw rect ortho patch ", &rest
)) {
4553 result
= program_must_be_in_use();
4554 program_subroutine_uniforms();
4555 parse_floats(rest
, c
, 4, NULL
);
4557 piglit_draw_rect_custom(-1.0 + 2.0 * (c
[0] / piglit_width
),
4558 -1.0 + 2.0 * (c
[1] / piglit_height
),
4559 2.0 * (c
[2] / piglit_width
),
4560 2.0 * (c
[3] / piglit_height
), true, 1);
4561 } else if (parse_str(line
, "draw rect ortho ", &rest
)) {
4562 result
= program_must_be_in_use();
4563 program_subroutine_uniforms();
4564 parse_floats(rest
, c
, 4, NULL
);
4566 piglit_draw_rect(-1.0 + 2.0 * (c
[0] / piglit_width
),
4567 -1.0 + 2.0 * (c
[1] / piglit_height
),
4568 2.0 * (c
[2] / piglit_width
),
4569 2.0 * (c
[3] / piglit_height
));
4570 } else if (parse_str(line
, "draw rect patch ", &rest
)) {
4571 result
= program_must_be_in_use();
4572 parse_floats(rest
, c
, 4, NULL
);
4573 piglit_draw_rect_custom(c
[0], c
[1], c
[2], c
[3], true, 1);
4574 } else if (parse_str(line
, "draw rect ", &rest
)) {
4575 result
= program_must_be_in_use();
4576 program_subroutine_uniforms();
4577 parse_floats(rest
, c
, 4, NULL
);
4578 piglit_draw_rect(c
[0], c
[1], c
[2], c
[3]);
4579 } else if (parse_str(line
, "draw instanced rect ortho patch ", &rest
)) {
4582 result
= program_must_be_in_use();
4583 sscanf(rest
, "%d %f %f %f %f",
4585 c
+ 0, c
+ 1, c
+ 2, c
+ 3);
4586 piglit_draw_rect_custom(-1.0 + 2.0 * (c
[0] / piglit_width
),
4587 -1.0 + 2.0 * (c
[1] / piglit_height
),
4588 2.0 * (c
[2] / piglit_width
),
4589 2.0 * (c
[3] / piglit_height
), true,
4591 } else if (parse_str(line
, "draw instanced rect ortho ", &rest
)) {
4594 result
= program_must_be_in_use();
4595 sscanf(rest
, "%d %f %f %f %f",
4597 c
+ 0, c
+ 1, c
+ 2, c
+ 3);
4598 piglit_draw_rect_custom(-1.0 + 2.0 * (c
[0] / piglit_width
),
4599 -1.0 + 2.0 * (c
[1] / piglit_height
),
4600 2.0 * (c
[2] / piglit_width
),
4601 2.0 * (c
[3] / piglit_height
), false,
4603 } else if (parse_str(line
, "draw instanced rect ", &rest
)) {
4606 result
= program_must_be_in_use();
4607 sscanf(rest
, "%d %f %f %f %f",
4609 c
+ 0, c
+ 1, c
+ 2, c
+ 3);
4610 draw_instanced_rect(primcount
, c
[0], c
[1], c
[2], c
[3]);
4611 } else if (sscanf(line
, "draw arrays instanced %31s %d %d %d", s
, &x
, &y
, &z
) == 4) {
4612 GLenum mode
= decode_drawing_mode(s
);
4614 size_t count
= (size_t) y
;
4615 size_t primcount
= (size_t) z
;
4616 draw_arrays_common(first
, count
);
4617 glDrawArraysInstanced(mode
, first
, count
, primcount
);
4618 } else if (sscanf(line
, "draw arrays %31s %d %d", s
, &x
, &y
) == 3) {
4619 GLenum mode
= decode_drawing_mode(s
);
4621 size_t count
= (size_t) y
;
4622 result
= draw_arrays_common(first
, count
);
4623 glDrawArrays(mode
, first
, count
);
4624 } else if (parse_str(line
, "disable ", &rest
)) {
4625 do_enable_disable(rest
, false);
4626 } else if (parse_str(line
, "enable ", &rest
)) {
4627 do_enable_disable(rest
, true);
4628 } else if (sscanf(line
, "depthfunc %31s", s
) == 1) {
4629 glDepthFunc(piglit_get_gl_enum_from_name(s
));
4630 } else if (parse_str(line
, "fb ", &rest
)) {
4631 const GLenum target
=
4632 parse_str(rest
, "draw ", &rest
) ? GL_DRAW_FRAMEBUFFER
:
4633 parse_str(rest
, "read ", &rest
) ? GL_READ_FRAMEBUFFER
:
4637 if (parse_str(rest
, "tex 2d ", &rest
)) {
4638 GLenum attachments
[32];
4639 unsigned num_attachments
= 0;
4641 glGenFramebuffers(1, &fbo
);
4642 glBindFramebuffer(target
, fbo
);
4644 while (parse_int(rest
, &tex
, &rest
)) {
4645 attachments
[num_attachments
] =
4646 GL_COLOR_ATTACHMENT0
+ num_attachments
;
4647 glFramebufferTexture2D(
4648 target
, attachments
[num_attachments
],
4650 tex
== -1 ? 0 : get_texture_binding(tex
)->obj
, 0);
4652 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
4654 "glFramebufferTexture2D error\n");
4655 piglit_report_result(PIGLIT_FAIL
);
4660 w
= get_texture_binding(tex
)->width
;
4661 h
= get_texture_binding(tex
)->height
;
4665 if (target
!= GL_READ_FRAMEBUFFER
)
4666 glDrawBuffers(num_attachments
, attachments
);
4669 } else if (parse_str(rest
, "tex slice ", &rest
)) {
4672 REQUIRE(parse_tex_target(rest
, &tex_target
, &rest
) &&
4673 parse_int(rest
, &tex
, &rest
) &&
4674 parse_int(rest
, &l
, &rest
) &&
4675 parse_int(rest
, &z
, &rest
),
4676 "Framebuffer binding command not "
4677 "understood at: %s\n", rest
);
4679 const GLuint tex_obj
= get_texture_binding(tex
)->obj
;
4681 glGenFramebuffers(1, &fbo
);
4682 glBindFramebuffer(target
, fbo
);
4684 if (tex_target
== GL_TEXTURE_1D
) {
4686 "Invalid layer index provided "
4687 "in command: %s\n", line
);
4688 glFramebufferTexture1D(
4689 target
, GL_COLOR_ATTACHMENT0
,
4690 tex_target
, tex_obj
, l
);
4692 } else if (tex_target
== GL_TEXTURE_2D
||
4693 tex_target
== GL_TEXTURE_RECTANGLE
||
4694 tex_target
== GL_TEXTURE_2D_MULTISAMPLE
) {
4696 "Invalid layer index provided "
4697 "in command: %s\n", line
);
4698 glFramebufferTexture2D(
4699 target
, GL_COLOR_ATTACHMENT0
,
4700 tex_target
, tex_obj
, l
);
4702 } else if (tex_target
== GL_TEXTURE_CUBE_MAP
) {
4703 static const GLenum cubemap_targets
[] = {
4704 GL_TEXTURE_CUBE_MAP_POSITIVE_X
,
4705 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
,
4706 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
4707 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
,
4708 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
,
4709 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
4711 REQUIRE(z
< ARRAY_SIZE(cubemap_targets
),
4712 "Invalid layer index provided "
4713 "in command: %s\n", line
);
4714 tex_target
= cubemap_targets
[z
];
4716 glFramebufferTexture2D(
4717 target
, GL_COLOR_ATTACHMENT0
,
4718 tex_target
, tex_obj
, l
);
4721 glFramebufferTextureLayer(
4722 target
, GL_COLOR_ATTACHMENT0
,
4726 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
4727 fprintf(stderr
, "Error binding texture "
4728 "attachment for command: %s\n",
4730 piglit_report_result(PIGLIT_FAIL
);
4733 w
= MAX2(1, get_texture_binding(tex
)->width
>> l
);
4734 h
= MAX2(1, get_texture_binding(tex
)->height
>> l
);
4736 } else if (sscanf(rest
, "tex layered %d", &tex
) == 1) {
4737 glGenFramebuffers(1, &fbo
);
4738 glBindFramebuffer(target
, fbo
);
4740 glFramebufferTexture(
4741 target
, GL_COLOR_ATTACHMENT0
,
4742 get_texture_binding(tex
)->obj
, 0);
4743 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
4745 "glFramebufferTexture error\n");
4746 piglit_report_result(PIGLIT_FAIL
);
4749 w
= get_texture_binding(tex
)->width
;
4750 h
= get_texture_binding(tex
)->height
;
4752 } else if (parse_str(rest
, "ms ", &rest
)) {
4757 REQUIRE(parse_enum_gl(rest
, &format
, &rest
) &&
4758 parse_int(rest
, &w
, &rest
) &&
4759 parse_int(rest
, &h
, &rest
) &&
4760 parse_int(rest
, &samples
, &rest
),
4761 "Framebuffer binding command not "
4762 "understood at: %s\n", rest
);
4764 glGenFramebuffers(1, &fbo
);
4765 glBindFramebuffer(target
, fbo
);
4767 glGenRenderbuffers(1, &rb
);
4768 glBindRenderbuffer(GL_RENDERBUFFER
, rb
);
4770 glRenderbufferStorageMultisample(GL_RENDERBUFFER
, samples
,
4773 glFramebufferRenderbuffer(target
,
4774 GL_COLOR_ATTACHMENT0
,
4775 GL_RENDERBUFFER
, rb
);
4777 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
4778 fprintf(stderr
, "glFramebufferRenderbuffer error\n");
4779 piglit_report_result(PIGLIT_FAIL
);
4782 } else if (parse_str(rest
, "winsys", &rest
)) {
4783 fbo
= piglit_winsys_fbo
;
4784 glBindFramebuffer(target
, fbo
);
4785 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
4786 fprintf(stderr
, "glBindFramebuffer error\n");
4787 piglit_report_result(PIGLIT_FAIL
);
4794 fprintf(stderr
, "Unknown fb bind subcommand "
4796 piglit_report_result(PIGLIT_FAIL
);
4799 const GLenum status
= glCheckFramebufferStatus(target
);
4800 if (status
!= GL_FRAMEBUFFER_COMPLETE
) {
4801 fprintf(stderr
, "incomplete fbo (status 0x%x)\n",
4803 piglit_report_result(PIGLIT_FAIL
);
4806 if (target
!= GL_READ_FRAMEBUFFER
) {
4810 /* Delete the previous draw FB in case
4811 * it's no longer reachable.
4813 if (draw_fbo
!= 0 &&
4814 draw_fbo
!= piglit_winsys_fbo
&&
4815 draw_fbo
!= (target
== GL_DRAW_FRAMEBUFFER
?
4817 glDeleteFramebuffers(1, &draw_fbo
);
4822 if (target
!= GL_DRAW_FRAMEBUFFER
) {
4826 /* Delete the previous read FB in case
4827 * it's no longer reachable.
4829 if (read_fbo
!= 0 &&
4830 read_fbo
!= piglit_winsys_fbo
&&
4831 read_fbo
!= (target
== GL_READ_FRAMEBUFFER
?
4833 glDeleteFramebuffers(1, &read_fbo
);
4838 } else if (parse_str(line
, "blit ", &rest
)) {
4839 static const struct string_to_enum buffers
[] = {
4840 { "color", GL_COLOR_BUFFER_BIT
},
4841 { "depth", GL_DEPTH_BUFFER_BIT
},
4842 { "stencil", GL_STENCIL_BUFFER_BIT
},
4845 static const struct string_to_enum filters
[] = {
4846 { "linear", GL_LINEAR
},
4847 { "nearest", GL_NEAREST
},
4850 unsigned buffer
, filter
;
4852 REQUIRE(parse_enum_tab(buffers
, rest
, &buffer
, &rest
) &&
4853 parse_enum_tab(filters
, rest
, &filter
, &rest
),
4854 "FB blit command not understood at: %s\n",
4857 glBlitFramebuffer(0, 0, read_width
, read_height
,
4858 0, 0, render_width
, render_height
,
4861 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
4862 fprintf(stderr
, "glBlitFramebuffer error\n");
4863 piglit_report_result(PIGLIT_FAIL
);
4866 } else if (parse_str(line
, "frustum", &rest
)) {
4867 parse_floats(rest
, c
, 6, NULL
);
4868 piglit_frustum_projection(false, c
[0], c
[1], c
[2],
4870 } else if (parse_str(line
, "hint", &rest
)) {
4872 } else if (sscanf(line
,
4873 "image texture %d %31s",
4875 const GLenum img_fmt
= piglit_get_gl_enum_from_name(s
);
4876 glBindImageTexture(tex
, get_texture_binding(tex
)->obj
, 0,
4877 GL_FALSE
, 0, GL_READ_WRITE
, img_fmt
);
4878 } else if (sscanf(line
, "memory barrier %s", s
) == 1) {
4879 glMemoryBarrier(piglit_get_gl_memory_barrier_enum_from_name(s
));
4880 } else if (parse_str(line
, "blend barrier", NULL
)) {
4882 } else if (parse_str(line
, "fbfetch barrier", NULL
)) {
4883 glFramebufferFetchBarrierEXT();
4884 } else if (sscanf(line
, "ortho %f %f %f %f",
4885 c
+ 0, c
+ 1, c
+ 2, c
+ 3) == 4) {
4886 piglit_gen_ortho_projection(c
[0], c
[1], c
[2], c
[3],
4888 } else if (parse_str(line
, "ortho", NULL
)) {
4889 piglit_ortho_projection(render_width
, render_height
,
4891 } else if (sscanf(line
, "viewport indexed %u %f %f %f %f",
4892 &x
, c
+ 0, c
+ 1, c
+ 2, c
+ 3) == 5) {
4893 glViewportIndexedfv(x
, c
);
4894 } else if (parse_str(line
, "probe rgba ", &rest
)) {
4895 parse_floats(rest
, c
, 6, NULL
);
4896 if (!piglit_probe_pixel_rgba((int) c
[0], (int) c
[1],
4898 result
= PIGLIT_FAIL
;
4900 } else if (parse_str(line
, "probe depth ", &rest
)) {
4901 parse_floats(rest
, c
, 3, NULL
);
4902 if (!piglit_probe_pixel_depth((int) c
[0], (int) c
[1],
4904 result
= PIGLIT_FAIL
;
4906 } else if (sscanf(line
,
4907 "probe atomic counter buffer %u %u %s %u",
4908 &ux
, &uy
, s
, &uz
) == 4) {
4909 if (!probe_atomic_counter(ux
, uy
, s
, uz
, true)) {
4910 result
= PIGLIT_FAIL
;
4912 } else if (sscanf(line
,
4913 "probe atomic counter %u %s %u",
4914 &ux
, s
, &uy
) == 3) {
4915 if (!probe_atomic_counter(0, ux
, s
, uy
, false)) {
4916 result
= PIGLIT_FAIL
;
4918 } else if (sscanf(line
, "probe ssbo uint %d %d %s 0x%x",
4919 &x
, &y
, s
, &z
) == 4) {
4920 if (!probe_ssbo_uint(x
, y
, s
, z
))
4921 result
= PIGLIT_FAIL
;
4922 } else if (sscanf(line
, "probe ssbo uint %d %d %s %d",
4923 &x
, &y
, s
, &z
) == 4) {
4924 if (!probe_ssbo_uint(x
, y
, s
, z
))
4925 result
= PIGLIT_FAIL
;
4926 } else if (sscanf(line
, "probe ssbo uint64 %d %d %s %"PRIu64
,
4927 &x
, &y
, s
, &luz
) == 4) {
4928 if (!probe_ssbo_uint64(x
, y
, s
, luz
))
4929 result
= PIGLIT_FAIL
;
4930 } else if (sscanf(line
, "probe ssbo int %d %d %s %d",
4931 &x
, &y
, s
, &z
) == 4) {
4932 if (!probe_ssbo_int(x
, y
, s
, z
))
4933 result
= PIGLIT_FAIL
;
4934 } else if (sscanf(line
, "probe ssbo int64 %d %d %s %"PRId64
,
4935 &x
, &y
, s
, &lz
) == 4) {
4936 if (!probe_ssbo_int64(x
, y
, s
, lz
))
4937 result
= PIGLIT_FAIL
;
4938 } else if (sscanf(line
, "probe ssbo double %d %d %s %lf",
4939 &x
, &y
, s
, &d
[0]) == 4) {
4940 if (!probe_ssbo_double(x
, y
, s
, d
[0]))
4941 result
= PIGLIT_FAIL
;
4942 } else if (sscanf(line
, "probe ssbo float %d %d %s %f",
4943 &x
, &y
, s
, &c
[0]) == 4) {
4944 if (!probe_ssbo_float(x
, y
, s
, c
[0]))
4945 result
= PIGLIT_FAIL
;
4946 } else if (sscanf(line
,
4947 "relative probe rgba ( %f , %f ) "
4948 "( %f , %f , %f , %f )",
4950 c
+ 2, c
+ 3, c
+ 4, c
+ 5) == 6) {
4951 x
= c
[0] * read_width
;
4952 y
= c
[1] * read_height
;
4953 if (x
>= read_width
)
4955 if (y
>= read_height
)
4956 y
= read_height
- 1;
4958 if (!piglit_probe_pixel_rgba(x
, y
, &c
[2])) {
4959 result
= PIGLIT_FAIL
;
4961 } else if (parse_str(line
, "probe rgb ", &rest
)) {
4962 parse_floats(rest
, c
, 5, NULL
);
4963 if (!piglit_probe_pixel_rgb((int) c
[0], (int) c
[1],
4965 result
= PIGLIT_FAIL
;
4967 } else if (sscanf(line
,
4968 "relative probe rgb ( %f , %f ) "
4971 c
+ 2, c
+ 3, c
+ 4) == 5) {
4972 x
= c
[0] * read_width
;
4973 y
= c
[1] * read_height
;
4974 if (x
>= read_width
)
4976 if (y
>= read_height
)
4977 y
= read_height
- 1;
4979 if (!piglit_probe_pixel_rgb(x
, y
, &c
[2])) {
4980 result
= PIGLIT_FAIL
;
4982 } else if (sscanf(line
, "probe rect rgba "
4983 "( %d , %d , %d , %d ) "
4984 "( %f , %f , %f , %f )",
4986 c
+ 0, c
+ 1, c
+ 2, c
+ 3) == 8) {
4987 if (!piglit_probe_rect_rgba(x
, y
, w
, h
, c
)) {
4988 result
= PIGLIT_FAIL
;
4990 } else if (sscanf(line
, "relative probe rect rgb "
4991 "( %f , %f , %f , %f ) "
4993 c
+ 0, c
+ 1, c
+ 2, c
+ 3,
4994 c
+ 4, c
+ 5, c
+ 6) == 7) {
4995 x
= c
[0] * read_width
;
4996 y
= c
[1] * read_height
;
4997 w
= c
[2] * read_width
;
4998 h
= c
[3] * read_height
;
5000 if (!piglit_probe_rect_rgb(x
, y
, w
, h
, &c
[4])) {
5001 result
= PIGLIT_FAIL
;
5003 } else if (sscanf(line
, "relative probe rect rgba "
5004 "( %f , %f , %f , %f ) "
5005 "( %f , %f , %f , %f )",
5006 c
+ 0, c
+ 1, c
+ 2, c
+ 3,
5007 c
+ 4, c
+ 5, c
+ 6, c
+ 7) == 8) {
5008 x
= c
[0] * read_width
;
5009 y
= c
[1] * read_height
;
5010 w
= c
[2] * read_width
;
5011 h
= c
[3] * read_height
;
5013 if (!piglit_probe_rect_rgba(x
, y
, w
, h
, &c
[4])) {
5014 result
= PIGLIT_FAIL
;
5016 } else if (sscanf(line
, "relative probe rect rgba int "
5017 "( %f , %f , %f , %f ) "
5018 "( %d , %d , %d , %d )",
5019 c
+ 0, c
+ 1, c
+ 2, c
+ 3,
5020 &x
, &y
, &z
, &w
) == 8) {
5021 const int expected
[] = { x
, y
, z
, w
};
5022 if (!piglit_probe_rect_rgba_int(c
[0] * read_width
,
5027 result
= PIGLIT_FAIL
;
5029 } else if (parse_str(line
, "polygon mode ", &rest
)) {
5032 REQUIRE(parse_enum_gl(rest
, &face
, &rest
) &&
5033 parse_enum_gl(rest
, &mode
, &rest
),
5034 "Polygon mode command not understood at %s\n",
5037 glPolygonMode(face
, mode
);
5039 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
5040 fprintf(stderr
, "glPolygonMode error\n");
5041 piglit_report_result(PIGLIT_FAIL
);
5043 } else if (parse_str(line
, "probe all rgba ", &rest
)) {
5044 parse_floats(rest
, c
, 4, NULL
);
5045 if (result
!= PIGLIT_FAIL
&&
5046 !piglit_probe_rect_rgba(0, 0, read_width
,
5048 result
= PIGLIT_FAIL
;
5049 } else if (parse_str(line
, "probe warn all rgba ", &rest
)) {
5050 parse_floats(rest
, c
, 4, NULL
);
5051 if (result
== PIGLIT_PASS
&&
5052 !piglit_probe_rect_rgba(0, 0, read_width
,
5054 result
= PIGLIT_WARN
;
5055 } else if (parse_str(line
, "probe all rgb", &rest
)) {
5056 parse_floats(rest
, c
, 3, NULL
);
5057 if (result
!= PIGLIT_FAIL
&&
5058 !piglit_probe_rect_rgb(0, 0, read_width
,
5060 result
= PIGLIT_FAIL
;
5061 } else if (parse_str(line
, "tolerance", &rest
)) {
5062 parse_floats(rest
, piglit_tolerance
, 4, NULL
);
5063 } else if (parse_str(line
, "shade model smooth", NULL
)) {
5064 glShadeModel(GL_SMOOTH
);
5065 } else if (parse_str(line
, "shade model flat", NULL
)) {
5066 glShadeModel(GL_FLAT
);
5067 } else if (sscanf(line
, "ssbo %d %d", &x
, &y
) == 2) {
5068 GLuint
*ssbo_init
= calloc(y
, 1);
5069 glGenBuffers(1, &ssbo
[x
]);
5070 glBindBufferBase(GL_SHADER_STORAGE_BUFFER
, x
, ssbo
[x
]);
5071 glBufferData(GL_SHADER_STORAGE_BUFFER
, y
,
5072 ssbo_init
, GL_DYNAMIC_DRAW
);
5075 else if (sscanf(line
, "xfb buffer object %u %u", &ux
, &uy
) == 2) {
5076 GLuint
*xfb_init
= calloc(uy
, 1);
5077 if (ux
>= MAX_XFB_BUFFERS
) {
5078 printf("xfb buffer id %d out of range\n", ux
);
5079 piglit_report_result(PIGLIT_FAIL
);
5081 glGenBuffers(1, &xfb
[ux
]);
5082 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER
, ux
, xfb
[ux
]);
5083 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER
, uy
,
5084 xfb_init
, GL_STREAM_READ
);
5086 } else if (sscanf(line
, "xfb draw arrays %31s %d %d", s
, &x
, &y
) == 3) {
5087 GLenum mode
= decode_drawing_mode(s
);
5089 size_t count
= (size_t) y
;
5090 result
= draw_arrays_common(first
, count
);
5091 piglit_xfb_draw_arrays(mode
, first
, count
);
5092 } else if (sscanf(line
, "probe xfb buffer float %u %u %f",
5093 &ux
, &uy
, &c
[0]) == 3) {
5094 if (!probe_xfb_float(xfb
[ux
], uy
, c
[0]))
5095 result
= PIGLIT_FAIL
;
5096 } else if (sscanf(line
, "probe xfb buffer double %u %u %lf",
5097 &ux
, &uy
, &d
[0]) == 3) {
5098 if (!probe_xfb_double(xfb
[ux
], uy
, d
[0]))
5099 result
= PIGLIT_FAIL
;
5100 } else if (sscanf(line
, "ssbo %d subdata float %d %f", &x
, &y
, &c
[0]) == 3) {
5101 glBindBuffer(GL_SHADER_STORAGE_BUFFER
, ssbo
[x
]);
5102 glBufferSubData(GL_SHADER_STORAGE_BUFFER
, y
, 4, &c
[0]);
5103 } else if (sscanf(line
, "ssbo %d subdata double %d %s", &x
, &y
, s
) == 3) {
5104 parse_doubles(s
, &d
[0], 1, NULL
);
5105 glBindBuffer(GL_SHADER_STORAGE_BUFFER
, ssbo
[x
]);
5106 glBufferSubData(GL_SHADER_STORAGE_BUFFER
, y
, sizeof(double), &d
[0]);
5107 } else if (sscanf(line
, "ssbo %d subdata int64 %"PRId64
" %s", &x
, &ly
, s
) == 3) {
5108 parse_int64s(s
, &lz
, 1, NULL
);
5109 glBindBuffer(GL_SHADER_STORAGE_BUFFER
, ssbo
[x
]);
5110 glBufferSubData(GL_SHADER_STORAGE_BUFFER
, ly
, sizeof(int64_t), &lz
);
5111 } else if (sscanf(line
, "ssbo %d subdata uint64 %"PRIu64
" %s", &x
, &luy
, s
) == 3) {
5112 parse_uint64s(s
, &luz
, 1, NULL
);
5113 glBindBuffer(GL_SHADER_STORAGE_BUFFER
, ssbo
[x
]);
5114 glBufferSubData(GL_SHADER_STORAGE_BUFFER
, luy
, sizeof(uint64_t), &luz
);
5115 } else if (sscanf(line
, "ssbo %d subdata int %d %s", &x
, &y
, s
) == 3) {
5116 parse_ints(s
, &z
, 1, NULL
);
5117 glBindBuffer(GL_SHADER_STORAGE_BUFFER
, ssbo
[x
]);
5118 glBufferSubData(GL_SHADER_STORAGE_BUFFER
, y
, 4, &z
);
5119 } else if (sscanf(line
, "texture rgbw %d ( %d", &tex
, &w
) == 2) {
5120 GLenum int_fmt
= GL_RGBA
;
5123 "texture rgbw %d ( %d , %d ) %31s",
5125 if (num_scanned
< 3) {
5127 "invalid texture rgbw command!\n");
5128 piglit_report_result(PIGLIT_FAIL
);
5131 if (num_scanned
>= 4) {
5132 int_fmt
= piglit_get_gl_enum_from_name(s
);
5135 glActiveTexture(GL_TEXTURE0
+ tex
);
5136 int handle
= piglit_rgbw_texture(
5137 int_fmt
, w
, h
, GL_FALSE
, GL_FALSE
,
5138 (piglit_is_gles() ? GL_UNSIGNED_BYTE
:
5139 GL_UNSIGNED_NORMALIZED
));
5140 set_texture_binding(tex
, handle
, w
, h
, 1);
5142 if (!piglit_is_core_profile
&&
5143 !(piglit_is_gles() && piglit_get_gl_version() >= 20))
5144 glEnable(GL_TEXTURE_2D
);
5146 } else if (sscanf(line
, "resident texture %d", &tex
) == 1) {
5149 glBindTexture(GL_TEXTURE_2D
, 0);
5151 handle
= glGetTextureHandleARB(get_texture_binding(tex
)->obj
);
5152 glMakeTextureHandleResidentARB(handle
);
5154 set_resident_handle(tex
, handle
, true);
5156 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
5158 "glMakeTextureHandleResidentARB error\n");
5159 piglit_report_result(PIGLIT_FAIL
);
5161 } else if (sscanf(line
, "resident texture 1D %d", &tex
) == 1) {
5164 glBindTexture(GL_TEXTURE_1D
, 0);
5166 handle
= glGetTextureHandleARB(get_texture_binding(tex
)->obj
);
5167 glMakeTextureHandleResidentARB(handle
);
5169 set_resident_handle(tex
, handle
, true);
5171 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
5173 "glMakeTextureHandleResidentARB error\n");
5174 piglit_report_result(PIGLIT_FAIL
);
5176 } else if (sscanf(line
, "resident image texture %d %31s",
5178 const GLenum img_fmt
= piglit_get_gl_enum_from_name(s
);
5181 glBindTexture(GL_TEXTURE_2D
, 0);
5183 handle
= glGetImageHandleARB(get_texture_binding(tex
)->obj
,
5184 0, GL_FALSE
, 0, img_fmt
);
5185 glMakeImageHandleResidentARB(handle
, GL_READ_WRITE
);
5187 set_resident_handle(tex
, handle
, false);
5189 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
5191 "glMakeImageHandleResidentARB error\n");
5192 piglit_report_result(PIGLIT_FAIL
);
5194 } else if (parse_str(line
, "texture integer ", &rest
)) {
5198 sscanf(rest
, "%d ( %d , %d ) ( %d, %d ) %31s",
5199 &tex
, &w
, &h
, &b
, &a
, s
);
5200 if (num_scanned
< 6) {
5202 "invalid texture integer command!\n");
5203 piglit_report_result(PIGLIT_FAIL
);
5206 int_fmt
= piglit_get_gl_enum_from_name(s
);
5208 glActiveTexture(GL_TEXTURE0
+ tex
);
5209 const GLuint handle
=
5210 piglit_integer_texture(int_fmt
, w
, h
, b
, a
);
5211 set_texture_binding(tex
, handle
, w
, h
, 1);
5213 } else if (sscanf(line
, "texture miptree %d", &tex
) == 1) {
5214 glActiveTexture(GL_TEXTURE0
+ tex
);
5215 const GLuint handle
= piglit_miptree_texture();
5216 set_texture_binding(tex
, handle
, 8, 8, 1);
5218 if (!piglit_is_core_profile
&&
5219 !(piglit_is_gles() && piglit_get_gl_version() >= 20))
5220 glEnable(GL_TEXTURE_2D
);
5221 } else if (sscanf(line
,
5222 "texture checkerboard %d %d ( %d , %d ) "
5223 "( %f , %f , %f , %f ) "
5224 "( %f , %f , %f , %f )",
5225 &tex
, &level
, &w
, &h
,
5226 c
+ 0, c
+ 1, c
+ 2, c
+ 3,
5227 c
+ 4, c
+ 5, c
+ 6, c
+ 7) == 12) {
5228 glActiveTexture(GL_TEXTURE0
+ tex
);
5229 const GLuint handle
= piglit_checkerboard_texture(
5230 0, level
, w
, h
, w
/ 2, h
/ 2, c
+ 0, c
+ 4);
5231 set_texture_binding(tex
, handle
, w
, h
, 1);
5233 if (!piglit_is_core_profile
&&
5234 !(piglit_is_gles() && piglit_get_gl_version() >= 20))
5235 glEnable(GL_TEXTURE_2D
);
5236 } else if (sscanf(line
,
5237 "texture quads %d %d ( %d , %d ) ( %d , %d ) "
5238 "( %f , %f , %f , %f ) "
5239 "( %f , %f , %f , %f ) "
5240 "( %f , %f , %f , %f ) "
5241 "( %f , %f , %f , %f )",
5242 &tex
, &level
, &w
, &h
, &x
, &y
,
5243 c
+ 0, c
+ 1, c
+ 2, c
+ 3,
5244 c
+ 4, c
+ 5, c
+ 6, c
+ 7,
5245 c
+ 8, c
+ 9, c
+ 10, c
+ 11,
5246 c
+ 12, c
+ 13, c
+ 14, c
+ 15) == 22) {
5247 glActiveTexture(GL_TEXTURE0
+ tex
);
5248 const GLuint handle
= piglit_quads_texture(
5249 0, level
, w
, h
, x
, y
, c
+ 0, c
+ 4, c
+ 8, c
+ 12);
5250 set_texture_binding(tex
, handle
, w
, h
, 1);
5252 if (!piglit_is_core_profile
&&
5253 !(piglit_is_gles() && piglit_get_gl_version() >= 20))
5254 glEnable(GL_TEXTURE_2D
);
5255 } else if (sscanf(line
,
5256 "texture junk 2DArray %d ( %d , %d , %d )",
5257 &tex
, &w
, &h
, &l
) == 4) {
5259 glActiveTexture(GL_TEXTURE0
+ tex
);
5260 glGenTextures(1, &texobj
);
5261 glBindTexture(GL_TEXTURE_2D_ARRAY
, texobj
);
5262 glTexImage3D(GL_TEXTURE_2D_ARRAY
, 0, GL_RGBA
,
5263 w
, h
, l
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, 0);
5264 set_texture_binding(tex
, texobj
, w
, h
, l
);
5266 } else if (parse_str(line
, "texture storage ", &rest
)) {
5267 GLenum target
, format
;
5271 REQUIRE(parse_int(rest
, &tex
, &rest
) &&
5272 parse_tex_target(rest
, &target
, &rest
) &&
5273 parse_enum_gl(rest
, &format
, &rest
) &&
5274 parse_str(rest
, "(", &rest
) &&
5275 parse_int(rest
, &l
, &rest
) &&
5276 parse_int(rest
, &w
, &rest
),
5277 "Texture storage command not understood "
5280 glActiveTexture(GL_TEXTURE0
+ tex
);
5281 glGenTextures(1, &tex_obj
);
5282 glBindTexture(target
, tex_obj
);
5284 if (!parse_int(rest
, &h
, &rest
))
5285 glTexStorage1D(target
, l
, format
, w
);
5286 else if (!parse_int(rest
, &d
, &rest
))
5287 glTexStorage2D(target
, l
, format
, w
, h
);
5289 glTexStorage3D(target
, l
, format
, w
, h
, d
);
5291 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
5292 fprintf(stderr
, "glTexStorage error\n");
5293 piglit_report_result(PIGLIT_FAIL
);
5296 if (target
== GL_TEXTURE_1D_ARRAY
)
5297 set_texture_binding(tex
, tex_obj
, w
, 1, h
);
5299 set_texture_binding(tex
, tex_obj
, w
, h
, d
);
5301 #ifdef PIGLIT_USE_OPENGL
5302 } else if (sscanf(line
,
5303 "texture rgbw 1D %d",
5305 glActiveTexture(GL_TEXTURE0
+ tex
);
5306 const GLuint handle
= piglit_rgbw_texture_1d();
5307 set_texture_binding(tex
, handle
, 4, 1, 1);
5310 } else if (sscanf(line
,
5311 "texture rgbw 3D %d",
5313 glActiveTexture(GL_TEXTURE0
+ tex
);
5314 const GLuint handle
= piglit_rgbw_texture_3d();
5315 set_texture_binding(tex
, handle
, 2, 2, 2);
5317 } else if (sscanf(line
,
5318 "texture rgbw 2DArray %d ( %d , %d , %d )",
5319 &tex
, &w
, &h
, &l
) == 4) {
5320 glActiveTexture(GL_TEXTURE0
+ tex
);
5321 const GLuint handle
= piglit_array_texture(
5322 GL_TEXTURE_2D_ARRAY
, GL_RGBA
, w
, h
, l
, GL_FALSE
);
5323 set_texture_binding(tex
, handle
, w
, h
, l
);
5325 } else if (sscanf(line
,
5326 "texture rgbw 1DArray %d ( %d , %d )",
5327 &tex
, &w
, &l
) == 3) {
5328 glActiveTexture(GL_TEXTURE0
+ tex
);
5330 const GLuint handle
= piglit_array_texture(
5331 GL_TEXTURE_1D_ARRAY
, GL_RGBA
, w
, h
, l
, GL_FALSE
);
5332 set_texture_binding(tex
, handle
, w
, 1, l
);
5334 } else if (sscanf(line
,
5335 "texture shadow2D %d ( %d , %d )",
5336 &tex
, &w
, &h
) == 3) {
5337 glActiveTexture(GL_TEXTURE0
+ tex
);
5338 const GLuint handle
= piglit_depth_texture(
5339 GL_TEXTURE_2D
, GL_DEPTH_COMPONENT
,
5341 glTexParameteri(GL_TEXTURE_2D
,
5342 GL_TEXTURE_COMPARE_MODE
,
5343 GL_COMPARE_R_TO_TEXTURE
);
5344 glTexParameteri(GL_TEXTURE_2D
,
5345 GL_TEXTURE_COMPARE_FUNC
,
5347 set_texture_binding(tex
, handle
, w
, h
, 1);
5349 if (!piglit_is_core_profile
&&
5350 !(piglit_is_gles() && piglit_get_gl_version() >= 20))
5351 glEnable(GL_TEXTURE_2D
);
5352 } else if (sscanf(line
,
5353 "texture shadowRect %d ( %d , %d )",
5354 &tex
, &w
, &h
) == 3) {
5355 glActiveTexture(GL_TEXTURE0
+ tex
);
5356 const GLuint handle
= piglit_depth_texture(
5357 GL_TEXTURE_RECTANGLE
, GL_DEPTH_COMPONENT
,
5359 glTexParameteri(GL_TEXTURE_RECTANGLE
,
5360 GL_TEXTURE_COMPARE_MODE
,
5361 GL_COMPARE_R_TO_TEXTURE
);
5362 glTexParameteri(GL_TEXTURE_RECTANGLE
,
5363 GL_TEXTURE_COMPARE_FUNC
,
5365 set_texture_binding(tex
, handle
, w
, h
, 1);
5366 } else if (sscanf(line
,
5367 "texture shadow1D %d ( %d )",
5369 glActiveTexture(GL_TEXTURE0
+ tex
);
5370 const GLuint handle
= piglit_depth_texture(
5371 GL_TEXTURE_1D
, GL_DEPTH_COMPONENT
,
5373 glTexParameteri(GL_TEXTURE_1D
,
5374 GL_TEXTURE_COMPARE_MODE
,
5375 GL_COMPARE_R_TO_TEXTURE
);
5376 glTexParameteri(GL_TEXTURE_1D
,
5377 GL_TEXTURE_COMPARE_FUNC
,
5379 set_texture_binding(tex
, handle
, w
, 1, 1);
5380 } else if (sscanf(line
,
5381 "texture shadow1DArray %d ( %d , %d )",
5382 &tex
, &w
, &l
) == 3) {
5383 glActiveTexture(GL_TEXTURE0
+ tex
);
5384 const GLuint handle
= piglit_depth_texture(
5385 GL_TEXTURE_1D_ARRAY
, GL_DEPTH_COMPONENT
,
5387 glTexParameteri(GL_TEXTURE_1D_ARRAY
,
5388 GL_TEXTURE_COMPARE_MODE
,
5389 GL_COMPARE_R_TO_TEXTURE
);
5390 glTexParameteri(GL_TEXTURE_1D_ARRAY
,
5391 GL_TEXTURE_COMPARE_FUNC
,
5393 set_texture_binding(tex
, handle
, w
, 1, l
);
5394 } else if (sscanf(line
,
5395 "texture shadow2DArray %d ( %d , %d , %d )",
5396 &tex
, &w
, &h
, &l
) == 4) {
5397 glActiveTexture(GL_TEXTURE0
+ tex
);
5398 const GLuint handle
= piglit_depth_texture(
5399 GL_TEXTURE_2D_ARRAY
, GL_DEPTH_COMPONENT
,
5401 glTexParameteri(GL_TEXTURE_2D_ARRAY
,
5402 GL_TEXTURE_COMPARE_MODE
,
5403 GL_COMPARE_R_TO_TEXTURE
);
5404 glTexParameteri(GL_TEXTURE_2D_ARRAY
,
5405 GL_TEXTURE_COMPARE_FUNC
,
5407 set_texture_binding(tex
, handle
, w
, h
, l
);
5408 } else if (sscanf(line
, "texcoord %d ( %f , %f , %f , %f )",
5409 &x
, c
+ 0, c
+ 1, c
+ 2, c
+ 3) == 5) {
5410 glMultiTexCoord4fv(GL_TEXTURE0
+ x
, c
);
5411 } else if (parse_str(line
, "texparameter ", &rest
)) {
5412 handle_texparameter(rest
);
5413 } else if (parse_str(line
, "uniform ", &rest
)) {
5414 result
= program_must_be_in_use();
5415 set_uniform(rest
, block_data
);
5416 } else if (parse_str(line
, "subuniform ", &rest
)) {
5417 result
= program_must_be_in_use();
5418 check_shader_subroutine_support();
5419 set_subroutine_uniform(rest
);
5420 } else if (parse_str(line
, "parameter ", &rest
)) {
5421 set_parameter(rest
);
5422 } else if (parse_str(line
, "patch parameter ", &rest
)) {
5423 set_patch_parameter(rest
);
5424 } else if (parse_str(line
, "program binary save restore", &rest
)) {
5425 program_binary_save_restore(true);
5426 } else if (parse_str(line
, "provoking vertex ", &rest
)) {
5427 set_provoking_vertex(rest
);
5428 } else if (parse_str(line
, "link error", &rest
)) {
5429 link_error_expected
= true;
5431 fprintf(stderr
, "shader link error expected, but it was successful!\n");
5432 piglit_report_result(PIGLIT_FAIL
);
5434 printf("Failed to link (as expected):\n%s\n", prog_err_info
);
5436 } else if (parse_str(line
, "link success", &rest
)) {
5437 result
= program_must_be_in_use();
5438 } else if (parse_str(line
, "ubo array index ", &rest
)) {
5439 /* we allow "ubo array index" in order to not
5440 * change existing tests using ubo array index
5442 parse_ints(rest
, &block_data
.array_index
, 1, NULL
);
5443 } else if (parse_str(line
, "block array index ", &rest
)) {
5444 parse_ints(rest
, &block_data
.array_index
, 1, NULL
);
5445 } else if (parse_str(line
, "block binding ", &rest
)) {
5446 parse_ints(rest
, &block_data
.binding
, 1, NULL
);
5447 } else if (parse_str(line
, "block offset ", &rest
)) {
5448 parse_ints(rest
, &block_data
.offset
, 1, NULL
);
5449 } else if (parse_str(line
, "block matrix stride", &rest
)) {
5450 parse_ints(rest
, &block_data
.matrix_stride
, 1, NULL
);
5451 } else if (parse_str(line
, "block row major", &rest
)) {
5452 parse_ints(rest
, &block_data
.row_major
, 1, NULL
);
5453 } else if (parse_str(line
, "active uniform ", &rest
)) {
5454 active_uniform(rest
);
5455 } else if (parse_str(line
, "verify program_query", &rest
)) {
5456 verify_program_query(rest
);
5457 } else if (parse_str(line
, "verify program_interface_query ", &rest
)) {
5458 active_program_interface(rest
, block_data
);
5459 } else if (parse_str(line
, "verify query_object", &rest
)) {
5460 result
= verify_query_object_result(rest
);
5461 } else if (parse_str(line
, "vertex attrib ", &rest
)) {
5462 set_vertex_attrib(rest
);
5463 } else if (parse_str(line
, "newlist ", &rest
)) {
5466 REQUIRE(parse_enum_gl(rest
, &mode
, &rest
),
5467 "NewList mode command not understood at %s\n",
5470 list
= glGenLists(1);
5471 glNewList(list
, mode
);
5472 } else if (parse_str(line
, "endlist", NULL
)) {
5474 } else if (parse_str(line
, "calllist", NULL
)) {
5476 } else if (parse_str(line
, "deletelist", NULL
)) {
5477 glDeleteLists(list
, 1);
5478 } else if (parse_str(line
, "viewport swizzle ", &rest
)) {
5479 handle_viewport_swizzle(rest
);
5480 } else if (parse_str(line
, "light ", &rest
)) {
5482 } else if ((line
[0] != '\n') && (line
[0] != '\0')
5483 && (line
[0] != '#')) {
5484 printf("unknown command \"%s\"\n", line
);
5485 piglit_report_result(PIGLIT_FAIL
);
5490 if (result
!= PIGLIT_PASS
) {
5491 printf("Test failure on line %u\n", line_num
);
5492 full_result
= result
;
5498 if (!link_ok
&& !link_error_expected
) {
5499 full_result
= program_must_be_in_use();
5502 piglit_present_results();
5504 if (piglit_automatic
) {
5507 /* Free our resources, useful for valgrinding. */
5508 free_subroutine_uniforms();
5510 for (i
= 0; i
< ARRAY_SIZE(resident_handles
); i
++)
5511 clear_resident_handle(i
);
5513 for (i
= 0; i
< ARRAY_SIZE(texture_bindings
); i
++)
5514 clear_texture_binding(i
);
5517 glDeleteProgram(prog
);
5521 glDeleteProgramsARB(1, &prog
);
5525 glDeleteProgramPipelines(1, &pipeline
);
5531 static enum piglit_result
5532 init_test(const char *file
)
5534 enum piglit_result result
;
5536 result
= process_test_script(file
);
5537 if (result
!= PIGLIT_PASS
)
5540 result
= link_and_use_shaders();
5541 if (result
!= PIGLIT_PASS
)
5545 glBindProgramPipeline(pipeline
);
5547 if (link_ok
&& vertex_data_start
!= NULL
) {
5548 result
= program_must_be_in_use();
5549 if (result
!= PIGLIT_PASS
)
5552 bind_vao_if_supported();
5554 num_vbo_rows
= setup_vbo_from_text(prog
, vertex_data_start
,
5563 recreate_gl_context(char *exec_arg
, int param_argc
, char **param_argv
)
5565 int argc
= param_argc
+ 4;
5566 char **argv
= malloc(sizeof(char*) * argc
);
5569 fprintf(stderr
, "%s: malloc failed.\n", __func__
);
5570 piglit_report_result(PIGLIT_FAIL
);
5574 memcpy(&argv
[1], param_argv
, param_argc
* sizeof(char*));
5575 argv
[argc
-3] = "-auto";
5576 argv
[argc
-2] = "-fbo";
5577 argv
[argc
-1] = "-report-subtests";
5580 gl_fw
->destroy(gl_fw
);
5583 exit(main(argc
, argv
));
5587 validate_current_gl_context(const char *filename
)
5589 struct piglit_gl_test_config config
= { 0 };
5591 if (!piglit_gl_test_config_override_size(&config
)) {
5592 config
.window_width
= DEFAULT_WINDOW_WIDTH
;
5593 config
.window_height
= DEFAULT_WINDOW_HEIGHT
;
5596 get_required_config(filename
, spirv_replaces_glsl
, &config
);
5598 if (!current_config
.supports_gl_compat_version
!=
5599 !config
.supports_gl_compat_version
)
5602 if (!current_config
.supports_gl_core_version
!=
5603 !config
.supports_gl_core_version
)
5606 if (!current_config
.supports_gl_es_version
!=
5607 !config
.supports_gl_es_version
)
5610 if (current_config
.window_width
!= config
.window_width
||
5611 current_config
.window_height
!= config
.window_height
)
5614 if (!(current_config
.window_visual
& PIGLIT_GL_VISUAL_DEPTH
) &&
5615 config
.window_visual
& PIGLIT_GL_VISUAL_DEPTH
)
5622 piglit_init(int argc
, char **argv
)
5626 bool core
= piglit_is_core_profile
;
5628 enum piglit_result result
;
5629 float default_piglit_tolerance
[4];
5631 use_get_program_binary
=
5632 piglit_strip_arg(&argc
, argv
, "-get-program-binary") ||
5633 piglit_env_var_as_boolean("SHADER_RUNNER_GET_PROGRAM_BINARY",
5636 report_subtests
= piglit_strip_arg(&argc
, argv
, "-report-subtests");
5637 force_glsl
= piglit_strip_arg(&argc
, argv
, "-glsl");
5638 ignore_missing_uniforms
= piglit_strip_arg(&argc
, argv
, "-ignore-missing-uniforms");
5640 force_no_names
= piglit_strip_arg(&argc
, argv
, "-force-no-names");
5642 if (force_glsl
&& spirv_replaces_glsl
) {
5643 printf("Options -glsl and -spirv can't be used at the same time\n");
5644 piglit_report_result(PIGLIT_FAIL
);
5647 if (spirv_replaces_glsl
)
5648 force_no_names
= true;
5651 printf("usage: shader_runner <test.shader_test> [-auto] [-fbo] [-png]"
5652 "[-rlimit <AS-limit>] [-samples=<N>] [-khr_no_error] [-compat] [-report-subtests]"
5653 "[-glsl] [-ignore-missing-uniforms] [-force-no-names]\n");
5657 memcpy(default_piglit_tolerance
, piglit_tolerance
,
5658 sizeof(piglit_tolerance
));
5660 piglit_require_GLSL();
5662 version_init(&gl_version
, VERSION_GL
,
5665 piglit_get_gl_version());
5666 piglit_get_glsl_version(&es
, &major
, &minor
);
5667 version_init(&glsl_version
, VERSION_GLSL
, core
, !core
, es
,
5668 (major
* 100) + minor
);
5670 #ifdef PIGLIT_USE_OPENGL
5671 if (piglit_get_gl_version() >= 32)
5672 glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS
,
5673 &gl_max_vertex_output_components
);
5674 if (piglit_get_gl_version() >= 20 ||
5675 piglit_is_extension_supported("GL_ARB_fragment_shader"))
5676 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
,
5677 &gl_max_fragment_uniform_components
);
5678 if (piglit_get_gl_version() >= 20 ||
5679 piglit_is_extension_supported("GL_ARB_vertex_shader"))
5680 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS
,
5681 &gl_max_vertex_uniform_components
);
5682 if (piglit_get_gl_version() >= 20 ||
5683 piglit_is_extension_supported("GL_ARB_vertex_shader") ||
5684 piglit_is_extension_supported("GL_ARB_geometry_shader4") ||
5685 piglit_is_extension_supported("GL_EXT_geometry_shader4"))
5686 glGetIntegerv(GL_MAX_VARYING_COMPONENTS
,
5687 &gl_max_varying_components
);
5689 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS
,
5690 &gl_max_fragment_uniform_components
);
5691 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS
,
5692 &gl_max_vertex_uniform_components
);
5693 glGetIntegerv(GL_MAX_VARYING_VECTORS
,
5694 &gl_max_varying_components
);
5695 gl_max_fragment_uniform_components
*= 4;
5696 gl_max_vertex_uniform_components
*= 4;
5697 gl_max_varying_components
*= 4;
5699 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max_clip_planes
);
5701 if (gl_version
.num
>= 20 ||
5702 piglit_is_extension_supported("GL_ARB_vertex_shader"))
5703 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS
,
5704 &gl_max_vertex_attribs
);
5706 gl_max_vertex_attribs
= 16;
5708 read_width
= render_width
= piglit_width
;
5709 read_height
= render_height
= piglit_height
;
5711 #ifdef PIGLIT_USE_OPENGL
5712 if (piglit_is_extension_supported("GL_ARB_get_program_binary"))
5713 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS
,
5714 &gl_num_program_binary_formats
);
5716 if (piglit_is_extension_supported("GL_OES_get_program_binary"))
5717 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES
,
5718 &gl_num_program_binary_formats
);
5721 if (use_get_program_binary
) {
5722 if (gl_num_program_binary_formats
== 0) {
5723 printf("Trying to use get_program_binary, but "
5724 "GL_NUM_PROGRAM_BINARY == 0\n");
5725 piglit_report_result(PIGLIT_SKIP
);
5729 /* Run multiple tests per session. */
5731 char testname
[4096], *ext
;
5733 enum piglit_result all
= PIGLIT_PASS
;
5735 for (i
= 1; i
< argc
; i
++) {
5736 const char *hit
, *filename
= argv
[i
];
5738 memcpy(piglit_tolerance
, default_piglit_tolerance
,
5739 sizeof(piglit_tolerance
));
5741 for (unsigned i
= 0; i
< ARRAY_SIZE(specializations
); i
++) {
5742 free(specializations
[i
].indices
);
5743 free(specializations
[i
].values
);
5745 memset(specializations
, 0, sizeof(specializations
));
5747 /* Re-initialize the GL context if a different GL config is required. */
5748 if (!validate_current_gl_context(filename
))
5749 recreate_gl_context(argv
[0], argc
- i
, argv
+ i
);
5751 /* Clear global variables to defaults. */
5753 assert(num_vertex_shaders
== 0);
5754 assert(num_tess_ctrl_shaders
== 0);
5755 assert(num_tess_eval_shaders
== 0);
5756 assert(num_geometry_shaders
== 0);
5757 assert(num_fragment_shaders
== 0);
5758 assert(num_compute_shaders
== 0);
5759 assert(num_uniform_blocks
== 0);
5760 assert(uniform_block_bos
== NULL
);
5761 assert(uniform_block_indexes
== NULL
);
5762 geometry_layout_input_type
= GL_TRIANGLES
;
5763 geometry_layout_output_type
= GL_TRIANGLE_STRIP
;
5764 geometry_layout_vertices_out
= 0;
5765 memset(atomics_bos
, 0, sizeof(atomics_bos
));
5766 memset(ssbo
, 0, sizeof(ssbo
));
5767 for (j
= 0; j
< ARRAY_SIZE(subuniform_locations
); j
++)
5768 assert(subuniform_locations
[j
] == NULL
);
5769 memset(num_subuniform_locations
, 0, sizeof(num_subuniform_locations
));
5770 shader_string
= NULL
;
5771 shader_string_size
= 0;
5772 vertex_data_start
= NULL
;
5773 vertex_data_end
= NULL
;
5775 sso_vertex_prog
= 0;
5776 sso_tess_control_prog
= 0;
5777 sso_tess_eval_prog
= 0;
5778 sso_geometry_prog
= 0;
5779 sso_fragment_prog
= 0;
5780 sso_compute_prog
= 0;
5782 vbo_present
= false;
5784 prog_in_use
= false;
5786 separable_program
= false;
5787 prog_err_info
= NULL
;
5790 /* Clear GL states to defaults. */
5791 glClearColor(0, 0, 0, 0);
5792 # if PIGLIT_USE_OPENGL
5797 glBindFramebuffer(GL_FRAMEBUFFER
, piglit_winsys_fbo
);
5798 glActiveTexture(GL_TEXTURE0
);
5800 glDisable(GL_DEPTH_TEST
);
5801 glBindBuffer(GL_ARRAY_BUFFER
, 0);
5803 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
5805 for (int k
= 0; k
< gl_max_clip_planes
; k
++) {
5806 static const GLdouble zero
[4];
5808 if (!piglit_is_core_profile
&& !es
)
5809 glClipPlane(GL_CLIP_PLANE0
+ k
, zero
);
5810 glDisable(GL_CLIP_PLANE0
+ k
);
5813 if (!(es
) && (gl_version
.num
>= 20 ||
5814 piglit_is_extension_supported("GL_ARB_vertex_program")))
5815 glDisable(GL_PROGRAM_POINT_SIZE
);
5817 for (int i
= 0; i
< 16; i
++)
5818 glDisableVertexAttribArray(i
);
5820 if (!piglit_is_core_profile
&& !es
) {
5821 glMatrixMode(GL_PROJECTION
);
5823 glMatrixMode(GL_MODELVIEW
);
5825 glShadeModel(GL_SMOOTH
);
5826 glDisable(GL_VERTEX_PROGRAM_TWO_SIDE
);
5829 if (piglit_is_extension_supported("GL_ARB_vertex_program")) {
5830 glDisable(GL_VERTEX_PROGRAM_ARB
);
5831 glBindProgramARB(GL_VERTEX_PROGRAM_ARB
, 0);
5833 if (piglit_is_extension_supported("GL_ARB_fragment_program")) {
5834 glDisable(GL_FRAGMENT_PROGRAM_ARB
);
5835 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, 0);
5837 if (piglit_is_extension_supported("GL_ARB_separate_shader_objects")) {
5839 glGenProgramPipelines(1, &pipeline
);
5840 glBindProgramPipeline(0);
5843 if (piglit_is_extension_supported("GL_EXT_provoking_vertex"))
5844 glProvokingVertexEXT(GL_LAST_VERTEX_CONVENTION_EXT
);
5846 # if PIGLIT_USE_OPENGL
5847 if (gl_version
.num
>= 40 ||
5848 piglit_is_extension_supported("GL_ARB_tessellation_shader")) {
5849 static float ones
[] = {1, 1, 1, 1};
5850 glPatchParameteri(GL_PATCH_VERTICES
, 3);
5851 glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL
, ones
);
5852 glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL
, ones
);
5855 /* Ideally one would use the following code:
5857 * if (gl_version.num >= 32) {
5858 * glPatchParameteri(GL_PATCH_VERTICES, 3);
5861 * however, that doesn't work with mesa because those
5862 * symbols apparently need to be exported, but that
5863 * breaks non-gles builds.
5865 * It seems rather unlikely that an implementation
5866 * would have GLES 3.2 support but not
5867 * OES_tessellation_shader.
5869 if (piglit_is_extension_supported("GL_OES_tessellation_shader")) {
5870 glPatchParameteriOES(GL_PATCH_VERTICES_OES
, 3);
5874 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
5876 /* Strip the file path. */
5877 hit
= strrchr(filename
, PIGLIT_PATH_SEP
);
5879 strcpy(testname
, hit
+1);
5881 strcpy(testname
, filename
);
5883 /* Strip the file extension. */
5884 ext
= strstr(testname
, ".shader_test");
5885 if (ext
&& !ext
[12])
5888 /* Print the name before we start the test, that way if
5889 * the test fails we can still resume and know which
5891 printf("PIGLIT TEST: %i - %s\n", test_num
, testname
);
5892 fprintf(stderr
, "PIGLIT TEST: %i - %s\n", test_num
, testname
);
5896 result
= init_test(filename
);
5898 if (result
== PIGLIT_PASS
) {
5899 result
= piglit_display();
5901 /* Use subtest when running with more than one test,
5902 * but use regular test result when running with just
5903 * one. This allows the standard process-at-a-time
5904 * mode to keep working.
5906 if (report_subtests
) {
5907 piglit_report_subtest_result(
5908 result
, "%s", testname
);
5910 piglit_merge_result(&all
, result
);
5913 /* destroy GL objects? */
5917 teardown_shader_include_paths();
5920 if (!report_subtests
)
5921 piglit_report_result(all
);
5925 result
= init_test(argv
[1]);
5926 if (result
!= PIGLIT_PASS
)
5927 piglit_report_result(result
);