Browse Source

radeonsi/gfx9: 2nd shader of merged shaders should hold a reference of the 1st

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
tags/17.2-branchpoint
Marek Olšák 8 years ago
parent
commit
ed9a51cd3b

+ 1
- 0
src/gallium/drivers/radeonsi/si_shader.h View File

@@ -493,6 +493,7 @@ struct si_shader {
struct si_compiler_ctx_state compiler_ctx_state;

struct si_shader_selector *selector;
struct si_shader_selector *previous_stage_sel; /* for refcounting */
struct si_shader *next_variant;

struct si_shader_part *prolog;

+ 25
- 10
src/gallium/drivers/radeonsi/si_state_shaders.c View File

@@ -1525,6 +1525,7 @@ static int si_shader_select_with_key(struct si_screen *sscreen,
int thread_index)
{
struct si_shader_selector *sel = state->cso;
struct si_shader_selector *previous_stage_sel = NULL;
struct si_shader *current = state->current;
struct si_shader *iter, *shader = NULL;

@@ -1592,6 +1593,14 @@ again:
shader->key = *key;
shader->compiler_ctx_state = *compiler_state;

/* If this is a merged shader, get the first shader's selector. */
if (sscreen->b.chip_class >= GFX9) {
if (sel->type == PIPE_SHADER_TESS_CTRL)
previous_stage_sel = key->part.tcs.ls;
else if (sel->type == PIPE_SHADER_GEOMETRY)
previous_stage_sel = key->part.gs.es;
}

/* Compile the main shader part if it doesn't exist. This can happen
* if the initial guess was wrong. */
bool is_pure_monolithic =
@@ -1608,22 +1617,18 @@ again:
* For merged shaders, check that the starting shader's main
* part is present.
*/
if (sscreen->b.chip_class >= GFX9 &&
(sel->type == PIPE_SHADER_TESS_CTRL ||
sel->type == PIPE_SHADER_GEOMETRY)) {
struct si_shader_selector *shader1 = NULL;
if (previous_stage_sel) {
struct si_shader_key shader1_key = zeroed;

if (sel->type == PIPE_SHADER_TESS_CTRL) {
shader1 = key->part.tcs.ls;
if (sel->type == PIPE_SHADER_TESS_CTRL)
shader1_key.as_ls = 1;
} else if (sel->type == PIPE_SHADER_GEOMETRY) {
shader1 = key->part.gs.es;
else if (sel->type == PIPE_SHADER_GEOMETRY)
shader1_key.as_es = 1;
} else
else
assert(0);

ok = si_check_missing_main_part(sscreen, shader1,
ok = si_check_missing_main_part(sscreen,
previous_stage_sel,
compiler_state, &shader1_key);
} else {
ok = si_check_missing_main_part(sscreen, sel,
@@ -1636,6 +1641,15 @@ again:
}
}

/* Keep the reference to the 1st shader of merged shaders, so that
* Gallium can't destroy it before we destroy the 2nd shader.
*
* Set sctx = NULL, because it's unused if we're not releasing
* the shader, and we don't have any sctx here.
*/
si_shader_selector_reference(NULL, &shader->previous_stage_sel,
previous_stage_sel);

/* Monolithic-only shaders don't make a distinction between optimized
* and unoptimized. */
shader->is_monolithic =
@@ -2245,6 +2259,7 @@ static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
}
}

si_shader_selector_reference(sctx, &shader->previous_stage_sel, NULL);
si_shader_destroy(shader);
free(shader);
}

Loading…
Cancel
Save