Copy each plane aspect of multi-planar images separately on vulkan

This commit is contained in:
baldurk
2018-12-14 15:40:09 +00:00
parent 46b0dc6c6e
commit 4c7ed0cb3c
3 changed files with 384 additions and 43 deletions
+210 -43
View File
@@ -176,6 +176,44 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
// backing the array image only.
}
uint32_t planeCount = GetYUVPlaneCount(layout->format);
uint32_t horizontalPlaneShift = 0;
uint32_t verticalPlaneShift = 0;
if(planeCount > 1)
{
switch(layout->format)
{
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
horizontalPlaneShift = verticalPlaneShift = 1;
break;
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: horizontalPlaneShift = 1; break;
default: break;
}
}
VkFormat sizeFormat = GetDepthOnlyFormat(layout->format);
for(int a = 0; a < numLayers; a++)
@@ -184,16 +222,27 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
{
bufInfo.size = AlignUp(bufInfo.size, bufAlignment);
bufInfo.size += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, sizeFormat, m);
if(sizeFormat != layout->format)
if(planeCount > 1)
{
// need to consider each plane aspect separately. We simplify the calculation by just
// aligning up the width to a multiple of 4, that ensures each plane will start at a
// multiple of 4 because the rowpitch must be a multiple of 4
bufInfo.size += GetByteSize(AlignUp4(layout->extent.width), layout->extent.height,
layout->extent.depth, sizeFormat, m);
}
else
{
// if there's stencil and depth, allocate space for stencil
bufInfo.size = AlignUp(bufInfo.size, bufAlignment);
bufInfo.size += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, VK_FORMAT_S8_UINT, m);
layout->extent.depth, sizeFormat, m);
if(sizeFormat != layout->format)
{
// if there's stencil and depth, allocate space for stencil
bufInfo.size = AlignUp(bufInfo.size, bufAlignment);
bufInfo.size += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, VK_FORMAT_S8_UINT, m);
}
}
}
}
@@ -228,9 +277,21 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
if(IsStencilOnlyFormat(layout->format))
{
aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT;
}
else if(IsDepthOrStencilFormat(layout->format))
{
aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else if(planeCount > 1)
{
aspectFlags = VK_IMAGE_ASPECT_PLANE_0_BIT;
if(planeCount >= 2)
aspectFlags |= VK_IMAGE_ASPECT_PLANE_1_BIT;
if(planeCount >= 3)
aspectFlags |= VK_IMAGE_ASPECT_PLANE_2_BIT;
}
VkImageMemoryBarrier srcimBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -336,29 +397,58 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
extent,
};
bufOffset = AlignUp(bufOffset, bufAlignment);
region.bufferOffset = bufOffset;
bufOffset += GetByteSize(layout->extent.width, layout->extent.height, layout->extent.depth,
sizeFormat, m);
ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), realim, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
Unwrap(dstBuf), 1, &region);
if(sizeFormat != layout->format)
if(planeCount > 1)
{
// need to consider each plane aspect separately
for(uint32_t i = 0; i < planeCount; i++)
{
bufOffset = AlignUp(bufOffset, bufAlignment);
region.imageExtent = extent;
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT << i;
if(i > 0)
{
region.imageExtent.width >>= horizontalPlaneShift;
region.imageExtent.height >>= verticalPlaneShift;
}
bufOffset += GetPlaneByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, sizeFormat, m, i);
ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), realim,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(dstBuf),
1, &region);
}
}
else
{
// if we removed stencil from the format, copy that separately now.
bufOffset = AlignUp(bufOffset, bufAlignment);
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
bufOffset += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, VK_FORMAT_S8_UINT, m);
layout->extent.depth, sizeFormat, m);
ObjDisp(d)->CmdCopyImageToBuffer(
Unwrap(cmd), realim, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(dstBuf), 1, &region);
if(sizeFormat != layout->format)
{
// if we removed stencil from the format, copy that separately now.
bufOffset = AlignUp(bufOffset, bufAlignment);
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
bufOffset += GetByteSize(layout->extent.width, layout->extent.height,
layout->extent.depth, VK_FORMAT_S8_UINT, m);
ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), realim,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(dstBuf),
1, &region);
}
}
// update the extent for the next mip
@@ -1051,8 +1141,8 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W
VkExtent3D extent = c.extent;
VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
VkFormat fmt = c.format;
if(IsStencilOnlyFormat(fmt))
aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT;
else if(IsDepthOrStencilFormat(fmt))
@@ -1311,12 +1401,14 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VkInitialContents ini
{
if(initial.tag == VkInitialContents::ClearColorImage)
{
if(IsBlockFormat(m_ImageLayouts[id].format))
VkFormat format = m_ImageLayouts[id].format;
if(IsBlockFormat(format) || IsYUVFormat(format))
{
RDCWARN(
"Trying to clear a compressed image %llu - should have initial states or be "
"stripped.",
id);
"Trying to clear a compressed/YUV image %llu with format %s - should have initial "
"states or be stripped.",
id, ToStr(format).c_str());
return;
}
@@ -1671,10 +1763,59 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VkInitialContents ini
VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
VkFormat fmt = m_CreationInfo.m_Image[id].format;
uint32_t planeCount = GetYUVPlaneCount(fmt);
uint32_t horizontalPlaneShift = 0;
uint32_t verticalPlaneShift = 0;
if(IsStencilOnlyFormat(fmt))
{
aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT;
}
else if(IsDepthOrStencilFormat(fmt))
{
aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else if(planeCount > 1)
{
aspectFlags = VK_IMAGE_ASPECT_PLANE_0_BIT;
if(planeCount >= 2)
aspectFlags |= VK_IMAGE_ASPECT_PLANE_1_BIT;
if(planeCount >= 3)
aspectFlags |= VK_IMAGE_ASPECT_PLANE_2_BIT;
}
if(planeCount > 1)
{
switch(fmt)
{
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
horizontalPlaneShift = verticalPlaneShift = 1;
break;
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: horizontalPlaneShift = 1; break;
default: break;
}
}
VkImageMemoryBarrier dstimBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -1751,30 +1892,56 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VkInitialContents ini
extent,
};
bufOffset = AlignUp(bufOffset, bufAlignment);
region.bufferOffset = bufOffset;
VkFormat sizeFormat = GetDepthOnlyFormat(fmt);
// pass 0 for mip since we've already pre-downscaled extent
bufOffset += GetByteSize(extent.width, extent.height, extent.depth, sizeFormat, 0);
ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle<VkImage>(live),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
if(sizeFormat != fmt)
if(planeCount > 1)
{
// need to consider each plane aspect separately
for(uint32_t i = 0; i < planeCount; i++)
{
bufOffset = AlignUp(bufOffset, bufAlignment);
region.imageExtent = extent;
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT << i;
if(i > 0)
{
region.imageExtent.width >>= horizontalPlaneShift;
region.imageExtent.height >>= verticalPlaneShift;
}
bufOffset += GetPlaneByteSize(extent.width, extent.height, extent.depth, fmt, 0, i);
ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle<VkImage>(live),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
}
}
else
{
// if we removed stencil from the format, copy that separately now.
bufOffset = AlignUp(bufOffset, bufAlignment);
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
bufOffset += GetByteSize(extent.width, extent.height, extent.depth, VK_FORMAT_S8_UINT, 0);
VkFormat sizeFormat = GetDepthOnlyFormat(fmt);
// pass 0 for mip since we've already pre-downscaled extent
bufOffset += GetByteSize(extent.width, extent.height, extent.depth, sizeFormat, 0);
ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle<VkImage>(live),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
if(sizeFormat != fmt)
{
// if we removed stencil from the format, copy that separately now.
bufOffset = AlignUp(bufOffset, bufAlignment);
region.bufferOffset = bufOffset;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
bufOffset += GetByteSize(extent.width, extent.height, extent.depth, VK_FORMAT_S8_UINT, 0);
ObjDisp(cmd)->CmdCopyBufferToImage(Unwrap(cmd), Unwrap(buf), ToHandle<VkImage>(live),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
}
}
// update the extent for the next mip
+169
View File
@@ -493,6 +493,54 @@ uint32_t GetYUVNumRows(VkFormat f, uint32_t height)
return height;
}
VkFormat GetYUVViewPlaneFormat(VkFormat f, uint32_t plane)
{
switch(f)
{
case VK_FORMAT_G8B8G8R8_422_UNORM:
case VK_FORMAT_B8G8R8G8_422_UNORM:
case VK_FORMAT_R10X6_UNORM_PACK16:
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case VK_FORMAT_R12X4_UNORM_PACK16:
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case VK_FORMAT_G16B16G16R16_422_UNORM:
case VK_FORMAT_B16G16R16G16_422_UNORM: return f;
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return VK_FORMAT_R8_UNORM;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
return plane == 0 ? VK_FORMAT_R8_UNORM : VK_FORMAT_R8G8_UNORM;
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: return VK_FORMAT_R10X6_UNORM_PACK16;
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
return plane == 0 ? VK_FORMAT_R10X6_UNORM_PACK16 : VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return VK_FORMAT_R12X4_UNORM_PACK16;
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
return plane == 0 ? VK_FORMAT_R12X4_UNORM_PACK16 : VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return VK_FORMAT_R16_UNORM;
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
return plane == 0 ? VK_FORMAT_R16_UNORM : VK_FORMAT_R16G16_UNORM;
default: break;
}
return f;
}
VkFormat GetDepthOnlyFormat(VkFormat f)
{
switch(f)
@@ -940,6 +988,86 @@ uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat F
return ret;
}
uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format,
uint32_t mip, uint32_t plane)
{
switch(Format)
{
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth,
VK_FORMAT_R8G8_UNORM, mip);
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth,
VK_FORMAT_R16G16_UNORM, mip);
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R8G8_UNORM, mip);
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R16G16_UNORM, mip);
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth,
VK_FORMAT_R8_UNORM, mip);
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth,
VK_FORMAT_R16_UNORM, mip);
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R8_UNORM, mip);
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
if(plane == 0)
return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip);
else
return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R16_UNORM, mip);
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip);
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip);
default: break;
}
return GetByteSize(Width, Height, Depth, Format, mip);
}
ResourceFormat MakeResourceFormat(VkFormat fmt)
{
ResourceFormat ret;
@@ -3038,6 +3166,47 @@ TEST_CASE("Vulkan formats", "[format][vulkan]")
CHECK(yuvsizes[i++] == GetByteSize(width, height, 1, f, 0));
}
};
SECTION("GetPlaneByteSize for planar YUV formats")
{
const uint32_t width = 24, height = 24;
for(VkFormat f : {
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
})
{
INFO("Format is " << ToStr(f));
uint32_t planeCount = GetYUVPlaneCount(f);
CHECK(planeCount > 1);
uint32_t planeSum = 0;
for(uint32_t p = 0; p < planeCount; p++)
planeSum += GetPlaneByteSize(width, height, 1, f, 0, p);
CHECK(planeSum == GetByteSize(width, height, 1, f, 0));
}
}
};
#endif // ENABLED(ENABLE_UNIT_TESTS)
+5
View File
@@ -1226,6 +1226,11 @@ bool IsDoubleFormat(VkFormat f);
bool IsSIntFormat(VkFormat f);
bool IsYUVFormat(VkFormat f);
uint32_t GetYUVPlaneCount(VkFormat f);
uint32_t GetYUVNumRows(VkFormat f, uint32_t height);
VkFormat GetYUVViewPlaneFormat(VkFormat f, uint32_t plane);
VkFormat GetDepthOnlyFormat(VkFormat f);
uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip);
uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format,
uint32_t mip, uint32_t plane);