radv: implement dynamic primitive restart enable

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10340>
This commit is contained in:
Samuel Pitoiset
2021-03-15 18:51:28 +01:00
committed by Marge Bot
parent f2933e9872
commit c40d7fadc3
6 changed files with 67 additions and 26 deletions

View File

@@ -107,6 +107,7 @@ const struct radv_dynamic_state default_dynamic_state = {
VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR},
}, },
.depth_bias_enable = 0u, .depth_bias_enable = 0u,
.primitive_restart_enable = 0u,
}; };
static void static void
@@ -305,6 +306,13 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy
} }
} }
if (copy_mask & RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE) {
if (dest->primitive_restart_enable != src->primitive_restart_enable) {
dest->primitive_restart_enable = src->primitive_restart_enable;
dest_mask |= RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
}
}
cmd_buffer->state.dirty |= dest_mask; cmd_buffer->state.dirty |= dest_mask;
} }
@@ -1273,7 +1281,8 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
if (!cmd_buffer->state.emitted_pipeline) if (!cmd_buffer->state.emitted_pipeline)
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY | cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |
RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS |
RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
if (!cmd_buffer->state.emitted_pipeline || if (!cmd_buffer->state.emitted_pipeline ||
cmd_buffer->state.emitted_pipeline->graphics.db_depth_control != cmd_buffer->state.emitted_pipeline->graphics.db_depth_control !=
@@ -1584,6 +1593,20 @@ radv_emit_fragment_shading_rate(struct radv_cmd_buffer *cmd_buffer)
radeon_set_context_reg(cmd_buffer->cs, R_028848_PA_CL_VRS_CNTL, pa_cl_vrs_cntl); radeon_set_context_reg(cmd_buffer->cs, R_028848_PA_CL_VRS_CNTL, pa_cl_vrs_cntl);
} }
static void
radv_emit_primitive_restart_enable(struct radv_cmd_buffer *cmd_buffer)
{
struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
radeon_set_uconfig_reg(cmd_buffer->cs, R_03092C_VGT_MULTI_PRIM_IB_RESET_EN,
d->primitive_restart_enable);
} else {
radeon_set_context_reg(cmd_buffer->cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN,
d->primitive_restart_enable);
}
}
static void static void
radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index, radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index,
struct radv_color_buffer_info *cb, struct radv_image_view *iview, struct radv_color_buffer_info *cb, struct radv_image_view *iview,
@@ -2581,6 +2604,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
if (states & RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE) if (states & RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE)
radv_emit_fragment_shading_rate(cmd_buffer); radv_emit_fragment_shading_rate(cmd_buffer);
if (states & RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)
radv_emit_primitive_restart_enable(cmd_buffer);
cmd_buffer->state.dirty &= ~states; cmd_buffer->state.dirty &= ~states;
} }
@@ -3070,12 +3096,13 @@ si_emit_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_dr
struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info; struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info;
struct radv_cmd_state *state = &cmd_buffer->state; struct radv_cmd_state *state = &cmd_buffer->state;
unsigned topology = state->dynamic.primitive_topology; unsigned topology = state->dynamic.primitive_topology;
bool prim_restart_enable = state->dynamic.primitive_restart_enable;
struct radeon_cmdbuf *cs = cmd_buffer->cs; struct radeon_cmdbuf *cs = cmd_buffer->cs;
unsigned ia_multi_vgt_param; unsigned ia_multi_vgt_param;
ia_multi_vgt_param = ia_multi_vgt_param =
si_get_ia_multi_vgt_param(cmd_buffer, instanced_draw, indirect_draw, count_from_stream_output, si_get_ia_multi_vgt_param(cmd_buffer, instanced_draw, indirect_draw, count_from_stream_output,
draw_vertex_count, topology); draw_vertex_count, topology, prim_restart_enable);
if (state->last_ia_multi_vgt_param != ia_multi_vgt_param) { if (state->last_ia_multi_vgt_param != ia_multi_vgt_param) {
if (info->chip_class == GFX9) { if (info->chip_class == GFX9) {
@@ -3096,7 +3123,6 @@ radv_emit_draw_registers(struct radv_cmd_buffer *cmd_buffer, const struct radv_d
struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info; struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info;
struct radv_cmd_state *state = &cmd_buffer->state; struct radv_cmd_state *state = &cmd_buffer->state;
struct radeon_cmdbuf *cs = cmd_buffer->cs; struct radeon_cmdbuf *cs = cmd_buffer->cs;
int32_t primitive_reset_en;
/* Draw state. */ /* Draw state. */
if (info->chip_class < GFX10) { if (info->chip_class < GFX10) {
@@ -3105,19 +3131,7 @@ radv_emit_draw_registers(struct radv_cmd_buffer *cmd_buffer, const struct radv_d
draw_info->indirect ? 0 : draw_info->count); draw_info->indirect ? 0 : draw_info->count);
} }
/* Primitive restart. */ if (state->dynamic.primitive_restart_enable) {
primitive_reset_en = draw_info->indexed && state->pipeline->graphics.prim_restart_enable;
if (primitive_reset_en != state->last_primitive_reset_en) {
state->last_primitive_reset_en = primitive_reset_en;
if (info->chip_class >= GFX9) {
radeon_set_uconfig_reg(cs, R_03092C_VGT_MULTI_PRIM_IB_RESET_EN, primitive_reset_en);
} else {
radeon_set_context_reg(cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, primitive_reset_en);
}
}
if (primitive_reset_en) {
uint32_t primitive_reset_index = radv_get_primitive_reset_index(cmd_buffer); uint32_t primitive_reset_index = radv_get_primitive_reset_index(cmd_buffer);
if (primitive_reset_index != state->last_primitive_reset_index) { if (primitive_reset_index != state->last_primitive_reset_index) {
@@ -4762,6 +4776,20 @@ radv_CmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasE
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE; state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
} }
void
radv_CmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable)
{
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
struct radv_cmd_state *state = &cmd_buffer->state;
if (state->dynamic.primitive_restart_enable == primitiveRestartEnable)
return;
state->dynamic.primitive_restart_enable = primitiveRestartEnable;
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
}
void void
radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
const VkCommandBuffer *pCmdBuffers) const VkCommandBuffer *pCmdBuffers)
@@ -5373,7 +5401,7 @@ radv_need_late_scissor_emission(struct radv_cmd_buffer *cmd_buffer,
uint32_t primitive_reset_index = radv_get_primitive_reset_index(cmd_buffer); uint32_t primitive_reset_index = radv_get_primitive_reset_index(cmd_buffer);
if (info->indexed && state->pipeline->graphics.prim_restart_enable && if (info->indexed && state->dynamic.primitive_restart_enable &&
primitive_reset_index != state->last_primitive_reset_index) primitive_reset_index != state->last_primitive_reset_index)
return true; return true;

View File

@@ -93,6 +93,8 @@ radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_
cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1]; cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1];
state->depth_bias_enable = cmd_buffer->state.dynamic.depth_bias_enable; state->depth_bias_enable = cmd_buffer->state.dynamic.depth_bias_enable;
state->primitive_restart_enable = cmd_buffer->state.dynamic.primitive_restart_enable;
} }
if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) { if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
@@ -178,6 +180,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf
cmd_buffer->state.dynamic.depth_bias_enable = state->depth_bias_enable; cmd_buffer->state.dynamic.depth_bias_enable = state->depth_bias_enable;
cmd_buffer->state.dynamic.primitive_restart_enable = state->primitive_restart_enable;
cmd_buffer->state.dirty |= cmd_buffer->state.dirty |=
RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR | RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE | RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
@@ -185,7 +189,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf
RADV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP | RADV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |
RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE |
RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP | RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP |
RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE; RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
} }
if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) { if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {

View File

@@ -92,6 +92,7 @@ struct radv_meta_saved_state {
} fragment_shading_rate; } fragment_shading_rate;
bool depth_bias_enable; bool depth_bias_enable;
bool primitive_restart_enable;
}; };
VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand); VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand);

