Add video texture format YUY2

This commit is contained in:
Wojtek Figat
2024-04-25 10:26:23 +02:00
parent ebe05d4a51
commit 3ebf73ec22
8 changed files with 49 additions and 74 deletions

View File

@@ -553,6 +553,11 @@ API_ENUM() enum class PixelFormat : uint32
/// </summary>
ASTC_10x10_UNorm_sRGB = 107,
/// <summary>
/// Packed YUV 4:2:2 video texture format. The mapping to the view channel in shader is Y0->R8, U0->G8, Y1->B8, and V0->A8.
/// </summary>
YUY2 = 108,
/// <summary>
/// The maximum format value (for internal use only).
/// </summary>

View File

@@ -46,6 +46,7 @@ void PixelFormatExtensions::Init()
PixelFormat::BC7_UNorm_sRGB,
PixelFormat::ASTC_4x4_UNorm,
PixelFormat::ASTC_4x4_UNorm_sRGB,
PixelFormat::YUY2,
};
InitFormat(formats2, 8);
@@ -373,19 +374,15 @@ bool PixelFormatExtensions::IsCompressedASTC(PixelFormat format)
}
}
bool PixelFormatExtensions::IsPacked(const PixelFormat format)
{
return format == PixelFormat::R8G8_B8G8_UNorm || format == PixelFormat::G8R8_G8B8_UNorm;
}
bool PixelFormatExtensions::IsPlanar(const PixelFormat format)
{
return false;
}
bool PixelFormatExtensions::IsVideo(const PixelFormat format)
{
return false;
switch (format)
{
case PixelFormat::YUY2:
return true;
default:
return false;
}
}
bool PixelFormatExtensions::IsSRGB(const PixelFormat format)
@@ -966,7 +963,6 @@ PixelFormat PixelFormatExtensions::FindShaderResourceFormat(const PixelFormat fo
return PixelFormat::R32_Float;
case PixelFormat::R16_Typeless:
return PixelFormat::R16_UNorm;
case PixelFormat::D16_UNorm:
return PixelFormat::R16_UNorm;
case PixelFormat::D24_UNorm_S8_UInt:
@@ -975,6 +971,8 @@ PixelFormat PixelFormatExtensions::FindShaderResourceFormat(const PixelFormat fo
return PixelFormat::R32_Float;
case PixelFormat::D32_Float_S8X24_UInt:
return PixelFormat::R32_Float_X8X24_Typeless;
case PixelFormat::YUY2:
return PixelFormat::R8G8B8A8_UNorm;
}
return format;
}
@@ -987,6 +985,8 @@ PixelFormat PixelFormatExtensions::FindUnorderedAccessFormat(const PixelFormat f
return PixelFormat::B8G8R8A8_UNorm;
case PixelFormat::R8G8B8A8_Typeless:
return PixelFormat::R8G8B8A8_UNorm;
case PixelFormat::YUY2:
return PixelFormat::R8G8B8A8_UNorm;
}
return format;
}

View File

@@ -102,20 +102,6 @@ public:
/// <returns>True if the <see cref="PixelFormat"/> is a compressed format from ASTC formats family.</returns>
API_FUNCTION() static bool IsCompressedASTC(PixelFormat format);
/// <summary>
/// Determines whether the specified <see cref="PixelFormat"/> is packed.
/// </summary>
/// <param name="format">The Pixel Format.</param>
/// <returns><c>true</c> if the specified <see cref="PixelFormat"/> is packed; otherwise, <c>false</c>.</returns>
API_FUNCTION() static bool IsPacked(PixelFormat format);
/// <summary>
/// Determines whether the specified <see cref="PixelFormat"/> is planar.
/// </summary>
/// <param name="format">The Pixel Format.</param>
/// <returns><c>true</c> if the specified <see cref="PixelFormat"/> is planar; otherwise, <c>false</c>.</returns>
API_FUNCTION() static bool IsPlanar(PixelFormat format);
/// <summary>
/// Determines whether the specified <see cref="PixelFormat"/> is video.
/// </summary>

View File

