diff --git a/impeller/renderer/backend/vulkan/surface_vk.cc b/impeller/renderer/backend/vulkan/surface_vk.cc index 3f1006e331fd6..ab1100664d470 100644 --- a/impeller/renderer/backend/vulkan/surface_vk.cc +++ b/impeller/renderer/backend/vulkan/surface_vk.cc @@ -12,12 +12,18 @@ namespace impeller { std::unique_ptr SurfaceVK::WrapSwapchainImage( const std::shared_ptr& context, - const std::shared_ptr& swapchain_image, + std::shared_ptr& swapchain_image, SwapCallback swap_callback) { if (!context || !swapchain_image || !swap_callback) { return nullptr; } + // Some Vulkan devices may not support memoryless (lazily allocated) textures. + // In this case we will cache the MSAA texture on the swapchain image to avoid + // thrasing the VMA heap. + bool supports_memoryless = + context->GetCapabilities()->SupportsMemorylessTextures(); + TextureDescriptor msaa_tex_desc; msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient; msaa_tex_desc.type = TextureType::kTexture2DMultisample; @@ -26,12 +32,20 @@ std::unique_ptr SurfaceVK::WrapSwapchainImage( msaa_tex_desc.size = swapchain_image->GetSize(); msaa_tex_desc.usage = static_cast(TextureUsage::kRenderTarget); - auto msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc); - if (!msaa_tex) { - VALIDATION_LOG << "Could not allocate MSAA color texture."; - return nullptr; + std::shared_ptr msaa_tex; + if (supports_memoryless || !swapchain_image->HasMSAATexture()) { + msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc); + msaa_tex->SetLabel("ImpellerOnscreenColorMSAA"); + if (!msaa_tex) { + VALIDATION_LOG << "Could not allocate MSAA color texture."; + return nullptr; + } + if (!supports_memoryless) { + swapchain_image->SetMSAATexture(msaa_tex); + } + } else { + msaa_tex = swapchain_image->GetMSAATexture(); } - msaa_tex->SetLabel("ImpellerOnscreenColorMSAA"); TextureDescriptor resolve_tex_desc; resolve_tex_desc.type = TextureType::kTexture2D; diff --git a/impeller/renderer/backend/vulkan/surface_vk.h b/impeller/renderer/backend/vulkan/surface_vk.h index b6824f55cf100..6138a8e44d3c1 100644 --- a/impeller/renderer/backend/vulkan/surface_vk.h +++ b/impeller/renderer/backend/vulkan/surface_vk.h @@ -19,7 +19,7 @@ class SurfaceVK final : public Surface { static std::unique_ptr WrapSwapchainImage( const std::shared_ptr& context, - const std::shared_ptr& swapchain_image, + std::shared_ptr& swapchain_image, SwapCallback swap_callback); // |Surface| diff --git a/impeller/renderer/backend/vulkan/swapchain_image_vk.cc b/impeller/renderer/backend/vulkan/swapchain_image_vk.cc index 392c76b645a9b..dee06c7568e46 100644 --- a/impeller/renderer/backend/vulkan/swapchain_image_vk.cc +++ b/impeller/renderer/backend/vulkan/swapchain_image_vk.cc @@ -35,6 +35,18 @@ bool SwapchainImageVK::IsValid() const { return is_valid_; } +std::shared_ptr SwapchainImageVK::GetMSAATexture() const { + return msaa_tex_; +} + +bool SwapchainImageVK::HasMSAATexture() const { + return msaa_tex_ != nullptr; +} + +void SwapchainImageVK::SetMSAATexture(std::shared_ptr msaa_tex) { + msaa_tex_ = std::move(msaa_tex); +} + PixelFormat SwapchainImageVK::GetPixelFormat() const { return desc_.format; } diff --git a/impeller/renderer/backend/vulkan/swapchain_image_vk.h b/impeller/renderer/backend/vulkan/swapchain_image_vk.h index 6cf1943b8729e..115cfa1824bdb 100644 --- a/impeller/renderer/backend/vulkan/swapchain_image_vk.h +++ b/impeller/renderer/backend/vulkan/swapchain_image_vk.h @@ -30,12 +30,19 @@ class SwapchainImageVK final : public TextureSourceVK { // |TextureSourceVK| vk::Image GetImage() const override; + std::shared_ptr GetMSAATexture() const; + + bool HasMSAATexture() const; + // |TextureSourceVK| vk::ImageView GetImageView() const override; + void SetMSAATexture(std::shared_ptr msaa_tex); + private: vk::Image image_ = VK_NULL_HANDLE; vk::UniqueImageView image_view_ = {}; + std::shared_ptr msaa_tex_; bool is_valid_ = false; FML_DISALLOW_COPY_AND_ASSIGN(SwapchainImageVK);