diff --git a/Source/Engine/Graphics/PixelFormat.h b/Source/Engine/Graphics/PixelFormat.h
index 1f96a4d82..9335b10c6 100644
--- a/Source/Engine/Graphics/PixelFormat.h
+++ b/Source/Engine/Graphics/PixelFormat.h
@@ -553,6 +553,11 @@ API_ENUM() enum class PixelFormat : uint32
///
ASTC_10x10_UNorm_sRGB = 107,
+ ///
+ /// 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.
+ ///
+ YUY2 = 108,
+
///
/// The maximum format value (for internal use only).
///
diff --git a/Source/Engine/Graphics/PixelFormatExtensions.cpp b/Source/Engine/Graphics/PixelFormatExtensions.cpp
index f77c15683..2b1f68457 100644
--- a/Source/Engine/Graphics/PixelFormatExtensions.cpp
+++ b/Source/Engine/Graphics/PixelFormatExtensions.cpp
@@ -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;
}
diff --git a/Source/Engine/Graphics/PixelFormatExtensions.h b/Source/Engine/Graphics/PixelFormatExtensions.h
index 498b9270c..d5296ea65 100644
--- a/Source/Engine/Graphics/PixelFormatExtensions.h
+++ b/Source/Engine/Graphics/PixelFormatExtensions.h
@@ -102,20 +102,6 @@ public:
/// True if the is a compressed format from ASTC formats family.
API_FUNCTION() static bool IsCompressedASTC(PixelFormat format);
- ///
- /// Determines whether the specified is packed.
- ///
- /// The Pixel Format.
- /// true if the specified is packed; otherwise, false.
- API_FUNCTION() static bool IsPacked(PixelFormat format);
-
- ///
- /// Determines whether the specified is planar.
- ///
- /// The Pixel Format.
- /// true if the specified is planar; otherwise, false.
- API_FUNCTION() static bool IsPlanar(PixelFormat format);
-
///
/// Determines whether the specified is video.
///
diff --git a/Source/Engine/Graphics/RenderTools.cpp b/Source/Engine/Graphics/RenderTools.cpp
index 679555141..e27cacf9c 100644
--- a/Source/Engine/Graphics/RenderTools.cpp
+++ b/Source/Engine/Graphics/RenderTools.cpp
@@ -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(1, (width + 3) / 4);
- uint32 nbh = Math::Max(1, (height + 3) / 4);
- rowPitch = nbw * 8;
- slicePitch = rowPitch * nbh;
- }
- break;
+ {
+ const uint32 nbw = Math::Max(1, (width + 3) / 4);
+ const uint32 nbh = Math::Max(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(1, (width + 3) / 4);
- uint32 nbh = Math::Max(1, (height + 3) / 4);
- rowPitch = nbw * 16;
- slicePitch = rowPitch * nbh;
- }
- break;
+ {
+ const uint32 nbw = Math::Max(1, (width + 3) / 4);
+ const uint32 nbh = Math::Max(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(1, Math::DivideAndRoundUp(width, blockSize));
- uint32 nbh = Math::Max(1, Math::DivideAndRoundUp(height, blockSize));
+ const uint32 nbw = Math::Max(1, Math::DivideAndRoundUp(width, blockSize));
+ const uint32 nbh = Math::Max(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;
}
}
diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp
index 07bd0ec69..2d90b50ae 100644
--- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp
+++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp
@@ -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(maxCount);
-}
-
bool GPUDeviceDX11::Init()
{
HRESULT result;
@@ -392,10 +380,16 @@ bool GPUDeviceDX11::Init()
{
auto format = static_cast(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(maxCount), (FormatSupport)formatSupport);
}
}
diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp
index b070a34d0..05da7c839 100644
--- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp
+++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp
@@ -398,14 +398,10 @@ bool GPUDeviceDX12::Init()
{
const PixelFormat format = static_cast(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);
}
}
diff --git a/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp b/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp
index dd4df4b23..43e751395 100644
--- a/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp
+++ b/Source/Engine/GraphicsDevice/DirectX/RenderToolsDX.cpp
@@ -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
diff --git a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp
index cd9d49b6b..d1fe90ee2 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.cpp
@@ -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] =