View File

@@ -1382,10 +1382,12 @@ radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreateInfo *pCreateIn
/* If rasterization is disabled we do not care about any of the /* If rasterization is disabled we do not care about any of the
* dynamic states, since they are all rasterization related only, * dynamic states, since they are all rasterization related only,
* except primitive topology and vertex binding stride. * except primitive topology, primitive restart enable and vertex
* binding stride.
*/ */
if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable) if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable)
return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE; return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE |
RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
if (!pCreateInfo->pRasterizationState->depthBiasEnable && if (!pCreateInfo->pRasterizationState->depthBiasEnable &&
!radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)) !radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT))
@@ -1515,7 +1517,6 @@ radv_pipeline_init_input_assembly_state(struct radv_pipeline *pipeline,
struct radv_shader_variant *tes = pipeline->shaders[MESA_SHADER_TESS_EVAL]; struct radv_shader_variant *tes = pipeline->shaders[MESA_SHADER_TESS_EVAL];
struct radv_shader_variant *gs = pipeline->shaders[MESA_SHADER_GEOMETRY]; 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); pipeline->graphics.can_use_guardband = radv_prim_can_use_guardband(ia_state->topology);
if (radv_pipeline_has_gs(pipeline)) { if (radv_pipeline_has_gs(pipeline)) {
@@ -1735,6 +1736,11 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
dynamic->depth_bias_enable = pCreateInfo->pRasterizationState->depthBiasEnable; dynamic->depth_bias_enable = pCreateInfo->pRasterizationState->depthBiasEnable;
} }
if (states & RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE) {
dynamic->primitive_restart_enable =
!!pCreateInfo->pInputAssemblyState->primitiveRestartEnable;
}
pipeline->dynamic_state.mask = states; pipeline->dynamic_state.mask = states;
} }

View File

@@ -1214,6 +1214,7 @@ struct radv_dynamic_state {
} fragment_shading_rate; } fragment_shading_rate;
bool depth_bias_enable; bool depth_bias_enable;
bool primitive_restart_enable;
}; };
extern const struct radv_dynamic_state default_dynamic_state; extern const struct radv_dynamic_state default_dynamic_state;
@@ -1490,7 +1491,8 @@ void si_write_scissors(struct radeon_cmdbuf *cs, int first, int count, const VkR
const VkViewport *viewports, bool can_use_guardband); const VkViewport *viewports, bool can_use_guardband);
uint32_t si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw, uint32_t si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw,
bool indirect_draw, bool count_from_stream_output, bool indirect_draw, bool count_from_stream_output,
uint32_t draw_vertex_count, unsigned topology); uint32_t draw_vertex_count, unsigned topology,
bool prim_restart_enable);
void si_cs_emit_write_event_eop(struct radeon_cmdbuf *cs, enum chip_class chip_class, bool is_mec, void si_cs_emit_write_event_eop(struct radeon_cmdbuf *cs, enum chip_class chip_class, bool is_mec,
unsigned event, unsigned event_flags, unsigned dst_sel, unsigned event, unsigned event_flags, unsigned dst_sel,
unsigned data_sel, uint64_t va, uint32_t new_fence, unsigned data_sel, uint64_t va, uint32_t new_fence,
@@ -1706,7 +1708,6 @@ struct radv_pipeline {
struct radv_binning_state binning; struct radv_binning_state binning;
struct radv_vrs_state vrs; struct radv_vrs_state vrs;
uint32_t spi_baryc_cntl; uint32_t spi_baryc_cntl;
bool prim_restart_enable;
unsigned esgs_ring_size; unsigned esgs_ring_size;
unsigned gsvs_ring_size; unsigned gsvs_ring_size;
uint32_t vtx_base_sgpr; uint32_t vtx_base_sgpr;

View File

@@ -792,7 +792,7 @@ static const struct radv_prim_vertex_count prim_size_table[] = {
uint32_t uint32_t
si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw, si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw,
bool indirect_draw, bool count_from_stream_output, bool indirect_draw, bool count_from_stream_output,
uint32_t draw_vertex_count, unsigned topology) uint32_t draw_vertex_count, unsigned topology, bool prim_restart_enable)
{ {
enum chip_class chip_class = cmd_buffer->device->physical_device->rad_info.chip_class; 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; enum radeon_family family = cmd_buffer->device->physical_device->rad_info.family;
@@ -831,7 +831,7 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_dra
if (cmd_buffer->device->physical_device->rad_info.max_se < 4 || if (cmd_buffer->device->physical_device->rad_info.max_se < 4 ||
topology == V_008958_DI_PT_POLYGON || topology == V_008958_DI_PT_LINELOOP || topology == V_008958_DI_PT_POLYGON || topology == V_008958_DI_PT_LINELOOP ||
topology == V_008958_DI_PT_TRIFAN || topology == V_008958_DI_PT_TRISTRIP_ADJ || topology == V_008958_DI_PT_TRIFAN || topology == V_008958_DI_PT_TRISTRIP_ADJ ||
(cmd_buffer->state.pipeline->graphics.prim_restart_enable && (prim_restart_enable &&
(cmd_buffer->device->physical_device->rad_info.family < CHIP_POLARIS10 || (cmd_buffer->device->physical_device->rad_info.family < CHIP_POLARIS10 ||
(topology != V_008958_DI_PT_POINTLIST && topology != V_008958_DI_PT_LINESTRIP)))) (topology != V_008958_DI_PT_POINTLIST && topology != V_008958_DI_PT_LINESTRIP))))
wd_switch_on_eop = true; wd_switch_on_eop = true;
@@ -899,7 +899,7 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_dra
/* Workaround for a VGT hang when strip primitive types are used with /* Workaround for a VGT hang when strip primitive types are used with
* primitive restart. * primitive restart.
*/ */
if (cmd_buffer->state.pipeline->graphics.prim_restart_enable && if (prim_restart_enable &&
(topology == V_008958_DI_PT_LINESTRIP || topology == V_008958_DI_PT_TRISTRIP || (topology == V_008958_DI_PT_LINESTRIP || topology == V_008958_DI_PT_TRISTRIP ||
topology == V_008958_DI_PT_LINESTRIP_ADJ || topology == V_008958_DI_PT_TRISTRIP_ADJ)) { topology == V_008958_DI_PT_LINESTRIP_ADJ || topology == V_008958_DI_PT_TRISTRIP_ADJ)) {
partial_vs_wave = true; partial_vs_wave = true;