From 231dcb19f928858ca4143e8b91e4bdc4f220ac87 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 14 May 2016 13:38:13 -0400 Subject: [PATCH] freedreno/ir3: cmdline compiler for glsl Use glsl/libstandalone.la to add support for taking glsl src files (in addition to .tgsi) as input. Then glsl->nir and feed the result into the ir3 backend as normal. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/Makefile.am | 2 + .../drivers/freedreno/ir3/ir3_cmdline.c | 89 ++++++++++++++++--- 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/freedreno/Makefile.am b/src/gallium/drivers/freedreno/Makefile.am index 9c0ccdf1eca..1af8dec54b3 100644 --- a/src/gallium/drivers/freedreno/Makefile.am +++ b/src/gallium/drivers/freedreno/Makefile.am @@ -37,6 +37,8 @@ ir3_compiler_LDADD = \ libfreedreno.la \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ $(top_builddir)/src/compiler/nir/libnir.la \ + $(top_builddir)/src/compiler/glsl/libstandalone.la \ $(top_builddir)/src/util/libmesautil.la \ + $(top_builddir)/src/mesa/libmesagallium.la \ $(GALLIUM_COMMON_LIB_DEPS) \ $(FREEDRENO_LIBS) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index 42beb4db6e3..7f5b483e13b 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -44,6 +44,9 @@ #include "instr-a3xx.h" #include "ir3.h" +#include "compiler/glsl/standalone.h" +#include "compiler/nir/glsl_to_nir.h" + static void dump_info(struct ir3_shader_variant *so, const char *str) { uint32_t *bin; @@ -54,6 +57,47 @@ static void dump_info(struct ir3_shader_variant *so, const char *str) free(bin); } +int st_glsl_type_size(const struct glsl_type *type); + +static nir_shader * +load_glsl(const char *filename, gl_shader_stage stage) +{ + static const struct standalone_options options = { + .glsl_version = 140, + .do_link = true, + }; + struct gl_shader_program *prog; + + prog = standalone_compile_shader(&options, 1, (char * const*)&filename); + if (!prog) + errx(1, "couldn't parse `%s'", filename); + + nir_shader *nir = glsl_to_nir(prog, stage, ir3_get_compiler_options()); + + standalone_compiler_cleanup(prog); + + /* required NIR passes: */ + /* TODO cmdline args for some of the conditional lowering passes? */ + + NIR_PASS_V(nir, nir_lower_io_to_temporaries, + nir_shader_get_entrypoint(nir), + true, true); + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS_V(nir, nir_lower_io_types); + + // TODO nir_assign_var_locations?? + + NIR_PASS_V(nir, nir_lower_system_values); + NIR_PASS_V(nir, nir_lower_io, nir_var_all, st_glsl_type_size); + NIR_PASS_V(nir, nir_lower_samplers, prog); + + return nir; +} static int read_file(const char *filename, void **ptr, size_t *size) @@ -85,7 +129,7 @@ read_file(const char *filename, void **ptr, size_t *size) static void print_usage(void) { - printf("Usage: ir3_compiler [OPTIONS]... FILE\n"); + printf("Usage: ir3_compiler [OPTIONS]... \n"); printf(" --verbose - verbose compiler/debug messages\n"); printf(" --binning-pass - generate binning pass shader (VERT)\n"); printf(" --color-two-side - emulate two-sided color (FRAG)\n"); @@ -104,8 +148,6 @@ int main(int argc, char **argv) { int ret = 0, n = 1; const char *filename; - struct tgsi_token toks[65536]; - struct tgsi_parse_context parse; struct ir3_shader_variant v; struct ir3_shader s; struct ir3_shader_key key = {}; @@ -233,31 +275,50 @@ int main(int argc, char **argv) if (fd_mesa_debug & FD_DBG_OPTMSGS) debug_printf("%s\n", (char *)ptr); - if (!tgsi_text_translate(ptr, toks, ARRAY_SIZE(toks))) - errx(1, "could not parse `%s'", filename); + nir_shader *nir; - if (fd_mesa_debug & FD_DBG_OPTMSGS) - tgsi_dump(toks, 0); + char *ext = rindex(filename, '.'); + + if (strcmp(ext, ".tgsi") == 0) { + struct tgsi_token toks[65536]; + + if (!tgsi_text_translate(ptr, toks, ARRAY_SIZE(toks))) + errx(1, "could not parse `%s'", filename); + + if (fd_mesa_debug & FD_DBG_OPTMSGS) + tgsi_dump(toks, 0); + + nir = ir3_tgsi_to_nir(toks); + s.from_tgsi = true; + } else if (strcmp(ext, ".frag") == 0) { + nir = load_glsl(filename, MESA_SHADER_FRAGMENT); + s.from_tgsi = false; + } else if (strcmp(ext, ".vert") == 0) { + nir = load_glsl(filename, MESA_SHADER_FRAGMENT); + s.from_tgsi = false; + } else { + print_usage(); + return -1; + } - nir_shader *nir = ir3_tgsi_to_nir(toks); - s.from_tgsi = true; s.compiler = ir3_compiler_create(NULL, gpu_id); s.nir = ir3_optimize_nir(&s, nir, NULL); v.key = key; v.shader = &s; - tgsi_parse_init(&parse, toks); - switch (parse.FullHeader.Processor.Processor) { - case PIPE_SHADER_FRAGMENT: + switch (nir->stage) { + case MESA_SHADER_FRAGMENT: s.type = v.type = SHADER_FRAGMENT; break; - case PIPE_SHADER_VERTEX: + case MESA_SHADER_VERTEX: s.type = v.type = SHADER_VERTEX; break; - case PIPE_SHADER_COMPUTE: + case MESA_SHADER_COMPUTE: s.type = v.type = SHADER_COMPUTE; break; + default: + errx(1, "unhandled shader stage: %d", nir->stage); } info = "NIR compiler";