freedreno/ir3: cmdline compiler for glsl
authorRob Clark <robclark@freedesktop.org>
Sat, 14 May 2016 17:38:13 +0000 (13:38 -0400)
committerRob Clark <robclark@freedesktop.org>
Wed, 25 May 2016 20:31:15 +0000 (16:31 -0400)
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 <robclark@freedesktop.org>
src/gallium/drivers/freedreno/Makefile.am
src/gallium/drivers/freedreno/ir3/ir3_cmdline.c

index 9c0ccdf1eca8189e420596718100e028a7c74928..1af8dec54b343130602c4015c02fae8281abd89a 100644 (file)
@@ -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)
index 42beb4db6e348f51a3b4d04217683ff66a6ac947..7f5b483e13bacae3e6b5760da6bcc0119b72434b 100644 (file)
@@ -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]... <file.tgsi | file.vert | file.frag>\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";