From: Marek Olšák <[email protected]>

The 2nd shader of merged shaders should take a reference of the 1st shader.
The next commit will do that.
---
 src/gallium/drivers/radeonsi/si_shader.h        |  1 +
 src/gallium/drivers/radeonsi/si_state_shaders.c | 27 ++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.h 
b/src/gallium/drivers/radeonsi/si_shader.h
index 4fb79e6..514bb3c 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -240,20 +240,21 @@ struct si_compiler_ctx_state {
        struct pipe_debug_callback      debug;
 
        /* Used for creating the log string for gallium/ddebug. */
        bool                            is_debug_context;
 };
 
 /* A shader selector is a gallium CSO and contains shader variants and
  * binaries for one TGSI program. This can be shared by multiple contexts.
  */
 struct si_shader_selector {
+       struct pipe_reference   reference;
        struct si_screen        *screen;
        struct util_queue_fence ready;
        struct si_compiler_ctx_state compiler_ctx_state;
 
        mtx_t           mutex;
        struct si_shader        *first_variant; /* immutable after the first 
variant */
        struct si_shader        *last_variant; /* mutable */
 
        /* The compiled TGSI shader expecting a prolog and/or epilog (not
         * uploaded to a buffer).
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c 
b/src/gallium/drivers/radeonsi/si_state_shaders.c
index d496d4a..c5fa01d 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1496,20 +1496,33 @@ static bool si_check_missing_main_part(struct si_screen 
*sscreen,
                                           main_part, false,
                                           &compiler_state->debug) != 0) {
                        FREE(main_part);
                        return false;
                }
                *mainp = main_part;
        }
        return true;
 }
 
+static void si_destroy_shader_selector(struct si_context *sctx,
+                                      struct si_shader_selector *sel);
+
+static void si_shader_selector_reference(struct si_context *sctx,
+                                        struct si_shader_selector **dst,
+                                        struct si_shader_selector *src)
+{
+       if (pipe_reference(&(*dst)->reference, &src->reference))
+               si_destroy_shader_selector(sctx, *dst);
+
+       *dst = src;
+}
+
 /* Select the hw shader variant depending on the current state. */
 static int si_shader_select_with_key(struct si_screen *sscreen,
                                     struct si_shader_ctx_state *state,
                                     struct si_compiler_ctx_state 
*compiler_state,
                                     struct si_shader_key *key,
                                     int thread_index)
 {
        struct si_shader_selector *sel = state->cso;
        struct si_shader *current = state->current;
        struct si_shader *iter, *shader = NULL;
@@ -1878,20 +1891,21 @@ static void *si_create_shader_selector(struct 
pipe_context *ctx,
                                       const struct pipe_shader_state *state)
 {
        struct si_screen *sscreen = (struct si_screen *)ctx->screen;
        struct si_context *sctx = (struct si_context*)ctx;
        struct si_shader_selector *sel = CALLOC_STRUCT(si_shader_selector);
        int i;
 
        if (!sel)
                return NULL;
 
+       sel->reference.count = 1;
        sel->screen = sscreen;
        sel->compiler_ctx_state.tm = sctx->tm;
        sel->compiler_ctx_state.debug = sctx->b.debug;
        sel->compiler_ctx_state.is_debug_context = sctx->is_debug;
        sel->tokens = tgsi_dup_tokens(state->tokens);
        if (!sel->tokens) {
                FREE(sel);
                return NULL;
        }
 
@@ -2227,24 +2241,23 @@ static void si_delete_shader(struct si_context *sctx, 
struct si_shader *shader)
                case PIPE_SHADER_FRAGMENT:
                        si_pm4_delete_state(sctx, ps, shader->pm4);
                        break;
                }
        }
 
        si_shader_destroy(shader);
        free(shader);
 }
 
-static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
+static void si_destroy_shader_selector(struct si_context *sctx,
+                                      struct si_shader_selector *sel)
 {
-       struct si_context *sctx = (struct si_context *)ctx;
-       struct si_shader_selector *sel = (struct si_shader_selector *)state;
        struct si_shader *p = sel->first_variant, *c;
        struct si_shader_ctx_state *current_shader[SI_NUM_SHADERS] = {
                [PIPE_SHADER_VERTEX] = &sctx->vs_shader,
                [PIPE_SHADER_TESS_CTRL] = &sctx->tcs_shader,
                [PIPE_SHADER_TESS_EVAL] = &sctx->tes_shader,
                [PIPE_SHADER_GEOMETRY] = &sctx->gs_shader,
                [PIPE_SHADER_FRAGMENT] = &sctx->ps_shader,
        };
 
        util_queue_fence_wait(&sel->ready);
@@ -2268,20 +2281,28 @@ static void si_delete_shader_selector(struct 
pipe_context *ctx, void *state)
                si_delete_shader(sctx, sel->main_shader_part_es);
        if (sel->gs_copy_shader)
                si_delete_shader(sctx, sel->gs_copy_shader);
 
        util_queue_fence_destroy(&sel->ready);
        mtx_destroy(&sel->mutex);
        free(sel->tokens);
        free(sel);
 }
 
+static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
+{
+       struct si_context *sctx = (struct si_context *)ctx;
+       struct si_shader_selector *sel = (struct si_shader_selector *)state;
+
+       si_shader_selector_reference(sctx, &sel, NULL);
+}
+
 static unsigned si_get_ps_input_cntl(struct si_context *sctx,
                                     struct si_shader *vs, unsigned name,
                                     unsigned index, unsigned interpolate)
 {
        struct tgsi_shader_info *vsinfo = &vs->selector->info;
        unsigned j, offset, ps_input_cntl = 0;
 
        if (interpolate == TGSI_INTERPOLATE_CONSTANT ||
            (interpolate == TGSI_INTERPOLATE_COLOR && sctx->flatshade))
                ps_input_cntl |= S_028644_FLAT_SHADE(1);
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to