@@ -298,14 +298,13 @@ void RenderTools::ComputePitch(PixelFormat format, int32 width, int32 height, ui
case PixelFormat::BC4_Typeless:
case PixelFormat::BC4_UNorm:
case PixelFormat::BC4_SNorm:
ASSERT(PixelFormatExtensions::IsCompressed(format));
{
uint32 nbw = Math::Max<uint32>(1, (width + 3) / 4);
uint32 nbh = Math::Max<uint32>(1, (height + 3) / 4);
rowPitch = nbw * 8;
slicePitch = rowPitch * nbh;
}
break;
{
const uint32 nbw = Math::Max<uint32>(1, (width + 3) / 4);
const uint32 nbh = Math::Max<uint32>(1, (height + 3) / 4);
rowPitch = nbw * 8;
slicePitch = rowPitch * nbh;
}
break;
case PixelFormat::BC2_Typeless:
case PixelFormat::BC2_UNorm:
case PixelFormat::BC2_UNorm_sRGB:
@@ -321,14 +320,13 @@ void RenderTools::ComputePitch(PixelFormat format, int32 width, int32 height, ui
case PixelFormat::BC7_Typeless:
case PixelFormat::BC7_UNorm:
case PixelFormat::BC7_UNorm_sRGB:
ASSERT(PixelFormatExtensions::IsCompressed(format));
{
uint32 nbw = Math::Max<uint32>(1, (width + 3) / 4);
uint32 nbh = Math::Max<uint32>(1, (height + 3) / 4);
rowPitch = nbw * 16;
slicePitch = rowPitch * nbh;
}
break;
{
const uint32 nbw = Math::Max<uint32>(1, (width + 3) / 4);
const uint32 nbh = Math::Max<uint32>(1, (height + 3) / 4);
rowPitch = nbw * 16;
slicePitch = rowPitch * nbh;
}
break;
case PixelFormat::ASTC_4x4_UNorm:
case PixelFormat::ASTC_4x4_UNorm_sRGB:
case PixelFormat::ASTC_6x6_UNorm:
@@ -339,28 +337,22 @@ void RenderTools::ComputePitch(PixelFormat format, int32 width, int32 height, ui
case PixelFormat::ASTC_10x10_UNorm_sRGB:
{
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
const uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
const uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
slicePitch = rowPitch * nbh;
}
break;
case PixelFormat::R8G8_B8G8_UNorm:
case PixelFormat::G8R8_G8B8_UNorm:
ASSERT(PixelFormatExtensions::IsPacked(format));
case PixelFormat::YUY2:
rowPitch = ((width + 1) >> 1) * 4;
slicePitch = rowPitch * height;
break;
default:
ASSERT(PixelFormatExtensions::IsValid(format));
ASSERT(!PixelFormatExtensions::IsCompressed(format) && !PixelFormatExtensions::IsPacked(format) && !PixelFormatExtensions::IsPlanar(format));
{
uint32 bpp = PixelFormatExtensions::SizeInBits(format);
// Default byte alignment
rowPitch = (width * bpp + 7) / 8;
slicePitch = rowPitch * height;
}
// Default byte alignment
rowPitch = (width * PixelFormatExtensions::SizeInBits(format) + 7) / 8;
slicePitch = rowPitch * height;
break;
}
}

View File

@@ -273,18 +273,6 @@ ID3D11BlendState* GPUDeviceDX11::GetBlendState(const BlendingMode& blending)
return blendState;
}
static MSAALevel GetMaximumMultisampleCount(ID3D11Device* device, DXGI_FORMAT dxgiFormat)
{
int32 maxCount = 1;
UINT numQualityLevels;
for (int32 i = 2; i <= 8; i *= 2)
{
if (SUCCEEDED(device->CheckMultisampleQualityLevels(dxgiFormat, i, &numQualityLevels)) && numQualityLevels > 0)
maxCount = i;
}
return static_cast<MSAALevel>(maxCount);
}
bool GPUDeviceDX11::Init()
{
HRESULT result;
@@ -392,10 +380,16 @@ bool GPUDeviceDX11::Init()
{
auto format = static_cast<PixelFormat>(i);
auto dxgiFormat = RenderToolsDX::ToDxgiFormat(format);
auto maximumMultisampleCount = GetMaximumMultisampleCount(_device, dxgiFormat);
int32 maxCount = 1;
UINT numQualityLevels;
for (int32 c = 2; c <= 8; c *= 2)
{
if (SUCCEEDED(_device->CheckMultisampleQualityLevels(dxgiFormat, c, &numQualityLevels)) && numQualityLevels > 0)
maxCount = c;
}
UINT formatSupport = 0;
_device->CheckFormatSupport(dxgiFormat, &formatSupport);
FeaturesPerFormat[i] = FormatFeatures(format, maximumMultisampleCount, (FormatSupport)formatSupport);
FeaturesPerFormat[i] = FormatFeatures(format, static_cast<MSAALevel>(maxCount), (FormatSupport)formatSupport);
}
}

View File

@@ -398,14 +398,10 @@ bool GPUDeviceDX12::Init()
{
const PixelFormat format = static_cast<PixelFormat>(i);
const DXGI_FORMAT dxgiFormat = RenderToolsDX::ToDxgiFormat(format);
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatInfo = { dxgiFormat };
if (FAILED(_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatInfo, sizeof(formatInfo))))
{
formatInfo.Support1 = D3D12_FORMAT_SUPPORT1_NONE;
}
const MSAALevel maximumMultisampleCount = GetMaximumMultisampleCount(_device, dxgiFormat);
FeaturesPerFormat[i] = FormatFeatures(format, maximumMultisampleCount, (FormatSupport)formatInfo.Support1);
}
}

View File

@@ -9,7 +9,7 @@
// @formatter:off
DXGI_FORMAT PixelFormatToDXGIFormat[108] =
DXGI_FORMAT PixelFormatToDXGIFormat[109] =
{
DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_R32G32B32A32_TYPELESS,
@@ -119,6 +119,7 @@ DXGI_FORMAT PixelFormatToDXGIFormat[108] =
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNorm_sRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNorm
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNorm_sRGB
DXGI_FORMAT_YUY2,
};
// @formatter:on

View File

@@ -8,7 +8,7 @@
// @formatter:off
VkFormat RenderToolsVulkan::PixelFormatToVkFormat[108] =
VkFormat RenderToolsVulkan::PixelFormatToVkFormat[109] =
{
VK_FORMAT_UNDEFINED,
VK_FORMAT_R32G32B32A32_SFLOAT,
@@ -118,6 +118,7 @@ VkFormat RenderToolsVulkan::PixelFormatToVkFormat[108] =
VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
VK_FORMAT_G8B8G8R8_422_UNORM, // YUY2
};
VkBlendFactor RenderToolsVulkan::BlendToVkBlendFactor[20] =