+ 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;
+}
+
+static void
+radv_pipeline_init_input_assembly_state(struct radv_pipeline *pipeline,
+ const VkGraphicsPipelineCreateInfo *pCreateInfo,
+ const struct radv_graphics_pipeline_create_info *extra)
+{
+ const VkPipelineInputAssemblyStateCreateInfo *ia_state = pCreateInfo->pInputAssemblyState;
+ struct radv_shader_variant *tes = pipeline->shaders[MESA_SHADER_TESS_EVAL];
+ struct radv_shader_variant *gs = pipeline->shaders[MESA_SHADER_GEOMETRY];
+
+ pipeline->graphics.prim_restart_enable = !!ia_state->primitiveRestartEnable;
+ pipeline->graphics.can_use_guardband = radv_prim_can_use_guardband(ia_state->topology);
+
+ if (radv_pipeline_has_gs(pipeline)) {
+ if (si_conv_gl_prim_to_gs_out(gs->info.gs.output_prim) == V_028A6C_OUTPRIM_TYPE_TRISTRIP)
+ pipeline->graphics.can_use_guardband = true;
+ } else if (radv_pipeline_has_tess(pipeline)) {
+ if (!tes->info.tes.point_mode &&
+ si_conv_gl_prim_to_gs_out(tes->info.tes.primitive_mode) == V_028A6C_OUTPRIM_TYPE_TRISTRIP)
+ pipeline->graphics.can_use_guardband = true;
+ }
+
+ if (extra && extra->use_rectlist) {
+ pipeline->graphics.can_use_guardband = true;
+ }
+
+ pipeline->graphics.ia_multi_vgt_param =
+ radv_compute_ia_multi_vgt_param_helpers(pipeline);
+}
+
+static void
+radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
+ const VkGraphicsPipelineCreateInfo *pCreateInfo,
+ const struct radv_graphics_pipeline_create_info *extra)
+{
+ uint32_t needed_states = radv_pipeline_needed_dynamic_state(pCreateInfo);
+ uint32_t states = needed_states;
+ RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass);
+ struct radv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass];
+
+ pipeline->dynamic_state = default_dynamic_state;
+ pipeline->graphics.needed_dynamic_state = needed_states;
+
+ if (pCreateInfo->pDynamicState) {
+ /* Remove all of the states that are marked as dynamic */
+ uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
+ for (uint32_t s = 0; s < count; s++)
+ states &= ~radv_dynamic_state_mask(pCreateInfo->pDynamicState->pDynamicStates[s]);
+ }
+
+ struct radv_dynamic_state *dynamic = &pipeline->dynamic_state;
+
+ if (needed_states & RADV_DYNAMIC_VIEWPORT) {
+ assert(pCreateInfo->pViewportState);
+
+ dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount;
+ if (states & RADV_DYNAMIC_VIEWPORT) {
+ typed_memcpy(dynamic->viewport.viewports,