summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-04-20 13:04:02 +0200
committerMarek Olšák <[email protected]>2017-04-28 21:47:35 +0200
commitef409378548bba05d2bc441c003a4d1cc3a2991b (patch)
tree7b6b46eecc17634f690d2ac497c2bee92977dd9e /src
parent6c15e15af49408399501e950b0c75f39c0d3af58 (diff)
radeonsi: add reference counting for shader selectors
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c27
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 a508ece85b1..f9ba79f56d6 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -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;
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 602bbfb7056..e5b72811c01 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -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)