glx-multithread-texture: Avoid front-buffer rendering.
[piglit.git] / tests / util / piglit-framework-cl.c
blob472998fa04a1e6b48ec4f4e55d2c634f9cf08871
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);
301 /* Check that we have at least 1 device. */
302 if (!num_devices) {
303 char* platform_name =
304 piglit_cl_get_platform_info(platform_id, CL_PLATFORM_NAME);
305 printf("\n# skipping platform %s because it has 0 devices\n\n",
306 platform_name);
307 free(platform_name);
311 /* run tests per each device */
312 for(j = 0; j < num_devices; j++) {
313 int device_version;
315 device_id = device_ids[j];
317 /* Filter device */
318 if(config->device_regex != NULL) {
319 char* device_name;
321 device_name = piglit_cl_get_device_info(device_id,
322 CL_DEVICE_NAME);
323 if(regexec(&device_regex, device_name, 0, NULL, 0)) {
324 printf("\n# Skipping device %s because it does not match device_regex.\n\n",
325 device_name);
326 free(device_name);
327 continue;
329 free(device_name);
332 /* Check device extensions */
333 if(!check_device_extensions(device_id, config->require_device_extensions)) {
334 continue;
337 /* Check platform version */
338 if(platform_version < final_version) {
339 printf("# Platform supporting only version %d.%d. Running test on that version.\n",
340 platform_version/10, platform_version%10);
341 final_version = platform_version;
343 /* Check device version */
344 device_version = piglit_cl_get_device_version(device_id);
345 if(device_version < final_version) {
346 printf("# Device supporting only version %d.%d. Running test on that version.\n",
347 device_version/10, device_version%10);
348 final_version = device_version;
351 print_test_info(config, version, platform_id, device_id);
352 piglit_merge_result(&result,
353 config->_test_run(argc,
354 (const char**)argv,
355 (void*)config,
356 final_version,
357 platform_id,
358 device_id));
361 free(device_ids);
365 if(config->platform_regex != NULL) {
366 regfree(&platform_regex);
368 if(config->device_regex != NULL) {
369 regfree(&device_regex);
372 free(platform_ids);
375 /* Clean */
376 if(config->clean_func != NULL) {
377 config->clean_func(argc, (const char**)argv, config);
380 /* Report merged result */
381 printf("# Result:\n");
382 piglit_report_result(result);
384 /* UNREACHED */
385 return 1;
388 /* Get command-line/environment variables */
390 const char*
391 piglit_cl_get_arg_value(const int argc, const char *argv[], const char* arg)
393 int i;
394 char* full_arg = calloc(strlen(arg) + 2, sizeof(char));
395 full_arg = strcpy(full_arg, "-");
396 full_arg = strcat(full_arg, arg);
398 for (i = 1; i < argc; i++) {
399 if (!strcmp(argv[i], full_arg)) {
400 if ((i+1) >= argc) {
401 fprintf(stderr,
402 "Argument error: %s requires a value\n",
403 full_arg);
404 free(full_arg);
405 piglit_report_result(PIGLIT_WARN);
406 } else {
407 free(full_arg);
408 return argv[i+1];
413 free(full_arg);
414 return NULL;
417 const char*
418 piglit_cl_get_unnamed_arg(const int argc, const char *argv[], int index)
420 int i;
421 int count = 0;
423 for (i = 1; i < argc; i++) {
424 if (strncmp(argv[i], "-", 1)) {
425 count++;
426 if((count - 1) == index) {
427 return argv[i];
429 } else {
430 i++;
434 return NULL;
437 bool
438 piglit_cl_is_arg_defined(const int argc, const char *argv[], const char* arg)
440 int i;
441 char* full_arg = calloc(strlen(arg) + 2, sizeof(char));
442 full_arg = strcpy(full_arg, "-");
443 full_arg = strcat(full_arg, arg);
445 for (i = 1; i < argc; i++) {
446 if (!strcmp(argv[i], full_arg)) {
447 free(full_arg);
448 return true;
452 free(full_arg);
453 return false;
457 piglit_cl_get_version_arg(int argc, const char** argv)
459 int version_major = 0;
460 int version_minor = 0;
462 const char* version_str;
464 /* First check argument then environment */
465 version_str = piglit_cl_get_arg_value(argc, argv, "version");
466 if(version_str == NULL) {
467 version_str = getenv("PIGLIT_CL_VERSION");
470 if(version_str != NULL) {
471 if(sscanf(version_str, "%i.%i", &version_major, &version_minor) != 2) {
472 version_major = 0;
473 version_minor = 0;
477 return version_major*10 + version_minor;
480 bool
481 piglit_cl_get_platform_arg(const int argc, const char** argv,
482 cl_platform_id* platform_id)
484 int i;
485 const char* arg_value;
487 /* First check argument then environment */
488 arg_value = piglit_cl_get_arg_value(argc, argv, "platform");
489 if(arg_value == NULL) {
490 arg_value = getenv("PIGLIT_CL_PLATFORM");
493 if(arg_value != NULL) {
494 unsigned int num_platforms;
495 cl_platform_id* platform_ids;
497 num_platforms = piglit_cl_get_platform_ids(&platform_ids);
499 for(i = 0; i < num_platforms; i++) {
500 char* platform_name = piglit_cl_get_platform_info(platform_ids[i],
501 CL_PLATFORM_NAME);
503 if(!strncmp(arg_value, platform_name, strlen(arg_value))) {
504 *platform_id = platform_ids[i];
506 free(platform_ids);
507 free(platform_name);
508 return true;
511 free(platform_name);
514 free(platform_ids);
515 fprintf(stderr,
516 "Could not find platform: %s\n",
517 arg_value);
518 piglit_report_result(PIGLIT_WARN);
521 return false;
524 bool
525 piglit_cl_get_device_arg(const int argc, const char** argv,
526 cl_platform_id platform_id, cl_device_id* device_id)
528 int i;
529 const char* arg_value;
531 /* First check argument then environment */
532 arg_value = piglit_cl_get_arg_value(argc, argv, "device");
533 if(arg_value == NULL) {
534 arg_value = getenv("PIGLIT_CL_DEVICE");
537 if(arg_value != NULL) {
538 unsigned int num_devices;
539 cl_device_id* device_ids;
541 num_devices = piglit_cl_get_device_ids(platform_id,
542 CL_DEVICE_TYPE_ALL,
543 &device_ids);
545 for(i = 0; i < num_devices; i++) {
546 char* device_name = piglit_cl_get_device_info(device_ids[i],
547 CL_DEVICE_NAME);
549 if(!strncmp(arg_value, device_name, strlen(arg_value))) {
550 *device_id = device_ids[i];
552 free(device_ids);
553 free(device_name);
554 return true;
557 free(device_name);
560 free(device_ids);
561 fprintf(stderr,
562 "Could not find device: %s\n",
563 arg_value);
564 piglit_report_result(PIGLIT_WARN);
567 return false;
570 bool piglit_cl_framework_check_local_work_size(
571 cl_device_id device_id,
572 size_t *local_work_size)
574 unsigned i;
575 size_t workgroup_size = 1;
576 size_t *max_workgroup_size = piglit_cl_get_device_info(device_id,
577 CL_DEVICE_MAX_WORK_GROUP_SIZE);
578 size_t *max_workitem_sizes = piglit_cl_get_device_info(device_id,
579 CL_DEVICE_MAX_WORK_ITEM_SIZES);
580 bool ret = true;
582 if (!local_work_size) {
583 goto out;
586 if (!max_workgroup_size || !max_workitem_sizes) {
587 ret = false;
588 goto out;
591 for (i = 0; i < 3; i++) {
592 size_t local_size = local_work_size[i];
593 if (local_size > max_workitem_sizes[i]) {
594 ret = false;
595 goto out;
597 if (local_size > 0) {
598 workgroup_size *= local_size;
602 if (workgroup_size > *max_workgroup_size) {
603 ret = false;
605 out:
606 free(max_workgroup_size);
607 free(max_workitem_sizes);
608 return ret;