radv: add and use a helper that merges shader info for merged stages on GFX9+

It looks much cleaner and it's pretty small.

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/18278>
This commit is contained in:
Samuel Pitoiset 2022-08-23 16:28:05 +02:00 committed by Marge Bot
parent 60a7115b4e
commit be9cded237
2 changed files with 51 additions and 76 deletions

View file

@ -2803,13 +2803,6 @@ radv_fill_shader_info(struct radv_pipeline *pipeline,
bool pipeline_has_ngg)
{
struct radv_device *device = pipeline->device;
unsigned active_stages = 0;
unsigned filled_stages = 0;
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
if (stages[i].nir)
active_stages |= (1 << i);
}
if (stages[MESA_SHADER_TESS_CTRL].nir) {
stages[MESA_SHADER_VERTEX].info.vs.as_ls = true;
@ -2822,70 +2815,10 @@ radv_fill_shader_info(struct radv_pipeline *pipeline,
stages[MESA_SHADER_VERTEX].info.vs.as_es = true;
}
if (device->physical_device->rad_info.gfx_level >= GFX9 &&
stages[MESA_SHADER_TESS_CTRL].nir) {
struct nir_shader *combined_nir[] = {stages[MESA_SHADER_VERTEX].nir, stages[MESA_SHADER_TESS_CTRL].nir};
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
if (!stages[i].nir)
continue;
radv_nir_shader_info_init(&stages[MESA_SHADER_TESS_CTRL].info);
/* Copy data to merged stage. */
stages[MESA_SHADER_TESS_CTRL].info.vs.num_linked_outputs =
stages[MESA_SHADER_VERTEX].info.vs.num_linked_outputs;
for (int i = 0; i < 2; i++) {
radv_nir_shader_info_pass(device, combined_nir[i], pipeline_layout, pipeline_key,
&stages[MESA_SHADER_TESS_CTRL].info);
}
stages[MESA_SHADER_VERTEX].info = stages[MESA_SHADER_TESS_CTRL].info;
stages[MESA_SHADER_VERTEX].info.vs.as_ls = true;
filled_stages |= (1 << MESA_SHADER_VERTEX);
filled_stages |= (1 << MESA_SHADER_TESS_CTRL);
}
if (device->physical_device->rad_info.gfx_level >= GFX9 &&
stages[MESA_SHADER_GEOMETRY].nir) {
gl_shader_stage pre_stage =
stages[MESA_SHADER_TESS_EVAL].nir ? MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX;
struct nir_shader *combined_nir[] = {stages[pre_stage].nir, stages[MESA_SHADER_GEOMETRY].nir};
radv_nir_shader_info_init(&stages[MESA_SHADER_GEOMETRY].info);
/* Copy data to merged stage. */
if (pre_stage == MESA_SHADER_VERTEX) {
stages[MESA_SHADER_GEOMETRY].info.vs.num_linked_outputs =
stages[MESA_SHADER_VERTEX].info.vs.num_linked_outputs;
} else {
stages[MESA_SHADER_GEOMETRY].info.tes.num_linked_outputs =
stages[MESA_SHADER_TESS_EVAL].info.tes.num_linked_outputs;
stages[MESA_SHADER_GEOMETRY].info.tes.num_linked_inputs =
stages[MESA_SHADER_TESS_EVAL].info.tes.num_linked_inputs;
stages[MESA_SHADER_GEOMETRY].info.tes.num_linked_patch_inputs =
stages[MESA_SHADER_TESS_EVAL].info.tes.num_linked_patch_inputs;
}
stages[MESA_SHADER_GEOMETRY].info.is_ngg = stages[pre_stage].info.is_ngg;
stages[MESA_SHADER_GEOMETRY].info.gs.es_type = pre_stage;
for (int i = 0; i < 2; i++) {
radv_nir_shader_info_pass(device, combined_nir[i], pipeline_layout, pipeline_key,
&stages[MESA_SHADER_GEOMETRY].info);
}
stages[pre_stage].info = stages[MESA_SHADER_GEOMETRY].info;
if (pre_stage == MESA_SHADER_VERTEX) {
stages[MESA_SHADER_VERTEX].info.vs.as_es = true;
} else {
stages[MESA_SHADER_TESS_EVAL].info.tes.as_es = true;
}
filled_stages |= (1 << pre_stage);
filled_stages |= (1 << MESA_SHADER_GEOMETRY);
}
active_stages ^= filled_stages;
while (active_stages) {
int i = u_bit_scan(&active_stages);
radv_nir_shader_info_init(&stages[i].info);
radv_nir_shader_info_pass(device, stages[i].nir, pipeline_layout, pipeline_key,
&stages[i].info);

View file

@ -1329,12 +1329,6 @@ radv_link_shaders_info(struct radv_device *device,
~tcs_stage->nir->info.tess.tcs_cross_invocation_inputs_read &
~tcs_stage->nir->info.inputs_read_indirectly &
~vs_stage->nir->info.outputs_accessed_indirectly;
/* Copy data to TCS so it can be accessed by the backend if they are merged. */
tcs_stage->info.vs.tcs_in_out_eq =
vs_stage->info.vs.tcs_in_out_eq;
tcs_stage->info.vs.tcs_temp_only_input_mask =
vs_stage->info.vs.tcs_temp_only_input_mask;
}
}
@ -1357,6 +1351,39 @@ radv_link_shaders_info(struct radv_device *device,
}
}
static void
radv_nir_shader_info_merge(const struct radv_pipeline_stage *src, struct radv_pipeline_stage *dst)
{
const struct radv_shader_info *src_info = &src->info;
struct radv_shader_info *dst_info = &dst->info;
assert((src->stage == MESA_SHADER_VERTEX && dst->stage == MESA_SHADER_TESS_CTRL) ||
(src->stage == MESA_SHADER_VERTEX && dst->stage == MESA_SHADER_GEOMETRY) ||
(src->stage == MESA_SHADER_TESS_EVAL && dst->stage == MESA_SHADER_GEOMETRY));
dst_info->loads_push_constants |= src_info->loads_push_constants;
dst_info->loads_dynamic_offsets |= src_info->loads_dynamic_offsets;
dst_info->desc_set_used_mask |= src_info->desc_set_used_mask;
dst_info->uses_view_index |= src_info->uses_view_index;
dst_info->uses_invocation_id |= src_info->uses_invocation_id;
dst_info->uses_prim_id |= src_info->uses_prim_id;
dst_info->inline_push_constant_mask |= src_info->inline_push_constant_mask;
/* Only inline all push constants if both allows it. */
dst_info->can_inline_all_push_constants &= src_info->can_inline_all_push_constants;
if (src->stage == MESA_SHADER_VERTEX) {
dst_info->vs = src_info->vs;
} else {
dst_info->tes = src_info->tes;
}
if (dst->stage == MESA_SHADER_GEOMETRY) {
dst_info->is_ngg = src_info->is_ngg;
dst_info->gs.es_type = src->stage;
}
}
static const gl_shader_stage graphics_shader_order[] = {
MESA_SHADER_VERTEX,
MESA_SHADER_TESS_CTRL,
@ -1382,4 +1409,19 @@ radv_nir_shader_info_link(struct radv_device *device, const struct radv_pipeline
radv_link_shaders_info(device, &stages[s], next_stage, pipeline_key);
next_stage = &stages[s];
}
if (device->physical_device->rad_info.gfx_level >= GFX9) {
/* Merge shader info for VS+TCS. */
if (stages[MESA_SHADER_TESS_CTRL].nir) {
radv_nir_shader_info_merge(&stages[MESA_SHADER_VERTEX], &stages[MESA_SHADER_TESS_CTRL]);
}
/* Merge shader info for VS+GS or TES+GS. */
if (stages[MESA_SHADER_GEOMETRY].nir) {
gl_shader_stage pre_stage =
stages[MESA_SHADER_TESS_EVAL].nir ? MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX;
radv_nir_shader_info_merge(&stages[pre_stage], &stages[MESA_SHADER_GEOMETRY]);
}
}
}