radeonsi: add reference counting for shader selectors
authorMarek Olšák <marek.olsak@amd.com>
Thu, 20 Apr 2017 11:04:02 +0000 (13:04 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 28 Apr 2017 19:47:35 +0000 (21:47 +0200)
The 2nd shader of merged shaders should take a reference of the 1st shader.
The next commit will do that.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index a508ece85b1ec9c9dbe5e924c039ef7055c1092d..f9ba79f56d66bcdb92ef7371d6c9310d03c42d4b 100644 (file)
@@ -247,6 +247,7 @@ struct si_compiler_ctx_state {
  * 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;
index 602bbfb705670e1d753184201e45b8f26490d096..e5b72811c014025395940a876aea434393b3052b 100644 (file)
@@ -1504,6 +1504,19 @@ static bool si_check_missing_main_part(struct si_screen *sscreen,
        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,
@@ -1886,6 +1899,7 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
        if (!sel)
                return NULL;
 
+       pipe_reference_init(&sel->reference, 1);
        sel->screen = sscreen;
        sel->compiler_ctx_state.tm = sctx->tm;
        sel->compiler_ctx_state.debug = sctx->b.debug;
@@ -2235,10 +2249,9 @@ static void si_delete_shader(struct si_context *sctx, struct si_shader *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,
@@ -2276,6 +2289,14 @@ static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
        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)