[FFmpeg-cvslog] vulkan(_decode): fix, simplify and improve queries

Lynne git at videolan.org
Mon Sep 9 08:10:10 EEST 2024


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Sun Sep  1 04:36:05 2024 +0000| [5e9845f11eddb8124910ece2d04c10799d8e6bd2] | committer: Lynne

vulkan(_decode): fix, simplify and improve queries

The old query code never worked properly, and did some hideous
heuristics to read the status bit, and work that into a return
code.
This is all best left to callers to do, which simplifies
our code a lot.

This also fixes minor validation errors regarding calling queries
which are not in their active state.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5e9845f11eddb8124910ece2d04c10799d8e6bd2
---

 libavcodec/vulkan_decode.c | 21 ++++++++++++++-------
 libavutil/vulkan.c         | 43 ++++++++-----------------------------------
 libavutil/vulkan.h         |  5 +++--
 3 files changed, 25 insertions(+), 44 deletions(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index f6b8866ff5..a8b906a9dd 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -294,6 +294,7 @@ void ff_vk_decode_flush(AVCodecContext *avctx)
 
     VkCommandBuffer cmd_buf;
     FFVkExecContext *exec = ff_vk_exec_get(&dec->exec_pool);
+    int had_submission = exec->had_submission;
     ff_vk_exec_start(&ctx->s, exec);
     cmd_buf = exec->buf;
 
@@ -301,6 +302,11 @@ void ff_vk_decode_flush(AVCodecContext *avctx)
     vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
     vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
     ff_vk_exec_submit(&ctx->s, exec);
+
+    /* If this is the very first time this context is used, then remove the
+     * had_submission flag to indicate that no query result is available,
+     * as no decode command was issued. */
+    exec->had_submission = had_submission;
 }
 
 int ff_vk_decode_frame(AVCodecContext *avctx,
@@ -348,19 +354,20 @@ int ff_vk_decode_frame(AVCodecContext *avctx,
     cur_vk_ref[0].slotIndex = -1;
     decode_start.referenceSlotCount++;
 
-    if (dec->exec_pool.nb_queries) {
-        int64_t prev_sub_res = 0;
-        ff_vk_exec_wait(&ctx->s, exec);
-        ret = ff_vk_exec_get_query(&ctx->s, exec, NULL, &prev_sub_res);
+    if (dec->exec_pool.nb_queries && exec->had_submission) {
+        uint32_t *result;
+        ret = ff_vk_exec_get_query(&ctx->s, exec, (void **)&result,
+                                   VK_QUERY_RESULT_WAIT_BIT);
         if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
             av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
                    ff_vk_ret2str(ret));
             return AVERROR_EXTERNAL;
         }
 
-        if (ret == VK_SUCCESS)
-            av_log(avctx, prev_sub_res < 0 ? AV_LOG_ERROR : AV_LOG_DEBUG,
-                   "Result of previous frame decoding: %"PRId64"\n", prev_sub_res);
+        av_log(avctx,
+               result[0] != VK_QUERY_RESULT_STATUS_COMPLETE_KHR ?
+                   AV_LOG_ERROR : AV_LOG_DEBUG,
+               "Result of previous frame decoding: %u\n", result[0]);
     }
 
     sd_buf = (FFVkBuffer *)vp->slices_buf->data;
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 4316886ca4..7edfa4004b 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -433,19 +433,12 @@ fail:
 }
 
 VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
-                              void **data, int64_t *status)
+                              void **data, VkQueryResultFlagBits flags)
 {
-    VkResult ret;
     FFVulkanFunctions *vk = &s->vkfn;
     const FFVkExecPool *pool = e->parent;
-
-    int32_t *res32 = e->query_data;
-    int64_t *res64 = e->query_data;
-    int64_t res = 0;
-    VkQueryResultFlags qf = 0;
-
-    if (!e->had_submission)
-        return VK_INCOMPLETE;
+    VkQueryResultFlags qf = flags & ~(VK_QUERY_RESULT_64_BIT |
+                                      VK_QUERY_RESULT_WITH_STATUS_BIT_KHR);
 
     if (!e->query_data) {
         av_log(s, AV_LOG_ERROR, "Requested a query with a NULL query_data pointer!\n");
@@ -457,34 +450,14 @@ VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
     qf |= pool->query_statuses ?
           VK_QUERY_RESULT_WITH_STATUS_BIT_KHR : 0x0;
 
-    ret = vk->GetQueryPoolResults(s->hwctx->act_dev, pool->query_pool,
-                                  e->query_idx,
-                                  pool->nb_queries,
-                                  pool->qd_size, e->query_data,
-                                  pool->qd_size, qf);
-    if (ret != VK_SUCCESS)
-        return ret;
-
-    if (pool->query_statuses && pool->query_64bit) {
-        for (int i = 0; i < pool->query_statuses; i++) {
-            res = (res64[i] < res) || (res >= 0 && res64[i] > res) ?
-                  res64[i] : res;
-            res64 += pool->query_status_stride;
-        }
-    } else if (pool->query_statuses) {
-        for (int i = 0; i < pool->query_statuses; i++) {
-            res = (res32[i] < res) || (res >= 0 && res32[i] > res) ?
-                  res32[i] : res;
-            res32 += pool->query_status_stride;
-        }
-    }
-
     if (data)
         *data = e->query_data;
-    if (status)
-        *status = res;
 
-    return VK_SUCCESS;
+    return vk->GetQueryPoolResults(s->hwctx->act_dev, pool->query_pool,
+                                   e->query_idx,
+                                   pool->nb_queries,
+                                   pool->qd_size, e->query_data,
+                                   pool->qd_size, qf);
 }
 
 FFVkExecContext *ff_vk_exec_get(FFVkExecPool *pool)
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 371de8ab51..df5507d19f 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -357,10 +357,11 @@ FFVkExecContext *ff_vk_exec_get(FFVkExecPool *pool);
 
 /**
  * Performs nb_queries queries and returns their results and statuses.
- * Execution must have been waited on to produce valid results.
+ * 64_BIT and WITH_STATUS flags are ignored as 64_BIT must be specified via
+ * query_64bit in ff_vk_exec_pool_init() and WITH_STATUS is always enabled.
  */
 VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
-                              void **data, int64_t *status);
+                              void **data, VkQueryResultFlagBits flags);
 
 /**
  * Start/submit/wait an execution.



More information about the ffmpeg-cvslog mailing list