14 vk::ImageLayout ComputeFinalLayout(
bool is_swapchain,
SampleCount count) {
16 return vk::ImageLayout::eGeneral;
18 return vk::ImageLayout::eShaderReadOnlyOptimal;
23 vk::PipelineStageFlagBits::eColorAttachmentOutput;
25 vk::AccessFlagBits::eColorAttachmentWrite;
28 vk::PipelineStageFlagBits::eFragmentShader;
30 vk::AccessFlagBits::eInputAttachmentRead;
44 vk::ImageLayout current_layout,
46 vk::AttachmentDescription desc;
51 desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
52 desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
54 desc.initialLayout = current_layout;
56 desc.initialLayout = vk::ImageLayout::eUndefined;
58 desc.finalLayout = ComputeFinalLayout(is_swapchain, sample_count);
64 if (performs_resolves) {
68 color0_resolve_ = desc;
70 color0_resolve_ = std::nullopt;
73 colors_[index] = desc;
74 if (performs_resolves) {
78 resolves_[index] = desc;
80 resolves_.erase(index);
91 vk::AttachmentDescription desc;
96 desc.stencilLoadOp = desc.loadOp;
97 desc.stencilStoreOp = desc.storeOp;
98 desc.initialLayout = vk::ImageLayout::eUndefined;
99 desc.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
100 depth_stencil_ = desc;
109 vk::AttachmentDescription desc;
112 desc.loadOp = vk::AttachmentLoadOp::eDontCare;
113 desc.storeOp = vk::AttachmentStoreOp::eDontCare;
116 desc.initialLayout = vk::ImageLayout::eUndefined;
117 desc.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
118 depth_stencil_ = desc;
123 const vk::Device& device)
const {
126 auto color_attachments_count =
127 colors_.empty() ? 0u : colors_.rbegin()->first + 1u;
128 if (color0_.has_value()) {
129 color_attachments_count++;
132 std::array<vk::AttachmentDescription, kMaxAttachments> attachments;
133 std::array<vk::AttachmentReference, kMaxColorAttachments> color_refs;
134 std::array<vk::AttachmentReference, kMaxColorAttachments> resolve_refs;
136 size_t attachments_index = 0;
137 size_t color_index = 0;
138 size_t resolve_index = 0;
140 if (color0_.has_value()) {
141 vk::AttachmentReference color_ref;
142 color_ref.attachment = attachments_index;
143 color_ref.layout = vk::ImageLayout::eGeneral;
144 color_refs.at(color_index++) = color_ref;
145 attachments.at(attachments_index++) = color0_.value();
147 if (color0_resolve_.has_value()) {
148 vk::AttachmentReference resolve_ref;
149 resolve_ref.attachment = attachments_index;
150 resolve_ref.layout = vk::ImageLayout::eGeneral;
151 resolve_refs.at(resolve_index++) = resolve_ref;
152 attachments.at(attachments_index++) = color0_resolve_.value();
158 for (
const auto& color : colors_) {
159 vk::AttachmentReference color_ref;
160 color_ref.attachment = attachments_index;
161 color_ref.layout = vk::ImageLayout::eGeneral;
162 color_refs.at(color_index++) = color_ref;
163 attachments.at(attachments_index++) = color.second;
165 if (
auto found = resolves_.find(color.first); found != resolves_.end()) {
166 vk::AttachmentReference resolve_ref;
167 resolve_ref.attachment = attachments_index;
168 resolve_ref.layout = vk::ImageLayout::eGeneral;
169 resolve_refs.at(resolve_index++) = resolve_ref;
170 attachments.at(attachments_index++) = found->second;
176 if (depth_stencil_.has_value()) {
177 depth_stencil_ref.attachment = attachments_index;
178 depth_stencil_ref.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
179 attachments.at(attachments_index++) = depth_stencil_.value();
182 vk::SubpassDescription subpass0;
183 subpass0.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
184 subpass0.setPInputAttachments(color_refs.data());
185 subpass0.setInputAttachmentCount(color_index);
186 subpass0.setPColorAttachments(color_refs.data());
187 subpass0.setColorAttachmentCount(color_index);
188 subpass0.setPResolveAttachments(resolve_refs.data());
190 subpass0.setPDepthStencilAttachment(&depth_stencil_ref);
192 vk::SubpassDependency deps[3];
197 deps[0].srcSubpass = VK_SUBPASS_EXTERNAL;
198 deps[0].dstSubpass = 0u;
199 deps[0].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
200 vk::PipelineStageFlagBits::eFragmentShader;
201 deps[0].srcAccessMask = vk::AccessFlagBits::eShaderRead |
202 vk::AccessFlagBits::eColorAttachmentWrite;
203 deps[0].dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
204 deps[0].dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
209 deps[1].srcSubpass = 0u;
210 deps[1].dstSubpass = 0u;
221 deps[2].srcSubpass = 0u;
222 deps[2].dstSubpass = VK_SUBPASS_EXTERNAL;
223 deps[2].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
224 deps[2].srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
225 deps[2].dstStageMask = vk::PipelineStageFlagBits::eFragmentShader;
226 deps[2].dstAccessMask = vk::AccessFlagBits::eShaderRead;
229 vk::RenderPassCreateInfo render_pass_desc;
230 render_pass_desc.setPAttachments(attachments.data());
231 render_pass_desc.setAttachmentCount(attachments_index);
232 render_pass_desc.setSubpasses(subpass0);
233 render_pass_desc.setPDependencies(deps);
234 render_pass_desc.setDependencyCount(3);
236 auto [result, pass] = device.createRenderPassUnique(render_pass_desc);
237 if (result != vk::Result::eSuccess) {
238 VALIDATION_LOG <<
"Failed to create render pass: " << vk::to_string(result);
241 return std::move(pass);
245 const vk::Image& image) {
248 vk::ImageMemoryBarrier barrier;
251 barrier.oldLayout = vk::ImageLayout::eGeneral;
252 barrier.newLayout = vk::ImageLayout::eGeneral;
253 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
254 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
255 barrier.image = image;
257 vk::ImageSubresourceRange image_levels;
258 image_levels.aspectMask = vk::ImageAspectFlagBits::eColor;
259 image_levels.baseArrayLayer = 0u;
260 image_levels.baseMipLevel = 0u;
261 image_levels.layerCount = VK_REMAINING_ARRAY_LAYERS;
262 image_levels.levelCount = VK_REMAINING_MIP_LEVELS;
263 barrier.subresourceRange = image_levels;
274 const std::map<size_t, vk::AttachmentDescription>&
279 const std::map<size_t, vk::AttachmentDescription>&
284 const std::optional<vk::AttachmentDescription>&
286 return depth_stencil_;
298 return color0_resolve_;
std::optional< vk::AttachmentDescription > GetColor0() const
RenderPassBuilderVK & SetDepthStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
const std::map< size_t, vk::AttachmentDescription > & GetColorAttachments() const
const std::map< size_t, vk::AttachmentDescription > & GetResolves() const
RenderPassBuilderVK & SetStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
const std::optional< vk::AttachmentDescription > & GetDepthStencil() const
RenderPassBuilderVK & SetColorAttachment(size_t index, PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action, vk::ImageLayout current_layout=vk::ImageLayout::eUndefined, bool is_swapchain=false)
vk::UniqueRenderPass Build(const vk::Device &device) const
std::optional< vk::AttachmentDescription > GetColor0Resolve() const
static constexpr vk::AttachmentReference kUnusedAttachmentReference
constexpr auto kSelfDependencyDstAccessMask
constexpr auto kSelfDependencySrcAccessMask
constexpr bool StoreActionPerformsResolve(StoreAction store_action)
constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(StoreAction store_action, bool is_resolve_texture)
constexpr auto kSelfDependencySrcStageMask
constexpr auto kSelfDependencyDstStageMask
constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count)
constexpr vk::Format ToVKImageFormat(PixelFormat format)
constexpr auto kSelfDependencyFlags
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...