[Mesa-dev] [PATCH 3/7] radeonsi: compile all TGSI compute shaders asynchronously
Christian Inci
chris.bugsfd at broke-the-inter.net
Sat Mar 18 06:00:52 UTC 2017
This patch results into an infinite, but interruptible, hang when trying to use OpenCL. Not even the piglit quick_cl tests are working. It works fine after revert.
System info:
Gentoo AMD64 Unstable
RX 470 8GB (Polaris 10)
LLVM, Clang, Mesa incl. dependencies on Git Master.
P.S.:
OpenCL on Oland is completely broken since a few months or so (it looks like a bug in LLVM), but that's another story.
> Message: 1
> Date: Sun, 12 Mar 2017 18:16:27 +0100
> From: Marek Olšák <maraeo at gmail.com>
> To: mesa-dev at lists.freedesktop.org
> Subject: [Mesa-dev] [PATCH 3/7] radeonsi: compile all TGSI compute
> shaders asynchronously
> Message-ID: <1489338991-7561-3-git-send-email-maraeo at gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> From: Marek Olšák <marek.olsak at amd.com>
>
> required by threaded gallium
> ---
> src/gallium/drivers/radeonsi/si_compute.c | 125 +++++++++++++++++++-----------
> 1 file changed, 81 insertions(+), 44 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c
> index 5097c81..ed02f49 100644
> --- a/src/gallium/drivers/radeonsi/si_compute.c
> +++ b/src/gallium/drivers/radeonsi/si_compute.c
> @@ -27,20 +27,25 @@
> #include "util/u_upload_mgr.h"
>
> #include "amd_kernel_code_t.h"
> #include "radeon/r600_cs.h"
> #include "si_pipe.h"
> #include "sid.h"
>
> #define MAX_GLOBAL_BUFFERS 22
>
> struct si_compute {
> + struct si_screen *screen;
> + struct tgsi_token *tokens;
> + struct util_queue_fence ready;
> + struct si_compiler_ctx_state compiler_ctx_state;
> +
> unsigned ir_type;
> unsigned local_size;
> unsigned private_size;
> unsigned input_size;
> struct si_shader shader;
>
> struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
> unsigned use_code_object_v2 : 1;
> unsigned variable_group_size : 1;
> };
> @@ -81,85 +86,111 @@ static void code_object_to_config(const amd_kernel_code_t *code_object,
> out_config->num_sgprs = code_object->wavefront_sgpr_count;
> out_config->num_vgprs = code_object->workitem_vgpr_count;
> out_config->float_mode = G_00B028_FLOAT_MODE(rsrc1);
> out_config->rsrc1 = rsrc1;
> out_config->lds_size = MAX2(out_config->lds_size, G_00B84C_LDS_SIZE(rsrc2));
> out_config->rsrc2 = rsrc2;
> out_config->scratch_bytes_per_wave =
> align(code_object->workitem_private_segment_byte_size * 64, 1024);
> }
>
> +/* Asynchronous compute shader compilation. */
> +static void si_create_compute_state_async(void *job, int thread_index)
> +{
> + struct si_compute *program = (struct si_compute *)job;
> + struct si_shader *shader = &program->shader;
> + struct si_shader_selector sel;
> + LLVMTargetMachineRef tm;
> + struct pipe_debug_callback *debug = &program->compiler_ctx_state.debug;
> +
> + if (thread_index >= 0) {
> + assert(thread_index < ARRAY_SIZE(program->screen->tm));
> + tm = program->screen->tm[thread_index];
> + if (!debug->async)
> + debug = NULL;
> + } else {
> + tm = program->compiler_ctx_state.tm;
> + }
> +
> + memset(&sel, 0, sizeof(sel));
> +
> + tgsi_scan_shader(program->tokens, &sel.info);
> + sel.tokens = program->tokens;
> + sel.type = PIPE_SHADER_COMPUTE;
> + sel.local_size = program->local_size;
> +
> + program->shader.selector = &sel;
> + program->shader.is_monolithic = true;
> +
> + if (si_shader_create(program->screen, tm, &program->shader, debug)) {
> + program->shader.compilation_failed = true;
> + } else {
> + bool scratch_enabled = shader->config.scratch_bytes_per_wave > 0;
> +
> + shader->config.rsrc1 =
> + S_00B848_VGPRS((shader->config.num_vgprs - 1) / 4) |
> + S_00B848_SGPRS((shader->config.num_sgprs - 1) / 8) |
> + S_00B848_DX10_CLAMP(1) |
> + S_00B848_FLOAT_MODE(shader->config.float_mode);
> +
> + shader->config.rsrc2 =
> + S_00B84C_USER_SGPR(SI_CS_NUM_USER_SGPR) |
> + S_00B84C_SCRATCH_EN(scratch_enabled) |
> + S_00B84C_TGID_X_EN(1) | S_00B84C_TGID_Y_EN(1) |
> + S_00B84C_TGID_Z_EN(1) | S_00B84C_TIDIG_COMP_CNT(2) |
> + S_00B84C_LDS_SIZE(shader->config.lds_size);
> +
> + program->variable_group_size =
> + sel.info.properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] == 0;
> + }
> +
> + FREE(program->tokens);
> + program->shader.selector = NULL;
> +}
> +
> static void *si_create_compute_state(
> struct pipe_context *ctx,
> const struct pipe_compute_state *cso)
> {
> struct si_context *sctx = (struct si_context *)ctx;
> struct si_screen *sscreen = (struct si_screen *)ctx->screen;
> struct si_compute *program = CALLOC_STRUCT(si_compute);
> - struct si_shader *shader = &program->shader;
> -
>
> + program->screen = (struct si_screen *)ctx->screen;
> program->ir_type = cso->ir_type;
> program->local_size = cso->req_local_mem;
> program->private_size = cso->req_private_mem;
> program->input_size = cso->req_input_mem;
> program->use_code_object_v2 = HAVE_LLVM >= 0x0400 &&
> cso->ir_type == PIPE_SHADER_IR_NATIVE;
>
> -
> if (cso->ir_type == PIPE_SHADER_IR_TGSI) {
> - struct si_shader_selector sel;
> - bool scratch_enabled;
> -
> - memset(&sel, 0, sizeof(sel));
> -
> - sel.tokens = tgsi_dup_tokens(cso->prog);
> - if (!sel.tokens) {
> + program->tokens = tgsi_dup_tokens(cso->prog);
> + if (!program->tokens) {
> FREE(program);
> return NULL;
> }
>
> - tgsi_scan_shader(cso->prog, &sel.info);
> - sel.type = PIPE_SHADER_COMPUTE;
> - sel.local_size = cso->req_local_mem;
> -
> + program->compiler_ctx_state.tm = sctx->tm;
> + program->compiler_ctx_state.debug = sctx->b.debug;
> + program->compiler_ctx_state.is_debug_context = sctx->is_debug;
> p_atomic_inc(&sscreen->b.num_shaders_created);
> -
> - program->shader.selector = &sel;
> - program->shader.is_monolithic = true;
> -
> - if (si_shader_create(sscreen, sctx->tm, &program->shader,
> - &sctx->b.debug)) {
> - FREE(sel.tokens);
> - FREE(program);
> - return NULL;
> - }
> -
> - scratch_enabled = shader->config.scratch_bytes_per_wave > 0;
> -
> - shader->config.rsrc1 =
> - S_00B848_VGPRS((shader->config.num_vgprs - 1) / 4) |
> - S_00B848_SGPRS((shader->config.num_sgprs - 1) / 8) |
> - S_00B848_DX10_CLAMP(1) |
> - S_00B848_FLOAT_MODE(shader->config.float_mode);
> -
> - shader->config.rsrc2 = S_00B84C_USER_SGPR(SI_CS_NUM_USER_SGPR) |
> - S_00B84C_SCRATCH_EN(scratch_enabled) |
> - S_00B84C_TGID_X_EN(1) | S_00B84C_TGID_Y_EN(1) |
> - S_00B84C_TGID_Z_EN(1) | S_00B84C_TIDIG_COMP_CNT(2) |
> - S_00B84C_LDS_SIZE(shader->config.lds_size);
> -
> - program->variable_group_size =
> - sel.info.properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] == 0;
> -
> - FREE(sel.tokens);
> - program->shader.selector = NULL;
> + util_queue_fence_init(&program->ready);
> +
> + if ((sctx->b.debug.debug_message && !sctx->b.debug.async) ||
> + sctx->is_debug ||
> + r600_can_dump_shader(&sscreen->b, PIPE_SHADER_COMPUTE))
> + si_create_compute_state_async(program, -1);
> + else
> + util_queue_add_job(&sscreen->shader_compiler_queue,
> + program, &program->ready,
> + si_create_compute_state_async, NULL);
> } else {
> const struct pipe_llvm_program_header *header;
> const char *code;
> header = cso->prog;
> code = cso->prog + sizeof(struct pipe_llvm_program_header);
>
> ac_elf_read(code, header->num_bytes, &program->shader.binary);
> if (program->use_code_object_v2) {
> const amd_kernel_code_t *code_object =
> si_compute_get_code_object(program, 0);
> @@ -708,20 +739,21 @@ static void si_launch_grid(
> bool cs_regalloc_hang =
> (sctx->b.chip_class == SI ||
> sctx->b.family == CHIP_BONAIRE ||
> sctx->b.family == CHIP_KABINI) &&
> info->block[0] * info->block[1] * info->block[2] > 256;
>
> if (cs_regalloc_hang)
> sctx->b.flags |= SI_CONTEXT_PS_PARTIAL_FLUSH |
> SI_CONTEXT_CS_PARTIAL_FLUSH;
>
> + util_queue_fence_wait(&program->ready);
> si_decompress_compute_textures(sctx);
>
> /* Add buffer sizes for memory checking in need_cs_space. */
> r600_context_add_resource_size(ctx, &program->shader.bo->b.b);
> /* TODO: add the scratch buffer */
>
> if (info->indirect) {
> r600_context_add_resource_size(ctx, info->indirect);
>
> /* The hw doesn't read the indirect buffer via TC L2. */
> @@ -787,20 +819,25 @@ static void si_launch_grid(
>
>
> static void si_delete_compute_state(struct pipe_context *ctx, void* state){
> struct si_compute *program = (struct si_compute *)state;
> struct si_context *sctx = (struct si_context*)ctx;
>
> if (!state) {
> return;
> }
>
> + if (program->ir_type == PIPE_SHADER_IR_TGSI) {
> + util_queue_fence_wait(&program->ready);
> + util_queue_fence_destroy(&program->ready);
> + }
> +
> if (program == sctx->cs_shader_state.program)
> sctx->cs_shader_state.program = NULL;
>
> if (program == sctx->cs_shader_state.emitted_program)
> sctx->cs_shader_state.emitted_program = NULL;
>
> si_shader_destroy(&program->shader);
> FREE(program);
> }
>
>
More information about the mesa-dev
mailing list