mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
Refactor code for glslang shader presets - buffer entire file
into memory before passing it on
This commit is contained in:
parent
05fecc4e15
commit
0fee6a9ef4
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool glslang_read_shader_file(const char *path, vector<string> *output, bool root_file)
|
static bool glslang_read_shader_file(const char *path, vector<string> *output, bool root_file)
|
||||||
{
|
{
|
||||||
vector<const char *> lines;
|
vector<const char *> lines;
|
||||||
char include_path[PATH_MAX_LENGTH];
|
char include_path[PATH_MAX_LENGTH];
|
||||||
@ -283,6 +283,113 @@ static glslang_format glslang_find_format(const char *fmt)
|
|||||||
return SLANG_FORMAT_UNKNOWN;
|
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<string> &lines, glslang_meta *meta)
|
bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||||
{
|
{
|
||||||
char id[64];
|
char id[64];
|
||||||
|
@ -105,9 +105,8 @@ struct glslang_output
|
|||||||
|
|
||||||
bool glslang_compile_shader(const char *shader_path, glslang_output *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<std::string> *output, bool root_file);
|
|
||||||
bool glslang_parse_meta(const std::vector<std::string> &lines, glslang_meta *meta);
|
bool glslang_parse_meta(const std::vector<std::string> &lines, glslang_meta *meta);
|
||||||
|
bool glslang_parse_meta(void *data, glslang_meta *meta);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *config_file_new_wrapper(const char *path);
|
void *config_file_new_wrapper(const char *path);
|
||||||
|
@ -89,14 +89,11 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool slang_preprocess_parse_parameters(const char *shader_path,
|
bool slang_preprocess_parse_parameters(void *data, struct video_shader *shader)
|
||||||
struct video_shader *shader)
|
|
||||||
{
|
{
|
||||||
glslang_meta meta;
|
glslang_meta meta;
|
||||||
vector<string> lines;
|
struct string_list *lines = (struct string_list*)data;
|
||||||
|
|
||||||
if (!glslang_read_shader_file(shader_path, &lines, true))
|
|
||||||
return false;
|
|
||||||
if (!glslang_parse_meta(lines, &meta))
|
if (!glslang_parse_meta(lines, &meta))
|
||||||
return false;
|
return false;
|
||||||
return slang_preprocess_parse_parameters(meta, shader);
|
return slang_preprocess_parse_parameters(meta, shader);
|
||||||
|
@ -26,7 +26,7 @@ RETRO_BEGIN_DECLS
|
|||||||
/* Utility function to implement the same parameter reflection
|
/* Utility function to implement the same parameter reflection
|
||||||
* which happens in the slang backend.
|
* which happens in the slang backend.
|
||||||
* This does preprocess over the input file to handle #includes and so on. */
|
* This does preprocess over the input file to handle #includes and so on. */
|
||||||
bool slang_preprocess_parse_parameters(const char *shader_path,
|
bool slang_preprocess_parse_parameters(void *data,
|
||||||
struct video_shader *shader);
|
struct video_shader *shader);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
@ -496,20 +496,6 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
|||||||
if (!path_is_valid(path))
|
if (!path_is_valid(path))
|
||||||
continue;
|
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 */
|
/* Read file contents */
|
||||||
if (!filestream_read_file(path, (void**)&buf, &buf_len))
|
if (!filestream_read_file(path, (void**)&buf, &buf_len))
|
||||||
continue;
|
continue;
|
||||||
@ -525,7 +511,21 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
|||||||
if (!lines)
|
if (!lines)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* even though the pass is set in the loop too, not all passes have parameters */
|
#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 */
|
||||||
param->pass = i;
|
param->pass = i;
|
||||||
|
|
||||||
while ((shader->num_parameters < ARRAY_SIZE(shader->parameters)) &&
|
while ((shader->num_parameters < ARRAY_SIZE(shader->parameters)) &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user