mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 04:40:09 +01:00
radeonsi: link ES-GS just like LS-HS
This reduces the shader key for ES. Use a fixed attrib location based on (semantic name, index). The ESGS item size is determined by the physical index of the highest ES output, so it's almost always larger than before, but I think that shouldn't matter as long as the ESGS ring buffer is large enough. Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
b1c5f3faa9
commit
d79a3449a7
3 changed files with 19 additions and 39 deletions
|
|
@ -775,6 +775,7 @@ static LLVMValueRef fetch_input_gs(
|
||||||
struct tgsi_shader_info *info = &shader->selector->info;
|
struct tgsi_shader_info *info = &shader->selector->info;
|
||||||
unsigned semantic_name = info->input_semantic_name[reg->Register.Index];
|
unsigned semantic_name = info->input_semantic_name[reg->Register.Index];
|
||||||
unsigned semantic_index = info->input_semantic_index[reg->Register.Index];
|
unsigned semantic_index = info->input_semantic_index[reg->Register.Index];
|
||||||
|
unsigned param;
|
||||||
|
|
||||||
if (swizzle != ~0 && semantic_name == TGSI_SEMANTIC_PRIMID)
|
if (swizzle != ~0 && semantic_name == TGSI_SEMANTIC_PRIMID)
|
||||||
return get_primitive_id(bld_base, swizzle);
|
return get_primitive_id(bld_base, swizzle);
|
||||||
|
|
@ -805,12 +806,10 @@ static LLVMValueRef fetch_input_gs(
|
||||||
vtx_offset_param),
|
vtx_offset_param),
|
||||||
4);
|
4);
|
||||||
|
|
||||||
|
param = si_shader_io_get_unique_index(semantic_name, semantic_index);
|
||||||
args[0] = si_shader_ctx->esgs_ring;
|
args[0] = si_shader_ctx->esgs_ring;
|
||||||
args[1] = vtx_offset;
|
args[1] = vtx_offset;
|
||||||
args[2] = lp_build_const_int32(gallivm,
|
args[2] = lp_build_const_int32(gallivm, (param * 4 + swizzle) * 256);
|
||||||
(get_param_index(semantic_name, semantic_index,
|
|
||||||
shader->selector->inputs_read) * 4 +
|
|
||||||
swizzle) * 256);
|
|
||||||
args[3] = uint->zero;
|
args[3] = uint->zero;
|
||||||
args[4] = uint->one; /* OFFEN */
|
args[4] = uint->one; /* OFFEN */
|
||||||
args[5] = uint->zero; /* IDXEN */
|
args[5] = uint->zero; /* IDXEN */
|
||||||
|
|
@ -2016,9 +2015,6 @@ static void si_llvm_emit_es_epilogue(struct lp_build_tgsi_context * bld_base)
|
||||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
|
LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
|
||||||
LLVMValueRef soffset = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
|
LLVMValueRef soffset = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
|
||||||
si_shader_ctx->param_es2gs_offset);
|
si_shader_ctx->param_es2gs_offset);
|
||||||
uint64_t enabled_outputs = si_shader_ctx->type == TGSI_PROCESSOR_TESS_EVAL ?
|
|
||||||
es->key.tes.es_enabled_outputs :
|
|
||||||
es->key.vs.es_enabled_outputs;
|
|
||||||
unsigned chan;
|
unsigned chan;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -2031,11 +2027,8 @@ static void si_llvm_emit_es_epilogue(struct lp_build_tgsi_context * bld_base)
|
||||||
info->output_semantic_name[i] == TGSI_SEMANTIC_LAYER)
|
info->output_semantic_name[i] == TGSI_SEMANTIC_LAYER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
param_index = get_param_index(info->output_semantic_name[i],
|
param_index = si_shader_io_get_unique_index(info->output_semantic_name[i],
|
||||||
info->output_semantic_index[i],
|
info->output_semantic_index[i]);
|
||||||
enabled_outputs);
|
|
||||||
if (param_index < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (chan = 0; chan < 4; chan++) {
|
for (chan = 0; chan < 4; chan++) {
|
||||||
LLVMValueRef out_val = LLVMBuildLoad(gallivm->builder, out_ptr[chan], "");
|
LLVMValueRef out_val = LLVMBuildLoad(gallivm->builder, out_ptr[chan], "");
|
||||||
|
|
@ -4023,10 +4016,6 @@ void si_dump_shader_key(unsigned shader, union si_shader_key *key, FILE *f)
|
||||||
fprintf(f, !i ? "%u" : ", %u",
|
fprintf(f, !i ? "%u" : ", %u",
|
||||||
key->vs.instance_divisors[i]);
|
key->vs.instance_divisors[i]);
|
||||||
fprintf(f, "}\n");
|
fprintf(f, "}\n");
|
||||||
|
|
||||||
if (key->vs.as_es)
|
|
||||||
fprintf(f, " es_enabled_outputs = 0x%"PRIx64"\n",
|
|
||||||
key->vs.es_enabled_outputs);
|
|
||||||
fprintf(f, " as_es = %u\n", key->vs.as_es);
|
fprintf(f, " as_es = %u\n", key->vs.as_es);
|
||||||
fprintf(f, " as_ls = %u\n", key->vs.as_ls);
|
fprintf(f, " as_ls = %u\n", key->vs.as_ls);
|
||||||
fprintf(f, " export_prim_id = %u\n", key->vs.export_prim_id);
|
fprintf(f, " export_prim_id = %u\n", key->vs.export_prim_id);
|
||||||
|
|
@ -4037,9 +4026,6 @@ void si_dump_shader_key(unsigned shader, union si_shader_key *key, FILE *f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIPE_SHADER_TESS_EVAL:
|
case PIPE_SHADER_TESS_EVAL:
|
||||||
if (key->tes.as_es)
|
|
||||||
fprintf(f, " es_enabled_outputs = 0x%"PRIx64"\n",
|
|
||||||
key->tes.es_enabled_outputs);
|
|
||||||
fprintf(f, " as_es = %u\n", key->tes.as_es);
|
fprintf(f, " as_es = %u\n", key->tes.as_es);
|
||||||
fprintf(f, " export_prim_id = %u\n", key->tes.export_prim_id);
|
fprintf(f, " export_prim_id = %u\n", key->tes.export_prim_id);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,15 @@
|
||||||
* Christian König <christian.koenig@amd.com>
|
* Christian König <christian.koenig@amd.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* How linking tessellation shader inputs and outputs works.
|
/* How linking shader inputs and outputs between vertex, tessellation, and
|
||||||
|
* geometry shaders works.
|
||||||
*
|
*
|
||||||
* Inputs and outputs between shaders are stored in a buffer. This buffer
|
* Inputs and outputs between shaders are stored in a buffer. This buffer
|
||||||
* lives in LDS (typical case for tessellation), but it can also live
|
* lives in LDS (typical case for tessellation), but it can also live
|
||||||
* in memory. Each input or output has a fixed location within a vertex.
|
* in memory (ESGS). Each input or output has a fixed location within a vertex.
|
||||||
* The highest used input or output determines the stride between vertices.
|
* The highest used input or output determines the stride between vertices.
|
||||||
*
|
*
|
||||||
* Since tessellation is only enabled in the OpenGL core profile,
|
* Since GS and tessellation are only possible in the OpenGL core profile,
|
||||||
* only these semantics are valid for per-vertex data:
|
* only these semantics are valid for per-vertex data:
|
||||||
*
|
*
|
||||||
* Name Location
|
* Name Location
|
||||||
|
|
@ -57,13 +58,11 @@
|
||||||
* That's how independent shaders agree on input and output locations.
|
* That's how independent shaders agree on input and output locations.
|
||||||
* The si_shader_io_get_unique_index function assigns the locations.
|
* The si_shader_io_get_unique_index function assigns the locations.
|
||||||
*
|
*
|
||||||
* Other required information for calculating the input and output addresses
|
* For tessellation, other required information for calculating the input and
|
||||||
* like the vertex stride, the patch stride, and the offsets where per-vertex
|
* output addresses like the vertex stride, the patch stride, and the offsets
|
||||||
* and per-patch data start, is passed to the shader via user data SGPRs.
|
* where per-vertex and per-patch data start, is passed to the shader via
|
||||||
* The offsets and strides are calculated at draw time and aren't available
|
* user data SGPRs. The offsets and strides are calculated at draw time and
|
||||||
* at compile time.
|
* aren't available at compile time.
|
||||||
*
|
|
||||||
* The same approach should be used for linking ES->GS in the future.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SI_SHADER_H
|
#ifndef SI_SHADER_H
|
||||||
|
|
@ -245,7 +244,6 @@ union si_shader_key {
|
||||||
/* Mask of "get_unique_index" bits - which outputs are read
|
/* Mask of "get_unique_index" bits - which outputs are read
|
||||||
* by the next stage (needed by ES).
|
* by the next stage (needed by ES).
|
||||||
* This describes how outputs are laid out in memory. */
|
* This describes how outputs are laid out in memory. */
|
||||||
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:1; /* when PS needs it and GS is disabled */
|
unsigned export_prim_id:1; /* when PS needs it and GS is disabled */
|
||||||
|
|
@ -257,7 +255,6 @@ union si_shader_key {
|
||||||
/* Mask of "get_unique_index" bits - which outputs are read
|
/* Mask of "get_unique_index" bits - which outputs are read
|
||||||
* by the next stage (needed by ES).
|
* by the next stage (needed by ES).
|
||||||
* This describes how outputs are laid out in memory. */
|
* This describes how outputs are laid out in memory. */
|
||||||
uint64_t es_enabled_outputs;
|
|
||||||
unsigned as_es:1; /* export shader */
|
unsigned as_es:1; /* export shader */
|
||||||
unsigned export_prim_id:1; /* when PS needs it and GS is disabled */
|
unsigned export_prim_id:1; /* when PS needs it and GS is disabled */
|
||||||
} tes; /* tessellation evaluation shader */
|
} tes; /* tessellation evaluation shader */
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,8 @@ static void si_shader_es(struct si_shader *shader)
|
||||||
}
|
}
|
||||||
assert(num_sgprs <= 104);
|
assert(num_sgprs <= 104);
|
||||||
|
|
||||||
|
si_pm4_set_reg(pm4, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
|
||||||
|
shader->selector->esgs_itemsize / 4);
|
||||||
si_pm4_set_reg(pm4, R_00B320_SPI_SHADER_PGM_LO_ES, va >> 8);
|
si_pm4_set_reg(pm4, R_00B320_SPI_SHADER_PGM_LO_ES, va >> 8);
|
||||||
si_pm4_set_reg(pm4, R_00B324_SPI_SHADER_PGM_HI_ES, va >> 40);
|
si_pm4_set_reg(pm4, R_00B324_SPI_SHADER_PGM_HI_ES, va >> 40);
|
||||||
si_pm4_set_reg(pm4, R_00B328_SPI_SHADER_PGM_RSRC1_ES,
|
si_pm4_set_reg(pm4, R_00B328_SPI_SHADER_PGM_RSRC1_ES,
|
||||||
|
|
@ -251,8 +253,6 @@ static void si_shader_gs(struct si_shader *shader)
|
||||||
si_pm4_set_reg(pm4, R_028A64_VGT_GSVS_RING_OFFSET_2, gsvs_itemsize * ((max_stream >= 2) ? 2 : 1));
|
si_pm4_set_reg(pm4, R_028A64_VGT_GSVS_RING_OFFSET_2, gsvs_itemsize * ((max_stream >= 2) ? 2 : 1));
|
||||||
si_pm4_set_reg(pm4, R_028A68_VGT_GSVS_RING_OFFSET_3, gsvs_itemsize * ((max_stream >= 3) ? 3 : 1));
|
si_pm4_set_reg(pm4, R_028A68_VGT_GSVS_RING_OFFSET_3, gsvs_itemsize * ((max_stream >= 3) ? 3 : 1));
|
||||||
|
|
||||||
si_pm4_set_reg(pm4, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
|
|
||||||
shader->selector->esgs_itemsize / 4);
|
|
||||||
si_pm4_set_reg(pm4, R_028AB0_VGT_GSVS_RING_ITEMSIZE, gsvs_itemsize * (max_stream + 1));
|
si_pm4_set_reg(pm4, R_028AB0_VGT_GSVS_RING_ITEMSIZE, gsvs_itemsize * (max_stream + 1));
|
||||||
|
|
||||||
si_pm4_set_reg(pm4, R_028B38_VGT_GS_MAX_VERT_OUT, gs_max_vert_out);
|
si_pm4_set_reg(pm4, R_028B38_VGT_GS_MAX_VERT_OUT, gs_max_vert_out);
|
||||||
|
|
@ -515,10 +515,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
|
||||||
|
|
||||||
if (sctx->tes_shader.cso)
|
if (sctx->tes_shader.cso)
|
||||||
key->vs.as_ls = 1;
|
key->vs.as_ls = 1;
|
||||||
else if (sctx->gs_shader.cso) {
|
else if (sctx->gs_shader.cso)
|
||||||
key->vs.as_es = 1;
|
key->vs.as_es = 1;
|
||||||
key->vs.es_enabled_outputs = sctx->gs_shader.cso->inputs_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sctx->gs_shader.cso && sctx->ps_shader.cso &&
|
if (!sctx->gs_shader.cso && sctx->ps_shader.cso &&
|
||||||
sctx->ps_shader.cso->info.uses_primid)
|
sctx->ps_shader.cso->info.uses_primid)
|
||||||
|
|
@ -529,10 +527,9 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
|
||||||
sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
|
sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
|
||||||
break;
|
break;
|
||||||
case PIPE_SHADER_TESS_EVAL:
|
case PIPE_SHADER_TESS_EVAL:
|
||||||
if (sctx->gs_shader.cso) {
|
if (sctx->gs_shader.cso)
|
||||||
key->tes.as_es = 1;
|
key->tes.as_es = 1;
|
||||||
key->tes.es_enabled_outputs = sctx->gs_shader.cso->inputs_read;
|
else if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
|
||||||
} else if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
|
|
||||||
key->tes.export_prim_id = 1;
|
key->tes.export_prim_id = 1;
|
||||||
break;
|
break;
|
||||||
case PIPE_SHADER_GEOMETRY:
|
case PIPE_SHADER_GEOMETRY:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue