2525#include " impeller/renderer/backend/vulkan/shared_object_vk.h"
2626#include " impeller/renderer/backend/vulkan/texture_vk.h"
2727#include " impeller/renderer/backend/vulkan/vk.h"
28+ #include " vulkan/vulkan_handles.hpp"
2829
2930namespace impeller {
3031
@@ -79,6 +80,7 @@ static std::vector<vk::ClearValue> GetVKClearValues(
7980
8081SharedHandleVK<vk::RenderPass> RenderPassVK::CreateVKRenderPass (
8182 const ContextVK& context,
83+ const SharedHandleVK<vk::RenderPass>& recycled_renderpass,
8284 const std::shared_ptr<CommandBufferVK>& command_buffer) const {
8385 BarrierVK barrier;
8486 barrier.new_layout = vk::ImageLayout::eGeneral;
@@ -127,6 +129,15 @@ SharedHandleVK<vk::RenderPass> RenderPassVK::CreateVKRenderPass(
127129 TextureVK::Cast (*stencil->texture ).SetLayout (barrier);
128130 }
129131
132+ // There may exist a previous recycled render pass that we can continue using.
133+ // This is probably compatible with the render pass we are about to construct,
134+ // but I have not conclusively proven this. If there are scenarios that
135+ // produce validation warnings, we could use them to determine if we need
136+ // additional checks at this point to determine reusability.
137+ if (recycled_renderpass != nullptr ) {
138+ return recycled_renderpass;
139+ }
140+
130141 auto pass = builder.Build (context.GetDevice ());
131142
132143 if (!pass) {
@@ -143,6 +154,11 @@ RenderPassVK::RenderPassVK(const std::shared_ptr<const Context>& context,
143154 const RenderTarget& target,
144155 std::shared_ptr<CommandBufferVK> command_buffer)
145156 : RenderPass(context, target), command_buffer_(std::move(command_buffer)) {
157+ color_image_vk_ =
158+ render_target_.GetColorAttachments ().find (0u )->second .texture ;
159+ resolve_image_vk_ =
160+ render_target_.GetColorAttachments ().find (0u )->second .resolve_texture ;
161+
146162 const auto & vk_context = ContextVK::Cast (*context);
147163 const std::shared_ptr<CommandEncoderVK>& encoder =
148164 command_buffer_->GetEncoder ();
@@ -154,16 +170,26 @@ RenderPassVK::RenderPassVK(const std::shared_ptr<const Context>& context,
154170 return true ;
155171 });
156172
173+ SharedHandleVK<vk::RenderPass> recycled_render_pass;
174+ SharedHandleVK<vk::Framebuffer> recycled_framebuffer;
175+ if (resolve_image_vk_) {
176+ recycled_render_pass = TextureVK::Cast (*resolve_image_vk_).GetRenderPass ();
177+ recycled_framebuffer = TextureVK::Cast (*resolve_image_vk_).GetFramebuffer ();
178+ }
179+
157180 const auto & target_size = render_target_.GetRenderTargetSize ();
158181
159- render_pass_ = CreateVKRenderPass (vk_context, command_buffer_);
182+ render_pass_ =
183+ CreateVKRenderPass (vk_context, recycled_render_pass, command_buffer_);
160184 if (!render_pass_) {
161185 VALIDATION_LOG << " Could not create renderpass." ;
162186 is_valid_ = false ;
163187 return ;
164188 }
165189
166- auto framebuffer = CreateVKFramebuffer (vk_context, *render_pass_);
190+ auto framebuffer = (recycled_framebuffer == nullptr )
191+ ? CreateVKFramebuffer (vk_context, *render_pass_)
192+ : recycled_framebuffer;
167193 if (!framebuffer) {
168194 VALIDATION_LOG << " Could not create framebuffer." ;
169195 is_valid_ = false ;
@@ -174,6 +200,10 @@ RenderPassVK::RenderPassVK(const std::shared_ptr<const Context>& context,
174200 is_valid_ = false ;
175201 return ;
176202 }
203+ if (resolve_image_vk_) {
204+ TextureVK::Cast (*resolve_image_vk_).SetFramebuffer (framebuffer);
205+ TextureVK::Cast (*resolve_image_vk_).SetRenderPass (render_pass_);
206+ }
177207
178208 auto clear_values = GetVKClearValues (render_target_);
179209
@@ -205,10 +235,6 @@ RenderPassVK::RenderPassVK(const std::shared_ptr<const Context>& context,
205235 .setExtent (vk::Extent2D (sc.GetWidth (), sc.GetHeight ()));
206236 command_buffer_vk_.setScissor (0 , 1 , &scissor);
207237
208- color_image_vk_ =
209- render_target_.GetColorAttachments ().find (0u )->second .texture ;
210- resolve_image_vk_ =
211- render_target_.GetColorAttachments ().find (0u )->second .resolve_texture ;
212238 is_valid_ = true ;
213239}
214240
0 commit comments