etnaviv: pass a preallocated variant to compiler
authorChristian Gmeiner <christian.gmeiner@gmail.com>
Sun, 19 Mar 2017 15:32:40 +0000 (16:32 +0100)
committerChristian Gmeiner <christian.gmeiner@gmail.com>
Wed, 5 Apr 2017 17:58:07 +0000 (19:58 +0200)
In the long run the compiler needs to know the specifc variant
'key' in order to compile appropriate assembly. With this commit
the variant knows its shader and we are able pass the preallocated
variant into etna_compile_shader(..). This saves us from passing
extra ptrs everywhere.

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
src/gallium/drivers/etnaviv/etnaviv_compiler.c
src/gallium/drivers/etnaviv/etnaviv_compiler.h
src/gallium/drivers/etnaviv/etnaviv_compiler_cmdline.c
src/gallium/drivers/etnaviv/etnaviv_shader.c

index be3838d777d2310ef8cd1d34fca26ca864661030..7552a8f9d237b4260f71c5d957ea8f99ad2c2e30 100644 (file)
@@ -54,6 +54,7 @@
 #include "etnaviv_context.h"
 #include "etnaviv_debug.h"
 #include "etnaviv_disasm.h"
+#include "etnaviv_shader.h"
 #include "etnaviv_uniforms.h"
 #include "etnaviv_util.h"
 
@@ -2253,15 +2254,18 @@ copy_uniform_state_to_shader(struct etna_compile *c, struct etna_shader_variant
    etna_set_shader_uniforms_dirty_flags(sobj);
 }
 
