freedreno/ir3: split out regmask
[mesa.git] / src / freedreno / ir3 / ir3_shader.c
index 76d3946c701b7a1629ab8ce1d6ae80211f3674bf..146cc352f1c57176f8cc64b735cb47408fcb6fe0 100644 (file)
@@ -171,17 +171,42 @@ assemble_variant(struct ir3_shader_variant *v)
        v->ir = NULL;
 }
 
+static bool
+compile_variant(struct ir3_shader_variant *v)
+{
+       int ret = ir3_compile_shader_nir(v->shader->compiler, v);
+       if (ret) {
+               _debug_printf("compile failed! (%s:%s)", v->shader->nir->info.name,
+                               v->shader->nir->info.label);
+               return false;
+       }
+
+       assemble_variant(v);
+       if (!v->bin) {
+               _debug_printf("assemble failed! (%s:%s)", v->shader->nir->info.name,
+                               v->shader->nir->info.label);
+               return false;
+       }
+
+       return true;
+}
+
 /*
  * For creating normal shader variants, 'nonbinning' is NULL.  For
  * creating binning pass shader, it is link to corresponding normal
  * (non-binning) variant.
  */
 static struct ir3_shader_variant *
-create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
+alloc_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
                struct ir3_shader_variant *nonbinning)
 {
-       struct ir3_shader_variant *v = rzalloc_size(shader, sizeof(*v));
-       int ret;
+       void *mem_ctx = shader;
+       /* hang the binning variant off it's non-binning counterpart instead
+        * of the shader, to simplify the error cleanup paths
+        */
+       if (nonbinning)
+               mem_ctx = nonbinning;
+       struct ir3_shader_variant *v = rzalloc_size(mem_ctx, sizeof(*v));
 
        if (!v)
                return NULL;
@@ -197,18 +222,53 @@ create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
        if (!v->binning_pass)
                v->const_state = rzalloc_size(v, sizeof(*v->const_state));
 
-       ret = ir3_compile_shader_nir(shader->compiler, v);
-       if (ret) {
-               debug_error("compile failed!");
+       return v;
+}
+
+static bool
+needs_binning_variant(struct ir3_shader_variant *v)
+{
+       if ((v->type == MESA_SHADER_VERTEX) && ir3_has_binning_vs(&v->key))
+               return true;
+       return false;
+}
+
+static struct ir3_shader_variant *
+create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
+{
+       struct ir3_shader_variant *v = alloc_variant(shader, key, NULL);
+
+       if (!v)
                goto fail;
+
+       if (needs_binning_variant(v)) {
+               v->binning = alloc_variant(shader, key, v);
+               if (!v->binning)
+                       goto fail;
        }
 
-       assemble_variant(v);
-       if (!v->bin) {
-               debug_error("assemble failed!");
-               goto fail;
+       if (ir3_disk_cache_retrieve(shader->compiler, v))
+               return v;
+
+       if (!shader->nir_finalized) {
+               ir3_nir_post_finalize(shader->compiler, shader->nir);
+
+               if (ir3_shader_debug & IR3_DBG_DISASM) {
+                       printf("dump nir%d: type=%d", shader->id, shader->type);
+                       nir_print_shader(shader->nir, stdout);
+               }
+
+               shader->nir_finalized = true;
        }
 
+       if (!compile_variant(v))
+               goto fail;
+
+       if (needs_binning_variant(v) && !compile_variant(v->binning))
+               goto fail;
+
+       ir3_disk_cache_store(shader->compiler, v);
+
        return v;
 
 fail:
@@ -217,26 +277,15 @@ fail:
 }
 
 static inline struct ir3_shader_variant *
-shader_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
-               bool *created)
+shader_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
 {
        struct ir3_shader_variant *v;
 
-       *created = false;
-
        for (v = shader->variants; v; v = v->next)
                if (ir3_shader_key_equal(key, &v->key))
                        return v;
 
-       /* compile new variant if it doesn't exist already: */
-       v = create_variant(shader, key, NULL);
-       if (v) {
-               v->next = shader->variants;
-               shader->variants = v;
-               *created = true;
-       }
-
-       return v;
+       return NULL;
 }
 
 struct ir3_shader_variant *
@@ -244,17 +293,23 @@ ir3_shader_get_variant(struct ir3_shader *shader, const struct ir3_shader_key *k
                bool binning_pass, bool *created)
 {
        mtx_lock(&shader->variants_lock);
-       struct ir3_shader_variant *v =
-                       shader_variant(shader, key, created);
-
-       if (v && binning_pass) {
-               if (!v->binning) {
-                       v->binning = create_variant(shader, key, v);
+       struct ir3_shader_variant *v = shader_variant(shader, key);
+
+       if (!v) {
+               /* compile new variant if it doesn't exist already: */
+               v = create_variant(shader, key);
+               if (v) {
+                       v->next = shader->variants;
+                       shader->variants = v;
                        *created = true;
                }
-               mtx_unlock(&shader->variants_lock);
-               return v->binning;
        }
+
+       if (v && binning_pass) {
+               v = v->binning;
+               assert(v);
+       }
+
        mtx_unlock(&shader->variants_lock);
 
        return v;
@@ -287,6 +342,8 @@ ir3_setup_used_key(struct ir3_shader *shader)
 
        key->safe_constlen = true;
 
+       key->ucp_enables = 0xff;
+
        if (info->stage == MESA_SHADER_FRAGMENT) {
                key->fsaturate_s = ~0;
                key->fsaturate_t = ~0;
@@ -299,6 +356,10 @@ ir3_setup_used_key(struct ir3_shader *shader)
                        key->color_two_side = true;
                }
 
+               if (info->inputs_read & VARYING_BIT_LAYER) {
+                       key->layer_zero = true;
+               }
+
                if ((info->outputs_written & ~(FRAG_RESULT_DEPTH |
                                                                FRAG_RESULT_STENCIL |
                                                                FRAG_RESULT_SAMPLE_MASK)) != 0) {
@@ -341,7 +402,7 @@ trim_constlens(unsigned *constlens,
       cur_total += constlens[i];
    }
 
-   unsigned max_stage;
+   unsigned max_stage = 0;
    unsigned max_const = 0;
    uint32_t trimmed = 0;
 
@@ -408,15 +469,9 @@ ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,
        if (stream_output)
                memcpy(&shader->stream_output, stream_output, sizeof(shader->stream_output));
        shader->num_reserved_user_consts = reserved_user_consts;
-
-       ir3_nir_post_finalize(compiler, nir);
-
        shader->nir = nir;
 
-       if (ir3_shader_debug & IR3_DBG_DISASM) {
-               printf("dump nir%d: type=%d", shader->id, shader->type);
-               nir_print_shader(shader->nir, stdout);
-       }
+       ir3_disk_cache_init_shader_key(compiler, shader);
 
        ir3_setup_used_key(shader);