1 /*
2  * Copyright © 2009 Intel Corporation
3  *
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:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #pragma once
25 #ifndef PIGLIT_FRAMEWORK_H
26 #define PIGLIT_FRAMEWORK_H
27 
28 #include <assert.h>
29 #include <stdbool.h>
30 
31 /**
32  * A bitmask of these enums specifies visual attributes for the test's window.
33  *
34  * \see piglit_gl_test_config::window_visual
35  */
36 enum piglit_gl_visual {
37 	PIGLIT_GL_VISUAL_RGB 		= 1 << 0,
38 	PIGLIT_GL_VISUAL_RGBA 		= 1 << 1,
39 	PIGLIT_GL_VISUAL_DOUBLE 	= 1 << 2,
40 	PIGLIT_GL_VISUAL_ACCUM 		= 1 << 3,
41 	PIGLIT_GL_VISUAL_DEPTH 		= 1 << 4,
42 	PIGLIT_GL_VISUAL_STENCIL 	= 1 << 5
43 };
44 
45 enum piglit_khr_no_error_support {
46 	PIGLIT_HAS_ERRORS,
47 	PIGLIT_NO_ERRORS,
48 	PIGLIT_UNKNOWN_ERROR_STATUS
49 };
50 
51 /**
52  * @brief Configuration for running an OpenGL test.
53  *
54  * To run a test, pass this to piglit_gl_test_run().
55  *
56  * This is named piglit_gl_test_config, rather than piglit_test_config, in
57  * order to distinguish it from other test types, such as EGL and GLX tests.
58  *
59  * At least one of the `supports` fields must be set.
60  *
61  * If `supports_gl_core_version` and `supports_gl_compat_version` are both
62  * set, then Piglit will first attempt to run the test under a GL core context
63  * of the requested version. If context creation fails, then Piglit will then
64  * attempt to run the test under a GL compatibility context of the requested
65  * version.
66  */
67 struct piglit_gl_test_config {
68 	/**
69 	 * If this field is non-zero, then the test is able to run under any
70 	 * OpenGL ES context whose version is backwards-compatible with the
71 	 * given version.
72 	 *
73 	 * For example, if this field's value is '10', then Piglit will
74 	 * attempt to run the test under an OpenGL ES 1.0 context. Likewise
75 	 * for '20' and OpenGL ES 2.0.
76 	 *
77 	 * If Piglit fails to acquire the waffle_config or to create the
78 	 * waffle_context, then it skips its attempt to run the test under
79 	 * an OpenGL ES context.
80 	 *
81 	 * If this field is 0, then the test is not able to run under an
82 	 * OpenGL ES context of any version.
83 	 */
84 	int supports_gl_es_version;
85 
86 	/**
87 	 * If this field is non-zero, then the test is able to run under a GL
88 	 * core context having at least the given version.
89 	 *
90 	 * When attempting run a test under a GL core context, Piglit chooses
91 	 * a waffle_config with the following attributes set.  (Note that
92 	 * Waffle ignores the profile attribute for versions less than 3.2).
93 	 *     - WAFFLE_CONTEXT_PROFILE       = WAFFLE_CONTEXT_CORE_PROFILE
94 	 *     - WAFFLE_CONTEXT_MAJOR_VERSION = supports_gl_core_version / 10
95 	 *     - WAFFLE_CONTEXT_MINOR_VERSION = supports_gl_core_version % 10
96 	 * If Piglit fails to acquire the waffle_config or to create the
97 	 * waffle_context, then it skips its attempt to run the test under
98 	 * a GL core context.
99 	 *
100 	 * It is an error if this field is less than 3.1 because the concept
101 	 * of "core context" does not apply before GL 3.1.
102 	 *
103 	 * Piglit handles a request for a GL 3.1 core context as a special
104 	 * case.  As noted above, Waffle ignores the profile attribute when
105 	 * choosing a 3.1 config. However, the concept of "core profile" is
106 	 * still applicable to 3.1 contexts and is indicated by the context's
107 	 * lack of support for the GL_ARB_compatibility extension. Therefore,
108 	 * Piglit attempts to run the test under a GL 3.1 core context by
109 	 * first creating the context and then skipping the attempt if the
110 	 * context supports the GL_ARB_compatibility extension.
111 	 *
112 	 * If this field is 0, then the test is not able to run under a GL
113 	 * core context of any version.
114 	 */
115 	int supports_gl_core_version;
116 
117 	/**
118 	 * If this field is non-zero, then the test is able to run under a GL
119 	 * compatibility context having at least the given version.
120 	 *
121 	 * When attempting run a test under a GL compatibility context, Piglit
122 	 * chooses a waffle_config with the following attribute set.
123 	 *
124 	 *     WAFFLE_CONTEXT_PROFILE = WAFFLE_CONTEXT_COMPATIBILITY_PROFILE
125 	 *
126 	 * If context creation succeeds, then Piglit verifies with
127 	 * glGetString() that the context's actual version is no less than the
128 	 * requested version. Otherwise, If the version verification fails,
129 	 * then Piglit skips its attempt to run the test under a GL
130 	 * compatibility context.
131 	 *
132 	 * Piglit handles a request for a GL 3.1 compatibility context as
133 	 * a special case.  As noted above, Waffle ignores the profile
134 	 * attribute when choosing a 3.1 config. However, the concept of
135 	 * "compatibility profile" is still applicable to 3.1 contexts and is
136 	 * indicated by the context's support for the GL_ARB_compatibility
137 	 * extension. Therefore, Piglit attempts to run under a GL 3.1
138 	 * compatibility context by first creating the context and then
139 	 * skipping the attempt if the context lacks the GL_ARB_compatibility
140 	 * extension.
141 	 *
142 	 * If this field is 0, then the test is not able to run under a GL
143 	 * compatibility context of any version.
144 	 */
145 	int supports_gl_compat_version;
146 
147 	/**
148 	 * If true, then this test requires a forward-compatible context.
149 	 *
150 	 * Piglit will choose a waffle_config with
151 	 * WAFFLE_CONTEXT_FORWARD_COMPATIBLE set to true. If context creation
152 	 * fails, then the test skips.
153 	 */
154 	bool require_forward_compatible_context;
155 
156 	/**
157 	 * If true, then this test requires a debug context.
158 	 *
159 	 * Piglit will choose a waffle_config with WAFFLE_CONTEXT_DEBUG set to
160 	 * true. If context creation fails, then the test skips.
161 	 */
162 	bool require_debug_context;
163 
164 	int window_width;
165 	int window_height;
166 	int window_samples;
167 
168 	/**
169 	 * A bitmask of `enum piglit_gl_visual`.
170 	 */
171 	int window_visual;
172 
173 	/**
174 	 * The test requires the window to be displayed in order to run
175 	 * correctly. Tests that read from the front buffer must enable
176 	 * this.
177 	 */
178 	bool requires_displayed_window;
179 
180 	/**
181 	 * This is called once per test, after the GL context has been created
182 	 * and made current but before display() is called.
183 	 */
184 	void
185 	(*init)(int argc, char *argv[]);
186 
187 	/**
188 	 * If the test is run in auto mode, then this is called once after
189 	 * init(). Otherwise, it is called repeatedly from some ill-defined
190 	 * event loop.
191 	 */
192 	enum piglit_result
193 	(*display)(void);
194 
195 	/**
196 	 * List of subtests supported by this test case
197 	 *
198 	 * This is only used during command line argument parsing to implement
199 	 * the -list-subtests option.
200 	 */
201 	const struct piglit_subtest *subtests;
202 
203 	/**
204 	 * Names of subtests supplied on the command line.
205 	 *
206 	 * The paramaters passed to each -subtest command line option is
207 	 * stored here in the order of appearance on the command line.
208 	 */
209 	const char **selected_subtests;
210 	size_t num_selected_subtests;
211 
212 	/**
213 	 * enum used for markin test as supporting KHR_no_error or not.
214 	 */
215 	enum piglit_khr_no_error_support khr_no_error_support;
216 };
217 
218 /**
219  * Initialize @a config with default values, some of which may come
220  * from command line arguments.
221  */
222 void
223 piglit_gl_test_config_init(struct piglit_gl_test_config *config);
224 
225 void
226 piglit_gl_process_args(int *argc, char *argv[],
227 		       struct piglit_gl_test_config *config);
228 
229 bool
230 piglit_gl_test_config_override_size(struct piglit_gl_test_config *config);
231 
232 /**
233  * Get the list of command-line selected tests from the piglit_gl_test_config
234  *
235  * If the config structure does not contain a list of subtests or if no tests
236  * were selected on the command line, this function will set \c
237  * *selected_subtests to \c NULL and will return zero.
238  *
239  * \returns
240  * The number of tests selected on the command line.
241  */
242 size_t
243 piglit_get_selected_tests(const char ***selected_subtests);
244 
245 /**
246  * Run the OpenGL test described by @a config. Does not return.
247  */
248 void
249 piglit_gl_test_run(int argc, char *argv[],
250 		   const struct piglit_gl_test_config *config);
251 
252 #ifdef __cplusplus
253 #  define PIGLIT_EXTERN_C_BEGIN extern "C" {
254 #  define PIGLIT_EXTERN_C_END   }
255 #else
256 #  define PIGLIT_EXTERN_C_BEGIN
257 #  define PIGLIT_EXTERN_C_END
258 #endif
259 
260 #define PIGLIT_GL_TEST_CONFIG_BEGIN                                          \
261                                                                              \
262         PIGLIT_EXTERN_C_BEGIN                                                \
263                                                                              \
264         void                                                                 \
265         piglit_init(int argc, char *argv[]);                                 \
266                                                                              \
267         enum piglit_result                                                   \
268         piglit_display(void);                                                \
269                                                                              \
270         PIGLIT_EXTERN_C_END                                                  \
271                                                                              \
272         int                                                                  \
273         main(int argc, char *argv[])                                         \
274         {                                                                    \
275                 struct piglit_gl_test_config config;                         \
276                                                                              \
277                 piglit_general_init();                                       \
278                                                                              \
279                 piglit_gl_test_config_init(&config);                         \
280                                                                              \
281                 config.init = piglit_init;                                   \
282                 config.display = piglit_display;                             \
283                                                                              \
284                 /* Open a new scope so that tests can declare locals */      \
285                 /* between here and PIGLIT_GL_TEST_CONFIG_END. */            \
286                 {
287 
288 
289 #define PIGLIT_GL_TEST_CONFIG_END                                            \
290                 }                                                            \
291                                                                              \
292                 piglit_gl_process_args(&argc, argv, &config);                \
293                 piglit_gl_test_run(argc, argv, &config);                     \
294                                                                              \
295                 assert(false);                                               \
296                 return 0;                                                    \
297         }
298 
299 extern int piglit_automatic;
300 
301 extern int piglit_width;
302 extern int piglit_height;
303 extern bool piglit_use_fbo;
304 extern bool piglit_khr_no_error;
305 extern unsigned int piglit_winsys_fbo;
306 extern struct piglit_gl_framework *gl_fw;
307 
308 void piglit_swap_buffers(void);
309 void piglit_present_results();
310 void piglit_post_redisplay(void);
311 void piglit_set_keyboard_func(void (*func)(unsigned char key, int x, int y));
312 void piglit_set_reshape_func(void (*func)(int w, int h));
313 
314 /**
315  * Convenience macro for invoking piglit_strip_arg() from within
316  * piglit_init() or between PIGLIT_GL_TEST_CONFIG_BEGIN and
317  * PIGLIT_GL_TEST_CONFIG_END.
318  */
319 #define PIGLIT_STRIP_ARG(arg) piglit_strip_arg(&argc, argv, arg)
320 
321 struct piglit_dma_buf;
322 
323 /**
324  * Create buffer suitable for dma_buf importing and set its contents to the
325  * given data (src_data). Different hardware may have different alignment
326  * constraints and hence one can specify one stride for the source and get
327  * another for the final buffer to be given further to EGL.
328  *
329  * The src stride is inferred from the width and the fourcc.  For planar
330  * YUV formats, for example, the U and V planes for YV12/YU12 have half the
331  * src_stride.
332  *
333  * The resulting per-plane stride and offset, which may be different than
334  * the src_stride due to hw constraints, are in the returned buf object.
335  *
336  * An buf handle is only returned upon success indicated by the return value
337  * PIGLIT_PASS, otherwise no buffer is created. In case the framework simply
338  * does not support dma buffers, the return value is PIGLIT_SKIP instead of
339  * PIGLIT_FAIL.
340  */
341 enum piglit_result
342 piglit_create_dma_buf(unsigned w, unsigned h, unsigned fourcc,
343 		      const void *src_data, struct piglit_dma_buf **buf);
344 
345 /**
346  * Release all the resources allocated for the designated buffer. If the given
347  * pointer (buf) is NULL no action is taken.
348  */
349 void
350 piglit_destroy_dma_buf(struct piglit_dma_buf *buf);
351 
352 #endif /* PIGLIT_FRAMEWORK_H */
353