radv: stop duplicating radv_vs_output_info

Only the last vertex stage needs to access this.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18210>
This commit is contained in:
Samuel Pitoiset
2022-08-22 19:23:57 +02:00
committed by Marge Bot
parent 45a0276cd1
commit ee5b9bcc57
9 changed files with 42 additions and 94 deletions

View File

@@ -10910,10 +10910,7 @@ export_vs_varying(isel_context* ctx, int slot, bool is_pos, int* next_pos)
assert(ctx->stage.hw == HWStage::VS || ctx->stage.hw == HWStage::NGG);
const uint8_t *vs_output_param_offset =
ctx->stage.has(SWStage::GS) ? ctx->program->info.vs.outinfo.vs_output_param_offset :
ctx->stage.has(SWStage::TES) ? ctx->program->info.tes.outinfo.vs_output_param_offset :
ctx->stage.has(SWStage::MS) ? ctx->program->info.ms.outinfo.vs_output_param_offset :
ctx->program->info.vs.outinfo.vs_output_param_offset;
ctx->program->info.outinfo.vs_output_param_offset;
assert(vs_output_param_offset);
@@ -10994,11 +10991,7 @@ static void
create_vs_exports(isel_context* ctx)
{
assert(ctx->stage.hw == HWStage::VS || ctx->stage.hw == HWStage::NGG);
const aco_vp_output_info* outinfo =
ctx->stage.has(SWStage::GS) ? &ctx->program->info.vs.outinfo :
ctx->stage.has(SWStage::TES) ? &ctx->program->info.tes.outinfo :
ctx->stage.has(SWStage::MS) ? &ctx->program->info.ms.outinfo :
&ctx->program->info.vs.outinfo;
const aco_vp_output_info* outinfo = &ctx->program->info.outinfo;
assert(outinfo);
ctx->block->kind |= block_kind_export_end;
@@ -11043,11 +11036,7 @@ static void
create_primitive_exports(isel_context *ctx, Temp prim_ch1)
{
assert(ctx->stage.hw == HWStage::NGG);
const aco_vp_output_info* outinfo =
ctx->stage.has(SWStage::GS) ? &ctx->program->info.vs.outinfo :
ctx->stage.has(SWStage::TES) ? &ctx->program->info.tes.outinfo :
ctx->stage.has(SWStage::MS) ? &ctx->program->info.ms.outinfo :
&ctx->program->info.vs.outinfo;
const aco_vp_output_info* outinfo = &ctx->program->info.outinfo;
Builder bld(ctx->program, ctx->block);

View File

@@ -247,9 +247,10 @@ get_reg_class(isel_context* ctx, RegType type, unsigned components, unsigned bit
}
void
setup_vs_output_info(isel_context* ctx, nir_shader* nir,
const aco_vp_output_info* outinfo)
setup_vs_output_info(isel_context* ctx, nir_shader* nir)
{
const aco_vp_output_info* outinfo = &ctx->program->info.outinfo;
ctx->export_clip_dists = outinfo->export_clip_dists;
ctx->num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
ctx->num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
@@ -269,7 +270,7 @@ void
setup_vs_variables(isel_context* ctx, nir_shader* nir)
{
if (ctx->stage == vertex_vs || ctx->stage == vertex_ngg) {
setup_vs_output_info(ctx, nir, &ctx->program->info.vs.outinfo);
setup_vs_output_info(ctx, nir);
/* TODO: NGG streamout */
if (ctx->stage.hw == HWStage::NGG)
@@ -291,7 +292,7 @@ setup_gs_variables(isel_context* ctx, nir_shader* nir)
ctx->program->config->lds_size =
ctx->program->info.gfx9_gs_ring_lds_size; /* Already in units of the alloc granularity */
} else if (ctx->stage == vertex_geometry_ngg || ctx->stage == tess_eval_geometry_ngg) {
setup_vs_output_info(ctx, nir, &ctx->program->info.vs.outinfo);
setup_vs_output_info(ctx, nir);
ctx->program->config->lds_size =
DIV_ROUND_UP(nir->info.shared_size, ctx->program->dev.lds_encoding_granule);
@@ -313,7 +314,7 @@ setup_tes_variables(isel_context* ctx, nir_shader* nir)
ctx->tcs_num_patches = ctx->program->info.num_tess_patches;
if (ctx->stage == tess_eval_vs || ctx->stage == tess_eval_ngg) {
setup_vs_output_info(ctx, nir, &ctx->program->info.tes.outinfo);
setup_vs_output_info(ctx, nir);
/* TODO: NGG streamout */
if (ctx->stage.hw == HWStage::NGG)
@@ -331,7 +332,7 @@ setup_tes_variables(isel_context* ctx, nir_shader* nir)
void
setup_ms_variables(isel_context* ctx, nir_shader* nir)
{
setup_vs_output_info(ctx, nir, &ctx->program->info.ms.outinfo);
setup_vs_output_info(ctx, nir);
ctx->program->config->lds_size =
DIV_ROUND_UP(nir->info.shared_size, ctx->program->dev.lds_encoding_granule);
@@ -920,7 +921,7 @@ setup_isel_context(Program* program, unsigned shader_count, struct nir_shader* c
unsigned scratch_size = 0;
if (program->stage == gs_copy_vs) {
assert(shader_count == 1);
setup_vs_output_info(&ctx, shaders[0], &program->info.vs.outinfo);
setup_vs_output_info(&ctx, shaders[0]);
} else {
for (unsigned i = 0; i < shader_count; i++) {
nir_shader* nir = shaders[i];

View File

@@ -107,8 +107,8 @@ struct aco_shader_info {
bool has_ngg_early_prim_export;
uint32_t num_tess_patches;
unsigned workgroup_size;
struct {
struct aco_vp_output_info outinfo;
struct {
bool as_es;
bool as_ls;
bool tcs_in_out_eq;
@@ -128,7 +128,6 @@ struct aco_shader_info {
uint32_t num_lds_blocks;
} tcs;
struct {
struct aco_vp_output_info outinfo;
bool as_es;
} tes;
struct {
@@ -142,9 +141,6 @@ struct aco_shader_info {
struct {
uint8_t subgroup_size;
} cs;
struct {
struct aco_vp_output_info outinfo;
} ms;
struct aco_streamout_info so;
uint32_t gfx9_gs_ring_lds_size;

View File

@@ -65,7 +65,6 @@ radv_aco_convert_shader_vp_info(struct aco_vp_output_info *aco_info,
/* don't use export params */
}
#define ASSIGN_OUTINFO(x) radv_aco_convert_shader_vp_info(&aco_info->x.outinfo, &radv->x.outinfo);
static inline void
radv_aco_convert_shader_info(struct aco_shader_info *aco_info,
const struct radv_shader_info *radv)
@@ -76,7 +75,7 @@ radv_aco_convert_shader_info(struct aco_shader_info *aco_info,
ASSIGN_FIELD(has_ngg_early_prim_export);
ASSIGN_FIELD(num_tess_patches);
ASSIGN_FIELD(workgroup_size);
ASSIGN_OUTINFO(vs);
radv_aco_convert_shader_vp_info(&aco_info->outinfo, &radv->outinfo);
ASSIGN_FIELD(vs.as_es);
ASSIGN_FIELD(vs.as_ls);
ASSIGN_FIELD(vs.tcs_in_out_eq);
@@ -90,7 +89,6 @@ radv_aco_convert_shader_info(struct aco_shader_info *aco_info,
ASSIGN_FIELD_CP(gs.output_streams);
ASSIGN_FIELD(gs.vertices_out);
ASSIGN_FIELD(tcs.num_lds_blocks);
ASSIGN_OUTINFO(tes);
ASSIGN_FIELD(tes.as_es);
ASSIGN_FIELD(ps.writes_z);
ASSIGN_FIELD(ps.writes_stencil);
@@ -99,7 +97,6 @@ radv_aco_convert_shader_info(struct aco_shader_info *aco_info,
ASSIGN_FIELD(ps.num_interp);
ASSIGN_FIELD(ps.spi_ps_input);
ASSIGN_FIELD(cs.subgroup_size);
ASSIGN_OUTINFO(ms);
radv_aco_convert_shader_so_info(aco_info, radv);
aco_info->gfx9_gs_ring_lds_size = radv->gs_ring_info.lds_size;
}
@@ -174,6 +171,5 @@ radv_aco_convert_opts(struct aco_compiler_options *aco_info,
#undef ASSIGN_VS_STATE_FIELD_CP
#undef ASSIGN_FIELD
#undef ASSIGN_FIELD_CP
#undef ASSIGN_OUTINFO
#endif

View File

@@ -1012,9 +1012,10 @@ radv_llvm_export_vs(struct radv_shader_context *ctx, struct radv_shader_output_v
}
static void
handle_vs_outputs_post(struct radv_shader_context *ctx, bool export_clip_dists,
const struct radv_vs_output_info *outinfo)
handle_vs_outputs_post(struct radv_shader_context *ctx)
{
const struct radv_vs_output_info *outinfo = &ctx->shader_info->outinfo;
const bool export_clip_dists = outinfo->export_clip_dists;
struct radv_shader_output_values *outputs;
unsigned noutput = 0;
@@ -1157,8 +1158,7 @@ handle_shader_outputs_post(struct ac_shader_abi *abi)
else if (ctx->shader_info->is_ngg)
break; /* Lowered in NIR */
else
handle_vs_outputs_post(ctx, ctx->shader_info->vs.outinfo.export_clip_dists,
&ctx->shader_info->vs.outinfo);
handle_vs_outputs_post(ctx);
break;
case MESA_SHADER_FRAGMENT:
handle_fs_outputs_post(ctx);
@@ -1177,8 +1177,7 @@ handle_shader_outputs_post(struct ac_shader_abi *abi)
else if (ctx->shader_info->is_ngg)
break; /* Lowered in NIR */
else
handle_vs_outputs_post(ctx, ctx->shader_info->tes.outinfo.export_clip_dists,
&ctx->shader_info->tes.outinfo);
handle_vs_outputs_post(ctx);
break;
default:
break;
@@ -1198,11 +1197,8 @@ static void
radv_llvm_visit_export_vertex(struct ac_shader_abi *abi)
{
struct radv_shader_context *ctx = radv_shader_context_from_abi(abi);
const struct radv_vs_output_info *outinfo = ctx->stage == MESA_SHADER_TESS_EVAL
? &ctx->shader_info->tes.outinfo
: &ctx->shader_info->vs.outinfo;
handle_vs_outputs_post(ctx, outinfo->export_clip_dists, outinfo);
handle_vs_outputs_post(ctx);
}
static void
@@ -1692,8 +1688,7 @@ ac_gs_copy_shader_emit(struct radv_shader_context *ctx)
radv_emit_streamout(ctx, stream);
if (stream == 0) {
handle_vs_outputs_post(ctx, ctx->shader_info->vs.outinfo.export_clip_dists,
&ctx->shader_info->vs.outinfo);
handle_vs_outputs_post(ctx);
}
LLVMBuildBr(ctx->ac.builder, end_bb);

View File

@@ -2193,7 +2193,7 @@ gfx10_get_ngg_info(const struct radv_pipeline_key *key, struct radv_pipeline *pi
* corresponding to the ES thread of the provoking vertex. All
* ES threads load and export PrimitiveID for their thread.
*/
if (!stages[MESA_SHADER_TESS_CTRL].nir && stages[MESA_SHADER_VERTEX].info.vs.outinfo.export_prim_id)
if (!stages[MESA_SHADER_TESS_CTRL].nir && stages[MESA_SHADER_VERTEX].info.outinfo.export_prim_id)
esvert_lds_size = MAX2(esvert_lds_size, 1);
}
@@ -2397,15 +2397,15 @@ get_vs_output_info(const struct radv_graphics_pipeline *pipeline)
{
if (radv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY))
if (radv_pipeline_has_ngg(pipeline))
return &pipeline->base.shaders[MESA_SHADER_GEOMETRY]->info.vs.outinfo;
return &pipeline->base.shaders[MESA_SHADER_GEOMETRY]->info.outinfo;
else
return &pipeline->base.gs_copy_shader->info.vs.outinfo;
return &pipeline->base.gs_copy_shader->info.outinfo;
else if (radv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_CTRL))
return &pipeline->base.shaders[MESA_SHADER_TESS_EVAL]->info.tes.outinfo;
return &pipeline->base.shaders[MESA_SHADER_TESS_EVAL]->info.outinfo;
else if (radv_pipeline_has_stage(pipeline, MESA_SHADER_MESH))
return &pipeline->base.shaders[MESA_SHADER_MESH]->info.ms.outinfo;
return &pipeline->base.shaders[MESA_SHADER_MESH]->info.outinfo;
else
return &pipeline->base.shaders[MESA_SHADER_VERTEX]->info.vs.outinfo;
return &pipeline->base.shaders[MESA_SHADER_VERTEX]->info.outinfo;
}
static bool
@@ -3244,7 +3244,7 @@ radv_determine_ngg_settings(struct radv_pipeline *pipeline,
unsigned lds_bytes_if_culling_off = 0;
/* We need LDS space when VS needs to export the primitive ID. */
if (es_stage == MESA_SHADER_VERTEX && stages[es_stage].info.vs.outinfo.export_prim_id)
if (es_stage == MESA_SHADER_VERTEX && stages[es_stage].info.outinfo.export_prim_id)
lds_bytes_if_culling_off = max_vtx_in * 4u;
stages[es_stage].info.num_lds_blocks_when_not_culling =
DIV_ROUND_UP(lds_bytes_if_culling_off, pdevice->rad_info.lds_encode_granularity);
@@ -3255,7 +3255,7 @@ radv_determine_ngg_settings(struct radv_pipeline *pipeline,
stages[es_stage].info.is_ngg_passthrough = stages[es_stage].info.is_ngg_passthrough &&
!stages[es_stage].info.has_ngg_culling &&
!(es_stage == MESA_SHADER_VERTEX &&
stages[es_stage].info.vs.outinfo.export_prim_id);
stages[es_stage].info.outinfo.export_prim_id);
}
}
@@ -3359,15 +3359,7 @@ radv_fill_shader_info(struct radv_pipeline *pipeline,
assert(last_vgt_api_stage != MESA_SHADER_NONE);
struct radv_shader_info *pre_ps_info = &stages[last_vgt_api_stage].info;
struct radv_vs_output_info *outinfo = NULL;
if (last_vgt_api_stage == MESA_SHADER_VERTEX ||
last_vgt_api_stage == MESA_SHADER_GEOMETRY) {
outinfo = &pre_ps_info->vs.outinfo;
} else if (last_vgt_api_stage == MESA_SHADER_TESS_EVAL) {
outinfo = &pre_ps_info->tes.outinfo;
} else if (last_vgt_api_stage == MESA_SHADER_MESH) {
outinfo = &pre_ps_info->ms.outinfo;
}
struct radv_vs_output_info *outinfo = &pre_ps_info->outinfo;
/* Add PS input requirements to the output of the pre-PS stage. */
bool ps_prim_id_in = stages[MESA_SHADER_FRAGMENT].info.ps.prim_id_input;
@@ -4253,8 +4245,8 @@ radv_pipeline_create_gs_copy_shader(struct radv_pipeline *pipeline,
struct radv_device *device = pipeline->device;
struct radv_shader_info info = {0};
if (stages[MESA_SHADER_GEOMETRY].info.vs.outinfo.export_clip_dists)
info.vs.outinfo.export_clip_dists = true;
if (stages[MESA_SHADER_GEOMETRY].info.outinfo.export_clip_dists)
info.outinfo.export_clip_dists = true;
radv_nir_shader_info_pass(device, stages[MESA_SHADER_GEOMETRY].nir, pipeline_layout, pipeline_key,
&info);

View File

@@ -1284,7 +1284,7 @@ void radv_lower_ngg(struct radv_device *device, struct radv_pipeline_stage *ngg_
num_vertices_per_prim = 2;
/* Manually mark the primitive ID used, so the shader can repack it. */
if (info->tes.outinfo.export_prim_id)
if (info->outinfo.export_prim_id)
BITSET_SET(nir->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID);
} else if (nir->info.stage == MESA_SHADER_VERTEX) {
@@ -1313,19 +1313,13 @@ void radv_lower_ngg(struct radv_device *device, struct radv_pipeline_stage *ngg_
if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL) {
bool export_prim_id;
bool export_prim_id = info->outinfo.export_prim_id;
assert(info->is_ngg);
if (info->has_ngg_culling)
radv_optimize_nir_algebraic(nir, false);
if (nir->info.stage == MESA_SHADER_VERTEX) {
export_prim_id = info->vs.outinfo.export_prim_id;
} else {
export_prim_id = info->tes.outinfo.export_prim_id;
}
NIR_PASS_V(nir, ac_nir_lower_ngg_nogs,
device->physical_device->rad_info.family,
max_vtx_in, num_vertices_per_prim,
@@ -1705,7 +1699,7 @@ radv_postprocess_config(const struct radv_device *device, const struct ac_shader
config_out->rsrc2 |= S_00B12C_OC_LDS_EN(1) | S_00B12C_EXCP_EN(excp_en);
} else {
bool enable_prim_id = info->tes.outinfo.export_prim_id || info->uses_prim_id;
bool enable_prim_id = info->outinfo.export_prim_id || info->uses_prim_id;
vgpr_comp_cnt = enable_prim_id ? 3 : 2;
config_out->rsrc1 |= S_00B128_MEM_ORDERED(pdevice->rad_info.gfx_level >= GFX10);
@@ -1760,7 +1754,7 @@ radv_postprocess_config(const struct radv_device *device, const struct ac_shader
*/
if (info->vs.needs_instance_id && pdevice->rad_info.gfx_level >= GFX10) {
vgpr_comp_cnt = 3;
} else if (info->vs.outinfo.export_prim_id) {
} else if (info->outinfo.export_prim_id) {
vgpr_comp_cnt = 2;
} else if (info->vs.needs_instance_id) {
vgpr_comp_cnt = 1;
@@ -1820,7 +1814,7 @@ radv_postprocess_config(const struct radv_device *device, const struct ac_shader
if (es_stage == MESA_SHADER_VERTEX) {
es_vgpr_comp_cnt = info->vs.needs_instance_id ? 3 : 0;
} else if (es_stage == MESA_SHADER_TESS_EVAL) {
bool enable_prim_id = info->tes.outinfo.export_prim_id || info->uses_prim_id;
bool enable_prim_id = info->outinfo.export_prim_id || info->uses_prim_id;
es_vgpr_comp_cnt = enable_prim_id ? 3 : 2;
} else if (es_stage == MESA_SHADER_MESH) {
es_vgpr_comp_cnt = 0;
@@ -1845,7 +1839,7 @@ radv_postprocess_config(const struct radv_device *device, const struct ac_shader
if (info->uses_invocation_id) {
gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID. */
} else if (info->uses_prim_id || (es_stage == MESA_SHADER_VERTEX &&
info->vs.outinfo.export_prim_id)) {
info->outinfo.export_prim_id)) {
gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */
} else if (need_gs_vtx_offset2) {
gs_vgpr_comp_cnt = 1; /* VGPR1 contains offsets 2, 3 */

View File

@@ -253,6 +253,7 @@ struct radv_shader_info {
uint32_t num_lds_blocks_when_not_culling;
uint32_t num_tess_patches;
uint32_t esgs_itemsize; /* Only for VS or TES as ES */
struct radv_vs_output_info outinfo;
unsigned workgroup_size;
bool force_vrs_per_vertex;
struct {
@@ -260,7 +261,6 @@ struct radv_shader_info {
uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1];
bool needs_draw_id;
bool needs_instance_id;
struct radv_vs_output_info outinfo;
bool as_es;
bool as_ls;
bool tcs_in_out_eq;
@@ -288,7 +288,6 @@ struct radv_shader_info {
} gs;
struct {
uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1];
struct radv_vs_output_info outinfo;
bool as_es;
enum tess_primitive_mode _primitive_mode;
enum gl_tess_spacing spacing;
@@ -361,7 +360,6 @@ struct radv_shader_info {
bool tes_reads_tess_factors : 1;
} tcs;
struct {
struct radv_vs_output_info outinfo;
enum shader_prim output_prim;
bool needs_ms_scratch_ring;
bool has_task; /* If mesh shader is used together with a task shader. */

View File

@@ -357,23 +357,10 @@ gather_info_output_decl_gs(const nir_shader *nir, const nir_variable *var,
static struct radv_vs_output_info *
get_vs_output_info(const nir_shader *nir, struct radv_shader_info *info)
{
switch (nir->info.stage) {
case MESA_SHADER_VERTEX:
if (!info->vs.as_ls && !info->vs.as_es)
return &info->vs.outinfo;
break;
case MESA_SHADER_GEOMETRY:
return &info->vs.outinfo;
break;
case MESA_SHADER_TESS_EVAL:
if (!info->tes.as_es)
return &info->tes.outinfo;
break;
case MESA_SHADER_MESH:
return &info->ms.outinfo;
default:
break;
if ((nir->info.stage == MESA_SHADER_VERTEX && !info->vs.as_ls && !info->vs.as_es) ||
(nir->info.stage == MESA_SHADER_TESS_EVAL && !info->tes.as_es) ||
nir->info.stage == MESA_SHADER_GEOMETRY || nir->info.stage == MESA_SHADER_MESH) {
return &info->outinfo;
}
return NULL;