From: Marek Olšák <marek.ol...@amd.com> Basically, don't load GRID_SIZE or BLOCK_SIZE if they are unused, determine whether to load BLOCK_ID for each component separately, and set the number of THREAD_ID VGPRs to load. Now we should get the maximum CS launch wave rate in most cases. --- src/gallium/drivers/radeonsi/si_compute.c | 71 ++++++++++++++--------- src/gallium/drivers/radeonsi/si_shader.c | 37 ++++++++---- src/gallium/drivers/radeonsi/si_shader.h | 11 ---- src/gallium/drivers/radeonsi/si_shader_internal.h | 5 ++ 4 files changed, 76 insertions(+), 48 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c index 2b2efae..b3399d1 100644 --- a/src/gallium/drivers/radeonsi/si_compute.c +++ b/src/gallium/drivers/radeonsi/si_compute.c @@ -41,20 +41,22 @@ struct si_compute { 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; + unsigned uses_grid_size:1; + unsigned uses_block_size:1; }; struct dispatch_packet { uint16_t header; uint16_t setup; uint16_t workgroup_size_x; uint16_t workgroup_size_y; uint16_t workgroup_size_z; uint16_t reserved0; uint32_t grid_size_x; @@ -114,37 +116,45 @@ static void si_create_compute_state_async(void *job, int thread_index) memset(&sel, 0, sizeof(sel)); sel.screen = program->screen; 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; + program->uses_grid_size = sel.info.uses_grid_size; + program->uses_block_size = sel.info.uses_block_size; 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; + unsigned user_sgprs = SI_NUM_RESOURCE_SGPRS + + (sel.info.uses_grid_size ? 3 : 0) + + (sel.info.uses_block_size ? 3 : 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_USER_SGPR(user_sgprs) | 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_TGID_X_EN(sel.info.uses_block_id[0]) | + S_00B84C_TGID_Y_EN(sel.info.uses_block_id[1]) | + S_00B84C_TGID_Z_EN(sel.info.uses_block_id[2]) | + S_00B84C_TIDIG_COMP_CNT(sel.info.uses_thread_id[2] ? 2 : + sel.info.uses_thread_id[1] ? 1 : 0) | 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; } @@ -644,50 +654,57 @@ static bool si_upload_compute_input(struct si_context *sctx, } r600_resource_reference(&input_buffer, NULL); return true; } static void si_setup_tgsi_grid(struct si_context *sctx, const struct pipe_grid_info *info) { + struct si_compute *program = sctx->cs_shader_state.program; struct radeon_winsys_cs *cs = sctx->b.gfx.cs; unsigned grid_size_reg = R_00B900_COMPUTE_USER_DATA_0 + - 4 * SI_SGPR_GRID_SIZE; + 4 * SI_NUM_RESOURCE_SGPRS; + unsigned block_size_reg = grid_size_reg + + /* 12 bytes = 3 dwords. */ + 12 * program->uses_grid_size; if (info->indirect) { - uint64_t base_va = r600_resource(info->indirect)->gpu_address; - uint64_t va = base_va + info->indirect_offset; - int i; - - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - (struct r600_resource *)info->indirect, - RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT); - - for (i = 0; i < 3; ++i) { - radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0)); - radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) | - COPY_DATA_DST_SEL(COPY_DATA_REG)); - radeon_emit(cs, (va + 4 * i)); - radeon_emit(cs, (va + 4 * i) >> 32); - radeon_emit(cs, (grid_size_reg >> 2) + i); - radeon_emit(cs, 0); + if (program->uses_grid_size) { + uint64_t base_va = r600_resource(info->indirect)->gpu_address; + uint64_t va = base_va + info->indirect_offset; + int i; + + radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, + (struct r600_resource *)info->indirect, + RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT); + + for (i = 0; i < 3; ++i) { + radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0)); + radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) | + COPY_DATA_DST_SEL(COPY_DATA_REG)); + radeon_emit(cs, (va + 4 * i)); + radeon_emit(cs, (va + 4 * i) >> 32); + radeon_emit(cs, (grid_size_reg >> 2) + i); + radeon_emit(cs, 0); + } } } else { - struct si_compute *program = sctx->cs_shader_state.program; - - radeon_set_sh_reg_seq(cs, grid_size_reg, program->variable_group_size ? 6 : 3); - radeon_emit(cs, info->grid[0]); - radeon_emit(cs, info->grid[1]); - radeon_emit(cs, info->grid[2]); - if (program->variable_group_size) { + if (program->uses_grid_size) { + radeon_set_sh_reg_seq(cs, grid_size_reg, 3); + radeon_emit(cs, info->grid[0]); + radeon_emit(cs, info->grid[1]); + radeon_emit(cs, info->grid[2]); + } + if (program->variable_group_size && program->uses_block_size) { + radeon_set_sh_reg_seq(cs, block_size_reg, 3); radeon_emit(cs, info->block[0]); radeon_emit(cs, info->block[1]); radeon_emit(cs, info->block[2]); } } } static void si_emit_dispatch_packets(struct si_context *sctx, const struct pipe_grid_info *info) { diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 086b279..0fef036 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1583,52 +1583,63 @@ static void declare_system_value(struct si_shader_context *ctx, LLVMConstInt(ctx->i32, (offset + i) * 4, 0)); value = lp_build_gather_values(gallivm, val, 4); break; } case TGSI_SEMANTIC_PRIMID: value = get_primitive_id(&ctx->bld_base, 0); break; case TGSI_SEMANTIC_GRID_SIZE: - value = LLVMGetParam(ctx->main_fn, SI_PARAM_GRID_SIZE); + value = LLVMGetParam(ctx->main_fn, ctx->param_grid_size); break; case TGSI_SEMANTIC_BLOCK_SIZE: { LLVMValueRef values[3]; unsigned i; unsigned *properties = ctx->shader->selector->info.properties; if (properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] != 0) { unsigned sizes[3] = { properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH], properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT], properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH] }; for (i = 0; i < 3; ++i) values[i] = LLVMConstInt(ctx->i32, sizes[i], 0); value = lp_build_gather_values(gallivm, values, 3); } else { - value = LLVMGetParam(ctx->main_fn, SI_PARAM_BLOCK_SIZE); + value = LLVMGetParam(ctx->main_fn, ctx->param_block_size); } break; } case TGSI_SEMANTIC_BLOCK_ID: - value = LLVMGetParam(ctx->main_fn, SI_PARAM_BLOCK_ID); + { + LLVMValueRef values[3]; + + for (int i = 0; i < 3; i++) { + values[i] = ctx->i32_0; + if (ctx->param_block_id[i] >= 0) { + values[i] = LLVMGetParam(ctx->main_fn, + ctx->param_block_id[i]); + } + } + value = lp_build_gather_values(gallivm, values, 3); break; + } case TGSI_SEMANTIC_THREAD_ID: - value = LLVMGetParam(ctx->main_fn, SI_PARAM_THREAD_ID); + value = LLVMGetParam(ctx->main_fn, ctx->param_thread_id); break; case TGSI_SEMANTIC_HELPER_INVOCATION: if (HAVE_LLVM >= 0x0309) { value = lp_build_intrinsic(gallivm->builder, "llvm.amdgcn.ps.live", ctx->i1, NULL, 0, LP_FUNC_ATTR_READNONE); value = LLVMBuildNot(gallivm->builder, value, ""); value = LLVMBuildSExt(gallivm->builder, value, ctx->i32, ""); @@ -6176,27 +6187,33 @@ static void create_function(struct si_shader_context *ctx) PS_EPILOG_SAMPLEMASK_MIN_LOC + 1); for (i = 0; i < num_return_sgprs; i++) returns[i] = ctx->i32; for (; i < num_returns; i++) returns[i] = ctx->f32; break; case PIPE_SHADER_COMPUTE: declare_default_desc_pointers(ctx, params, &num_params); - params[SI_PARAM_GRID_SIZE] = v3i32; - params[SI_PARAM_BLOCK_SIZE] = v3i32; - params[SI_PARAM_BLOCK_ID] = v3i32; - last_sgpr = SI_PARAM_BLOCK_ID; + if (shader->selector->info.uses_grid_size) + params[ctx->param_grid_size = num_params++] = v3i32; + if (shader->selector->info.uses_block_size) + params[ctx->param_block_size = num_params++] = v3i32; + + for (i = 0; i < 3; i++) { + ctx->param_block_id[i] = -1; + if (shader->selector->info.uses_block_id[i]) + params[ctx->param_block_id[i] = num_params++] = ctx->i32; + } + last_sgpr = num_params - 1; - params[SI_PARAM_THREAD_ID] = v3i32; - num_params = SI_PARAM_THREAD_ID + 1; + params[ctx->param_thread_id = num_params++] = v3i32; break; default: assert(0 && "unimplemented shader"); return; } assert(num_params <= ARRAY_SIZE(params)); si_create_function(ctx, "main", returns, num_returns, params, num_params, last_sgpr, diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index c9bd904..4248b80 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -213,25 +213,20 @@ enum { GFX9_SGPR_GS_SHADER_BUFFERS_HI, GFX9_GS_NUM_USER_SGPR, /* GS limits */ GFX6_GS_NUM_USER_SGPR = SI_NUM_RESOURCE_SGPRS, SI_GSCOPY_NUM_USER_SGPR = SI_SGPR_RW_BUFFERS_HI + 1, /* PS only */ SI_SGPR_ALPHA_REF = SI_NUM_RESOURCE_SGPRS, SI_PS_NUM_USER_SGPR, - - /* CS only */ - SI_SGPR_GRID_SIZE = SI_NUM_RESOURCE_SGPRS, - SI_SGPR_BLOCK_SIZE = SI_SGPR_GRID_SIZE + 3, - SI_CS_NUM_USER_SGPR = SI_SGPR_BLOCK_SIZE + 3 }; /* LLVM function parameter indices */ enum { SI_NUM_RESOURCE_PARAMS = 5, /* PS only parameters */ SI_PARAM_ALPHA_REF = SI_NUM_RESOURCE_PARAMS, SI_PARAM_PRIM_MASK, SI_PARAM_PERSP_SAMPLE, @@ -244,26 +239,20 @@ enum { SI_PARAM_LINE_STIPPLE_TEX, SI_PARAM_POS_X_FLOAT, SI_PARAM_POS_Y_FLOAT, SI_PARAM_POS_Z_FLOAT, SI_PARAM_POS_W_FLOAT, SI_PARAM_FRONT_FACE, SI_PARAM_ANCILLARY, SI_PARAM_SAMPLE_COVERAGE, SI_PARAM_POS_FIXED_PT, - /* CS only parameters */ - SI_PARAM_GRID_SIZE = SI_NUM_RESOURCE_PARAMS, - SI_PARAM_BLOCK_SIZE, - SI_PARAM_BLOCK_ID, - SI_PARAM_THREAD_ID, - SI_NUM_PARAMS = SI_PARAM_POS_FIXED_PT + 9, /* +8 for COLOR[0..1] */ }; /* Fields of driver-defined VS state SGPR. */ /* Clamp vertex color output (only used in VS as VS). */ #define S_VS_STATE_CLAMP_VERTEX_COLOR(x) (((unsigned)(x) & 0x1) << 0) #define C_VS_STATE_CLAMP_VERTEX_COLOR 0xFFFFFFFE #define S_VS_STATE_INDEXED(x) (((unsigned)(x) & 0x1) << 1) #define C_VS_STATE_INDEXED 0xFFFFFFFD #define S_VS_STATE_LS_OUT_PATCH_SIZE(x) (((unsigned)(x) & 0x1FFF) << 8) diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 954b83d..cad2db3 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -188,20 +188,25 @@ struct si_shader_context { int param_gs_vtx1_offset; /* in dwords (GFX6) */ int param_gs_prim_id; int param_gs_vtx2_offset; /* in dwords (GFX6) */ int param_gs_vtx3_offset; /* in dwords (GFX6) */ int param_gs_vtx4_offset; /* in dwords (GFX6) */ int param_gs_vtx5_offset; /* in dwords (GFX6) */ int param_gs_instance_id; int param_gs_vtx01_offset; /* in dwords (GFX9) */ int param_gs_vtx23_offset; /* in dwords (GFX9) */ int param_gs_vtx45_offset; /* in dwords (GFX9) */ + /* CS */ + int param_grid_size; + int param_block_size; + int param_block_id[3]; + int param_thread_id; LLVMTargetMachineRef tm; unsigned range_md_kind; unsigned fpmath_md_kind; LLVMValueRef fpmath_md_2p5_ulp; /* Preloaded descriptors. */ LLVMValueRef esgs_ring; LLVMValueRef gsvs_ring[4]; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev