+static struct radv_ia_multi_vgt_param_helpers
+radv_compute_ia_multi_vgt_param_helpers(struct radv_pipeline *pipeline)
+{
+ struct radv_ia_multi_vgt_param_helpers ia_multi_vgt_param = {0};
+ const struct radv_device *device = pipeline->device;
+
+ if (radv_pipeline_has_tess(pipeline))
+ ia_multi_vgt_param.primgroup_size = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.num_patches;
+ else if (radv_pipeline_has_gs(pipeline))
+ ia_multi_vgt_param.primgroup_size = 64;
+ else
+ ia_multi_vgt_param.primgroup_size = 128; /* recommended without a GS */
+
+ /* GS requirement. */
+ ia_multi_vgt_param.partial_es_wave = false;
+ if (radv_pipeline_has_gs(pipeline) && device->physical_device->rad_info.chip_class <= GFX8)
+ if (SI_GS_PER_ES / ia_multi_vgt_param.primgroup_size >= pipeline->device->gs_table_depth - 3)
+ ia_multi_vgt_param.partial_es_wave = true;
+
+ ia_multi_vgt_param.ia_switch_on_eoi = false;
+ if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.ps.prim_id_input)
+ ia_multi_vgt_param.ia_switch_on_eoi = true;
+ if (radv_pipeline_has_gs(pipeline) &&
+ pipeline->shaders[MESA_SHADER_GEOMETRY]->info.uses_prim_id)
+ ia_multi_vgt_param.ia_switch_on_eoi = true;
+ if (radv_pipeline_has_tess(pipeline)) {
+ /* SWITCH_ON_EOI must be set if PrimID is used. */
+ if (pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.uses_prim_id ||
+ radv_get_shader(pipeline, MESA_SHADER_TESS_EVAL)->info.uses_prim_id)
+ ia_multi_vgt_param.ia_switch_on_eoi = true;
+ }
+
+ ia_multi_vgt_param.partial_vs_wave = false;
+ if (radv_pipeline_has_tess(pipeline)) {
+ /* Bug with tessellation and GS on Bonaire and older 2 SE chips. */
+ if ((device->physical_device->rad_info.family == CHIP_TAHITI ||
+ device->physical_device->rad_info.family == CHIP_PITCAIRN ||
+ device->physical_device->rad_info.family == CHIP_BONAIRE) &&
+ radv_pipeline_has_gs(pipeline))
+ ia_multi_vgt_param.partial_vs_wave = true;
+ /* Needed for 028B6C_DISTRIBUTION_MODE != 0 */
+ if (device->physical_device->rad_info.has_distributed_tess) {
+ if (radv_pipeline_has_gs(pipeline)) {
+ if (device->physical_device->rad_info.chip_class <= GFX8)
+ ia_multi_vgt_param.partial_es_wave = true;
+ } else {
+ ia_multi_vgt_param.partial_vs_wave = true;
+ }
+ }
+ }
+
+ if (radv_pipeline_has_gs(pipeline)) {
+ /* On these chips there is the possibility of a hang if the
+ * pipeline uses a GS and partial_vs_wave is not set.
+ *
+ * This mostly does not hit 4-SE chips, as those typically set
+ * ia_switch_on_eoi and then partial_vs_wave is set for pipelines
+ * with GS due to another workaround.
+ *
+ * Reproducer: https://bugs.freedesktop.org/show_bug.cgi?id=109242
+ */
+ if (device->physical_device->rad_info.family == CHIP_TONGA ||
+ device->physical_device->rad_info.family == CHIP_FIJI ||
+ device->physical_device->rad_info.family == CHIP_POLARIS10 ||
+ device->physical_device->rad_info.family == CHIP_POLARIS11 ||
+ device->physical_device->rad_info.family == CHIP_POLARIS12 ||
+ device->physical_device->rad_info.family == CHIP_VEGAM) {
+ ia_multi_vgt_param.partial_vs_wave = true;
+ }
+ }
+
+ ia_multi_vgt_param.base =
+ S_028AA8_PRIMGROUP_SIZE(ia_multi_vgt_param.primgroup_size - 1) |
+ /* The following field was moved to VGT_SHADER_STAGES_EN in GFX9. */
+ S_028AA8_MAX_PRIMGRP_IN_WAVE(device->physical_device->rad_info.chip_class == GFX8 ? 2 : 0) |
+ S_030960_EN_INST_OPT_BASIC(device->physical_device->rad_info.chip_class >= GFX9) |
+ S_030960_EN_INST_OPT_ADV(device->physical_device->rad_info.chip_class >= GFX9);
+
+ return ia_multi_vgt_param;
+}
+