From 56b98bb36dd69859c0fa93725b8c4fb9ff903f18 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 25 Jan 2023 16:22:16 +0100 Subject: [PATCH] radv: add dynamic support for rectangles enable/mode This is in VK_EXT_discard_rectangles version 2. Signed-off-by: Samuel Pitoiset Part-of: --- docs/relnotes/new_features.txt | 1 + src/amd/vulkan/radv_cmd_buffer.c | 70 +++++++++++++++++++++++++++----- src/amd/vulkan/radv_pipeline.c | 46 +++++++-------------- src/amd/vulkan/radv_private.h | 24 ++++++----- 4 files changed, 89 insertions(+), 52 deletions(-) diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index e1e76e73d87..872e5046f4b 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -2,3 +2,4 @@ VK_EXT_pipeline_library_group_handles on RADV VK_EXT_image_sliced_view_of_3d on RADV/GFX10+ VK_KHR_map_memory2 on ANV and RADV fullyCoveredFragmentShaderInputVariable on RADV/GFX9+ +VK_EXT_discard_rectangles version 2 on RADV diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 4af8e4b05aa..2ee5362a605 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -239,6 +239,9 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy RADV_CMP_COPY(vk.fsr.combiner_ops[0], RADV_DYNAMIC_FRAGMENT_SHADING_RATE); RADV_CMP_COPY(vk.fsr.combiner_ops[1], RADV_DYNAMIC_FRAGMENT_SHADING_RATE); + RADV_CMP_COPY(vk.dr.enable, RADV_DYNAMIC_DISCARD_RECTANGLE_ENABLE); + RADV_CMP_COPY(vk.dr.mode, RADV_DYNAMIC_DISCARD_RECTANGLE_MODE); + #undef RADV_CMP_COPY cmd_buffer->state.dirty |= dest_mask; @@ -2030,18 +2033,39 @@ static void radv_emit_discard_rectangle(struct radv_cmd_buffer *cmd_buffer) { const struct radv_dynamic_state *d = &cmd_buffer->state.dynamic; + uint32_t cliprect_rule = 0; - if (!d->vk.dr.rectangle_count) - return; + if (!d->vk.dr.enable) { + cliprect_rule = 0xffff; + } else { + for (unsigned i = 0; i < (1u << MAX_DISCARD_RECTANGLES); ++i) { + /* Interpret i as a bitmask, and then set the bit in + * the mask if that combination of rectangles in which + * the pixel is contained should pass the cliprect + * test. + */ + unsigned relevant_subset = i & ((1u << d->vk.dr.rectangle_count) - 1); - radeon_set_context_reg_seq(cmd_buffer->cs, R_028210_PA_SC_CLIPRECT_0_TL, - d->vk.dr.rectangle_count * 2); - for (unsigned i = 0; i < d->vk.dr.rectangle_count; ++i) { - VkRect2D rect = d->vk.dr.rectangles[i]; - radeon_emit(cmd_buffer->cs, S_028210_TL_X(rect.offset.x) | S_028210_TL_Y(rect.offset.y)); - radeon_emit(cmd_buffer->cs, S_028214_BR_X(rect.offset.x + rect.extent.width) | - S_028214_BR_Y(rect.offset.y + rect.extent.height)); + if (d->vk.dr.mode == VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT && !relevant_subset) + continue; + + if (d->vk.dr.mode == VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT && relevant_subset) + continue; + + cliprect_rule |= 1u << i; + } + + radeon_set_context_reg_seq(cmd_buffer->cs, R_028210_PA_SC_CLIPRECT_0_TL, + d->vk.dr.rectangle_count * 2); + for (unsigned i = 0; i < d->vk.dr.rectangle_count; ++i) { + VkRect2D rect = d->vk.dr.rectangles[i]; + radeon_emit(cmd_buffer->cs, S_028210_TL_X(rect.offset.x) | S_028210_TL_Y(rect.offset.y)); + radeon_emit(cmd_buffer->cs, S_028214_BR_X(rect.offset.x + rect.extent.width) | + S_028214_BR_Y(rect.offset.y + rect.extent.height)); + } } + + radeon_set_context_reg(cmd_buffer->cs, R_02820C_PA_SC_CLIPRECT_RULE, cliprect_rule); } static void @@ -4350,7 +4374,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pip if (states & RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS) radv_emit_depth_bias(cmd_buffer); - if (states & RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE) + if (states & (RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE | + RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE_ENABLE | + RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE_MODE)) radv_emit_discard_rectangle(cmd_buffer); if (states & RADV_CMD_DIRTY_DYNAMIC_CONSERVATIVE_RAST_MODE) @@ -7329,6 +7355,30 @@ radv_CmdSetColorBlendEquationEXT(VkCommandBuffer commandBuffer, uint32_t firstAt state->dirty |= RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_EQUATION; } +VKAPI_ATTR void VKAPI_CALL +radv_CmdSetDiscardRectangleEnableEXT(VkCommandBuffer commandBuffer, VkBool32 discardRectangleEnable) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; + + state->dynamic.vk.dr.enable = discardRectangleEnable; + state->dynamic.vk.dr.rectangle_count = discardRectangleEnable ? MAX_DISCARD_RECTANGLES : 0; + + state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE_ENABLE; +} + +VKAPI_ATTR void VKAPI_CALL +radv_CmdSetDiscardRectangleModeEXT(VkCommandBuffer commandBuffer, + VkDiscardRectangleModeEXT discardRectangleMode) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; + + state->dynamic.vk.dr.mode = discardRectangleMode; + + state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE_MODE; +} + VKAPI_ATTR void VKAPI_CALL radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCmdBuffers) diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index b377f9750c9..8eb32e7192f 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -670,6 +670,10 @@ radv_dynamic_state_mask(VkDynamicState state) return RADV_DYNAMIC_LINE_RASTERIZATION_MODE; case VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT: return RADV_DYNAMIC_COLOR_BLEND_EQUATION; + case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT: + return RADV_DYNAMIC_DISCARD_RECTANGLE_ENABLE; + case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT: + return RADV_DYNAMIC_DISCARD_RECTANGLE_MODE; default: unreachable("Unhandled dynamic state"); } @@ -741,7 +745,8 @@ radv_pipeline_needed_dynamic_state(const struct radv_graphics_pipeline *pipeline states &= ~(RADV_DYNAMIC_STENCIL_COMPARE_MASK | RADV_DYNAMIC_STENCIL_WRITE_MASK | RADV_DYNAMIC_STENCIL_REFERENCE | RADV_DYNAMIC_STENCIL_OP); - if (!state->dr->rectangle_count) + if (!(pipeline->dynamic_states & RADV_DYNAMIC_DISCARD_RECTANGLE_ENABLE) && + !state->dr->rectangle_count) states &= ~RADV_DYNAMIC_DISCARD_RECTANGLE; if (!state->ms || !state->ms->sample_locations_enable) @@ -1324,6 +1329,14 @@ radv_pipeline_init_dynamic_state(struct radv_graphics_pipeline *pipeline, } } + if (states & RADV_DYNAMIC_DISCARD_RECTANGLE_ENABLE) { + dynamic->vk.dr.enable = state->dr->rectangle_count > 0; + } + + if (states & RADV_DYNAMIC_DISCARD_RECTANGLE_MODE) { + dynamic->vk.dr.mode = state->dr->mode; + } + pipeline->dynamic_state.mask = states; } @@ -4180,36 +4193,6 @@ radv_pipeline_emit_vgt_shader_config(const struct radv_device *device, struct ra radeon_set_context_reg(ctx_cs, R_028B54_VGT_SHADER_STAGES_EN, stages); } -static void -radv_pipeline_emit_cliprect_rule(struct radeon_cmdbuf *ctx_cs, - const struct vk_graphics_pipeline_state *state) -{ - uint32_t cliprect_rule = 0; - - if (!state->dr->rectangle_count) { - cliprect_rule = 0xffff; - } else { - for (unsigned i = 0; i < (1u << MAX_DISCARD_RECTANGLES); ++i) { - /* Interpret i as a bitmask, and then set the bit in - * the mask if that combination of rectangles in which - * the pixel is contained should pass the cliprect - * test. - */ - unsigned relevant_subset = i & ((1u << state->dr->rectangle_count) - 1); - - if (state->dr->mode == VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT && !relevant_subset) - continue; - - if (state->dr->mode == VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT && relevant_subset) - continue; - - cliprect_rule |= 1u << i; - } - } - - radeon_set_context_reg(ctx_cs, R_02820C_PA_SC_CLIPRECT_RULE, cliprect_rule); -} - static void radv_pipeline_emit_vgt_gs_out(const struct radv_device *device, struct radeon_cmdbuf *ctx_cs, const struct radv_graphics_pipeline *pipeline, @@ -4367,7 +4350,6 @@ radv_pipeline_emit_pm4(const struct radv_device *device, radv_emit_ps_inputs(device, ctx_cs, last_vgt_shader, ps); radv_pipeline_emit_vgt_vertex_reuse(device, ctx_cs, pipeline); radv_pipeline_emit_vgt_shader_config(device, ctx_cs, pipeline); - radv_pipeline_emit_cliprect_rule(ctx_cs, state); radv_pipeline_emit_vgt_gs_out(device, ctx_cs, pipeline, vgt_gs_out_prim_type); if (pdevice->rad_info.gfx_level >= GFX10_3) { diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 4d237003702..6ce32f51fee 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1283,7 +1283,9 @@ enum radv_dynamic_state_bits { RADV_DYNAMIC_RASTERIZATION_SAMPLES = 1ull << 43, RADV_DYNAMIC_LINE_RASTERIZATION_MODE = 1ull << 44, RADV_DYNAMIC_COLOR_BLEND_EQUATION = 1ull << 45, - RADV_DYNAMIC_ALL = (1ull << 46) - 1, + RADV_DYNAMIC_DISCARD_RECTANGLE_ENABLE = 1ull << 46, + RADV_DYNAMIC_DISCARD_RECTANGLE_MODE = 1ull << 47, + RADV_DYNAMIC_ALL = (1ull << 48) - 1, }; enum radv_cmd_dirty_bits { @@ -1335,15 +1337,17 @@ enum radv_cmd_dirty_bits { RADV_CMD_DIRTY_DYNAMIC_RASTERIZATION_SAMPLES = 1ull << 43, RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE = 1ull << 44, RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_EQUATION = 1ull << 45, - RADV_CMD_DIRTY_DYNAMIC_ALL = (1ull << 46) - 1, - RADV_CMD_DIRTY_PIPELINE = 1ull << 46, - RADV_CMD_DIRTY_INDEX_BUFFER = 1ull << 47, - RADV_CMD_DIRTY_FRAMEBUFFER = 1ull << 48, - RADV_CMD_DIRTY_VERTEX_BUFFER = 1ull << 49, - RADV_CMD_DIRTY_STREAMOUT_BUFFER = 1ull << 50, - RADV_CMD_DIRTY_GUARDBAND = 1ull << 51, - RADV_CMD_DIRTY_RBPLUS = 1ull << 52, - RADV_CMD_DIRTY_NGG_QUERY = 1ull << 53, + RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE_ENABLE = 1ull << 46, + RADV_CMD_DIRTY_DYNAMIC_DISCARD_RECTANGLE_MODE = 1ull << 47, + RADV_CMD_DIRTY_DYNAMIC_ALL = (1ull << 48) - 1, + RADV_CMD_DIRTY_PIPELINE = 1ull << 48, + RADV_CMD_DIRTY_INDEX_BUFFER = 1ull << 49, + RADV_CMD_DIRTY_FRAMEBUFFER = 1ull << 50, + RADV_CMD_DIRTY_VERTEX_BUFFER = 1ull << 51, + RADV_CMD_DIRTY_STREAMOUT_BUFFER = 1ull << 52, + RADV_CMD_DIRTY_GUARDBAND = 1ull << 53, + RADV_CMD_DIRTY_RBPLUS = 1ull << 54, + RADV_CMD_DIRTY_NGG_QUERY = 1ull << 55, }; enum radv_cmd_flush_bits {