[Impeller] cache MSAA texture in swapchain for devices that do not support memoryless. (#43349)
For devices that don't support memoryless textures, the fullscreen MSAA texture adds a substantial amount of memory thrashing when it is allocated and deallocated. For these devices, lets cache the MSAA texture in the swapchain image.
https://github.com/flutter/flutter/issues/129737
diff --git a/impeller/renderer/backend/vulkan/surface_vk.cc b/impeller/renderer/backend/vulkan/surface_vk.cc
index 3f1006e..ab11006 100644
--- a/impeller/renderer/backend/vulkan/surface_vk.cc
+++ b/impeller/renderer/backend/vulkan/surface_vk.cc
@@ -12,12 +12,18 @@
std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
const std::shared_ptr<Context>& context,
- const std::shared_ptr<SwapchainImageVK>& swapchain_image,
+ std::shared_ptr<SwapchainImageVK>& 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 @@
msaa_tex_desc.size = swapchain_image->GetSize();
msaa_tex_desc.usage = static_cast<uint64_t>(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<Texture> 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 b6824f5..6138a8e 100644
--- a/impeller/renderer/backend/vulkan/surface_vk.h
+++ b/impeller/renderer/backend/vulkan/surface_vk.h
@@ -19,7 +19,7 @@
static std::unique_ptr<SurfaceVK> WrapSwapchainImage(
const std::shared_ptr<Context>& context,
- const std::shared_ptr<SwapchainImageVK>& swapchain_image,
+ std::shared_ptr<SwapchainImageVK>& 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 392c76b..dee06c7 100644
--- a/impeller/renderer/backend/vulkan/swapchain_image_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain_image_vk.cc
@@ -35,6 +35,18 @@
return is_valid_;
}
+std::shared_ptr<Texture> SwapchainImageVK::GetMSAATexture() const {
+ return msaa_tex_;
+}
+
+bool SwapchainImageVK::HasMSAATexture() const {
+ return msaa_tex_ != nullptr;
+}
+
+void SwapchainImageVK::SetMSAATexture(std::shared_ptr<Texture> 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 6cf1943..115cfa1 100644
--- a/impeller/renderer/backend/vulkan/swapchain_image_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain_image_vk.h
@@ -30,12 +30,19 @@
// |TextureSourceVK|
vk::Image GetImage() const override;
+ std::shared_ptr<Texture> GetMSAATexture() const;
+
+ bool HasMSAATexture() const;
+
// |TextureSourceVK|
vk::ImageView GetImageView() const override;
+ void SetMSAATexture(std::shared_ptr<Texture> msaa_tex);
+
private:
vk::Image image_ = VK_NULL_HANDLE;
vk::UniqueImageView image_view_ = {};
+ std::shared_ptr<Texture> msaa_tex_;
bool is_valid_ = false;
FML_DISALLOW_COPY_AND_ASSIGN(SwapchainImageVK);