diff --git a/gfx/drivers_shader/glslang_util.cpp b/gfx/drivers_shader/glslang_util.cpp index 915b6cf80e..40c0281cdc 100644 --- a/gfx/drivers_shader/glslang_util.cpp +++ b/gfx/drivers_shader/glslang_util.cpp @@ -38,7 +38,7 @@ using namespace std; -static bool glslang_read_shader_file(const char *path, vector *output, bool root_file) +bool glslang_read_shader_file(const char *path, vector *output, bool root_file) { vector lines; char include_path[PATH_MAX_LENGTH]; @@ -283,113 +283,6 @@ static glslang_format glslang_find_format(const char *fmt) return SLANG_FORMAT_UNKNOWN; } -bool glslang_parse_meta(void *data, glslang_meta *meta) -{ - char id[64]; - char desc[64]; - size_t line_index = 0; - struct string_list *lines = (struct string_list*)data; - - id[0] = desc[0] = '\0'; - - *meta = glslang_meta{}; - - while (line_index < lines->size) - { - const char *line_c = lines->elems[line_index].data; - line_index++; - - if (!strncmp("#pragma name", line_c, STRLEN_CONST("#pragma name"))) - { - const char *str = NULL; - - if (!meta->name.empty()) - { - RARCH_ERR("[slang]: Trying to declare multiple names for file.\n"); - string_list_free(lines); - return false; - } - - str = line_c + STRLEN_CONST("#pragma name "); - - while (*str == ' ') - str++; - meta->name = str; - } - if (!strncmp("#pragma parameter", line_c, STRLEN_CONST("#pragma parameter"))) - { - float initial, minimum, maximum, step; - int ret = sscanf(line_c, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", - id, desc, &initial, &minimum, &maximum, &step); - - if (ret == 5) - { - step = 0.1f * (maximum - minimum); - ret = 6; - } - - if (ret == 6) - { - auto itr = find_if(begin(meta->parameters), end(meta->parameters), [&](const glslang_parameter ¶m) { - return param.id == id; - }); - - /* Allow duplicate #pragma parameter, but only - * if they are exactly the same. */ - if (itr != end(meta->parameters)) - { - if ( itr->desc != desc || - itr->initial != initial || - itr->minimum != minimum || - itr->maximum != maximum || - itr->step != step - ) - { - RARCH_ERR("[slang]: Duplicate parameters found for \"%s\", but arguments do not match.\n", id); - string_list_free(lines); - return false; - } - } - else - meta->parameters.push_back({ id, desc, initial, minimum, maximum, step }); - } - else - { - RARCH_ERR("[slang]: Invalid #pragma parameter line: \"%s\".\n", line_c); - string_list_free(lines); - return false; - } - } - else if (!strncmp("#pragma format", line_c, STRLEN_CONST("#pragma format"))) - { - const char *str = NULL; - - if (meta->rt_format != SLANG_FORMAT_UNKNOWN) - { - RARCH_ERR("[slang]: Trying to declare format multiple times for file.\n"); - string_list_free(lines); - return false; - } - - str = line_c + STRLEN_CONST("#pragma format "); - - while (*str == ' ') - str++; - - meta->rt_format = glslang_find_format(str); - if (meta->rt_format == SLANG_FORMAT_UNKNOWN) - { - RARCH_ERR("[slang]: Failed to find format \"%s\".\n", str); - string_list_free(lines); - return false; - } - } - } - - string_list_free(lines); - return true; -} - bool glslang_parse_meta(const vector &lines, glslang_meta *meta) { char id[64]; diff --git a/gfx/drivers_shader/glslang_util.h b/gfx/drivers_shader/glslang_util.h index 3586685572..24f86f190e 100644 --- a/gfx/drivers_shader/glslang_util.h +++ b/gfx/drivers_shader/glslang_util.h @@ -105,8 +105,9 @@ struct glslang_output bool glslang_compile_shader(const char *shader_path, glslang_output *output); +/* Helpers for internal use. */ +bool glslang_read_shader_file(const char *path, std::vector *output, bool root_file); bool glslang_parse_meta(const std::vector &lines, glslang_meta *meta); -bool glslang_parse_meta(void *data, glslang_meta *meta); #endif void *config_file_new_wrapper(const char *path); diff --git a/gfx/drivers_shader/slang_preprocess.cpp b/gfx/drivers_shader/slang_preprocess.cpp index c9127ad95e..a814359e06 100644 --- a/gfx/drivers_shader/slang_preprocess.cpp +++ b/gfx/drivers_shader/slang_preprocess.cpp @@ -89,11 +89,14 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta, return true; } -bool slang_preprocess_parse_parameters(void *data, struct video_shader *shader) +bool slang_preprocess_parse_parameters(const char *shader_path, + struct video_shader *shader) { glslang_meta meta; - struct string_list *lines = (struct string_list*)data; + vector lines; + if (!glslang_read_shader_file(shader_path, &lines, true)) + return false; if (!glslang_parse_meta(lines, &meta)) return false; return slang_preprocess_parse_parameters(meta, shader); diff --git a/gfx/drivers_shader/slang_preprocess.h b/gfx/drivers_shader/slang_preprocess.h index b542c24860..b730582ffe 100644 --- a/gfx/drivers_shader/slang_preprocess.h +++ b/gfx/drivers_shader/slang_preprocess.h @@ -26,7 +26,7 @@ RETRO_BEGIN_DECLS /* Utility function to implement the same parameter reflection * which happens in the slang backend. * This does preprocess over the input file to handle #includes and so on. */ -bool slang_preprocess_parse_parameters(void *data, +bool slang_preprocess_parse_parameters(const char *shader_path, struct video_shader *shader); RETRO_END_DECLS diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 7507f2a593..3c606760e8 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -496,6 +496,20 @@ bool video_shader_resolve_parameters(config_file_t *conf, if (!path_is_valid(path)) continue; +#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) + /* First try to use the more robust slang + * implementation to support #includes. */ + /* FIXME: The check for slang can be removed + * if it's sufficiently tested for + * GLSL/Cg as well, it should be the same implementation. */ + if (string_is_equal(path_get_extension(path), "slang") && + slang_preprocess_parse_parameters(path, shader)) + continue; + + /* If that doesn't work, fallback to the old path. + * Ideally, we'd get rid of this path sooner or later. */ +#endif + /* Read file contents */ if (!filestream_read_file(path, (void**)&buf, &buf_len)) continue; @@ -511,21 +525,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, if (!lines) continue; -#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) - /* First try to use the more robust slang - * implementation to support #includes. */ - /* FIXME: The check for slang can be removed - * if it's sufficiently tested for - * GLSL/Cg as well, it should be the same implementation. */ - if (string_is_equal(path_get_extension(path), "slang") && - slang_preprocess_parse_parameters(lines, shader)) - continue; - - /* If that doesn't work, fallback to the old path. - * Ideally, we'd get rid of this path sooner or later. */ -#endif - /* even though the pass is set in the loop too, not all - * passes have parameters */ + /* even though the pass is set in the loop too, not all passes have parameters */ param->pass = i; while ((shader->num_parameters < ARRAY_SIZE(shader->parameters)) &&