Flutter Impeller
render_pass_builder_vk.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <vector>
8 
10 
11 namespace impeller {
12 
14  vk::PipelineStageFlagBits::eColorAttachmentOutput;
16  vk::AccessFlagBits::eColorAttachmentWrite;
17 
19  vk::PipelineStageFlagBits::eFragmentShader;
21  vk::AccessFlagBits::eInputAttachmentRead;
22 
23 constexpr auto kSelfDependencyFlags = vk::DependencyFlagBits::eByRegion;
24 
26 
28 
30  size_t index,
31  PixelFormat format,
32  SampleCount sample_count,
33  LoadAction load_action,
34  StoreAction store_action) {
35  vk::AttachmentDescription desc;
36  desc.format = ToVKImageFormat(format);
37  desc.samples = ToVKSampleCount(sample_count);
38  desc.loadOp = ToVKAttachmentLoadOp(load_action);
39  desc.storeOp = ToVKAttachmentStoreOp(store_action, false);
40  desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
41  desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
42  desc.initialLayout = vk::ImageLayout::eGeneral;
43  desc.finalLayout = vk::ImageLayout::eGeneral;
44  colors_[index] = desc;
45 
46  if (StoreActionPerformsResolve(store_action)) {
47  desc.storeOp = ToVKAttachmentStoreOp(store_action, true);
48  desc.samples = vk::SampleCountFlagBits::e1;
49  resolves_[index] = desc;
50  } else {
51  resolves_.erase(index);
52  }
53  return *this;
54 }
55 
57  PixelFormat format,
58  SampleCount sample_count,
59  LoadAction load_action,
60  StoreAction store_action) {
61  vk::AttachmentDescription desc;
62  desc.format = ToVKImageFormat(format);
63  desc.samples = ToVKSampleCount(sample_count);
64  desc.loadOp = ToVKAttachmentLoadOp(load_action);
65  desc.storeOp = ToVKAttachmentStoreOp(store_action, false);
66  desc.stencilLoadOp = desc.loadOp; // Not separable in Impeller.
67  desc.stencilStoreOp = desc.storeOp; // Not separable in Impeller.
68  desc.initialLayout = vk::ImageLayout::eUndefined;
69  desc.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
70  depth_stencil_ = desc;
71  return *this;
72 }
73 
75  PixelFormat format,
76  SampleCount sample_count,
77  LoadAction load_action,
78  StoreAction store_action) {
79  vk::AttachmentDescription desc;
80  desc.format = ToVKImageFormat(format);
81  desc.samples = ToVKSampleCount(sample_count);
82  desc.loadOp = vk::AttachmentLoadOp::eDontCare;
83  desc.storeOp = vk::AttachmentStoreOp::eDontCare;
84  desc.stencilLoadOp = ToVKAttachmentLoadOp(load_action);
85  desc.stencilStoreOp = ToVKAttachmentStoreOp(store_action, false);
86  desc.initialLayout = vk::ImageLayout::eUndefined;
87  desc.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
88  depth_stencil_ = desc;
89  return *this;
90 }
91 
92 vk::UniqueRenderPass RenderPassBuilderVK::Build(
93  const vk::Device& device) const {
94  // This must be less than `VkPhysicalDeviceLimits::maxColorAttachments` but we
95  // are not checking.
96  const auto color_attachments_count =
97  colors_.empty() ? 0u : colors_.rbegin()->first + 1u;
98 
99  std::vector<vk::AttachmentDescription> attachments;
100 
101  std::vector<vk::AttachmentReference> color_refs(color_attachments_count,
103  std::vector<vk::AttachmentReference> resolve_refs(color_attachments_count,
105  vk::AttachmentReference depth_stencil_ref = kUnusedAttachmentReference;
106 
107  for (const auto& color : colors_) {
108  vk::AttachmentReference color_ref;
109  color_ref.attachment = attachments.size();
110  color_ref.layout = vk::ImageLayout::eGeneral;
111  color_refs[color.first] = color_ref;
112  attachments.push_back(color.second);
113 
114  if (auto found = resolves_.find(color.first); found != resolves_.end()) {
115  vk::AttachmentReference resolve_ref;
116  resolve_ref.attachment = attachments.size();
117  resolve_ref.layout = vk::ImageLayout::eGeneral;
118  resolve_refs[color.first] = resolve_ref;
119  attachments.push_back(found->second);
120  }
121  }
122 
123  if (depth_stencil_.has_value()) {
124  depth_stencil_ref.attachment = attachments.size();
125  depth_stencil_ref.layout = vk::ImageLayout::eGeneral;
126  attachments.push_back(depth_stencil_.value());
127  }
128 
129  vk::SubpassDescription subpass0;
130  subpass0.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
131  subpass0.setInputAttachments(color_refs);
132  subpass0.setColorAttachments(color_refs);
133  subpass0.setResolveAttachments(resolve_refs);
134  subpass0.setPDepthStencilAttachment(&depth_stencil_ref);
135 
136  vk::SubpassDependency self_dep;
137  self_dep.srcSubpass = 0u; // first subpass
138  self_dep.dstSubpass = 0u; // to itself
139  self_dep.srcStageMask = kSelfDependencySrcStageMask;
140  self_dep.srcAccessMask = kSelfDependencySrcAccessMask;
141  self_dep.dstStageMask = kSelfDependencyDstStageMask;
142  self_dep.dstAccessMask = kSelfDependencyDstAccessMask;
143  self_dep.dependencyFlags = kSelfDependencyFlags;
144 
145  vk::RenderPassCreateInfo render_pass_desc;
146  render_pass_desc.setAttachments(attachments);
147  render_pass_desc.setSubpasses(subpass0);
148  render_pass_desc.setDependencies(self_dep);
149 
150  auto [result, pass] = device.createRenderPassUnique(render_pass_desc);
151  if (result != vk::Result::eSuccess) {
152  VALIDATION_LOG << "Failed to create render pass: " << vk::to_string(result);
153  return {};
154  }
155  return std::move(pass);
156 }
157 
158 void InsertBarrierForInputAttachmentRead(const vk::CommandBuffer& buffer,
159  const vk::Image& image) {
160  // This barrier must be a subset of the masks specified in the subpass
161  // dependency setup.
162  vk::ImageMemoryBarrier barrier;
163  barrier.srcAccessMask = kSelfDependencySrcAccessMask;
164  barrier.dstAccessMask = kSelfDependencyDstAccessMask;
165  barrier.oldLayout = vk::ImageLayout::eGeneral;
166  barrier.newLayout = vk::ImageLayout::eGeneral;
167  barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
168  barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
169  barrier.image = image;
170 
171  vk::ImageSubresourceRange image_levels;
172  image_levels.aspectMask = vk::ImageAspectFlagBits::eColor;
173  image_levels.baseArrayLayer = 0u;
174  image_levels.baseMipLevel = 0u;
175  image_levels.layerCount = VK_REMAINING_ARRAY_LAYERS;
176  image_levels.levelCount = VK_REMAINING_MIP_LEVELS;
177  barrier.subresourceRange = image_levels;
178 
179  buffer.pipelineBarrier(kSelfDependencySrcStageMask, //
182  {}, //
183  {}, //
184  barrier //
185  );
186 }
187 
188 const std::map<size_t, vk::AttachmentDescription>&
190  return colors_;
191 }
192 
193 const std::map<size_t, vk::AttachmentDescription>&
195  return resolves_;
196 }
197 
198 const std::optional<vk::AttachmentDescription>&
200  return depth_stencil_;
201 }
202 
203 } // namespace impeller
impeller::ToVKSampleCount
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
Definition: formats_vk.h:203
impeller::StoreAction
StoreAction
Definition: formats.h:209
impeller::kSelfDependencyDstAccessMask
constexpr auto kSelfDependencyDstAccessMask
Definition: render_pass_builder_vk.cc:20
impeller::RenderPassBuilderVK::SetStencilAttachment
RenderPassBuilderVK & SetStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
Definition: render_pass_builder_vk.cc:74
impeller::kSelfDependencySrcStageMask
constexpr auto kSelfDependencySrcStageMask
Definition: render_pass_builder_vk.cc:13
impeller::RenderPassBuilderVK
Definition: render_pass_builder_vk.h:17
formats_vk.h
impeller::kSelfDependencyFlags
constexpr auto kSelfDependencyFlags
Definition: render_pass_builder_vk.cc:23
impeller::RenderPassBuilderVK::GetColorAttachments
const std::map< size_t, vk::AttachmentDescription > & GetColorAttachments() const
Definition: render_pass_builder_vk.cc:189
impeller::ToVKAttachmentStoreOp
constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(StoreAction store_action, bool is_resolve_texture)
Definition: formats_vk.h:314
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:100
impeller::RenderPassBuilderVK::SetDepthStencilAttachment
RenderPassBuilderVK & SetDepthStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
Definition: render_pass_builder_vk.cc:56
impeller::RenderPassBuilderVK::GetDepthStencil
const std::optional< vk::AttachmentDescription > & GetDepthStencil() const
Definition: render_pass_builder_vk.cc:199
impeller::ToVKImageFormat
constexpr vk::Format ToVKImageFormat(PixelFormat format)
Definition: formats_vk.h:135
impeller::RenderPassBuilderVK::RenderPassBuilderVK
RenderPassBuilderVK()
impeller::InsertBarrierForInputAttachmentRead
void InsertBarrierForInputAttachmentRead(const vk::CommandBuffer &buffer, const vk::Image &image)
Inserts the appropriate barriers to ensure that subsequent commands can read from the specified image...
Definition: render_pass_builder_vk.cc:158
impeller::LoadAction
LoadAction
Definition: formats.h:203
impeller::RenderPassBuilderVK::GetResolves
const std::map< size_t, vk::AttachmentDescription > & GetResolves() const
Definition: render_pass_builder_vk.cc:194
impeller::kSelfDependencyDstStageMask
constexpr auto kSelfDependencyDstStageMask
Definition: render_pass_builder_vk.cc:18
impeller::RenderPassBuilderVK::SetColorAttachment
RenderPassBuilderVK & SetColorAttachment(size_t index, PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
Definition: render_pass_builder_vk.cc:29
render_pass_builder_vk.h
impeller::RenderPassBuilderVK::~RenderPassBuilderVK
~RenderPassBuilderVK()
impeller::ToVKAttachmentLoadOp
constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action)
Definition: formats_vk.h:301
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::SampleCount
SampleCount
Definition: formats.h:296
impeller::kUnusedAttachmentReference
static constexpr vk::AttachmentReference kUnusedAttachmentReference
Definition: formats_vk.h:416
impeller::RenderPassBuilderVK::Build
vk::UniqueRenderPass Build(const vk::Device &device) const
Definition: render_pass_builder_vk.cc:92
impeller::kSelfDependencySrcAccessMask
constexpr auto kSelfDependencySrcAccessMask
Definition: render_pass_builder_vk.cc:15
impeller
Definition: aiks_blur_unittests.cc:20
impeller::StoreActionPerformsResolve
constexpr bool StoreActionPerformsResolve(StoreAction store_action)
Definition: formats_vk.h:338