From: Marek Olšák <marek.ol...@amd.com>

It must be obtained from the VS.

The GS scenario A must be enabled for PrimID to be generated for the VS.

+ 4 piglits
---
 src/gallium/drivers/radeonsi/si_shader.c        | 22 +++++++++++++++++++---
 src/gallium/drivers/radeonsi/si_shader.h        | 12 ++++++++++++
 src/gallium/drivers/radeonsi/si_state.c         |  1 -
 src/gallium/drivers/radeonsi/si_state_shaders.c | 23 ++++++++++++++++++-----
 4 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 9c3b59c..4288e9b 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -73,6 +73,7 @@ struct si_shader_context
        int param_streamout_offset[4];
        int param_vertex_id;
        int param_rel_auto_id;
+       int param_vs_prim_id;
        int param_instance_id;
        int param_tes_u;
        int param_tes_v;
@@ -486,6 +487,9 @@ static LLVMValueRef get_primitive_id(struct 
lp_build_tgsi_context *bld_base,
                return bld_base->uint_bld.zero;
 
        switch (si_shader_ctx->type) {
+       case TGSI_PROCESSOR_VERTEX:
+               return LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
+                                   si_shader_ctx->param_vs_prim_id);
        case TGSI_PROCESSOR_TESS_CTRL:
                return LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
                                    SI_PARAM_PATCH_ID);
@@ -2027,7 +2031,7 @@ static void si_llvm_emit_vs_epilogue(struct 
lp_build_tgsi_context * bld_base)
        struct si_shader_output_values *outputs = NULL;
        int i,j;
 
-       outputs = MALLOC(info->num_outputs * sizeof(outputs[0]));
+       outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
 
        for (i = 0; i < info->num_outputs; i++) {
                outputs[i].name = info->output_semantic_name[i];
@@ -2040,7 +2044,19 @@ static void si_llvm_emit_vs_epilogue(struct 
lp_build_tgsi_context * bld_base)
                                              "");
        }
 
-       si_llvm_export_vs(bld_base, outputs, info->num_outputs);
+       /* Export PrimitiveID when PS needs it. */
+       if (si_vs_exports_prim_id(si_shader_ctx->shader)) {
+               outputs[i].name = TGSI_SEMANTIC_PRIMID;
+               outputs[i].sid = 0;
+               outputs[i].values[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+                                              get_primitive_id(bld_base, 0));
+               outputs[i].values[1] = bld_base->base.undef;
+               outputs[i].values[2] = bld_base->base.undef;
+               outputs[i].values[3] = bld_base->base.undef;
+               i++;
+       }
+
+       si_llvm_export_vs(bld_base, outputs, i);
        FREE(outputs);
 }
 
@@ -3432,7 +3448,7 @@ static void create_function(struct si_shader_context 
*si_shader_ctx)
                /* VGPRs */
                params[si_shader_ctx->param_vertex_id = num_params++] = i32;
                params[si_shader_ctx->param_rel_auto_id = num_params++] = i32;
-               params[num_params++] = i32; /* unused */
+               params[si_shader_ctx->param_vs_prim_id = num_params++] = i32;
                params[si_shader_ctx->param_instance_id = num_params++] = i32;
                break;
 
diff --git a/src/gallium/drivers/radeonsi/si_shader.h 
b/src/gallium/drivers/radeonsi/si_shader.h
index 82e9c91..cd845c1 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -221,6 +221,7 @@ union si_shader_key {
                uint64_t        es_enabled_outputs;
                unsigned        as_es:1; /* export shader */
                unsigned        as_ls:1; /* local shader */
+               unsigned        export_prim_id; /* when PS needs it and GS is 
disabled */
        } vs;
        struct {
                unsigned        prim_mode:3;
@@ -231,6 +232,7 @@ union si_shader_key {
                 * This describes how outputs are laid out in memory. */
                uint64_t        es_enabled_outputs;
                unsigned        as_es:1; /* export shader */
+               unsigned        export_prim_id; /* when PS needs it and GS is 
disabled */
        } tes; /* tessellation evaluation shader */
 };
 
@@ -289,6 +291,16 @@ static inline struct si_shader* si_get_vs_state(struct 
si_context *sctx)
                return sctx->vs_shader->current;
 }
 
