summaryrefslogtreecommitdiff
path: root/libavutil/hwcontext_vulkan.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavutil/hwcontext_vulkan.c')
-rw-r--r--libavutil/hwcontext_vulkan.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 51fdbd2489..6c2372f7fb 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -1139,12 +1139,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
return 0;
}
-static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
+enum PrepMode {
+ PREP_MODE_WRITE,
+ PREP_MODE_RO_SHADER,
+};
+
+static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
+ AVVkFrame *frame, enum PrepMode pmode)
{
VkResult ret;
+ VkImageLayout new_layout;
+ VkAccessFlags new_access;
AVHWDeviceContext *ctx = hwfc->device_ctx;
AVVulkanDeviceContext *hwctx = ctx->hwctx;
- VulkanFramesPriv *s = hwfc->internal->priv;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 };
@@ -1157,13 +1164,24 @@ static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
VkSubmitInfo s_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.commandBufferCount = 1,
- .pCommandBuffers = &s->cmd.buf,
+ .pCommandBuffers = &ectx->buf,
.pSignalSemaphores = frame->sem,
.signalSemaphoreCount = planes,
};
- ret = vkBeginCommandBuffer(s->cmd.buf, &cmd_start);
+ switch (pmode) {
+ case PREP_MODE_WRITE:
+ new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
+ break;
+ case PREP_MODE_RO_SHADER:
+ new_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ new_access = VK_ACCESS_TRANSFER_READ_BIT;
+ break;
+ }
+
+ ret = vkBeginCommandBuffer(ectx->buf, &cmd_start);
if (ret != VK_SUCCESS)
return AVERROR_EXTERNAL;
@@ -1173,9 +1191,9 @@ static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
for (int i = 0; i < planes; i++) {
img_bar[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
img_bar[i].srcAccessMask = 0x0;
- img_bar[i].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ img_bar[i].dstAccessMask = new_access;
img_bar[i].oldLayout = frame->layout[i];
- img_bar[i].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ img_bar[i].newLayout = new_layout;
img_bar[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
img_bar[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
img_bar[i].image = frame->img[i];
@@ -1187,20 +1205,20 @@ static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
frame->access[i] = img_bar[i].dstAccessMask;
}
- vkCmdPipelineBarrier(s->cmd.buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ vkCmdPipelineBarrier(ectx->buf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
0, NULL, 0, NULL, planes, img_bar);
- ret = vkEndCommandBuffer(s->cmd.buf);
+ ret = vkEndCommandBuffer(ectx->buf);
if (ret != VK_SUCCESS)
return AVERROR_EXTERNAL;
- ret = vkQueueSubmit(s->cmd.queue, 1, &s_info, s->cmd.fence);
+ ret = vkQueueSubmit(ectx->queue, 1, &s_info, ectx->fence);
if (ret != VK_SUCCESS) {
return AVERROR_EXTERNAL;
} else {
- vkWaitForFences(hwctx->act_dev, 1, &s->cmd.fence, VK_TRUE, UINT64_MAX);
- vkResetFences(hwctx->act_dev, 1, &s->cmd.fence);
+ vkWaitForFences(hwctx->act_dev, 1, &ectx->fence, VK_TRUE, UINT64_MAX);
+ vkResetFences(hwctx->act_dev, 1, &ectx->fence);
}
return 0;
@@ -1371,7 +1389,7 @@ static AVBufferRef *vulkan_pool_alloc(void *opaque, int size)
if (err)
goto fail;
- err = prepare_frame(hwfc, f);
+ err = prepare_frame(hwfc, &p->cmd, f, PREP_MODE_WRITE);
if (err)
goto fail;
@@ -1775,7 +1793,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
/* We'd import a semaphore onto the one we created using
* vkImportSemaphoreFdKHR but unfortunately neither DRM nor VAAPI
* offer us anything we could import and sync with, so instead
- * leave the semaphore unsignalled and enjoy the validation spam. */
+ * just signal the semaphore we created. */
f->layout[i] = image_create_info.initialLayout;
f->access[i] = 0x0;
@@ -1796,6 +1814,13 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
return AVERROR_EXTERNAL;
}
+ /* NOTE: This is completely uneccesary and unneeded once we can import
+ * semaphores from DRM. Otherwise we have to activate the semaphores.
+ * We're reusing the exec context that's also used for uploads/downloads. */
+ err = prepare_frame(hwfc, &p->cmd, f, PREP_MODE_RO_SHADER);
+ if (err)
+ goto fail;
+
*frame = f;
return 0;