diff --git a/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc b/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc index 32f62dddf1907..8dfa1ed47268f 100644 --- a/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_builder_vk.cc @@ -4,8 +4,6 @@ #include "impeller/renderer/backend/vulkan/render_pass_builder_vk.h" -#include - #include "impeller/core/formats.h" #include "impeller/renderer/backend/vulkan/formats_vk.h" #include "vulkan/vulkan_enums.hpp" @@ -119,57 +117,64 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build( color_attachments_count++; } - std::vector attachments; - - std::vector color_refs(color_attachments_count, - kUnusedAttachmentReference); - std::vector resolve_refs(color_attachments_count, - kUnusedAttachmentReference); + std::array attachments; + std::array color_refs; + std::array resolve_refs; vk::AttachmentReference depth_stencil_ref = kUnusedAttachmentReference; + size_t attachments_index = 0; + size_t color_index = 0; + size_t resolve_index = 0; if (color0_.has_value()) { vk::AttachmentReference color_ref; - color_ref.attachment = attachments.size(); + color_ref.attachment = attachments_index; color_ref.layout = vk::ImageLayout::eGeneral; - color_refs[0] = color_ref; - attachments.push_back(color0_.value()); + color_refs.at(color_index++) = color_ref; + attachments.at(attachments_index++) = color0_.value(); if (color0_resolve_.has_value()) { vk::AttachmentReference resolve_ref; - resolve_ref.attachment = attachments.size(); + resolve_ref.attachment = attachments_index; resolve_ref.layout = vk::ImageLayout::eGeneral; - resolve_refs[0] = resolve_ref; - attachments.push_back(color0_resolve_.value()); + resolve_refs.at(resolve_index++) = resolve_ref; + attachments.at(attachments_index++) = color0_resolve_.value(); + } else { + resolve_refs.at(resolve_index++) = kUnusedAttachmentReference; } } for (const auto& color : colors_) { vk::AttachmentReference color_ref; - color_ref.attachment = attachments.size(); + color_ref.attachment = attachments_index; color_ref.layout = vk::ImageLayout::eGeneral; - color_refs[color.first] = color_ref; - attachments.push_back(color.second); + color_refs.at(color_index++) = color_ref; + attachments.at(attachments_index++) = color.second; if (auto found = resolves_.find(color.first); found != resolves_.end()) { vk::AttachmentReference resolve_ref; - resolve_ref.attachment = attachments.size(); + resolve_ref.attachment = attachments_index; resolve_ref.layout = vk::ImageLayout::eGeneral; - resolve_refs[color.first] = resolve_ref; - attachments.push_back(found->second); + resolve_refs.at(resolve_index++) = resolve_ref; + attachments.at(attachments_index++) = found->second; + } else { + resolve_refs.at(resolve_index++) = kUnusedAttachmentReference; } } if (depth_stencil_.has_value()) { - depth_stencil_ref.attachment = attachments.size(); + depth_stencil_ref.attachment = attachments_index; depth_stencil_ref.layout = vk::ImageLayout::eGeneral; - attachments.push_back(depth_stencil_.value()); + attachments.at(attachments_index++) = depth_stencil_.value(); } vk::SubpassDescription subpass0; subpass0.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; - subpass0.setInputAttachments(color_refs); - subpass0.setColorAttachments(color_refs); - subpass0.setResolveAttachments(resolve_refs); + subpass0.setPInputAttachments(color_refs.data()); + subpass0.setInputAttachmentCount(color_index); + subpass0.setPColorAttachments(color_refs.data()); + subpass0.setColorAttachmentCount(color_index); + subpass0.setPResolveAttachments(resolve_refs.data()); + subpass0.setPDepthStencilAttachment(&depth_stencil_ref); vk::SubpassDependency self_dep; @@ -182,7 +187,8 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build( self_dep.dependencyFlags = kSelfDependencyFlags; vk::RenderPassCreateInfo render_pass_desc; - render_pass_desc.setAttachments(attachments); + render_pass_desc.setPAttachments(attachments.data()); + render_pass_desc.setAttachmentCount(attachments_index); render_pass_desc.setSubpasses(subpass0); render_pass_desc.setDependencies(self_dep); diff --git a/impeller/renderer/backend/vulkan/render_pass_builder_vk.h b/impeller/renderer/backend/vulkan/render_pass_builder_vk.h index 4e9632d9a6d13..5a48ed87d90aa 100644 --- a/impeller/renderer/backend/vulkan/render_pass_builder_vk.h +++ b/impeller/renderer/backend/vulkan/render_pass_builder_vk.h @@ -8,13 +8,16 @@ #include #include -#include "flutter/fml/macros.h" #include "impeller/core/formats.h" #include "impeller/renderer/backend/vulkan/context_vk.h" #include "impeller/renderer/backend/vulkan/vk.h" namespace impeller { +static constexpr size_t kMaxColorAttachments = 16; +static constexpr size_t kMaxAttachments = + (kMaxColorAttachments * 2) + 1; // MSAA + resolve plus depth/stencil + class RenderPassBuilderVK { public: RenderPassBuilderVK(); diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index 46315ffe0b8fc..21721b760b499 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -6,7 +6,6 @@ #include #include -#include #include "fml/status.h" #include "impeller/base/validation.h" @@ -52,15 +51,16 @@ static vk::ClearDepthStencilValue VKClearValueFromDepthStencil(uint32_t stencil, return value; } -static std::vector GetVKClearValues( - const RenderTarget& target) { - std::vector clears; - +static size_t GetVKClearValues( + const RenderTarget& target, + std::array& values) { + size_t offset = 0u; target.IterateAllColorAttachments( - [&clears](size_t index, const ColorAttachment& attachment) -> bool { - clears.emplace_back(VKClearValueFromColor(attachment.clear_color)); + [&values, &offset](size_t index, + const ColorAttachment& attachment) -> bool { + values.at(offset++) = VKClearValueFromColor(attachment.clear_color); if (attachment.resolve_texture) { - clears.emplace_back(VKClearValueFromColor(attachment.clear_color)); + values.at(offset++) = VKClearValueFromColor(attachment.clear_color); } return true; }); @@ -69,14 +69,13 @@ static std::vector GetVKClearValues( const auto& stencil = target.GetStencilAttachment(); if (depth.has_value()) { - clears.emplace_back(VKClearValueFromDepthStencil( - stencil ? stencil->clear_stencil : 0u, depth->clear_depth)); + values.at(offset++) = VKClearValueFromDepthStencil( + stencil ? stencil->clear_stencil : 0u, depth->clear_depth); } else if (stencil.has_value()) { - clears.emplace_back(VKClearValueFromDepthStencil( - stencil->clear_stencil, depth ? depth->clear_depth : 0.0f)); + values.at(offset++) = VKClearValueFromDepthStencil( + stencil->clear_stencil, depth ? depth->clear_depth : 0.0f); } - - return clears; + return offset; } SharedHandleVK RenderPassVK::CreateVKRenderPass( @@ -191,7 +190,8 @@ RenderPassVK::RenderPassVK(const std::shared_ptr& context, TextureVK::Cast(*resolve_image_vk_).SetCachedRenderPass(render_pass_); } - auto clear_values = GetVKClearValues(render_target_); + std::array clears; + size_t clear_count = GetVKClearValues(render_target_, clears); vk::RenderPassBeginInfo pass_info; pass_info.renderPass = *render_pass_; @@ -199,7 +199,8 @@ RenderPassVK::RenderPassVK(const std::shared_ptr& context, pass_info.renderArea.extent.width = static_cast(target_size.width); pass_info.renderArea.extent.height = static_cast(target_size.height); - pass_info.setClearValues(clear_values); + pass_info.setPClearValues(clears.data()); + pass_info.setClearValueCount(clear_count); command_buffer_vk_.beginRenderPass(pass_info, vk::SubpassContents::eInline); @@ -252,34 +253,37 @@ SharedHandleVK RenderPassVK::CreateVKFramebuffer( fb_info.height = target_size.height; fb_info.layers = 1u; - std::vector attachments; + std::array attachments; + size_t count = 0; // This bit must be consistent to ensure compatibility with the pass created // earlier. Follow this order: Color attachments, then depth-stencil, then // stencil. render_target_.IterateAllColorAttachments( - [&attachments](size_t index, const ColorAttachment& attachment) -> bool { + [&attachments, &count](size_t index, + const ColorAttachment& attachment) -> bool { // The bind point doesn't matter here since that information is present // in the render pass. - attachments.emplace_back( - TextureVK::Cast(*attachment.texture).GetRenderTargetView()); + attachments[count++] = + TextureVK::Cast(*attachment.texture).GetRenderTargetView(); if (attachment.resolve_texture) { - attachments.emplace_back(TextureVK::Cast(*attachment.resolve_texture) - .GetRenderTargetView()); + attachments[count++] = TextureVK::Cast(*attachment.resolve_texture) + .GetRenderTargetView(); } return true; }); if (auto depth = render_target_.GetDepthAttachment(); depth.has_value()) { - attachments.emplace_back( - TextureVK::Cast(*depth->texture).GetRenderTargetView()); + attachments[count++] = + TextureVK::Cast(*depth->texture).GetRenderTargetView(); } else if (auto stencil = render_target_.GetStencilAttachment(); stencil.has_value()) { - attachments.emplace_back( - TextureVK::Cast(*stencil->texture).GetRenderTargetView()); + attachments[count++] = + TextureVK::Cast(*stencil->texture).GetRenderTargetView(); } - fb_info.setAttachments(attachments); + fb_info.setPAttachments(attachments.data()); + fb_info.setAttachmentCount(count); auto [result, framebuffer] = context.GetDevice().createFramebufferUnique(fb_info);