Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
d870e75c
F
Ffmpeg
项目概览
小白菜888
/
Ffmpeg
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
Ffmpeg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
d870e75c
编写于
5月 15, 2020
作者:
L
Lynne
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hwcontext_vulkan: split uploading and downloading contexts
This allows us to speed up only-uploading or only-downloading use cases.
上级
192997dd
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
66 addition
and
57 deletion
+66
-57
libavutil/hwcontext_vulkan.c
libavutil/hwcontext_vulkan.c
+66
-57
未找到文件。
libavutil/hwcontext_vulkan.c
浏览文件 @
d870e75c
...
...
@@ -72,10 +72,6 @@ typedef struct VulkanDevicePriv {
/* Debug callback */
VkDebugUtilsMessengerEXT
debug_ctx
;
/* Image transfers */
VulkanExecCtx
upload_ctx
;
VulkanExecCtx
download_ctx
;
/* Extensions */
uint64_t
extensions
;
...
...
@@ -89,6 +85,10 @@ typedef struct VulkanDevicePriv {
typedef
struct
VulkanFramesPriv
{
/* Image conversions */
VulkanExecCtx
conv_ctx
;
/* Image transfers */
VulkanExecCtx
upload_ctx
;
VulkanExecCtx
download_ctx
;
}
VulkanFramesPriv
;
typedef
struct
AVVkFrameInternal
{
...
...
@@ -732,11 +732,11 @@ fail:
return
AVERROR
(
ENOMEM
);
}
static
int
create_exec_ctx
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
,
static
int
create_exec_ctx
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
,
int
queue_family_index
,
int
num_queues
)
{
VkResult
ret
;
AVVulkanDeviceContext
*
hwctx
=
ctx
->
hwctx
;
AVVulkanDeviceContext
*
hwctx
=
hwfc
->
device_
ctx
->
hwctx
;
VkCommandPoolCreateInfo
cqueue_create
=
{
.
sType
=
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
,
...
...
@@ -763,7 +763,7 @@ static int create_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd,
ret
=
vkCreateCommandPool
(
hwctx
->
act_dev
,
&
cqueue_create
,
hwctx
->
alloc
,
&
cmd
->
pool
);
if
(
ret
!=
VK_SUCCESS
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Command pool creation failure: %s
\n
"
,
av_log
(
hwfc
,
AV_LOG_ERROR
,
"Command pool creation failure: %s
\n
"
,
vk_ret2str
(
ret
));
return
AVERROR_EXTERNAL
;
}
...
...
@@ -773,7 +773,7 @@ static int create_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd,
/* Allocate command buffer */
ret
=
vkAllocateCommandBuffers
(
hwctx
->
act_dev
,
&
cbuf_create
,
cmd
->
bufs
);
if
(
ret
!=
VK_SUCCESS
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Command buffer alloc failure: %s
\n
"
,
av_log
(
hwfc
,
AV_LOG_ERROR
,
"Command buffer alloc failure: %s
\n
"
,
vk_ret2str
(
ret
));
return
AVERROR_EXTERNAL
;
}
...
...
@@ -787,9 +787,9 @@ static int create_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd,
return
0
;
}
static
void
free_exec_ctx
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
)
static
void
free_exec_ctx
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
)
{
AVVulkanDeviceContext
*
hwctx
=
ctx
->
hwctx
;
AVVulkanDeviceContext
*
hwctx
=
hwfc
->
device_
ctx
->
hwctx
;
/* Make sure all queues have finished executing */
for
(
int
i
=
0
;
i
<
cmd
->
nb_queues
;
i
++
)
{
...
...
@@ -819,12 +819,12 @@ static void free_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd)
av_freep
(
&
cmd
->
queues
);
}
static
VkCommandBuffer
get_buf_exec_ctx
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
)
static
VkCommandBuffer
get_buf_exec_ctx
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
)
{
return
cmd
->
bufs
[
cmd
->
cur_queue_idx
];
}
static
void
unref_exec_ctx_deps
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
)
static
void
unref_exec_ctx_deps
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
)
{
VulkanQueueCtx
*
q
=
&
cmd
->
queues
[
cmd
->
cur_queue_idx
];
...
...
@@ -833,10 +833,10 @@ static void unref_exec_ctx_deps(AVHWDeviceContext *ctx, VulkanExecCtx *cmd)
q
->
nb_buf_deps
=
0
;
}
static
int
wait_start_exec_ctx
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
)
static
int
wait_start_exec_ctx
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
)
{
VkResult
ret
;
AVVulkanDeviceContext
*
hwctx
=
ctx
->
hwctx
;
AVVulkanDeviceContext
*
hwctx
=
hwfc
->
device_
ctx
->
hwctx
;
VulkanQueueCtx
*
q
=
&
cmd
->
queues
[
cmd
->
cur_queue_idx
];
VkCommandBufferBeginInfo
cmd_start
=
{
...
...
@@ -852,7 +852,7 @@ static int wait_start_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd)
ret
=
vkCreateFence
(
hwctx
->
act_dev
,
&
fence_spawn
,
hwctx
->
alloc
,
&
q
->
fence
);
if
(
ret
!=
VK_SUCCESS
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Failed to queue frame fence: %s
\n
"
,
av_log
(
hwfc
,
AV_LOG_ERROR
,
"Failed to queue frame fence: %s
\n
"
,
vk_ret2str
(
ret
));
return
AVERROR_EXTERNAL
;
}
...
...
@@ -862,11 +862,11 @@ static int wait_start_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd)
}
/* Discard queue dependencies */
unref_exec_ctx_deps
(
ctx
,
cmd
);
unref_exec_ctx_deps
(
hwfc
,
cmd
);
ret
=
vkBeginCommandBuffer
(
cmd
->
bufs
[
cmd
->
cur_queue_idx
],
&
cmd_start
);
if
(
ret
!=
VK_SUCCESS
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Unable to init command buffer: %s
\n
"
,
av_log
(
hwfc
,
AV_LOG_ERROR
,
"Unable to init command buffer: %s
\n
"
,
vk_ret2str
(
ret
));
return
AVERROR_EXTERNAL
;
}
...
...
@@ -874,7 +874,7 @@ static int wait_start_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd)
return
0
;
}
static
int
add_buf_dep_exec_ctx
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
,
static
int
add_buf_dep_exec_ctx
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
,
AVBufferRef
*
const
*
deps
,
int
nb_deps
)
{
AVBufferRef
**
dst
;
...
...
@@ -900,11 +900,11 @@ static int add_buf_dep_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd,
return
0
;
err:
unref_exec_ctx_deps
(
ctx
,
cmd
);
unref_exec_ctx_deps
(
hwfc
,
cmd
);
return
AVERROR
(
ENOMEM
);
}
static
int
submit_exec_ctx
(
AVHW
DeviceContext
*
ctx
,
VulkanExecCtx
*
cmd
,
static
int
submit_exec_ctx
(
AVHW
FramesContext
*
hwfc
,
VulkanExecCtx
*
cmd
,
VkSubmitInfo
*
s_info
,
int
synchronous
)
{
VkResult
ret
;
...
...
@@ -912,9 +912,9 @@ static int submit_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd,
ret
=
vkEndCommandBuffer
(
cmd
->
bufs
[
cmd
->
cur_queue_idx
]);
if
(
ret
!=
VK_SUCCESS
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Unable to finish command buffer: %s
\n
"
,
av_log
(
hwfc
,
AV_LOG_ERROR
,
"Unable to finish command buffer: %s
\n
"
,
vk_ret2str
(
ret
));
unref_exec_ctx_deps
(
ctx
,
cmd
);
unref_exec_ctx_deps
(
hwfc
,
cmd
);
return
AVERROR_EXTERNAL
;
}
...
...
@@ -923,17 +923,17 @@ static int submit_exec_ctx(AVHWDeviceContext *ctx, VulkanExecCtx *cmd,
ret
=
vkQueueSubmit
(
q
->
queue
,
1
,
s_info
,
q
->
fence
);
if
(
ret
!=
VK_SUCCESS
)
{
unref_exec_ctx_deps
(
ctx
,
cmd
);
unref_exec_ctx_deps
(
hwfc
,
cmd
);
return
AVERROR_EXTERNAL
;
}
q
->
was_synchronous
=
synchronous
;
if
(
synchronous
)
{
AVVulkanDeviceContext
*
hwctx
=
ctx
->
hwctx
;
AVVulkanDeviceContext
*
hwctx
=
hwfc
->
device_
ctx
->
hwctx
;
vkWaitForFences
(
hwctx
->
act_dev
,
1
,
&
q
->
fence
,
VK_TRUE
,
UINT64_MAX
);
vkResetFences
(
hwctx
->
act_dev
,
1
,
&
q
->
fence
);
unref_exec_ctx_deps
(
ctx
,
cmd
);
unref_exec_ctx_deps
(
hwfc
,
cmd
);
}
else
{
/* Rotate queues */
cmd
->
cur_queue_idx
=
(
cmd
->
cur_queue_idx
+
1
)
%
cmd
->
nb_queues
;
}
...
...
@@ -946,8 +946,6 @@ static void vulkan_device_free(AVHWDeviceContext *ctx)
VulkanDevicePriv
*
p
=
ctx
->
internal
->
priv
;
AVVulkanDeviceContext
*
hwctx
=
ctx
->
hwctx
;
free_exec_ctx
(
ctx
,
&
p
->
cmd
);
vkDestroyDevice
(
hwctx
->
act_dev
,
hwctx
->
alloc
);
if
(
p
->
debug_ctx
)
{
...
...
@@ -1062,7 +1060,6 @@ end:
static
int
vulkan_device_init
(
AVHWDeviceContext
*
ctx
)
{
int
err
;
uint32_t
queue_num
;
AVVulkanDeviceContext
*
hwctx
=
ctx
->
hwctx
;
VulkanDevicePriv
*
p
=
ctx
->
internal
->
priv
;
...
...
@@ -1105,12 +1102,6 @@ if (n >= queue_num) {
(
hwctx
->
queue_family_comp_index
!=
hwctx
->
queue_family_tx_index
))
p
->
qfs
[
p
->
num_qfs
++
]
=
hwctx
->
queue_family_comp_index
;
/* Create exec context - if there's something invalid this will error out */
err
=
create_exec_ctx
(
ctx
,
&
p
->
cmd
,
hwctx
->
queue_family_tx_index
,
GET_QUEUE_COUNT
(
hwctx
,
0
,
0
,
1
));
if
(
err
)
return
err
;
/* Get device capabilities */
vkGetPhysicalDeviceMemoryProperties
(
hwctx
->
phys_dev
,
&
p
->
mprops
);
...
...
@@ -1431,7 +1422,6 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
uint32_t
dst_qf
;
VkImageLayout
new_layout
;
VkAccessFlags
new_access
;
AVHWDeviceContext
*
ctx
=
hwfc
->
device_ctx
;
const
int
planes
=
av_pix_fmt_count_planes
(
hwfc
->
sw_format
);
VkImageMemoryBarrier
img_bar
[
AV_NUM_DATA_POINTERS
]
=
{
0
};
...
...
@@ -1467,7 +1457,7 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
break
;
}
if
((
err
=
wait_start_exec_ctx
(
ctx
,
ectx
)))
if
((
err
=
wait_start_exec_ctx
(
hwfc
,
ectx
)))
return
err
;
/* Change the image layout to something more optimal for writes.
...
...
@@ -1490,12 +1480,12 @@ static int prepare_frame(AVHWFramesContext *hwfc, VulkanExecCtx *ectx,
frame
->
access
[
i
]
=
img_bar
[
i
].
dstAccessMask
;
}
vkCmdPipelineBarrier
(
get_buf_exec_ctx
(
ctx
,
ectx
),
vkCmdPipelineBarrier
(
get_buf_exec_ctx
(
hwfc
,
ectx
),
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
,
VK_PIPELINE_STAGE_TRANSFER_BIT
,
0
,
0
,
NULL
,
0
,
NULL
,
planes
,
img_bar
);
return
submit_exec_ctx
(
ctx
,
ectx
,
&
s_info
,
0
);
return
submit_exec_ctx
(
hwfc
,
ectx
,
&
s_info
,
0
);
}
static
int
create_frame
(
AVHWFramesContext
*
hwfc
,
AVVkFrame
**
frame
,
...
...
@@ -1687,7 +1677,9 @@ static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
{
VulkanFramesPriv
*
fp
=
hwfc
->
internal
->
priv
;
free_exec_ctx
(
hwfc
->
device_ctx
,
&
fp
->
conv_ctx
);
free_exec_ctx
(
hwfc
,
&
fp
->
conv_ctx
);
free_exec_ctx
(
hwfc
,
&
fp
->
upload_ctx
);
free_exec_ctx
(
hwfc
,
&
fp
->
download_ctx
);
}
static
int
vulkan_frames_init
(
AVHWFramesContext
*
hwfc
)
...
...
@@ -1706,19 +1698,28 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
if
(
!
hwctx
->
usage
)
hwctx
->
usage
=
DEFAULT_USAGE_FLAGS
;
err
=
create_exec_ctx
(
hwfc
->
device_ctx
,
&
fp
->
conv_ctx
,
err
=
create_exec_ctx
(
hwfc
,
&
fp
->
conv_ctx
,
dev_hwctx
->
queue_family_comp_index
,
GET_QUEUE_COUNT
(
dev_hwctx
,
0
,
1
,
0
));
if
(
err
)
return
err
;
goto
fail
;
err
=
create_exec_ctx
(
hwfc
,
&
fp
->
upload_ctx
,
dev_hwctx
->
queue_family_tx_index
,
GET_QUEUE_COUNT
(
dev_hwctx
,
0
,
0
,
1
));
if
(
err
)
goto
fail
;
err
=
create_exec_ctx
(
hwfc
,
&
fp
->
download_ctx
,
dev_hwctx
->
queue_family_tx_index
,
1
);
if
(
err
)
goto
fail
;
/* Test to see if allocation will fail */
err
=
create_frame
(
hwfc
,
&
f
,
hwctx
->
tiling
,
hwctx
->
usage
,
hwctx
->
create_pnext
);
if
(
err
)
{
free_exec_ctx
(
hwfc
->
device_ctx
,
&
fp
->
conv_ctx
);
return
err
;
}
if
(
err
)
goto
fail
;
vulkan_frame_free
(
hwfc
,
(
uint8_t
*
)
f
);
...
...
@@ -1729,12 +1730,19 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
hwfc
,
vulkan_pool_alloc
,
NULL
);
if
(
!
hwfc
->
internal
->
pool_internal
)
{
free_exec_ctx
(
hwfc
->
device_ctx
,
&
fp
->
conv_ctx
);
return
AVERROR
(
ENOMEM
)
;
err
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
}
return
0
;
fail:
free_exec_ctx
(
hwfc
,
&
fp
->
conv_ctx
);
free_exec_ctx
(
hwfc
,
&
fp
->
upload_ctx
);
free_exec_ctx
(
hwfc
,
&
fp
->
download_ctx
);
return
err
;
}
static
int
vulkan_get_buffer
(
AVHWFramesContext
*
hwfc
,
AVFrame
*
frame
)
...
...
@@ -2776,13 +2784,13 @@ static int unmap_buffers(AVHWDeviceContext *ctx, AVBufferRef **bufs,
return
err
;
}
static
int
transfer_image_buf
(
AVHW
DeviceContext
*
ctx
,
const
AVFrame
*
f
,
static
int
transfer_image_buf
(
AVHW
FramesContext
*
hwfc
,
const
AVFrame
*
f
,
AVBufferRef
**
bufs
,
const
int
*
buf_stride
,
int
w
,
int
h
,
enum
AVPixelFormat
pix_fmt
,
int
to_buf
)
{
int
err
;
AVVkFrame
*
frame
=
(
AVVkFrame
*
)
f
->
data
[
0
];
Vulkan
DevicePriv
*
s
=
ctx
->
internal
->
priv
;
Vulkan
FramesPriv
*
fp
=
hwfc
->
internal
->
priv
;
int
bar_num
=
0
;
VkPipelineStageFlagBits
sem_wait_dst
[
AV_NUM_DATA_POINTERS
];
...
...
@@ -2791,7 +2799,8 @@ static int transfer_image_buf(AVHWDeviceContext *ctx, const AVFrame *f,
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
pix_fmt
);
VkImageMemoryBarrier
img_bar
[
AV_NUM_DATA_POINTERS
]
=
{
0
};
VkCommandBuffer
cmd_buf
=
get_buf_exec_ctx
(
ctx
,
&
s
->
cmd
);
VulkanExecCtx
*
ectx
=
to_buf
?
&
fp
->
download_ctx
:
&
fp
->
upload_ctx
;
VkCommandBuffer
cmd_buf
=
get_buf_exec_ctx
(
hwfc
,
ectx
);
VkSubmitInfo
s_info
=
{
.
sType
=
VK_STRUCTURE_TYPE_SUBMIT_INFO
,
...
...
@@ -2802,7 +2811,7 @@ static int transfer_image_buf(AVHWDeviceContext *ctx, const AVFrame *f,
.
waitSemaphoreCount
=
planes
,
};
if
((
err
=
wait_start_exec_ctx
(
ctx
,
&
s
->
cmd
)))
if
((
err
=
wait_start_exec_ctx
(
hwfc
,
ectx
)))
return
err
;
/* Change the image layout to something more optimal for transfers */
...
...
@@ -2879,14 +2888,14 @@ static int transfer_image_buf(AVHWDeviceContext *ctx, const AVFrame *f,
for
(
ref
=
0
;
ref
<
AV_NUM_DATA_POINTERS
;
ref
++
)
{
if
(
!
f
->
buf
[
ref
])
break
;
if
((
err
=
add_buf_dep_exec_ctx
(
hwfc
,
&
s
->
cmd
,
&
f
->
buf
[
ref
],
1
)))
if
((
err
=
add_buf_dep_exec_ctx
(
hwfc
,
ectx
,
&
f
->
buf
[
ref
],
1
)))
return
err
;
}
if
(
ref
&&
(
err
=
add_buf_dep_exec_ctx
(
hwfc
,
&
s
->
cmd
,
bufs
,
planes
)))
if
(
ref
&&
(
err
=
add_buf_dep_exec_ctx
(
hwfc
,
ectx
,
bufs
,
planes
)))
return
err
;
return
submit_exec_ctx
(
hwfc
,
&
s
->
cmd
,
&
s_info
,
!
ref
);
return
submit_exec_ctx
(
hwfc
,
ectx
,
&
s_info
,
!
ref
);
}
else
{
return
submit_exec_ctx
(
hwfc
,
&
s
->
cmd
,
&
s_info
,
1
);
return
submit_exec_ctx
(
hwfc
,
ectx
,
&
s_info
,
1
);
}
}
...
...
@@ -2955,7 +2964,7 @@ static int vulkan_transfer_data_from_mem(AVHWFramesContext *hwfc, AVFrame *dst,
goto
end
;
/* Copy buffers to image */
err
=
transfer_image_buf
(
dev_ctx
,
dst
,
bufs
,
tmp
.
linesize
,
err
=
transfer_image_buf
(
hwfc
,
dst
,
bufs
,
tmp
.
linesize
,
src
->
width
,
src
->
height
,
src
->
format
,
0
);
end:
...
...
@@ -3100,7 +3109,7 @@ static int vulkan_transfer_data_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
}
/* Copy image to buffer */
if
((
err
=
transfer_image_buf
(
dev_ctx
,
src
,
bufs
,
tmp
.
linesize
,
if
((
err
=
transfer_image_buf
(
hwfc
,
src
,
bufs
,
tmp
.
linesize
,
dst
->
width
,
dst
->
height
,
dst
->
format
,
1
)))
goto
end
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录