diff options
author | Dave Airlie <[email protected]> | 2017-02-13 07:30:29 +0000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-02-14 20:29:19 +0000 |
commit | 3360dbe0c1ebeead9046955b3de4dcdf86cfbb40 (patch) | |
tree | eb90b19485798402d238b6df8897175ac85c533d /src/amd/vulkan/si_cmd_buffer.c | |
parent | a465eae38fbf5f95170a73009e646daca2aa5181 (diff) |
radv: fixup IA_MULTI_VGT_PARAM handling.
This ports the remains of the workarounds from radeonsi for
the non-TESS cases. It should provide equivalent workarounds
for hawaii and bonarie.
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd/vulkan/si_cmd_buffer.c')
-rw-r--r-- | src/amd/vulkan/si_cmd_buffer.c | 78 |
1 files changed, 58 insertions, 20 deletions
diff --git a/src/amd/vulkan/si_cmd_buffer.c b/src/amd/vulkan/si_cmd_buffer.c index 7d81c2b084c..e20e3bd101e 100644 --- a/src/amd/vulkan/si_cmd_buffer.c +++ b/src/amd/vulkan/si_cmd_buffer.c @@ -565,8 +565,25 @@ si_write_scissors(struct radeon_winsys_cs *cs, int first, } } +static inline unsigned +radv_prims_for_vertices(struct radv_prim_vertex_count *info, unsigned num) +{ + if (num == 0) + return 0; + + if (info->incr == 0) + return 0; + + if (num < info->min) + return 0; + + return 1 + ((num - info->min) / info->incr); +} + uint32_t -si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer) +si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, + bool instanced_or_indirect_draw, + uint32_t draw_vertex_count) { enum chip_class chip_class = cmd_buffer->device->physical_device->rad_info.chip_class; enum radeon_family family = cmd_buffer->device->physical_device->rad_info.family; @@ -580,10 +597,14 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer) bool ia_switch_on_eoi = false; bool partial_vs_wave = false; bool partial_es_wave = false; + uint32_t num_prims = radv_prims_for_vertices(&cmd_buffer->state.pipeline->graphics.prim_vertex_count, draw_vertex_count); + bool multi_instances_smaller_than_primgroup; if (radv_pipeline_has_gs(cmd_buffer->state.pipeline)) primgroup_size = 64; /* recommended with a GS */ + multi_instances_smaller_than_primgroup = (instanced_or_indirect_draw || + num_prims < primgroup_size); /* TODO TES */ /* TODO linestipple */ @@ -596,12 +617,30 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer) prim == V_008958_DI_PT_POLYGON || prim == V_008958_DI_PT_LINELOOP || prim == V_008958_DI_PT_TRIFAN || - prim == V_008958_DI_PT_TRISTRIP_ADJ) - // info->primitive_restart || - // info->count_from_stream_output) + prim == V_008958_DI_PT_TRISTRIP_ADJ || + (cmd_buffer->state.pipeline->graphics.prim_restart_enable && + (family < CHIP_POLARIS10 || + (prim != V_008958_DI_PT_POINTLIST && + prim != V_008958_DI_PT_LINESTRIP && + prim != V_008958_DI_PT_TRISTRIP)))) wd_switch_on_eop = true; - /* TODO HAWAII */ + /* Hawaii hangs if instancing is enabled and WD_SWITCH_ON_EOP is 0. + * We don't know that for indirect drawing, so treat it as + * always problematic. */ + if (family == CHIP_HAWAII && + instanced_or_indirect_draw) + wd_switch_on_eop = true; + + /* Performance recommendation for 4 SE Gfx7-8 parts if + * instances are smaller than a primgroup. + * Assume indirect draws always use small instances. + * This is needed for good VS wave utilization. + */ + if (chip_class <= VI && + info->max_se == 4 && + multi_instances_smaller_than_primgroup) + wd_switch_on_eop = true; /* Required on CIK and later. */ if (info->max_se > 2 && !wd_switch_on_eop) @@ -614,12 +653,11 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer) (radv_pipeline_has_gs(cmd_buffer->state.pipeline) || max_primgroup_in_wave != 2)))) partial_vs_wave = true; -#if 0 /* Instancing bug on Bonaire. */ if (family == CHIP_BONAIRE && ia_switch_on_eoi && - (info->indirect || info->instance_count > 1)) + instanced_or_indirect_draw) partial_vs_wave = true; -#endif + /* If the WD switch is false, the IA switch must be false too. */ assert(wd_switch_on_eop || !ia_switch_on_eop); } @@ -627,19 +665,19 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer) if (ia_switch_on_eoi) partial_es_wave = true; - /* GS requirement. */ - if (SI_GS_PER_ES / primgroup_size >= cmd_buffer->device->gs_table_depth - 3) - partial_es_wave = true; + if (radv_pipeline_has_gs(cmd_buffer->state.pipeline)) { + /* GS requirement. */ + if (SI_GS_PER_ES / primgroup_size >= cmd_buffer->device->gs_table_depth - 3) + partial_es_wave = true; + + /* Hw bug with single-primitive instances and SWITCH_ON_EOI + * on multi-SE chips. */ + if (info->max_se >= 2 && ia_switch_on_eoi && + (instanced_or_indirect_draw && + num_prims <= 1)) + cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_VGT_FLUSH; + } - /* Hw bug with single-primitive instances and SWITCH_ON_EOI - * on multi-SE chips. */ -#if 0 - if (info->max_se >= 2 && ia_switch_on_eoi && - (info->indirect || - (info->instance_count > 1 && - si_num_prims_for_vertices(info) <= 1))) - sctx->b.flags |= SI_CONTEXT_VGT_FLUSH; -#endif return S_028AA8_SWITCH_ON_EOP(ia_switch_on_eop) | S_028AA8_SWITCH_ON_EOI(ia_switch_on_eoi) | S_028AA8_PARTIAL_VS_WAVE_ON(partial_vs_wave) | |