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.
This commit is contained in:
parent
3415e0533f
commit
5e9845f11e
@ -294,6 +294,7 @@ void ff_vk_decode_flush(AVCodecContext *avctx)
|
|||||||
|
|
||||||
VkCommandBuffer cmd_buf;
|
VkCommandBuffer cmd_buf;
|
||||||
FFVkExecContext *exec = ff_vk_exec_get(&dec->exec_pool);
|
FFVkExecContext *exec = ff_vk_exec_get(&dec->exec_pool);
|
||||||
|
int had_submission = exec->had_submission;
|
||||||
ff_vk_exec_start(&ctx->s, exec);
|
ff_vk_exec_start(&ctx->s, exec);
|
||||||
cmd_buf = exec->buf;
|
cmd_buf = exec->buf;
|
||||||
|
|
||||||
@ -301,6 +302,11 @@ void ff_vk_decode_flush(AVCodecContext *avctx)
|
|||||||
vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
|
vk->CmdControlVideoCodingKHR(cmd_buf, &decode_ctrl);
|
||||||
vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
|
vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
|
||||||
ff_vk_exec_submit(&ctx->s, exec);
|
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,
|
int ff_vk_decode_frame(AVCodecContext *avctx,
|
||||||
@ -348,19 +354,20 @@ int ff_vk_decode_frame(AVCodecContext *avctx,
|
|||||||
cur_vk_ref[0].slotIndex = -1;
|
cur_vk_ref[0].slotIndex = -1;
|
||||||
decode_start.referenceSlotCount++;
|
decode_start.referenceSlotCount++;
|
||||||
|
|
||||||
if (dec->exec_pool.nb_queries) {
|
if (dec->exec_pool.nb_queries && exec->had_submission) {
|
||||||
int64_t prev_sub_res = 0;
|
uint32_t *result;
|
||||||
ff_vk_exec_wait(&ctx->s, exec);
|
ret = ff_vk_exec_get_query(&ctx->s, exec, (void **)&result,
|
||||||
ret = ff_vk_exec_get_query(&ctx->s, exec, NULL, &prev_sub_res);
|
VK_QUERY_RESULT_WAIT_BIT);
|
||||||
if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
|
if (ret != VK_NOT_READY && ret != VK_SUCCESS) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
|
av_log(avctx, AV_LOG_ERROR, "Unable to perform query: %s!\n",
|
||||||
ff_vk_ret2str(ret));
|
ff_vk_ret2str(ret));
|
||||||
return AVERROR_EXTERNAL;
|
return AVERROR_EXTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == VK_SUCCESS)
|
av_log(avctx,
|
||||||
av_log(avctx, prev_sub_res < 0 ? AV_LOG_ERROR : AV_LOG_DEBUG,
|
result[0] != VK_QUERY_RESULT_STATUS_COMPLETE_KHR ?
|
||||||
"Result of previous frame decoding: %"PRId64"\n", prev_sub_res);
|
AV_LOG_ERROR : AV_LOG_DEBUG,
|
||||||
|
"Result of previous frame decoding: %u\n", result[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_buf = (FFVkBuffer *)vp->slices_buf->data;
|
sd_buf = (FFVkBuffer *)vp->slices_buf->data;
|
||||||
|
@ -433,19 +433,12 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
|
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;
|
FFVulkanFunctions *vk = &s->vkfn;
|
||||||
const FFVkExecPool *pool = e->parent;
|
const FFVkExecPool *pool = e->parent;
|
||||||
|
VkQueryResultFlags qf = flags & ~(VK_QUERY_RESULT_64_BIT |
|
||||||
int32_t *res32 = e->query_data;
|
VK_QUERY_RESULT_WITH_STATUS_BIT_KHR);
|
||||||
int64_t *res64 = e->query_data;
|
|
||||||
int64_t res = 0;
|
|
||||||
VkQueryResultFlags qf = 0;
|
|
||||||
|
|
||||||
if (!e->had_submission)
|
|
||||||
return VK_INCOMPLETE;
|
|
||||||
|
|
||||||
if (!e->query_data) {
|
if (!e->query_data) {
|
||||||
av_log(s, AV_LOG_ERROR, "Requested a query with a NULL query_data pointer!\n");
|
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 ?
|
qf |= pool->query_statuses ?
|
||||||
VK_QUERY_RESULT_WITH_STATUS_BIT_KHR : 0x0;
|
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)
|
if (data)
|
||||||
*data = e->query_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)
|
FFVkExecContext *ff_vk_exec_get(FFVkExecPool *pool)
|
||||||
|
@ -357,10 +357,11 @@ FFVkExecContext *ff_vk_exec_get(FFVkExecPool *pool);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs nb_queries queries and returns their results and statuses.
|
* 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,
|
VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
|
||||||
void **data, int64_t *status);
|
void **data, VkQueryResultFlagBits flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start/submit/wait an execution.
|
* Start/submit/wait an execution.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user