glx-oml-sync-control-timing: Fix error message if glXWaitForMscOML fails
[piglit.git] / tests / util / piglit-framework-cl.c
blob235f160877cfb2a567a2901a3285856bb4f65239
1 /*
2 * Copyright © 2012 Blaž Tomažič <blaz.tomazic@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 #include <stdlib.h>
25 #include <regex.h>
27 #include "piglit-framework-cl.h"
30 /* Default test header configuration values */
31 const struct piglit_cl_test_config_header
32 PIGLIT_CL_DEFAULT_TEST_CONFIG_HEADER = {
33 ._filename = "",
34 .name = NULL,
36 .run_per_platform = false,
37 .run_per_device = false,
39 .platform_regex = NULL,
40 .device_regex = NULL,
42 .require_platform_extensions = NULL,
43 .require_device_extensions = NULL,
45 .init_func = NULL,
46 .clean_func = NULL,
50 /* Print test configuration */
51 static void
52 print_test_info(const struct piglit_cl_test_config_header* config,
53 int version,
54 const cl_platform_id platform_id,
55 const cl_device_id device_id) {
56 if(config->run_per_platform || config->run_per_device) {
57 char* platform_name;
59 platform_name = piglit_cl_get_platform_info(platform_id,
60 CL_PLATFORM_NAME);
62 printf("# Running on:\n"
63 "# Platform: %s\n",
64 platform_name);
66 if(config->run_per_device) {
67 char* device_name = piglit_cl_get_device_info(device_id,
68 CL_DEVICE_NAME);
70 printf("# Device: %s\n", device_name);
72 free(device_name);
75 printf("# OpenCL version: %d.%d\n", version/10, version%10);
77 free(platform_name);
78 } else {
79 // print nothing
83 /* Check extensions */
85 bool check_platform_extensions(cl_platform_id platform_id, char* extensions)
87 char* pch;
89 if (!extensions)
90 return true;
92 pch = strtok(extensions, " ");
93 while(pch != NULL) {
94 if( strlen(pch) > 0
95 && !piglit_cl_is_platform_extension_supported(platform_id, pch)) {
96 char* platform_name = piglit_cl_get_platform_info(platform_id,
97 CL_PLATFORM_NAME);
98 printf("\n# Skipping platform %s because extension %s is not supported.\n\n",
99 platform_name,
100 pch);
101 free(platform_name);
102 return false;
104 pch = strtok(NULL, " ");
107 return true;
110 bool check_device_extensions(cl_device_id device_id, char* extensions)
112 char* pch;
114 if (!extensions)
115 return true;
117 pch = strtok(extensions, " ");
118 while(pch != NULL) {
119 if( strlen(pch) > 0
120 && !piglit_cl_is_device_extension_supported(device_id, pch)) {
121 char* device_name = piglit_cl_get_device_info(device_id,
122 CL_DEVICE_NAME);
123 printf("\n# Skipping device %s because extension %s is not supported.\n\n",
124 device_name,
125 pch);
126 free(device_name);
127 return false;
129 pch = strtok(NULL, " ");
132 return true;
135 /* Run the test(s) */
136 int piglit_cl_framework_run(int argc, char** argv)
138 enum piglit_result result = PIGLIT_SKIP;
140 int version = 0;
141 cl_platform_id platform_id = NULL;
142 cl_device_id device_id = NULL;
144 /* Get test configuration */
145 struct piglit_cl_test_config_header *config =
146 piglit_cl_get_test_config(argc,
147 (const char**)argv,
148 &PIGLIT_CL_DEFAULT_TEST_CONFIG_HEADER);
150 /* Check that config is valid */
151 // run_per_platform, run_per_device
152 if(config->run_per_platform && config->run_per_device) {
153 fprintf(stderr,
154 "Invalid configuration, only one of run_per_platform and run_per_device can be true.\n");
155 piglit_report_result(PIGLIT_WARN);
158 /* Init */
159 if(config->init_func != NULL) {
160 config->init_func(argc, (const char**)argv, config);
163 /* Print test name and file */
164 printf("## Test: %s (%s) ##\n\n", config->name != NULL ? config->name : "",
165 config->_filename);
167 /* Get version to test against */
168 version = piglit_cl_get_version_arg(argc, (const char **)argv);
169 if(version > 0) {
170 if(version > PIGLIT_CL_VERSION) {
171 printf("Piglit was compiled with lower OpenCL version (%d.%d) than version argument: %d.%d.\n",
172 PIGLIT_CL_VERSION/10, PIGLIT_CL_VERSION%10,
173 version/10, version%10);
174 piglit_report_result(PIGLIT_SKIP);
176 } else {
178 * If version was not provided on the command line, set it to
179 * the version against which Piglit was compiled (PIGLIT_CL_VERSION)
181 version = PIGLIT_CL_VERSION;
184 /* Run the actual test */
185 if(!(config->run_per_platform || config->run_per_device)) {
186 print_test_info(config, version, NULL, NULL);
187 result = config->_test_run(argc, (const char**)argv, (void*)config,
188 version, NULL, NULL);
189 } else {
190 /* Run tests per platform or device */
191 int i;
192 regex_t platform_regex;
193 regex_t device_regex;
195 bool platform_defined;
196 unsigned int num_platforms;
197 cl_platform_id* platform_ids = NULL;
199 /* Create regexes */
200 if( config->platform_regex != NULL
201 && regcomp(&platform_regex, config->platform_regex, REG_EXTENDED | REG_NEWLINE)) {
202 fprintf(stderr,
203 "Regex to filter platforms is invalid, ignoring it.\n");
204 regcomp(&platform_regex, "", REG_EXTENDED | REG_NEWLINE);
205 piglit_merge_result(&result, PIGLIT_WARN);
207 if( config->device_regex != NULL
208 && regcomp(&device_regex, config->device_regex, REG_EXTENDED | REG_NEWLINE)) {
209 fprintf(stderr,
210 "Regex to filter devices is invalid, ignoring it.\n");
211 regcomp(&device_regex, "", REG_EXTENDED | REG_NEWLINE);
212 piglit_merge_result(&result, PIGLIT_WARN);
215 /* check for command-line/environment platform */
216 platform_defined = piglit_cl_get_platform_arg(argc, (const char**)argv,
217 &platform_id);
219 /* generate platforms list */
220 if(platform_defined) {
221 /* use platform defined by command-line/environment */
222 num_platforms = 1;
223 platform_ids = malloc(sizeof(cl_platform_id));
224 platform_ids[0] = platform_id;
225 } else {
226 /* use all available platforms */
227 num_platforms = piglit_cl_get_platform_ids(&platform_ids);
230 /* execute test for each platform in platforms list */
231 for(i = 0; i < num_platforms; i++) {
232 int final_version = version;
233 int platform_version;
235 platform_id = platform_ids[i];
237 /* Filter platform */
238 if(config->platform_regex != NULL) {
239 char* platform_name;
241 platform_name = piglit_cl_get_platform_info(platform_id,
242 CL_PLATFORM_NAME);
243 if(regexec(&platform_regex, platform_name, 0, NULL, 0)) {
244 printf("\n# Skipping platform %s because it does not match platform_regex.\n\n",
245 platform_name);
246 free(platform_name);
247 continue;
249 free(platform_name);
252 /* Check platform extensions */
253 if(!check_platform_extensions(platform_id, config->require_platform_extensions)) {
254 continue;
257 /* Get platform version */
258 platform_version = piglit_cl_get_platform_version(platform_id);
260 if(config->run_per_platform) {
261 /* Check platform version */
262 if(platform_version < final_version) {
263 printf("# Platform supporting only version %d.%d. Running test on that version.\n",
264 platform_version/10, platform_version%10);
265 final_version = platform_version;
268 /* run test on platform */
269 print_test_info(config, final_version, platform_id, NULL);
270 piglit_merge_result(&result,
271 config->_test_run(argc,
272 (const char**)argv,
273 (void*)config,
274 final_version,
275 platform_id,
276 NULL));
277 } else { //config->run_per_device
278 int j;
280 bool device_defined;
281 unsigned int num_devices;
282 cl_device_id* device_ids;
284 /* check for command-line/environment device */
285 device_defined = piglit_cl_get_device_arg(argc,
286 (const char**)argv,
287 platform_id,
288 &device_id);
290 /* generate devices list */
291 if(device_defined) {
292 /* use device defined by command-line/environment */
293 num_devices = 1;
294 device_ids = malloc(sizeof(cl_device_id));
295 device_ids[0] = device_id;
296 } else {
297 /* use all available devices */
298 num_devices = piglit_cl_get_device_ids(platform_id,
299 CL_DEVICE_TYPE_ALL,
300 &device_ids);
303 /* run tests per each device */
304 for(j = 0; j < num_devices; j++) {
305 int device_version;
307 device_id = device_ids[j];
309 /* Filter device */
310 if(config->device_regex != NULL) {
311 char* device_name;
313 device_name = piglit_cl_get_device_info(device_id,
314 CL_DEVICE_NAME);
315 if(regexec(&device_regex, device_name, 0, NULL, 0)) {
316 printf("\n# Skipping device %s because it does not match device_regex.\n\n",
317 device_name);
318 free(device_name);
319 continue;
321 free(device_name);
324 /* Check device extensions */
325 if(!check_device_extensions(device_id, config->require_device_extensions)) {
326 continue;
329 /* Check platform version */
330 if(platform_version < final_version) {
331 printf("# Platform supporting only version %d.%d. Running test on that version.\n",
332 platform_version/10, platform_version%10);
333 final_version = platform_version;
335 /* Check device version */
336 device_version = piglit_cl_get_device_version(device_id);
337 if(device_version < final_version) {
338 printf("# Device supporting only version %d.%d. Running test on that version.\n",
339 device_version/10, device_version%10);
340 final_version = device_version;
343 print_test_info(config, version, platform_id, device_id);
344 piglit_merge_result(&result,
345 config->_test_run(argc,
346 (const char**)argv,
347 (void*)config,
348 final_version,
349 platform_id,
350 device_id));
353 free(device_ids);
357 if(config->platform_regex != NULL) {
358 regfree(&platform_regex);
360 if(config->device_regex != NULL) {
361 regfree(&device_regex);
364 free(platform_ids);
367 /* Clean */
368 if(config->clean_func != NULL) {
369 config->clean_func(argc, (const char**)argv, config);
372 /* Report merged result */
373 printf("# Result:\n");
374 piglit_report_result(result);
376 /* UNREACHED */
377 return 1;
380 /* Get command-line/environment variables */
382 const char*
383 piglit_cl_get_arg_value(const int argc, const char *argv[], const char* arg)
385 int i;
386 char* full_arg = calloc(strlen(arg) + 2, sizeof(char));
387 full_arg = strcpy(full_arg, "-");
388 full_arg = strcat(full_arg, arg);
390 for (i = 1; i < argc; i++) {
391 if (!strcmp(argv[i], full_arg)) {
392 if ((i+1) >= argc) {
393 fprintf(stderr,
394 "Argument error: %s requires a value\n",
395 full_arg);
396 free(full_arg);
397 piglit_report_result(PIGLIT_WARN);
398 } else {
399 free(full_arg);
400 return argv[i+1];
405 free(full_arg);
406 return NULL;
409 const char*
410 piglit_cl_get_unnamed_arg(const int argc, const char *argv[], int index)
412 int i;
413 int count = 0;
415 for (i = 1; i < argc; i++) {
416 if (strncmp(argv[i], "-", 1)) {
417 count++;
418 if((count - 1) == index) {
419 return argv[i];
421 } else {
422 i++;
426 return NULL;
429 bool
430 piglit_cl_is_arg_defined(const int argc, const char *argv[], const char* arg)
432 int i;
433 char* full_arg = calloc(strlen(arg) + 2, sizeof(char));
434 full_arg = strcpy(full_arg, "-");
435 full_arg = strcat(full_arg, arg);
437 for (i = 1; i < argc; i++) {
438 if (!strcmp(argv[i], full_arg)) {
439 free(full_arg);
440 return true;
444 free(full_arg);
445 return false;
449 piglit_cl_get_version_arg(int argc, const char** argv)
451 int version_major = 0;
452 int version_minor = 0;
454 const char* version_str;
456 /* First check argument then environment */
457 version_str = piglit_cl_get_arg_value(argc, argv, "version");
458 if(version_str == NULL) {
459 version_str = getenv("PIGLIT_CL_VERSION");
462 if(version_str != NULL) {
463 if(sscanf(version_str, "%i.%i", &version_major, &version_minor) != 2) {
464 version_major = 0;
465 version_minor = 0;
469 return version_major*10 + version_minor;
472 bool
473 piglit_cl_get_platform_arg(const int argc, const char** argv,
474 cl_platform_id* platform_id)
476 int i;
477 const char* arg_value;
479 /* First check argument then environment */
480 arg_value = piglit_cl_get_arg_value(argc, argv, "platform");
481 if(arg_value == NULL) {
482 arg_value = getenv("PIGLIT_CL_PLATFORM");
485 if(arg_value != NULL) {
486 unsigned int num_platforms;
487 cl_platform_id* platform_ids;
489 num_platforms = piglit_cl_get_platform_ids(&platform_ids);
491 for(i = 0; i < num_platforms; i++) {
492 char* platform_name = piglit_cl_get_platform_info(platform_ids[i],
493 CL_PLATFORM_NAME);
495 if(!strncmp(arg_value, platform_name, strlen(arg_value))) {
496 *platform_id = platform_ids[i];
498 free(platform_ids);
499 free(platform_name);
500 return true;
503 free(platform_name);
506 free(platform_ids);
507 fprintf(stderr,
508 "Could not find platform: %s\n",
509 arg_value);
510 piglit_report_result(PIGLIT_WARN);
513 return false;
516 bool
517 piglit_cl_get_device_arg(const int argc, const char** argv,
518 cl_platform_id platform_id, cl_device_id* device_id)
520 int i;
521 const char* arg_value;
523 /* First check argument then environment */
524 arg_value = piglit_cl_get_arg_value(argc, argv, "device");
525 if(arg_value == NULL) {
526 arg_value = getenv("PIGLIT_CL_DEVICE");
529 if(arg_value != NULL) {
530 unsigned int num_devices;
531 cl_device_id* device_ids;
533 num_devices = piglit_cl_get_device_ids(platform_id,
534 CL_DEVICE_TYPE_ALL,
535 &device_ids);
537 for(i = 0; i < num_devices; i++) {
538 char* device_name = piglit_cl_get_device_info(device_ids[i],
539 CL_DEVICE_NAME);
541 if(!strncmp(arg_value, device_name, strlen(arg_value))) {
542 *device_id = device_ids[i];
544 free(device_ids);
545 free(device_name);
546 return true;
549 free(device_name);
552 free(device_ids);
553 fprintf(stderr,
554 "Could not find device: %s\n",
555 arg_value);
556 piglit_report_result(PIGLIT_WARN);
559 return false;
562 bool piglit_cl_framework_check_local_work_size(
563 cl_device_id device_id,
564 size_t *local_work_size)
566 unsigned i;
567 size_t workgroup_size = 1;
568 size_t *max_workgroup_size = piglit_cl_get_device_info(device_id,
569 CL_DEVICE_MAX_WORK_GROUP_SIZE);
570 size_t *max_workitem_sizes = piglit_cl_get_device_info(device_id,
571 CL_DEVICE_MAX_WORK_ITEM_SIZES);
572 bool ret = true;
574 if (!local_work_size) {
575 goto out;
578 if (!max_workgroup_size || !max_workitem_sizes) {
579 ret = false;
580 goto out;
583 for (i = 0; i < 3; i++) {
584 size_t local_size = local_work_size[i];
585 if (local_size > max_workitem_sizes[i]) {
586 ret = false;
587 goto out;
589 if (local_size > 0) {
590 workgroup_size *= local_size;
594 if (workgroup_size > *max_workgroup_size) {
595 ret = false;
597 out:
598 free(max_workgroup_size);
599 free(max_workitem_sizes);
600 return ret;