diff --git a/impeller/renderer/backend/vulkan/formats_vk.h b/impeller/renderer/backend/vulkan/formats_vk.h index d73705f90f0b2..3886c0147b999 100644 --- a/impeller/renderer/backend/vulkan/formats_vk.h +++ b/impeller/renderer/backend/vulkan/formats_vk.h @@ -314,18 +314,39 @@ constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action) { FML_UNREACHABLE(); } -constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp( - StoreAction store_action) { +constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(StoreAction store_action, + bool is_resolve_texture) { switch (store_action) { case StoreAction::kStore: + // Both MSAA and resolve textures need to be stored. A resolve is NOT + // performed. return vk::AttachmentStoreOp::eStore; case StoreAction::kDontCare: + // Both MSAA and resolve textures can be discarded. A resolve is NOT + // performed. return vk::AttachmentStoreOp::eDontCare; case StoreAction::kMultisampleResolve: + // The resolve texture is stored but the MSAA texture can be discarded. A + // resolve IS performed. + return is_resolve_texture ? vk::AttachmentStoreOp::eStore + : vk::AttachmentStoreOp::eDontCare; case StoreAction::kStoreAndMultisampleResolve: - return vk::AttachmentStoreOp::eDontCare; + // Both MSAA and resolve textures need to be stored. A resolve IS + // performed. + return vk::AttachmentStoreOp::eStore; } + FML_UNREACHABLE(); +} +constexpr bool StoreActionPerformsResolve(StoreAction store_action) { + switch (store_action) { + case StoreAction::kDontCare: + case StoreAction::kStore: + return false; + case StoreAction::kMultisampleResolve: + case StoreAction::kStoreAndMultisampleResolve: + return true; + } FML_UNREACHABLE(); } diff --git a/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc b/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc index 5edd04441553f..f07a3fe890e97 100644 --- a/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc @@ -37,15 +37,20 @@ RenderPassBuilderVK& RenderPassBuilderVK::SetColorAttachment( desc.format = ToVKImageFormat(format); desc.samples = ToVKSampleCount(sample_count); desc.loadOp = ToVKAttachmentLoadOp(load_action); - desc.storeOp = ToVKAttachmentStoreOp(store_action); + desc.storeOp = ToVKAttachmentStoreOp(store_action, false); desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare; desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare; desc.initialLayout = vk::ImageLayout::eGeneral; desc.finalLayout = vk::ImageLayout::eGeneral; colors_[index] = desc; - desc.samples = vk::SampleCountFlagBits::e1; - resolves_[index] = desc; + if (StoreActionPerformsResolve(store_action)) { + desc.storeOp = ToVKAttachmentStoreOp(store_action, true); + desc.samples = vk::SampleCountFlagBits::e1; + resolves_[index] = desc; + } else { + resolves_.erase(index); + } return *this; } @@ -59,7 +64,7 @@ RenderPassBuilderVK& RenderPassBuilderVK::SetDepthStencilAttachment( desc.format = ToVKImageFormat(format); desc.samples = ToVKSampleCount(sample_count); desc.loadOp = ToVKAttachmentLoadOp(load_action); - desc.storeOp = ToVKAttachmentStoreOp(store_action); + desc.storeOp = ToVKAttachmentStoreOp(store_action, false); desc.stencilLoadOp = desc.loadOp; // Not separable in Impeller. desc.stencilStoreOp = desc.storeOp; // Not separable in Impeller. desc.initialLayout = vk::ImageLayout::eGeneral; @@ -79,7 +84,7 @@ RenderPassBuilderVK& RenderPassBuilderVK::SetStencilAttachment( desc.loadOp = vk::AttachmentLoadOp::eDontCare; desc.storeOp = vk::AttachmentStoreOp::eDontCare; desc.stencilLoadOp = ToVKAttachmentLoadOp(load_action); - desc.stencilStoreOp = ToVKAttachmentStoreOp(store_action); + desc.stencilStoreOp = ToVKAttachmentStoreOp(store_action, false); desc.initialLayout = vk::ImageLayout::eGeneral; desc.finalLayout = vk::ImageLayout::eGeneral; depth_stencil_ = desc; @@ -88,8 +93,6 @@ RenderPassBuilderVK& RenderPassBuilderVK::SetStencilAttachment( vk::UniqueRenderPass RenderPassBuilderVK::Build( const vk::Device& device) const { - FML_DCHECK(colors_.size() == resolves_.size()); - // This must be less than `VkPhysicalDeviceLimits::maxColorAttachments` but we // are not checking. const auto color_attachments_count = @@ -110,12 +113,12 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build( color_refs[color.first] = color_ref; attachments.push_back(color.second); - if (color.second.samples != vk::SampleCountFlagBits::e1) { + if (auto found = resolves_.find(color.first); found != resolves_.end()) { vk::AttachmentReference resolve_ref; resolve_ref.attachment = attachments.size(); resolve_ref.layout = vk::ImageLayout::eGeneral; resolve_refs[color.first] = resolve_ref; - attachments.push_back(resolves_.at(color.first)); + attachments.push_back(found->second); } }