[Impeller] cache MSAA texture in swapchain for devices that do not support memoryless. (flutter/engine#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
This commit is contained in:
Jonah Williams 2023-06-30 11:34:29 -07:00 committed by GitHub
parent 70cb44975f
commit cb7fd03312
4 changed files with 40 additions and 7 deletions

View File

@ -12,12 +12,18 @@ namespace impeller {
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 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
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;

View File

@ -19,7 +19,7 @@ class SurfaceVK final : public Surface {
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|

View File

@ -35,6 +35,18 @@ bool SwapchainImageVK::IsValid() const {
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;
}

View File

@ -30,12 +30,19 @@ class SwapchainImageVK final : public TextureSourceVK {
// |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);