radeonsi: add support for gl_PrimitiveID in the fragment shader
It must be obtained from the VS. The GS scenario A must be enabled for PrimID to be generated for the VS. + 4 piglits Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
8e11be0ddb
commit
e7a52a5cb8
|
@ -73,6 +73,7 @@ struct si_shader_context
|
||||||
int param_streamout_offset[4];
|
int param_streamout_offset[4];
|
||||||
int param_vertex_id;
|
int param_vertex_id;
|
||||||
int param_rel_auto_id;
|
int param_rel_auto_id;
|
||||||
|
int param_vs_prim_id;
|
||||||
int param_instance_id;
|
int param_instance_id;
|
||||||
int param_tes_u;
|
int param_tes_u;
|
||||||
int param_tes_v;
|
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;
|
return bld_base->uint_bld.zero;
|
||||||
|
|
||||||
switch (si_shader_ctx->type) {
|
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:
|
case TGSI_PROCESSOR_TESS_CTRL:
|
||||||
return LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
|
return LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
|
||||||
SI_PARAM_PATCH_ID);
|
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;
|
struct si_shader_output_values *outputs = NULL;
|
||||||
int i,j;
|
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++) {
|
for (i = 0; i < info->num_outputs; i++) {
|
||||||
outputs[i].name = info->output_semantic_name[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);
|
FREE(outputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3415,7 +3431,7 @@ static void create_function(struct si_shader_context *si_shader_ctx)
|
||||||
/* VGPRs */
|
/* VGPRs */
|
||||||
params[si_shader_ctx->param_vertex_id = num_params++] = i32;
|
params[si_shader_ctx->param_vertex_id = num_params++] = i32;
|
||||||
params[si_shader_ctx->param_rel_auto_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;
|
params[si_shader_ctx->param_instance_id = num_params++] = i32;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,7 @@ union si_shader_key {
|
||||||
uint64_t es_enabled_outputs;
|
uint64_t es_enabled_outputs;
|
||||||
unsigned as_es:1; /* export shader */
|
unsigned as_es:1; /* export shader */
|
||||||
unsigned as_ls:1; /* local shader */
|
unsigned as_ls:1; /* local shader */
|
||||||
|
unsigned export_prim_id; /* when PS needs it and GS is disabled */
|
||||||
} vs;
|
} vs;
|
||||||
struct {
|
struct {
|
||||||
unsigned prim_mode:3;
|
unsigned prim_mode:3;
|
||||||
|
@ -231,6 +232,7 @@ union si_shader_key {
|
||||||
* This describes how outputs are laid out in memory. */
|
* This describes how outputs are laid out in memory. */
|
||||||
uint64_t es_enabled_outputs;
|
uint64_t es_enabled_outputs;
|
||||||
unsigned as_es:1; /* export shader */
|
unsigned as_es:1; /* export shader */
|
||||||
|
unsigned export_prim_id; /* when PS needs it and GS is disabled */
|
||||||
} tes; /* tessellation evaluation shader */
|
} 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;
|
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 */
|
/* radeonsi_shader.c */
|
||||||
int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
|
int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
|
||||||
struct si_shader *shader);
|
struct si_shader *shader);
|
||||||
|
|
|
@ -3136,7 +3136,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_028A58_VGT_ES_PER_GS, 0x40);
|
||||||
si_pm4_set_reg(pm4, R_028A5C_VGT_GS_PER_VS, 0x2);
|
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_028A8C_VGT_PRIMITIVEID_RESET, 0x0);
|
||||||
si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0);
|
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);
|
si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
|
||||||
|
|
|
@ -308,6 +308,7 @@ static void si_shader_vs(struct si_shader *shader)
|
||||||
uint64_t va;
|
uint64_t va;
|
||||||
unsigned window_space =
|
unsigned window_space =
|
||||||
shader->selector->info.properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION];
|
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);
|
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.
|
/* If this is the GS copy shader, the GS state writes this register.
|
||||||
* Otherwise, the VS state writes it.
|
* Otherwise, the VS state writes it.
|
||||||
*/
|
*/
|
||||||
if (!shader->is_gs_copy_shader)
|
if (!shader->is_gs_copy_shader) {
|
||||||
si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE, 0);
|
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;
|
va = shader->bo->gpu_address;
|
||||||
si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ, RADEON_PRIO_SHADER_DATA);
|
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. */
|
vgpr_comp_cnt = 0; /* only VertexID is needed for GS-COPY. */
|
||||||
num_user_sgprs = SI_GSCOPY_NUM_USER_SGPR;
|
num_user_sgprs = SI_GSCOPY_NUM_USER_SGPR;
|
||||||
} else if (shader->selector->type == PIPE_SHADER_VERTEX) {
|
} 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;
|
num_user_sgprs = SI_VS_NUM_USER_SGPR;
|
||||||
} else if (shader->selector->type == PIPE_SHADER_TESS_EVAL) {
|
} else if (shader->selector->type == PIPE_SHADER_TESS_EVAL) {
|
||||||
vgpr_comp_cnt = 3; /* all components are needed for TES */
|
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.as_es = 1;
|
||||||
key->vs.es_enabled_outputs = sctx->gs_shader->inputs_read;
|
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;
|
break;
|
||||||
case PIPE_SHADER_TESS_CTRL:
|
case PIPE_SHADER_TESS_CTRL:
|
||||||
key->tcs.prim_mode =
|
key->tcs.prim_mode =
|
||||||
|
@ -543,7 +552,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
|
||||||
if (sctx->gs_shader) {
|
if (sctx->gs_shader) {
|
||||||
key->tes.as_es = 1;
|
key->tes.as_es = 1;
|
||||||
key->tes.es_enabled_outputs = sctx->gs_shader->inputs_read;
|
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;
|
break;
|
||||||
case PIPE_SHADER_GEOMETRY:
|
case PIPE_SHADER_GEOMETRY:
|
||||||
break;
|
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.
|
/* No corresponding output found, load defaults into input.
|
||||||
* Don't set any other bits.
|
* Don't set any other bits.
|
||||||
* (FLAT_SHADE=1 completely changes behavior) */
|
* (FLAT_SHADE=1 completely changes behavior) */
|
||||||
|
|
Loading…
Reference in New Issue