summaryrefslogtreecommitdiff
path: root/libavutil
diff options
context:
space:
mode:
authorLynne <dev@lynne.ee>2020-05-10 22:00:38 +0100
committerLynne <dev@lynne.ee>2020-05-10 23:20:49 +0100
commitfc99a24782fb2b763b0ea37757561d531272195e (patch)
treedc4589de7182a425104311a3ba8be4ba352c6272 /libavutil
parent875c1707e5f6287a6dabc7bc2dc5e1a9f3dc811b (diff)
hwcontext_vulkan: convert to general layout and transfer queue when exporting
The specs note that images should be in the GENERAL layout when exporting for maximum compatibility. CUDA exported images are handled differently, and the queue is the same, so we don't need to do that there.
Diffstat (limited to 'libavutil')
-rw-r--r--libavutil/hwcontext_vulkan.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index df738457c1..a5983f2735 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -1225,12 +1225,14 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
enum PrepMode {
PREP_MODE_WRITE,
PREP_MODE_RO_SHADER,
+ PREP_MODE_EXTERNAL_EXPORT,
};
static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
AVVkFrame *frame, enum PrepMode pmode)
{
VkResult ret;
+ uint32_t dst_qf;
VkImageLayout new_layout;
VkAccessFlags new_access;
AVHWDeviceContext *ctx = hwfc->device_ctx;
@@ -1244,6 +1246,8 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};
+ VkPipelineStageFlagBits wait_st = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+
VkSubmitInfo s_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.commandBufferCount = 1,
@@ -1257,10 +1261,20 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
case PREP_MODE_WRITE:
new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
new_access = VK_ACCESS_TRANSFER_WRITE_BIT;
+ dst_qf = VK_QUEUE_FAMILY_IGNORED;
break;
case PREP_MODE_RO_SHADER:
new_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
new_access = VK_ACCESS_TRANSFER_READ_BIT;
+ dst_qf = VK_QUEUE_FAMILY_IGNORED;
+ break;
+ case PREP_MODE_EXTERNAL_EXPORT:
+ new_layout = VK_IMAGE_LAYOUT_GENERAL;
+ new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
+ dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
+ s_info.pWaitSemaphores = &frame->sem;
+ s_info.pWaitDstStageMask = &wait_st;
+ s_info.waitSemaphoreCount = 1;
break;
}
@@ -1278,7 +1292,7 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
img_bar[i].oldLayout = frame->layout[i];
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].dstQueueFamilyIndex = dst_qf;
img_bar[i].image = frame->img[i];
img_bar[i].subresourceRange.levelCount = 1;
img_bar[i].subresourceRange.layerCount = 1;
@@ -2288,6 +2302,10 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst,
if (!drm_desc)
return AVERROR(ENOMEM);
+ err = prepare_frame(hwfc, &p->cmd, f, PREP_MODE_EXTERNAL_EXPORT);
+ if (err < 0)
+ goto end;
+
err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, &vulkan_unmap_to_drm, drm_desc);
if (err < 0)
goto end;