mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Copy each plane aspect of multi-planar images separately on vulkan
This commit is contained in:
@@ -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, ®ion);
|
||||
|
||||
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, ®ion);
|
||||
}
|
||||
}
|
||||
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, ®ion);
|
||||
|
||||
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, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
// 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, ®ion);
|
||||
|
||||
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, ®ion);
|
||||
}
|
||||
}
|
||||
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, ®ion);
|
||||
|
||||
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, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
// update the extent for the next mip
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user