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

Reply via email to