+static inline bool si_vs_exports_prim_id(struct si_shader *shader)
+{
+       if (shader->selector->type == PIPE_SHADER_VERTEX)
+               return shader->key.vs.export_prim_id;
+       else if (shader->selector->type == PIPE_SHADER_TESS_EVAL)
+               return shader->key.tes.export_prim_id;
+       else
+               return false;
+}
+
 /* radeonsi_shader.c */
 int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
                     struct si_shader *shader);
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index f2a9776..bd11c4b 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3179,7 +3179,6 @@ static void si_init_config(struct si_context *sctx)
        si_pm4_set_reg(pm4, R_028A58_VGT_ES_PER_GS, 0x40);
        si_pm4_set_reg(pm4, R_028A5C_VGT_GS_PER_VS, 0x2);
 
-       si_pm4_set_reg(pm4, R_028A84_VGT_PRIMITIVEID_EN, 0x0);
        si_pm4_set_reg(pm4, R_028A8C_VGT_PRIMITIVEID_RESET, 0x0);
        si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0);
        si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c 
b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 19efbbf..0347014 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -308,6 +308,7 @@ static void si_shader_vs(struct si_shader *shader)
        uint64_t va;
        unsigned window_space =
           
shader->selector->info.properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION];
+       bool enable_prim_id = si_vs_exports_prim_id(shader);
 
        pm4 = shader->pm4 = CALLOC_STRUCT(si_pm4_state);
 
@@ -317,8 +318,12 @@ static void si_shader_vs(struct si_shader *shader)
        /* If this is the GS copy shader, the GS state writes this register.
         * Otherwise, the VS state writes it.
         */
-       if (!shader->is_gs_copy_shader)
-               si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE, 0);
+       if (!shader->is_gs_copy_shader) {
+               si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE,
+                              S_028A40_MODE(enable_prim_id ? 
V_028A40_GS_SCENARIO_A : 0));
+               si_pm4_set_reg(pm4, R_028A84_VGT_PRIMITIVEID_EN, 
enable_prim_id);
+       } else
+               si_pm4_set_reg(pm4, R_028A84_VGT_PRIMITIVEID_EN, 0);
 
        va = shader->bo->gpu_address;
        si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ, 
RADEON_PRIO_SHADER_DATA);
@@ -327,7 +332,7 @@ static void si_shader_vs(struct si_shader *shader)
                vgpr_comp_cnt = 0; /* only VertexID is needed for GS-COPY. */
                num_user_sgprs = SI_GSCOPY_NUM_USER_SGPR;
        } else if (shader->selector->type == PIPE_SHADER_VERTEX) {
-               vgpr_comp_cnt = shader->uses_instanceid ? 3 : 0;
+               vgpr_comp_cnt = shader->uses_instanceid ? 3 : (enable_prim_id ? 
2 : 0);
                num_user_sgprs = SI_VS_NUM_USER_SGPR;
        } else if (shader->selector->type == PIPE_SHADER_TESS_EVAL) {
                vgpr_comp_cnt = 3; /* all components are needed for TES */
@@ -534,6 +539,10 @@ static inline void si_shader_selector_key(struct 
pipe_context *ctx,
                        key->vs.as_es = 1;
                        key->vs.es_enabled_outputs = 
sctx->gs_shader->inputs_read;
                }
+
+               if (!sctx->gs_shader && sctx->ps_shader &&
+                   sctx->ps_shader->info.uses_primid)
+                       key->vs.export_prim_id = 1;
                break;
        case PIPE_SHADER_TESS_CTRL:
                key->tcs.prim_mode =
@@ -543,7 +552,8 @@ static inline void si_shader_selector_key(struct 
pipe_context *ctx,
                if (sctx->gs_shader) {
                        key->tes.as_es = 1;
                        key->tes.es_enabled_outputs = 
sctx->gs_shader->inputs_read;
-               }
+               } else if (sctx->ps_shader && sctx->ps_shader->info.uses_primid)
+                       key->tes.export_prim_id = 1;
                break;
        case PIPE_SHADER_GEOMETRY:
                break;
@@ -977,7 +987,10 @@ bcolor:
                        }
                }
 
-               if (j == vsinfo->num_outputs && !G_028644_PT_SPRITE_TEX(tmp)) {
+               if (name == TGSI_SEMANTIC_PRIMID)
+                       /* PrimID is written after the last output. */
+                       tmp |= 
S_028644_OFFSET(vs->vs_output_param_offset[vsinfo->num_outputs]);
+               else if (j == vsinfo->num_outputs && 
!G_028644_PT_SPRITE_TEX(tmp)) {
                        /* No corresponding output found, load defaults into 
input.
                         * Don't set any other bits.
                         * (FLAT_SHADE=1 completely changes behavior) */
-- 
2.1.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to