From d07ca3fcf4812c8c17f23999b245bdee9c5573ca Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Mon, 15 Nov 2021 16:37:36 +0100 Subject: [PATCH] Add support for older Android devices that don't support R11G11B10 texture format --- .../Platform/Android/AndroidPlatformTools.cpp | 9 ++++- .../GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 34 +++++++++++++++++-- .../Vulkan/GPUTextureVulkan.cpp | 5 +++ Source/Engine/Renderer/PostProcessingPass.cpp | 3 +- Source/Engine/Scripting/SoftObjectReference.h | 2 +- 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index 71f01fa5d..92eb9542c 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -98,7 +98,14 @@ PixelFormat AndroidPlatformTools::GetTextureFormat(CookingData& data, TextureBas } } - return format; + switch (format) + { + // Not all Android devices support R11G11B10 textures (eg. M6 Note) + case PixelFormat::R11G11B10_Float: + return PixelFormat::R16G16B16A16_UNorm; + default: + return format; + } } void AndroidPlatformTools::OnBuildStarted(CookingData& data) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index a7872d334..143b973df 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -1307,6 +1307,8 @@ PixelFormat GPUDeviceVulkan::GetClosestSupportedPixelFormat(PixelFormat format, if (!IsVkFormatSupported(RenderToolsVulkan::ToVulkanFormat(format), wantedFeatureFlags, optimalTiling)) { + auto remap = format; + // Special case for depth-stencil formats if (flags & GPUTextureFlags::DepthStencil) { @@ -1328,9 +1330,37 @@ PixelFormat GPUDeviceVulkan::GetClosestSupportedPixelFormat(PixelFormat format, } else { - // TODO: implement it? - LOG(Warning, "Unsupported Vulkan format {0}", (int32)format); + // Perform remapping to bigger format that might be supported (more likely) + switch (format) + { + case PixelFormat::R11G11B10_Float: + case PixelFormat::R10G10B10A2_UNorm: + remap = PixelFormat::R16G16B16A16_Float; + break; + case PixelFormat::R16_Float: + remap = PixelFormat::R32_Float; + break; + case PixelFormat::R16G16_UNorm: + case PixelFormat::R16G16_Float: + remap = PixelFormat::R32G32_Float; + break; + case PixelFormat::R32G32B32A32_Float: + // RGBA32 is essential + return PixelFormat::Unknown; + default: + // Ultimate performance eater + remap = PixelFormat::R32G32B32A32_Float; + break; + } } + +#if !BUILD_RELEASE + if (format != remap) + { + LOG(Warning, "Unsupported Vulkan format {0}. Remapping to {1}", (int32)format, (int32)remap); + format = GetClosestSupportedPixelFormat(remap, flags, optimalTiling); + } +#endif } return format; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp index 28451bd66..995dc5fdd 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp @@ -238,6 +238,11 @@ bool GPUTextureVulkan::OnInit() if (useDSV) format = PixelFormatExtensions::FindDepthStencilFormat(format); _desc.Format = _device->GetClosestSupportedPixelFormat(format, _desc.Flags, optimalTiling); + if (_desc.Format == PixelFormat::Unknown) + { + LOG(Error, "Unsupported texture format {0}.", (int32)format); + return true; + } // Setup texture description VkImageCreateInfo imageInfo; diff --git a/Source/Engine/Renderer/PostProcessingPass.cpp b/Source/Engine/Renderer/PostProcessingPass.cpp index 660e76ac5..66de74388 100644 --- a/Source/Engine/Renderer/PostProcessingPass.cpp +++ b/Source/Engine/Renderer/PostProcessingPass.cpp @@ -183,7 +183,6 @@ void PostProcessingPass::Dispose() void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output, GPUTexture* colorGradingLUT) { - ASSERT(output->Format() == PixelFormat::R11G11B10_Float); auto device = GPUDevice::Instance; auto context = device->GetMainContext(); auto& view = renderContext.View; @@ -311,7 +310,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input, //////////////////////////////////////////////////////////////////////////////////// // Bloom - auto tempDesc = GPUTextureDescription::New2D(w2, h2, 0, PixelFormat::R11G11B10_Float, GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews); + auto tempDesc = GPUTextureDescription::New2D(w2, h2, 0, output->Format(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews); auto bloomTmp1 = RenderTargetPool::Get(tempDesc); // TODO: bloomTmp2 could be quarter res because we don't use it's first mip auto bloomTmp2 = RenderTargetPool::Get(tempDesc); diff --git a/Source/Engine/Scripting/SoftObjectReference.h b/Source/Engine/Scripting/SoftObjectReference.h index 39ef7946c..0c1ad2cae 100644 --- a/Source/Engine/Scripting/SoftObjectReference.h +++ b/Source/Engine/Scripting/SoftObjectReference.h @@ -194,7 +194,7 @@ public: } FORCE_INLINE SoftObjectReference& operator=(const Guid& id) { - Set(id); + OnSet(id); return *this; } FORCE_INLINE operator T*() const