summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2016-10-31 21:10:37 +0100
committerNicolai Hähnle <nicolai.haehnle@amd.com>2016-11-02 12:36:32 +0100
commit764b5eef29c9e684b3a0679cd6f62e688ae11b3e (patch)
tree4a0107ef1c988d20ae2b7e2a32ac44e0e8050a8d
parent7225a25ff195b94f2cf5a32ffd9a2ec883bcbfc8 (diff)
radeonsi: make the GS copy shader owned by the GS selector
The copy shader only depends on the selector. This change avoids creating separate code paths for monolithic vs. non-monolithic geometry shaders.
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h2
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c18
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h9
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c22
4 files changed, 31 insertions, 20 deletions
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 0240a3c191..e7617bc497 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -450,7 +450,7 @@ static inline struct tgsi_shader_info *si_get_vs_info(struct si_context *sctx)
static inline struct si_shader* si_get_vs_state(struct si_context *sctx)
{
if (sctx->gs_shader.current)
- return sctx->gs_shader.current->gs_copy_shader;
+ return sctx->gs_shader.cso->gs_copy_shader;
else if (sctx->tes_shader.current)
return sctx->tes_shader.current;
else
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index e7553991fe..38f65f3b77 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -5951,7 +5951,7 @@ static const char *si_get_shader_name(struct si_shader *shader,
else
return "Tessellation Evaluation Shader as VS";
case PIPE_SHADER_GEOMETRY:
- if (shader->gs_copy_shader == NULL)
+ if (shader->is_gs_copy_shader)
return "GS Copy Shader as VS";
else
return "Geometry Shader";
@@ -6080,7 +6080,7 @@ static void si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret)
}
/* Generate code for the hardware VS shader stage to go with a geometry shader */
-static struct si_shader *
+struct si_shader *
si_generate_gs_copy_shader(struct si_screen *sscreen,
LLVMTargetMachineRef tm,
struct si_shader_selector *gs_selector,
@@ -6103,6 +6103,8 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
return NULL;
shader->selector = gs_selector;
+ shader->is_gs_copy_shader = true;
+
si_init_shader_ctx(&ctx, sscreen, shader, tm);
ctx.type = PIPE_SHADER_VERTEX;
ctx.is_gs_copy_shader = true;
@@ -7150,13 +7152,6 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
shader->info.num_input_vgprs += 1;
}
- if (ctx.type == PIPE_SHADER_GEOMETRY) {
- shader->gs_copy_shader =
- si_generate_gs_copy_shader(sscreen, tm, shader->selector, debug);
- if (!shader->gs_copy_shader)
- return -1;
- }
-
return 0;
}
@@ -8098,11 +8093,6 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
void si_shader_destroy(struct si_shader *shader)
{
- if (shader->gs_copy_shader) {
- si_shader_destroy(shader->gs_copy_shader);
- FREE(shader->gs_copy_shader);
- }
-
if (shader->scratch_bo)
r600_resource_reference(&shader->scratch_bo, NULL);
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 6c7a05f01b..91f9cbffd8 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -257,6 +257,8 @@ struct si_shader_selector {
*/
struct si_shader *main_shader_part;
+ struct si_shader *gs_copy_shader;
+
struct tgsi_token *tokens;
struct pipe_stream_output_info so;
struct tgsi_shader_info info;
@@ -444,12 +446,12 @@ struct si_shader {
struct si_shader_part *prolog;
struct si_shader_part *epilog;
- struct si_shader *gs_copy_shader;
struct si_pm4_state *pm4;
struct r600_resource *bo;
struct r600_resource *scratch_bo;
union si_shader_key key;
bool is_binary_shared;
+ bool is_gs_copy_shader;
/* The following data is all that's needed for binary shaders. */
struct radeon_shader_binary binary;
@@ -471,6 +473,11 @@ struct si_shader_part {
};
/* si_shader.c */
+struct si_shader *
+si_generate_gs_copy_shader(struct si_screen *sscreen,
+ LLVMTargetMachineRef tm,
+ struct si_shader_selector *gs_selector,
+ struct pipe_debug_callback *debug);
int si_compile_tgsi_shader(struct si_screen *sscreen,
LLVMTargetMachineRef tm,
struct si_shader *shader,
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index ebe7a75a2f..4c647cbbf0 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -836,7 +836,6 @@ static void si_shader_init_pm4_state(struct si_screen *sscreen,
break;
case PIPE_SHADER_GEOMETRY:
si_shader_gs(shader);
- si_shader_vs(sscreen, shader->gs_copy_shader, shader->selector);
break;
case PIPE_SHADER_FRAGMENT:
si_shader_ps(shader);
@@ -1236,6 +1235,17 @@ void si_init_shader_selector_async(void *job, int thread_index)
false, sel->is_debug_context))
fprintf(stderr, "radeonsi: can't create a monolithic shader\n");
}
+
+ /* The GS copy shader is always pre-compiled. */
+ if (sel->type == PIPE_SHADER_GEOMETRY) {
+ sel->gs_copy_shader = si_generate_gs_copy_shader(sscreen, tm, sel, debug);
+ if (!sel->gs_copy_shader) {
+ fprintf(stderr, "radeonsi: can't create GS copy shader\n");
+ return;
+ }
+
+ si_shader_vs(sscreen, sel->gs_copy_shader, sel);
+ }
}
static void *si_create_shader_selector(struct pipe_context *ctx,
@@ -1518,8 +1528,10 @@ static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
si_pm4_delete_state(sctx, vs, shader->pm4);
break;
case PIPE_SHADER_GEOMETRY:
- si_pm4_delete_state(sctx, gs, shader->pm4);
- si_pm4_delete_state(sctx, vs, shader->gs_copy_shader->pm4);
+ if (shader->is_gs_copy_shader)
+ si_pm4_delete_state(sctx, vs, shader->pm4);
+ else
+ si_pm4_delete_state(sctx, gs, shader->pm4);
break;
case PIPE_SHADER_FRAGMENT:
si_pm4_delete_state(sctx, ps, shader->pm4);
@@ -1559,6 +1571,8 @@ static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
if (sel->main_shader_part)
si_delete_shader(sctx, sel->main_shader_part);
+ if (sel->gs_copy_shader)
+ si_delete_shader(sctx, sel->gs_copy_shader);
util_queue_fence_destroy(&sel->ready);
pipe_mutex_destroy(sel->mutex);
@@ -2215,7 +2229,7 @@ bool si_update_shaders(struct si_context *sctx)
if (r)
return false;
si_pm4_bind_state(sctx, gs, sctx->gs_shader.current->pm4);
- si_pm4_bind_state(sctx, vs, sctx->gs_shader.current->gs_copy_shader->pm4);
+ si_pm4_bind_state(sctx, vs, sctx->gs_shader.cso->gs_copy_shader->pm4);
si_update_so(sctx, sctx->gs_shader.cso);
if (!si_update_gs_ring_buffers(sctx))