hwcontext_vulkan: remove linear+host_visible "fast" path

The idea was that it's faster to map linear images and copy them
via regular memcpy. This is a very niche use, plus very inconsistently
useful, as it would only really be faster on a few Intel GPUs.
Even then, using the non-cached memcpy would've been better.

Instead, scrap this code. Drivers are better at figuring out
what copy to use, and if we're host-mapping, it should actually be
just as fast, if not faster.
This commit is contained in:
Lynne 2023-02-18 14:55:14 +01:00
parent 48f85de0e7
commit 32fc36ee61
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464

View File

@ -2675,144 +2675,6 @@ static int vulkan_transfer_get_formats(AVHWFramesContext *hwfc,
return 0;
}
typedef struct VulkanMapping {
AVVkFrame *frame;
int flags;
} VulkanMapping;
static void vulkan_unmap_frame(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
{
VulkanMapping *map = hwmap->priv;
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
FFVulkanFunctions *vk = &p->vkfn;
/* Check if buffer needs flushing */
if ((map->flags & AV_HWFRAME_MAP_WRITE) &&
!(map->frame->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
VkResult ret;
VkMappedMemoryRange flush_ranges[AV_NUM_DATA_POINTERS] = { { 0 } };
for (int i = 0; i < planes; i++) {
flush_ranges[i].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
flush_ranges[i].memory = map->frame->mem[i];
flush_ranges[i].size = VK_WHOLE_SIZE;
}
ret = vk->FlushMappedMemoryRanges(hwctx->act_dev, planes,
flush_ranges);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to flush memory: %s\n",
vk_ret2str(ret));
}
}
for (int i = 0; i < planes; i++)
vk->UnmapMemory(hwctx->act_dev, map->frame->mem[i]);
av_free(map);
}
static int vulkan_map_frame_to_mem(AVHWFramesContext *hwfc, AVFrame *dst,
const AVFrame *src, int flags)
{
VkResult ret;
int err, nb_mem = 0, mapped_mem_count = 0, mem_planes = 0;
AVVkFrame *f = (AVVkFrame *)src->data[0];
AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
AVVulkanFramesContext *hwfctx = hwfc->hwctx;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
FFVulkanFunctions *vk = &p->vkfn;
VulkanMapping *map = av_mallocz(sizeof(VulkanMapping));
if (!map)
return AVERROR(EINVAL);
if (src->format != AV_PIX_FMT_VULKAN) {
av_log(hwfc, AV_LOG_ERROR, "Cannot map from pixel format %s!\n",
av_get_pix_fmt_name(src->format));
err = AVERROR(EINVAL);
goto fail;
}
if (!(f->flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ||
!(hwfctx->tiling == VK_IMAGE_TILING_LINEAR)) {
av_log(hwfc, AV_LOG_ERROR, "Unable to map frame, not host visible "
"and linear!\n");
err = AVERROR(EINVAL);
goto fail;
}
dst->width = src->width;
dst->height = src->height;
for (int i = 0; i < AV_NUM_DATA_POINTERS; i++)
nb_mem += !!f->mem[i];
for (int i = 0; i < nb_mem; i++) {
ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to map %ith frame memory: %s\n",
i, vk_ret2str(ret));
err = AVERROR_EXTERNAL;
goto fail;
}
mapped_mem_count++;
}
for (int i = 0; i < planes; i++)
dst->data[i] = dst->data[i] + f->offset[i];
/* Check if the memory contents matter */
if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) &&
!(f->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
VkMappedMemoryRange map_mem_ranges[AV_NUM_DATA_POINTERS] = { { 0 } };
for (int i = 0; i < nb_mem; i++) {
map_mem_ranges[i].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
map_mem_ranges[i].size = VK_WHOLE_SIZE;
map_mem_ranges[i].memory = f->mem[i];
}
ret = vk->InvalidateMappedMemoryRanges(hwctx->act_dev, nb_mem,
map_mem_ranges);
if (ret != VK_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to invalidate memory: %s\n",
vk_ret2str(ret));
err = AVERROR_EXTERNAL;
goto fail;
}
}
for (int i = 0; i < planes; i++) {
VkImageSubresource sub = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
};
VkSubresourceLayout layout;
vk->GetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, &layout);
dst->linesize[i] = layout.rowPitch;
}
map->frame = f;
map->flags = flags;
err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src,
&vulkan_unmap_frame, map);
if (err < 0)
goto fail;
return 0;
fail:
for (int i = 0; i < mapped_mem_count; i++)
vk->UnmapMemory(hwctx->act_dev, f->mem[i]);
av_free(map);
return err;
}
#if CONFIG_LIBDRM
static void vulkan_unmap_from_drm(AVHWFramesContext *hwfc, HWMapDescriptor *hwmap)
{
@ -3692,8 +3554,9 @@ static int vulkan_map_from(AVHWFramesContext *hwfc, AVFrame *dst,
#endif
#endif
default:
return vulkan_map_frame_to_mem(hwfc, dst, src, flags);
break;
}
return AVERROR(ENOSYS);
}
typedef struct ImageBuffer {
@ -4100,23 +3963,6 @@ static int vulkan_transfer_data(AVHWFramesContext *hwfc, const AVFrame *vkf,
if (swf->width > hwfc->width || swf->height > hwfc->height)
return AVERROR(EINVAL);
/* For linear, host visiable images */
if (fc->tiling == VK_IMAGE_TILING_LINEAR &&
f->flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
AVFrame *map = av_frame_alloc();
if (!map)
return AVERROR(ENOMEM);
map->format = swf->format;
err = vulkan_map_frame_to_mem(hwfc, map, vkf, AV_HWFRAME_MAP_WRITE);
if (err)
return err;
err = av_frame_copy((AVFrame *)(from ? swf : map), from ? map : swf);
av_frame_free(&map);
return err;
}
/* Create buffers */
for (int i = 0; i < planes; i++) {
size_t req_size;