Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e352461

Browse files
[Impeller] remove std::vector usage in render pass vk. (#57132)
Remove std::vector usage in vulkan render pass. Fixed size array + offsets, should be faster than heap allocations.
1 parent 0b34fae commit e352461

File tree

3 files changed

+67
-54
lines changed

3 files changed

+67
-54
lines changed

impeller/renderer/backend/vulkan/render_pass_builder_vk.cc

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
#include "impeller/renderer/backend/vulkan/render_pass_builder_vk.h"
66

7-
#include <vector>
8-
97
#include "impeller/core/formats.h"
108
#include "impeller/renderer/backend/vulkan/formats_vk.h"
119
#include "vulkan/vulkan_enums.hpp"
@@ -119,57 +117,64 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build(
119117
color_attachments_count++;
120118
}
121119

122-
std::vector<vk::AttachmentDescription> attachments;
123-
124-
std::vector<vk::AttachmentReference> color_refs(color_attachments_count,
125-
kUnusedAttachmentReference);
126-
std::vector<vk::AttachmentReference> resolve_refs(color_attachments_count,
127-
kUnusedAttachmentReference);
120+
std::array<vk::AttachmentDescription, kMaxAttachments> attachments;
121+
std::array<vk::AttachmentReference, kMaxColorAttachments> color_refs;
122+
std::array<vk::AttachmentReference, kMaxColorAttachments> resolve_refs;
128123
vk::AttachmentReference depth_stencil_ref = kUnusedAttachmentReference;
124+
size_t attachments_index = 0;
125+
size_t color_index = 0;
126+
size_t resolve_index = 0;
129127

130128
if (color0_.has_value()) {
131129
vk::AttachmentReference color_ref;
132-
color_ref.attachment = attachments.size();
130+
color_ref.attachment = attachments_index;
133131
color_ref.layout = vk::ImageLayout::eGeneral;
134-
color_refs[0] = color_ref;
135-
attachments.push_back(color0_.value());
132+
color_refs.at(color_index++) = color_ref;
133+
attachments.at(attachments_index++) = color0_.value();
136134

137135
if (color0_resolve_.has_value()) {
138136
vk::AttachmentReference resolve_ref;
139-
resolve_ref.attachment = attachments.size();
137+
resolve_ref.attachment = attachments_index;
140138
resolve_ref.layout = vk::ImageLayout::eGeneral;
141-
resolve_refs[0] = resolve_ref;
142-
attachments.push_back(color0_resolve_.value());
139+
resolve_refs.at(resolve_index++) = resolve_ref;
140+
attachments.at(attachments_index++) = color0_resolve_.value();
141+
} else {
142+
resolve_refs.at(resolve_index++) = kUnusedAttachmentReference;
143143
}
144144
}
145145

146146
for (const auto& color : colors_) {
147147
vk::AttachmentReference color_ref;
148-
color_ref.attachment = attachments.size();
148+
color_ref.attachment = attachments_index;
149149
color_ref.layout = vk::ImageLayout::eGeneral;
150-
color_refs[color.first] = color_ref;
151-
attachments.push_back(color.second);
150+
color_refs.at(color_index++) = color_ref;
151+
attachments.at(attachments_index++) = color.second;
152152

153153
if (auto found = resolves_.find(color.first); found != resolves_.end()) {
154154
vk::AttachmentReference resolve_ref;
155-
resolve_ref.attachment = attachments.size();
155+
resolve_ref.attachment = attachments_index;
156156
resolve_ref.layout = vk::ImageLayout::eGeneral;
157-
resolve_refs[color.first] = resolve_ref;
158-
attachments.push_back(found->second);
157+
resolve_refs.at(resolve_index++) = resolve_ref;
158+
attachments.at(attachments_index++) = found->second;
159+
} else {
160+
resolve_refs.at(resolve_index++) = kUnusedAttachmentReference;
159161
}
160162
}
161163

162164
if (depth_stencil_.has_value()) {
163-
depth_stencil_ref.attachment = attachments.size();
165+
depth_stencil_ref.attachment = attachments_index;
164166
depth_stencil_ref.layout = vk::ImageLayout::eGeneral;
165-
attachments.push_back(depth_stencil_.value());
167+
attachments.at(attachments_index++) = depth_stencil_.value();
166168
}
167169

168170
vk::SubpassDescription subpass0;
169171
subpass0.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
170-
subpass0.setInputAttachments(color_refs);
171-
subpass0.setColorAttachments(color_refs);
172-
subpass0.setResolveAttachments(resolve_refs);
172+
subpass0.setPInputAttachments(color_refs.data());
173+
subpass0.setInputAttachmentCount(color_index);
174+
subpass0.setPColorAttachments(color_refs.data());
175+
subpass0.setColorAttachmentCount(color_index);
176+
subpass0.setPResolveAttachments(resolve_refs.data());
177+
173178
subpass0.setPDepthStencilAttachment(&depth_stencil_ref);
174179

175180
vk::SubpassDependency self_dep;
@@ -182,7 +187,8 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build(
182187
self_dep.dependencyFlags = kSelfDependencyFlags;
183188

184189
vk::RenderPassCreateInfo render_pass_desc;
185-
render_pass_desc.setAttachments(attachments);
190+
render_pass_desc.setPAttachments(attachments.data());
191+
render_pass_desc.setAttachmentCount(attachments_index);
186192
render_pass_desc.setSubpasses(subpass0);
187193
render_pass_desc.setDependencies(self_dep);
188194

impeller/renderer/backend/vulkan/render_pass_builder_vk.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
#include <map>
99
#include <optional>
1010

11-
#include "flutter/fml/macros.h"
1211
#include "impeller/core/formats.h"
1312
#include "impeller/renderer/backend/vulkan/context_vk.h"
1413
#include "impeller/renderer/backend/vulkan/vk.h"
1514

1615
namespace impeller {
1716

17+
static constexpr size_t kMaxColorAttachments = 16;
18+
static constexpr size_t kMaxAttachments =
19+
(kMaxColorAttachments * 2) + 1; // MSAA + resolve plus depth/stencil
20+
1821
class RenderPassBuilderVK {
1922
public:
2023
RenderPassBuilderVK();

impeller/renderer/backend/vulkan/render_pass_vk.cc

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include <array>
88
#include <cstdint>
9-
#include <vector>
109

1110
#include "fml/status.h"
1211
#include "impeller/base/validation.h"
@@ -52,15 +51,16 @@ static vk::ClearDepthStencilValue VKClearValueFromDepthStencil(uint32_t stencil,
5251
return value;
5352
}
5453

55-
static std::vector<vk::ClearValue> GetVKClearValues(
56-
const RenderTarget& target) {
57-
std::vector<vk::ClearValue> clears;
58-
54+
static size_t GetVKClearValues(
55+
const RenderTarget& target,
56+
std::array<vk::ClearValue, kMaxAttachments>& values) {
57+
size_t offset = 0u;
5958
target.IterateAllColorAttachments(
60-
[&clears](size_t index, const ColorAttachment& attachment) -> bool {
61-
clears.emplace_back(VKClearValueFromColor(attachment.clear_color));
59+
[&values, &offset](size_t index,
60+
const ColorAttachment& attachment) -> bool {
61+
values.at(offset++) = VKClearValueFromColor(attachment.clear_color);
6262
if (attachment.resolve_texture) {
63-
clears.emplace_back(VKClearValueFromColor(attachment.clear_color));
63+
values.at(offset++) = VKClearValueFromColor(attachment.clear_color);
6464
}
6565
return true;
6666
});
@@ -69,14 +69,13 @@ static std::vector<vk::ClearValue> GetVKClearValues(
6969
const auto& stencil = target.GetStencilAttachment();
7070

7171
if (depth.has_value()) {
72-
clears.emplace_back(VKClearValueFromDepthStencil(
73-
stencil ? stencil->clear_stencil : 0u, depth->clear_depth));
72+
values.at(offset++) = VKClearValueFromDepthStencil(
73+
stencil ? stencil->clear_stencil : 0u, depth->clear_depth);
7474
} else if (stencil.has_value()) {
75-
clears.emplace_back(VKClearValueFromDepthStencil(
76-
stencil->clear_stencil, depth ? depth->clear_depth : 0.0f));
75+
values.at(offset++) = VKClearValueFromDepthStencil(
76+
stencil->clear_stencil, depth ? depth->clear_depth : 0.0f);
7777
}
78-
79-
return clears;
78+
return offset;
8079
}
8180

8281
SharedHandleVK<vk::RenderPass> RenderPassVK::CreateVKRenderPass(
@@ -191,15 +190,17 @@ RenderPassVK::RenderPassVK(const std::shared_ptr<const Context>& context,
191190
TextureVK::Cast(*resolve_image_vk_).SetCachedRenderPass(render_pass_);
192191
}
193192

194-
auto clear_values = GetVKClearValues(render_target_);
193+
std::array<vk::ClearValue, kMaxAttachments> clears;
194+
size_t clear_count = GetVKClearValues(render_target_, clears);
195195

196196
vk::RenderPassBeginInfo pass_info;
197197
pass_info.renderPass = *render_pass_;
198198
pass_info.framebuffer = *framebuffer;
199199
pass_info.renderArea.extent.width = static_cast<uint32_t>(target_size.width);
200200
pass_info.renderArea.extent.height =
201201
static_cast<uint32_t>(target_size.height);
202-
pass_info.setClearValues(clear_values);
202+
pass_info.setPClearValues(clears.data());
203+
pass_info.setClearValueCount(clear_count);
203204

204205
command_buffer_vk_.beginRenderPass(pass_info, vk::SubpassContents::eInline);
205206

@@ -252,34 +253,37 @@ SharedHandleVK<vk::Framebuffer> RenderPassVK::CreateVKFramebuffer(
252253
fb_info.height = target_size.height;
253254
fb_info.layers = 1u;
254255

255-
std::vector<vk::ImageView> attachments;
256+
std::array<vk::ImageView, kMaxAttachments> attachments;
257+
size_t count = 0;
256258

257259
// This bit must be consistent to ensure compatibility with the pass created
258260
// earlier. Follow this order: Color attachments, then depth-stencil, then
259261
// stencil.
260262
render_target_.IterateAllColorAttachments(
261-
[&attachments](size_t index, const ColorAttachment& attachment) -> bool {
263+
[&attachments, &count](size_t index,
264+
const ColorAttachment& attachment) -> bool {
262265
// The bind point doesn't matter here since that information is present
263266
// in the render pass.
264-
attachments.emplace_back(
265-
TextureVK::Cast(*attachment.texture).GetRenderTargetView());
267+
attachments[count++] =
268+
TextureVK::Cast(*attachment.texture).GetRenderTargetView();
266269
if (attachment.resolve_texture) {
267-
attachments.emplace_back(TextureVK::Cast(*attachment.resolve_texture)
268-
.GetRenderTargetView());
270+
attachments[count++] = TextureVK::Cast(*attachment.resolve_texture)
271+
.GetRenderTargetView();
269272
}
270273
return true;
271274
});
272275

273276
if (auto depth = render_target_.GetDepthAttachment(); depth.has_value()) {
274-
attachments.emplace_back(
275-
TextureVK::Cast(*depth->texture).GetRenderTargetView());
277+
attachments[count++] =
278+
TextureVK::Cast(*depth->texture).GetRenderTargetView();
276279
} else if (auto stencil = render_target_.GetStencilAttachment();
277280
stencil.has_value()) {
278-
attachments.emplace_back(
279-
TextureVK::Cast(*stencil->texture).GetRenderTargetView());
281+
attachments[count++] =
282+
TextureVK::Cast(*stencil->texture).GetRenderTargetView();
280283
}
281284

282-
fb_info.setAttachments(attachments);
285+
fb_info.setPAttachments(attachments.data());
286+
fb_info.setAttachmentCount(count);
283287

284288
auto [result, framebuffer] =
285289
context.GetDevice().createFramebufferUnique(fb_info);

0 commit comments

Comments
 (0)