/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include #include #include "piglit-util-gl.h" #include "piglit-framework-gl/piglit_gl_framework.h" struct piglit_gl_framework *gl_fw; const char *piglit_binary_name; bool piglit_dump_png = false; bool piglit_use_fbo = false; bool piglit_khr_no_error = false; int piglit_automatic = 0; unsigned piglit_winsys_fbo = 0; int piglit_width; int piglit_height; static void process_args(int *argc, char *argv[], unsigned *force_samples, struct piglit_gl_test_config *config); bool piglit_gl_test_config_override_size(struct piglit_gl_test_config *config) { const char *default_size; unsigned int width; unsigned int height; default_size = getenv("PIGLIT_DEFAULT_SIZE"); if (!default_size) return false; if (sscanf(default_size, "%ux%u", &width, &height) != 2) return false; if (width == 0 || height == 0) return false; config->window_width = width; config->window_height = height; return true; } void piglit_gl_test_config_init(struct piglit_gl_test_config *config) { memset(config, 0, sizeof(*config)); if (!piglit_gl_test_config_override_size(config)) { /* Default window size. Note: Win8's min window width */ /* seems to be 160 pixels. When the window size is */ /* unexpectedly resized, tests are marked as "WARN". */ /* Let's use a larger default to avoid that. */ config->window_width = 160; config->window_height = 160; } config->khr_no_error_support = PIGLIT_UNKNOWN_ERROR_STATUS; } static void delete_arg(char *argv[], int *argc, int arg) { int i; for (i = arg + 1; i < *argc; i++) { argv[i - 1] = argv[i]; } (*argc)--; } /** * Recognized arguments are removed from @a argv. The updated array * length is returned in @a argc. */ static void process_args(int *argc, char *argv[], unsigned *force_samples, struct piglit_gl_test_config *config) { int j; piglit_binary_name = argv[0]; piglit_parse_subtest_args(argc, argv, config->subtests, &config->selected_subtests, &config->num_selected_subtests); /* Find/remove "-auto" and "-fbo" from the argument vector. */ for (j = 1; j < *argc; j++) { if (!strcmp(argv[j], "-auto")) { piglit_automatic = 1; delete_arg(argv, argc, j--); } else if (!strcmp(argv[j], "-fbo")) { piglit_use_fbo = true; delete_arg(argv, argc, j--); } else if (!strcmp(argv[j], "-png")) { piglit_dump_png = true; delete_arg(argv, argc, j--); } else if (!strcmp(argv[j], "-rlimit")) { char *ptr; unsigned long lim; int i; j++; if (j >= *argc) { fprintf(stderr, "-rlimit requires an argument\n"); piglit_report_result(PIGLIT_FAIL); } lim = strtoul(argv[j], &ptr, 0); if (ptr == argv[j]) { fprintf(stderr, "-rlimit requires an argument\n"); piglit_report_result(PIGLIT_FAIL); } piglit_set_rlimit(lim); /* Remove 2 arguments (hence the 'i - 2') from the * command line. */ for (i = j + 1; i < *argc; i++) { argv[i - 2] = argv[i]; } *argc -= 2; j -= 2; } else if (!strncmp(argv[j], "-samples=", 9)) { *force_samples = atoi(argv[j]+9); delete_arg(argv, argc, j--); } else if (!strcmp(argv[j], "-khr_no_error")) { piglit_khr_no_error = true; delete_arg(argv, argc, j--); if (config->khr_no_error_support == PIGLIT_UNKNOWN_ERROR_STATUS) { fprintf(stderr, "khr_no_error_support unknown " "skipping test!\n"); piglit_report_result(PIGLIT_SKIP); } else if (config->khr_no_error_support == PIGLIT_HAS_ERRORS) { piglit_report_result(PIGLIT_SKIP); } else { assert(config->khr_no_error_support == PIGLIT_NO_ERRORS); } } else if (!strcmp(argv[j], "-compat")) { if (config->supports_gl_es_version) { fprintf(stderr, "-compat isn't allowed with ES tests!\n"); piglit_report_result(PIGLIT_FAIL); } config->supports_gl_compat_version = 10; config->supports_gl_core_version = 0; puts("The compatibility profile forced."); delete_arg(argv, argc, j--); } } } void piglit_gl_process_args(int *argc, char *argv[], struct piglit_gl_test_config *config) { unsigned force_samples = 0; process_args(argc, argv, &force_samples, config); if (force_samples > 1) config->window_samples = force_samples; } static void destroy(void) { if (!gl_fw) return; if (gl_fw->destroy) gl_fw->destroy(gl_fw); gl_fw = NULL; } void piglit_gl_test_run(int argc, char *argv[], const struct piglit_gl_test_config *config) { piglit_width = config->window_width; piglit_height = config->window_height; gl_fw = piglit_gl_framework_factory(config); if (gl_fw == NULL) { printf("piglit: error: failed to create " "piglit_gl_framework\n"); piglit_report_result(PIGLIT_FAIL); } atexit(destroy); gl_fw->run_test(gl_fw, argc, argv); assert(false); } void piglit_post_redisplay(void) { if (gl_fw->post_redisplay) gl_fw->post_redisplay(gl_fw); } void piglit_set_keyboard_func(void (*func)(unsigned char key, int x, int y)) { if (gl_fw->set_keyboard_func) gl_fw->set_keyboard_func(gl_fw, func); } void piglit_swap_buffers(void) { if (gl_fw->swap_buffers) gl_fw->swap_buffers(gl_fw); } void piglit_present_results(void) { if (piglit_dump_png) { static char *fileprefix = NULL; static int frame = 0; char *filename; GLenum base_format = GL_RGBA; GLubyte *image; if (fileprefix == NULL) { int i; fileprefix = strdup(piglit_binary_name); fileprefix = basename(fileprefix); /* Strip potentially bad characters */ for (i = 0; fileprefix[i]; i++) { if (!isalnum(fileprefix[i]) && fileprefix[i] != '-') fileprefix[i] = '_'; } } image = malloc(4 * piglit_width * piglit_height); glReadPixels(0, 0, piglit_width, piglit_height, base_format, GL_UNSIGNED_BYTE, image); assert(glGetError() == GL_NO_ERROR); (void)!asprintf(&filename, "%s%03d.png", fileprefix, frame++); printf("Writing %s...\n", filename); piglit_write_png(filename, base_format, piglit_width, piglit_height, image, true); free(filename); free(image); } if (!piglit_automatic) piglit_swap_buffers(); } void piglit_set_reshape_func(void (*func)(int w, int h)) { if (!gl_fw->set_reshape_func) gl_fw->set_reshape_func(gl_fw, func); } enum piglit_result piglit_create_dma_buf(unsigned w, unsigned h, unsigned fourcc, const void *src_data, struct piglit_dma_buf **buf) { if (!gl_fw->create_dma_buf) return PIGLIT_SKIP; return gl_fw->create_dma_buf(w, h, fourcc, src_data, buf); } void piglit_destroy_dma_buf(struct piglit_dma_buf *buf) { if (gl_fw->destroy_dma_buf) gl_fw->destroy_dma_buf(buf); } size_t piglit_get_selected_tests(const char ***selected_subtests) { *selected_subtests = gl_fw->test_config->selected_subtests; return gl_fw->test_config->num_selected_subtests; }