hwcontext_vulkan: fix BGRA/BGR0 images

The fix was a lot simpler than I thought it was.
This commit is contained in:
Lynne
2026-06-12 09:54:36 +09:00
parent 8a10a8a03e
commit 03be563053
3 changed files with 22 additions and 20 deletions
+14 -2
View File
@@ -432,13 +432,13 @@ static const struct FFVkFormatEntry {
{ VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GRAYF32, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R32_SFLOAT } },
/* RGB formats */
// { VK_FORMAT_B8G8R8A8_UNORM, AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
{ VK_FORMAT_R8G8B8A8_UNORM, AV_PIX_FMT_BGRA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
{ VK_FORMAT_R8G8B8A8_UNORM, AV_PIX_FMT_RGBA, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
{ VK_FORMAT_R8G8B8_UNORM, AV_PIX_FMT_RGB24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8_UNORM } },
{ VK_FORMAT_B8G8R8_UNORM, AV_PIX_FMT_BGR24, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8_UNORM } },
{ VK_FORMAT_R16G16B16_UNORM, AV_PIX_FMT_RGB48, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16_UNORM } },
{ VK_FORMAT_R16G16B16A16_UNORM, AV_PIX_FMT_RGBA64, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R16G16B16A16_UNORM } },
// { VK_FORMAT_B8G8R8A8_UNORM, AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_B8G8R8A8_UNORM } },
{ VK_FORMAT_R8G8B8A8_UNORM, AV_PIX_FMT_BGR0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
{ VK_FORMAT_R8G8B8A8_UNORM, AV_PIX_FMT_RGB0, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_R8G8B8A8_UNORM } },
{ VK_FORMAT_A2R10G10B10_UNORM_PACK32, AV_PIX_FMT_X2RGB10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } },
{ VK_FORMAT_A2B10G10R10_UNORM_PACK32, AV_PIX_FMT_X2BGR10, VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 1, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } },
@@ -3424,6 +3424,18 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
VK_SHARING_MODE_EXCLUSIVE,
};
/* The DRM fourcc fixes a specific channel order (f.ex ARGB8888 maps to
* B8G8R8A8), but image views are always created from the destination
* frames context sw_format (like how bgra maps to R8G8B8A8). For a
* single plane layer, create the image with the sw_format's compatible
* VkFormat so the image and its views agree without a mutable format
* list, the format query below validates this */
if (planes == 1) {
const VkFormat *sw_vkfmts = av_vkfmt_from_pixfmt(hwfc->sw_format);
if (sw_vkfmts && sw_vkfmts[i] != VK_FORMAT_UNDEFINED)
create_info.format = sw_vkfmts[i];
}
/* Image format verification */
VkExternalImageFormatProperties ext_props = {
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
+8
View File
@@ -1618,6 +1618,14 @@ void ff_vk_set_perm(enum AVPixelFormat pix_fmt, int lut[4], int inv)
lut[2] = 1;
lut[3] = 3;
break;
case AV_PIX_FMT_BGRA:
case AV_PIX_FMT_BGR0:
/* Stored in RGBA images, so reverse them */
lut[0] = 2;
lut[1] = 1;
lut[2] = 0;
lut[3] = 3;
break;
default:
lut[0] = 0;
lut[1] = 1;
-18
View File
@@ -1628,24 +1628,6 @@ static int compile(SwsContext *sws, const SwsOpList *ops, SwsCompiledOp *out,
if (err < 0)
goto fail;
if (ops->src.format == AV_PIX_FMT_BGR0 ||
ops->src.format == AV_PIX_FMT_BGRA ||
ops->dst.format == AV_PIX_FMT_BGR0 ||
ops->dst.format == AV_PIX_FMT_BGRA) {
VkFormatProperties2 prop = {
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
};
FFVulkanFunctions *vk = &s->vkctx.vkfn;
vk->GetPhysicalDeviceFormatProperties2(s->vkctx.hwctx->phys_dev,
VK_FORMAT_B8G8R8A8_UNORM,
&prop);
if (!(prop.formatProperties.optimalTilingFeatures &
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT)) {
err = AVERROR(ENOTSUP);
goto fail;
}
}
if (glsl) {
err = AVERROR(ENOTSUP);
#if CONFIG_LIBSHADERC || CONFIG_LIBGLSLANG