Module: Mesa Branch: main Commit: aa9558698e35a234602e28a894aa1a09bf55a3f4 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=aa9558698e35a234602e28a894aa1a09bf55a3f4
Author: Timur Kristóf <[email protected]> Date: Thu Sep 22 13:24:07 2022 -0700 radv/amdgpu: Extract CS chain and unchain functions. Also add a comment that explains what chaining means and add a check to make sure the HW IP type supports it. Signed-off-by: Timur Kristóf <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22220> --- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 89 +++++++++++++++++---------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index a8b91495c70..c883a465864 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -509,6 +509,57 @@ radv_amdgpu_cs_reset(struct radeon_cmdbuf *_cs) } } +static void +radv_amdgpu_cs_unchain(struct radeon_cmdbuf *cs) +{ + struct radv_amdgpu_cs *acs = radv_amdgpu_cs(cs); + + if (!acs->is_chained) + return; + + assert(cs->cdw <= cs->max_dw + 4); + assert(get_nop_packet(acs) == PKT3_NOP_PAD); /* Other shouldn't chain. */ + + acs->is_chained = false; + cs->buf[cs->cdw - 4] = PKT3_NOP_PAD; + cs->buf[cs->cdw - 3] = PKT3_NOP_PAD; + cs->buf[cs->cdw - 2] = PKT3_NOP_PAD; + cs->buf[cs->cdw - 1] = PKT3_NOP_PAD; +} + +static bool +radv_amdgpu_cs_chain(struct radeon_cmdbuf *cs, struct radeon_cmdbuf *next_cs, bool pre_ena) +{ + /* Chains together two CS (command stream) objects by editing + * the end of the first CS to add a command that jumps to the + * second CS. + * + * After this, it is enough to submit the first CS to the GPU + * and not necessary to submit the second CS because it is already + * executed by the first. + */ + + struct radv_amdgpu_cs *acs = radv_amdgpu_cs(cs); + struct radv_amdgpu_cs *next_acs = radv_amdgpu_cs(next_cs); + + /* Only some HW IP types have packets that we can use for chaining. */ + if (!hw_can_chain(acs->hw_ip)) + return false; + + assert(cs->cdw <= cs->max_dw + 4); + assert(get_nop_packet(acs) == PKT3_NOP_PAD); /* Other shouldn't chain. */ + + acs->is_chained = true; + + cs->buf[cs->cdw - 4] = PKT3(PKT3_INDIRECT_BUFFER_CIK, 2, 0); + cs->buf[cs->cdw - 3] = next_acs->ib.ib_mc_address; + cs->buf[cs->cdw - 2] = next_acs->ib.ib_mc_address >> 32; + cs->buf[cs->cdw - 1] = + S_3F2_CHAIN(1) | S_3F2_VALID(1) | S_3F2_PRE_ENA(pre_ena) | next_acs->ib.size; + + return true; +} + static int radv_amdgpu_cs_find_buffer(struct radv_amdgpu_cs *cs, uint32_t bo) { @@ -897,35 +948,18 @@ radv_amdgpu_winsys_cs_submit_chained(struct radv_amdgpu_ctx *ctx, int queue_idx, struct drm_amdgpu_bo_list_entry *handles = NULL; struct radv_amdgpu_cs_request request; struct radv_amdgpu_cs_ib_info ibs[1 + AMD_NUM_IP_TYPES]; + bool enable_preemption = cs0->hw_ip == AMDGPU_HW_IP_GFX && uses_shadow_regs; unsigned num_handles = 0; - uint32_t pre_ena = cs0->hw_ip == AMDGPU_HW_IP_GFX && uses_shadow_regs ? S_3F2_PRE_ENA(1) : 0; + VkResult result; for (unsigned i = cs_count; i--;) { - struct radv_amdgpu_cs *cs = radv_amdgpu_cs(cs_array[i]); + struct radeon_cmdbuf *cmdbuf = cs_array[i]; - if (cs->is_chained) { - assert(cs->base.cdw <= cs->base.max_dw + 4); - assert(get_nop_packet(cs) == PKT3_NOP_PAD); /* Other shouldn't chain. */ - - cs->is_chained = false; - cs->base.buf[cs->base.cdw - 4] = PKT3_NOP_PAD; - cs->base.buf[cs->base.cdw - 3] = PKT3_NOP_PAD; - cs->base.buf[cs->base.cdw - 2] = PKT3_NOP_PAD; - cs->base.buf[cs->base.cdw - 1] = PKT3_NOP_PAD; - } + radv_amdgpu_cs_unchain(cmdbuf); if (i + 1 < cs_count) { - struct radv_amdgpu_cs *next = radv_amdgpu_cs(cs_array[i + 1]); - assert(cs->base.cdw <= cs->base.max_dw + 4); - assert(get_nop_packet(cs) == PKT3_NOP_PAD); /* Other shouldn't chain. */ - - cs->is_chained = true; - - cs->base.buf[cs->base.cdw - 4] = PKT3(PKT3_INDIRECT_BUFFER_CIK, 2, 0); - cs->base.buf[cs->base.cdw - 3] = next->ib.ib_mc_address; - cs->base.buf[cs->base.cdw - 2] = next->ib.ib_mc_address >> 32; - cs->base.buf[cs->base.cdw - 1] = S_3F2_CHAIN(1) | S_3F2_VALID(1) | pre_ena | next->ib.size; + radv_amdgpu_cs_chain(cmdbuf, cs_array[i + 1], enable_preemption); } } @@ -1019,16 +1053,7 @@ radv_amdgpu_winsys_cs_submit_fallback(struct radv_amdgpu_ctx *ctx, int queue_idx struct radv_amdgpu_cs *cs = radv_amdgpu_cs(cs_array[i]); ibs[i + preamble_count] = cs->ib; - - if (cs->is_chained) { - assert(get_nop_packet(cs) == PKT3_NOP_PAD); /* Other shouldn't chain. */ - - cs->base.buf[cs->base.cdw - 4] = PKT3_NOP_PAD; - cs->base.buf[cs->base.cdw - 3] = PKT3_NOP_PAD; - cs->base.buf[cs->base.cdw - 2] = PKT3_NOP_PAD; - cs->base.buf[cs->base.cdw - 1] = PKT3_NOP_PAD; - cs->is_chained = false; - } + radv_amdgpu_cs_unchain(&cs->base); if (uses_shadow_regs && cs->ib.ip_type == AMDGPU_HW_IP_GFX) cs->ib.flags |= AMDGPU_IB_FLAG_PREEMPT;
