spirv: Let spirv2nir find out the shader to use

Previous behavior was to default to "main"/fs, this wasn't nice
when the SPIR-V module had a single shader that didn't match that spec.

New behavior is to look at the available shaders:

- if there's only one, use just use it
- if multiple, narrow down using --stage and --entry as criteria
- if still multiple after narrowing down, print the list and fail

Note you can use just one --stage or --entry if that already narrows
down to a single match.  Note that in SPIR-V it is valid to have a
shader module with two shaders sharing the same entry-point name but
different stages.  Because of that in rare cases both --stage and
--entry will be needed.

This patch should remove the need of using --stage and --entry for most
of the uses of spirv2nir.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25461>
This commit is contained in:
Caio Oliveira
2023-09-28 02:02:55 -07:00
committed by Marge Bot
parent c4734714ce
commit 9dcc74e557
+21 -11
View File
@@ -114,8 +114,8 @@ struct entry_point {
gl_shader_stage stage;
};
static bool
check_entry_point(void *mem_ctx, const uint32_t *words, size_t word_count,
static struct entry_point
select_entry_point(void *mem_ctx, const uint32_t *words, size_t word_count,
struct entry_point args)
{
/* Create a dummy vtn_builder to use with vtn_string_literal. */
@@ -151,39 +151,48 @@ check_entry_point(void *mem_ctx, const uint32_t *words, size_t word_count,
w += count;
}
struct entry_point r = {0};
if (util_dynarray_num_elements(&candidates, struct entry_point) == 0) {
fprintf(stderr, "ERROR: No entry-points available.\n");
return false;
return r;
}
int matches = 0;
util_dynarray_foreach(&candidates, struct entry_point, e) {
if ((!args.name || !strcmp(args.name, e->name)) &&
(args.stage == MESA_SHADER_NONE || args.stage == e->stage)) {
if (matches == 0) {
/* Save the first match we found. */
r = *e;
}
matches++;
}
}
}
if (matches != 1) {
if (matches == 0)
if (matches == 0) {
fprintf(stderr, "No matching entry-point for arguments passed.\n");
else
} else {
fprintf(stderr, "Multiple entry-points available, select with --stage and/or --entry.\n");
/* Discard whatever we found before. */
r.name = NULL;
r.stage = MESA_SHADER_NONE;
}
fprintf(stderr, "Entry-points available:\n");
util_dynarray_foreach(&candidates, struct entry_point, e)
fprintf(stderr, " --entry e \"%s\" --stage %s\n", e->name, stage_to_abbrev(e->stage));
return false;
}
return true;
return r;
}
int main(int argc, char **argv)
{
struct entry_point entry_point = {
.name = "main",
.stage = MESA_SHADER_FRAGMENT,
.name = NULL,
.stage = MESA_SHADER_NONE,
};
int ch;
bool optimize = false;
@@ -264,7 +273,8 @@ int main(int argc, char **argv)
void *mem_ctx = ralloc_context(NULL);
if (!check_entry_point(mem_ctx, map, word_count, entry_point))
entry_point = select_entry_point(mem_ctx, map, word_count, entry_point);
if (!entry_point.name)
return 1;
glsl_type_singleton_init_or_ref();