-struct etna_shader_variant *
-etna_compile_shader(const struct etna_specs *specs,
-                    const struct tgsi_token *tokens)
+bool
+etna_compile_shader(struct etna_shader_variant *v)
 {
    /* Create scratch space that may be too large to fit on stack
     */
    bool ret;
    struct etna_compile *c;
-   struct etna_shader_variant *shader;
+
+   if (unlikely(!v))
+      return false;
+
+   const struct etna_specs *specs = v->shader->specs;
 
    struct tgsi_lowering_config lconfig = {
       .lower_SCS = specs->has_sin_cos_sqrt,
@@ -2278,11 +2282,9 @@ etna_compile_shader(const struct etna_specs *specs,
 
    c = CALLOC_STRUCT(etna_compile);
    if (!c)
-      return NULL;
+      return false;
 
-   shader = CALLOC_STRUCT(etna_shader_variant);
-   if (!shader)
-      goto out;
+   const struct tgsi_token *tokens = v->shader->tokens;
 
    c->specs = specs;
    c->tokens = tgsi_transform_lowering(&lconfig, tokens, &c->info);
@@ -2412,30 +2414,27 @@ etna_compile_shader(const struct etna_specs *specs,
    etna_compile_fill_in_labels(c);
 
    ret = etna_compile_check_limits(c);
-   if (!ret) {
-      FREE(shader);
-      shader = NULL;
+   if (!ret)
       goto out;
-   }
 
    /* fill in output structure */
-   shader->processor = c->info.processor;
-   shader->code_size = c->inst_ptr * 4;
-   shader->code = mem_dup(c->code, c->inst_ptr * 16);
-   shader->num_loops = c->num_loops;
-   shader->num_temps = c->next_free_native;
-   shader->vs_pos_out_reg = -1;
-   shader->vs_pointsize_out_reg = -1;
-   shader->ps_color_out_reg = -1;
-   shader->ps_depth_out_reg = -1;
-   copy_uniform_state_to_shader(c, shader);
+   v->processor = c->info.processor;
+   v->code_size = c->inst_ptr * 4;
+   v->code = mem_dup(c->code, c->inst_ptr * 16);
+   v->num_loops = c->num_loops;
+   v->num_temps = c->next_free_native;
+   v->vs_pos_out_reg = -1;
+   v->vs_pointsize_out_reg = -1;
+   v->ps_color_out_reg = -1;
+   v->ps_depth_out_reg = -1;
+   copy_uniform_state_to_shader(c, v);
 
    if (c->info.processor == PIPE_SHADER_VERTEX) {
-      fill_in_vs_inputs(shader, c);
-      fill_in_vs_outputs(shader, c);
+      fill_in_vs_inputs(v, c);
+      fill_in_vs_outputs(v, c);
    } else if (c->info.processor == PIPE_SHADER_FRAGMENT) {
-      fill_in_ps_inputs(shader, c);
-      fill_in_ps_outputs(shader, c);
+      fill_in_ps_inputs(v, c);
+      fill_in_ps_outputs(v, c);
    }
 
 out:
@@ -2445,7 +2444,7 @@ out:
    FREE(c->labels);
    FREE(c);
 
-   return shader;
+   return ret;
 }
 
 extern const char *tgsi_swizzle_names[];
index 8de01264a9b32eb8809fe94d667e44a72014fe1e..8582e305a073cd170b20b5551ce267df7338a269 100644 (file)
@@ -95,6 +95,9 @@ struct etna_shader_variant {
 
    /* shader variants form a linked list */
    struct etna_shader_variant *next;
+
+   /* replicated here to avoid passing extra ptrs everywhere */
+   struct etna_shader *shader;
 };
 
 struct etna_varying {
@@ -110,8 +113,8 @@ struct etna_shader_link_info {
    struct etna_varying varyings[ETNA_NUM_INPUTS];
 };
 
-struct etna_shader_variant *
-etna_compile_shader(const struct etna_specs *specs, const struct tgsi_token *tokens);
+bool
+etna_compile_shader(struct etna_shader_variant *shader);
 
 void
 etna_dump_shader(const struct etna_shader_variant *shader);
index 48f74b84b982c9d8fd1e2e961b9b1f2efb96d150..035ee86f4beaad4d6d07b39ee03781d603e29041 100644 (file)
@@ -38,6 +38,9 @@
 #include "etnaviv_compiler.h"
 #include "etnaviv_debug.h"
 #include "etnaviv_internal.h"
+#include "etnaviv_shader.h"
+
+#include "util/u_memory.h"
 
 static const struct etna_specs specs_gc2000 = {
    .vs_need_z_div = 0,
@@ -98,10 +101,16 @@ main(int argc, char **argv)
    const char *filename;
    struct tgsi_token toks[65536];
    struct tgsi_parse_context parse;
-   struct etna_shader_variant *shader_obj;
+   struct etna_shader s = {};
    void *ptr;
    size_t size;
 
+   struct etna_shader_variant *v = CALLOC_STRUCT(etna_shader_variant);
+   if (!v) {
+      fprintf(stderr, "malloc failed!\n");
+      return 1;
+   }
+
    etna_mesa_debug = ETNA_DBG_MSGS;
 
    while (n < argc) {
@@ -134,13 +143,16 @@ main(int argc, char **argv)
 
    tgsi_parse_init(&parse, toks);
 
-   shader_obj = etna_compile_shader(&specs_gc2000, toks);
+   s.specs = &specs_gc2000;
+   s.tokens = toks;
+
+   v->shader = &s;
 
-   if (shader_obj == NULL) {
+   if (!etna_compile_shader(v)) {
       fprintf(stderr, "compiler failed!\n");
       return 1;
    }
 
-   etna_dump_shader(shader_obj);
-   etna_destroy_shader(shader_obj);
+   etna_dump_shader(v);
+   etna_destroy_shader(v);
 }
index 6996187871f6a549be9a528c0678914b58d2b187..5035eaffde6e7750599a21e49b234b2773fe67a1 100644 (file)
@@ -270,17 +270,27 @@ etna_shader_update_vertex(struct etna_context *ctx)
 static struct etna_shader_variant *
 create_variant(struct etna_shader *shader)
 {
-   struct etna_shader_variant *v;
+   struct etna_shader_variant *v = CALLOC_STRUCT(etna_shader_variant);
+   int ret;
 
-   v = etna_compile_shader(shader->specs, shader->tokens);
-   if (!v) {
-      debug_error("compile failed!");
+   if (!v)
       return NULL;
+
+   v->shader = shader;
+
+   ret = etna_compile_shader(v);
+   if (!ret) {
+      debug_error("compile failed!");
+      goto fail;
    }
 
    v->id = ++shader->variant_count;
 
    return v;
+
+fail:
+   FREE(v);
+   return NULL;
 }
 
 static void *