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] =