From 59a3ca233320dd60cdf24d940592d65724cace9b Mon Sep 17 00:00:00 2001 From: David Rosca Date: Wed, 13 Aug 2025 15:16:57 +0200 Subject: [PATCH] radv/video: Fix waiting on encode feedback query Currently we wait until the second dword in feedback buffer changes from 0 to 1, and then the rest of the feedback is read. There is no guarantee that the rest of the feedback will be available, which can cause bitstream size to be incorrectly returned as 0. Add write memory command after encode, marking the query as available to ensure the entire feedback buffer is ready. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13601 Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_query.c | 5 +++-- src/amd/vulkan/radv_video.h | 2 ++ src/amd/vulkan/radv_video_enc.c | 10 +++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/amd/vulkan/radv_query.c b/src/amd/vulkan/radv_query.c index 5687dcbaf9b..bad5ee9b690 100644 --- a/src/amd/vulkan/radv_query.c +++ b/src/amd/vulkan/radv_query.c @@ -2392,12 +2392,13 @@ radv_GetQueryPoolResults(VkDevice _device, VkQueryPool queryPool, uint32_t first } case VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR: { uint32_t *src32 = (uint32_t *)src; + uint32_t ready_idx = radv_video_write_memory_supported(pdev) ? RADV_ENC_FEEDBACK_STATUS_IDX : 1; uint32_t value; do { - value = p_atomic_read(&src32[1]); + value = p_atomic_read(&src32[ready_idx]); } while (value != 1 && (flags & VK_QUERY_RESULT_WAIT_BIT) && !(timed_out = (atimeout < os_time_get_nano()))); - available = value != 0; + available = value == 1; if (timed_out) result = VK_ERROR_DEVICE_LOST; diff --git a/src/amd/vulkan/radv_video.h b/src/amd/vulkan/radv_video.h index d266272fa39..086a1b23317 100644 --- a/src/amd/vulkan/radv_video.h +++ b/src/amd/vulkan/radv_video.h @@ -33,6 +33,8 @@ struct radv_cmd_stream; #define RADV_BIND_ENCODE_QP_MAP 3 #define RADV_BIND_ENCODE_AV1_CDF_STORE RADV_BIND_DECODER_CTX +#define RADV_ENC_FEEDBACK_STATUS_IDX 10 + struct radv_vid_mem { struct radv_device_memory *mem; VkDeviceSize offset; diff --git a/src/amd/vulkan/radv_video_enc.c b/src/amd/vulkan/radv_video_enc.c index 04e15fcbdf8..8c22a16170c 100644 --- a/src/amd/vulkan/radv_video_enc.c +++ b/src/amd/vulkan/radv_video_enc.c @@ -2763,8 +2763,10 @@ radv_vcn_encode_video(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInf if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5) radv_enc_qp_map_input(cmd_buffer, enc_info); - if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_4) - radv_vcn_sq_header(cs, &cmd_buffer->video.sq, RADEON_VCN_ENGINE_TYPE_ENCODE, false); + if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_2) { + radv_vcn_sq_header(cs, &cmd_buffer->video.sq, RADEON_VCN_ENGINE_TYPE_ENCODE, + pdev->enc_hw_ver < RADV_VIDEO_ENC_HW_4); + } const struct VkVideoInlineQueryInfoKHR *inline_queries = NULL; if (vid->vk.flags & VK_VIDEO_SESSION_CREATE_INLINE_QUERIES_BIT_KHR) { @@ -2857,8 +2859,10 @@ radv_vcn_encode_video(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInf *enc->p_task_size = enc->total_task_size; - if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_4) + if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_2) { radv_vcn_sq_tail(cs, &cmd_buffer->video.sq); + radv_vcn_write_memory(cmd_buffer, feedback_query_va + RADV_ENC_FEEDBACK_STATUS_IDX * sizeof(uint32_t), 1); + } } static void