radeonsi: use an SGPR instead of VGT_INDX_OFFSET
authorMarek Olšák <marek.olsak@amd.com>
Wed, 23 Apr 2014 14:15:36 +0000 (16:15 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 17 Jul 2014 23:58:58 +0000 (01:58 +0200)
The draw indirect packets cannot set VGT_INDX_OFFSET, they can only set user
data SGPRs. This is the only way to support start/index_bias with indirect
drawing.

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_draw.c

index 5d9c497b0bc1333f4fb0829ae7f6c449f69e1685..4c3e83f9605d6d36fd1bcbf9a6f724fa593e7fa0 100644 (file)
@@ -223,10 +223,12 @@ static void declare_input_vs(
                si_shader_ctx->shader->shader.uses_instanceid = true;
                buffer_index = get_instance_index_for_fetch(&si_shader_ctx->radeon_bld, divisor);
        } else {
-               /* Load the buffer index, which is always stored in VGPR0
-                * for Vertex Shaders */
-               buffer_index = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
-                                           si_shader_ctx->param_vertex_id);
+               /* Load the buffer index for vertices. */
+               LLVMValueRef vertex_id = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
+                                                     si_shader_ctx->param_vertex_id);
+               LLVMValueRef base_vertex = LLVMGetParam(radeon_bld->main_fn,
+                                                       SI_PARAM_BASE_VERTEX);
+               buffer_index = LLVMBuildAdd(gallivm->builder, base_vertex, vertex_id, "");
        }
 
        vec4_type = LLVMVectorType(base->elem_type, 4);
@@ -2342,6 +2344,7 @@ static void create_function(struct si_shader_context *si_shader_ctx)
        switch (si_shader_ctx->type) {
        case TGSI_PROCESSOR_VERTEX:
                params[SI_PARAM_VERTEX_BUFFER] = const_array(v16i8, SI_NUM_VERTEX_BUFFERS);
+               params[SI_PARAM_BASE_VERTEX] = i32;
                params[SI_PARAM_START_INSTANCE] = i32;
                num_params = SI_PARAM_START_INSTANCE+1;
                if (shader->key.vs.as_es) {
index 81997c0b5867b0ff8981e4858ab6e88633dd3861..6891604db6c610c17aba3210ed2cb1efab55d43a 100644 (file)
 #define SI_SGPR_RESOURCE       4
 #define SI_SGPR_RW_BUFFERS     6  /* rings (& stream-out, VS only) */
 #define SI_SGPR_VERTEX_BUFFER  8  /* VS only */
-#define SI_SGPR_START_INSTANCE 10 /* VS only */
+#define SI_SGPR_BASE_VERTEX    10 /* VS only */
+#define SI_SGPR_START_INSTANCE 11 /* VS only */
 #define SI_SGPR_ALPHA_REF      8  /* PS only */
 
-#define SI_VS_NUM_USER_SGPR    11
+#define SI_VS_NUM_USER_SGPR    12
 #define SI_GS_NUM_USER_SGPR    8
 #define SI_PS_NUM_USER_SGPR    9
 
 
 /* VS only parameters */
 #define SI_PARAM_VERTEX_BUFFER 4
-#define SI_PARAM_START_INSTANCE        5
+#define SI_PARAM_BASE_VERTEX   5
+#define SI_PARAM_START_INSTANCE        6
 /* the other VS parameters are assigned dynamically */
 
 /* ES only parameters */
-#define SI_PARAM_ES2GS_OFFSET  6
+#define SI_PARAM_ES2GS_OFFSET  7
 
 /* GS only parameters */
 #define SI_PARAM_GS2VS_OFFSET  4
index 49fba731c5f4e0d3e20b6d4ffb7ae51cf81bb5cc..c106747a67df15a803eb5a3d210061320ca3413d 100644 (file)
@@ -3209,6 +3209,7 @@ void si_init_config(struct si_context *sctx)
                       S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE));
        si_pm4_set_reg(pm4, R_028400_VGT_MAX_VTX_INDX, ~0);
        si_pm4_set_reg(pm4, R_028404_VGT_MIN_VTX_INDX, 0);
+       si_pm4_set_reg(pm4, R_028408_VGT_INDX_OFFSET, 0);
 
        if (sctx->b.chip_class >= CIK) {
                si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS, S_00B118_CU_EN(0xffff));
index 01564eba84302542ead504f6e4f11280845b1009..0007a70fe69c4bccda762297d501797b1b8c66f1 100644 (file)
@@ -426,14 +426,8 @@ static bool si_update_draw_info_state(struct si_context *sctx,
        }
 
        si_pm4_set_reg(pm4, R_028A6C_VGT_GS_OUT_PRIM_TYPE, gs_out_prim);
-       si_pm4_set_reg(pm4, R_028408_VGT_INDX_OFFSET,
-                      info->indexed ? info->index_bias : info->start);
        si_pm4_set_reg(pm4, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info->restart_index);
        si_pm4_set_reg(pm4, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info->primitive_restart);
-       si_pm4_set_reg(pm4, SI_SGPR_START_INSTANCE * 4 +
-                      (sctx->gs_shader ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
-                       R_00B130_SPI_SHADER_USER_DATA_VS_0),
-                      info->start_instance);
 
         if (prim == V_008958_DI_PT_LINELIST)
                 ls_mask = 1;
@@ -730,6 +724,8 @@ static void si_state_draw(struct si_context *sctx,
                          const struct pipe_draw_info *info,
                          const struct pipe_index_buffer *ib)
 {
+       unsigned sh_base_reg = (sctx->gs_shader ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
+                                                 R_00B130_SPI_SHADER_USER_DATA_VS_0);
        struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
 
        if (pm4 == NULL)
@@ -791,6 +787,13 @@ static void si_state_draw(struct si_context *sctx,
        si_pm4_cmd_add(pm4, info->instance_count);
        si_pm4_cmd_end(pm4, sctx->b.predicate_drawing);
 
+       if (!info->indirect) {
+               si_pm4_set_reg(pm4, sh_base_reg + SI_SGPR_BASE_VERTEX * 4,
+                              info->indexed ? info->index_bias : info->start);
+               si_pm4_set_reg(pm4, sh_base_reg + SI_SGPR_START_INSTANCE * 4,
+                              info->start_instance);
+       }
+
        if (info->indexed) {
                uint32_t max_size = (ib->buffer->width0 - ib->offset) /
                                 sctx->index_buffer.index_size;