/* * Copyright © 2018 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 * on the rights to use, copy, modify, merge, publish, distribute, sub * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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 "piglit-shader-test.h" #include /* FIXME: C&P from parse_utils, that is local to shader_runner. At * this point it is not worth to move all parse_utils to a common * library. Perhaps in the future if we start to use all the utils */ bool parse_whitespace(const char *s, const char **rest) { const char *end = s; for (; *end && *end != '\n' && isspace(*end); end++); if (rest) *rest = end; return end != s; } /* FIXME: C&P from parse_utils, that is local to shader_runner. At * this point it is not worth to move all parse_utils to a common * library. Perhaps in the future if we start to use all the utils */ bool parse_str(const char *s, const char *lit, const char **rest) { const char *t; parse_whitespace(s, &t); const bool ret = strncmp(t, lit, strlen(lit)) == 0; if (rest) *rest = (ret ? t + strlen(lit) : s); return ret; } static void group_name_for_stage(GLenum shader_type, bool spirv, char *group_name) { char *stage_name; switch(shader_type) { case GL_VERTEX_SHADER: stage_name = "vertex"; break; case GL_FRAGMENT_SHADER: stage_name = "fragment"; break; case GL_TESS_CONTROL_SHADER: stage_name = "tessellation control"; break; case GL_TESS_EVALUATION_SHADER: stage_name = "tessellation evaluation"; break; case GL_GEOMETRY_SHADER: stage_name = "geometry"; break; case GL_COMPUTE_SHADER: stage_name = "compute"; break; default: stage_name = "error"; } if (!spirv) sprintf(group_name, "[%s shader]", stage_name); else sprintf(group_name, "[%s shader spirv]", stage_name); } bool piglit_load_source_from_shader_test(const char *filename, GLenum shader_type, bool spirv, char **output_source, unsigned *output_source_size) { char group_name[4096]; unsigned text_size; char *line = NULL; char *first_line = NULL; group_name_for_stage(shader_type, spirv, group_name); char *text = piglit_load_text_file(filename, &text_size); line = text; if (line == NULL) { fprintf(stderr, "Could not read file \"%s\"\n", filename); return false; } while (line[0] != '\0') { if (line[0] == '[' && first_line != NULL) { break; } if (line[0] == '[' && first_line == NULL) { if (parse_str(line, group_name, NULL)) { first_line = strchrnul(line, '\n'); if (first_line[0] != '\0') first_line++; } } line = strchrnul(line, '\n'); if (line[0] != '\0') line++; } if (first_line == NULL) { fprintf(stderr, "Could not find groupname \"%s\" on file \"%s\"\n", group_name, filename); free(text); return false; } text_size = line - first_line; if (output_source) *output_source = strndup(first_line, text_size); if (output_source_size) *output_source_size = text_size; free(text); return true; }