From: Nicolai Hähnle Date: Mon, 31 Oct 2016 20:10:37 +0000 (+0100) Subject: radeonsi: make the GS copy shader owned by the GS selector X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3b2516721b91165936a25d1cfd88c65104ca04b1;p=mesa.git 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. Reviewed-by: Marek Olšák --- diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 0240a3c191d..e7617bc4975 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 e7553991fe5..38f65f3b770 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 6c7a05f01bf..91f9cbffd8e 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 ebe7a75a2f8..4c647cbbf02 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))