vOOlkan
An object oriented approach to Vulkan
Subpass.h
Go to the documentation of this file.
1#ifndef VULKAN_SUBPASS
2#define VULKAN_SUBPASS
3
4#include <vulkan/vulkan.h>
5#include <vector>
6#include <tuple>
7
8#include "Attachment.h"
10#include "VulkanException.h"
11
12
14 class Subpass;
15
16 template<typename T>
17 concept IsBoundAttachment = requires(T t) {
18 std::same_as<T, AttachmentDescription::BoundAttachmentDescription> || std::same_as<T, std::pair<AttachmentDescription::BoundAttachmentDescription, bool>>;
19 };
20}
21
22
29 public:
30
39 template<IsBoundAttachment... BA>
40 Subpass(VkPipelineBindPoint bindPoint = VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, const BA&... boundAttachments) : subpass{} {
41 //put each attachment in the correct array
42 buildAttachmentsTypesArrays(boundAttachments...);
43
44 //create the structure
45 subpass.pipelineBindPoint = bindPoint;
46 subpass.inputAttachmentCount = inputRefs.size();
47 subpass.pInputAttachments = inputRefs.empty() ? nullptr : inputRefs.data();
48 subpass.colorAttachmentCount = colorRefs.size();
49 subpass.pColorAttachments = colorRefs.empty() ? nullptr : colorRefs.data();;
50 subpass.pDepthStencilAttachment = depthStencilRefs.empty() ? nullptr : depthStencilRefs.data();;
51 subpass.preserveAttachmentCount = preserveRefs.size();
52 subpass.pPreserveAttachments = preserveRefs.empty() ? nullptr : preserveRefs.data();
53 }
54
55
61 Subpass(VkSubpassDescription baseSubpass) : subpass{ baseSubpass } {}
62
63
69 const VkSubpassDescription& operator+() {
70 return subpass;
71 }
72
73
79 std::vector<VkPipelineColorBlendAttachmentState> getColorBlendingDescriptors() const {
80 std::vector<VkPipelineColorBlendAttachmentState> result;
81 for (const auto& acbm : colorBlendingModes) {
82 result.push_back(+acbm);
83 }
84 return result;
85 }
86
87 private:
88
89 //given the BoundAttachmentDescription(s), it extract their references and put them into 3 arrays, based on the type of the AttachmentDescription: input ref, color ref, depth/stencil ref
90 template<IsBoundAttachment... BA>
91 void buildAttachmentsTypesArrays(const BA&... boundAttachments) {
92 //create a vector containing the BoundAttachmentDescription and a bool (true if that bound attachment should be added to the preserve array)
93 std::vector<std::pair<AttachmentDescription::BoundAttachmentDescription, bool>> parsedBoundAttachments;
94 (parsedBoundAttachments.push_back(parseBoundAttachment(boundAttachments)), ...);
95
96 //for each BoundAttachmentDescription
97 for (const auto& boundAttachment : parsedBoundAttachments) {
98 //if the BoundAttachmentDescription should be preserved, add its index (VkAttachmentReference.attachment) to the preserve array
99 if (boundAttachment.second) {
100 preserveRefs.push_back(boundAttachment.first.getAttachmentReferenceIndex());
101 }
102 else {
103 //add it to the correct array: <input, color, depth/stencil>
104 switch (boundAttachment.first.getType()) {
106 inputRefs.push_back(boundAttachment.first.getAttachmentReference());
107 break;
109 colorRefs.push_back(boundAttachment.first.getAttachmentReference());
110 colorBlendingModes.push_back(boundAttachment.first.getColorBlendingMode());
111 break;
113 depthStencilRefs.push_back(boundAttachment.first.getAttachmentReference());
114 break;
115 default:
116 throw VulkanException("BoundAttachmentDescription type not valid");
117 break;
118 }
119 }
120 }
121 }
122
123
124 //These 2 functions are used to create standard pairs of bound attachments and whether they should be left untouched during this render subpass
125 static std::pair<AttachmentDescription::BoundAttachmentDescription, bool> parseBoundAttachment(const AttachmentDescription::BoundAttachmentDescription& boundAttachment) {
126 return { boundAttachment, false }; //by deafult the attachment is not part of the preserve set
127 }
128
129 //These 2 functions are used to create standard pairs of bound attachments and whether they should be left untouched during this render subpass
130 static std::pair<AttachmentDescription::BoundAttachmentDescription, bool> parseBoundAttachment(const std::pair<AttachmentDescription::BoundAttachmentDescription, bool>& boundAttachment) {
131 return { boundAttachment.first, boundAttachment.second };
132 }
133
134
135 VkSubpassDescription subpass;
136
137 //arrays containing the references to each AttachmentType of attachment
138 std::vector<VkAttachmentReference> inputRefs;
139 std::vector<VkAttachmentReference> colorRefs;
140 std::vector<VkAttachmentReference> depthStencilRefs;
141
142 std::vector<uint32_t> preserveRefs; //contains the indexes of the attachments to leave untouched during this render pass
143
144 std::vector<AttachmentColorBlendingMode> colorBlendingModes; //the blend mode for each color attachment
145};
146
147#endif
148
A Subpass is a step of a RenderPass.
Definition: Subpass.h:28
Subpass(VkSubpassDescription baseSubpass)
Creates a Subpass starting from the underlying Vulkan object.
Definition: Subpass.h:61
const VkSubpassDescription & operator+()
Returns the underlying Vulkan VkSubpassDescription.
Definition: Subpass.h:69
std::vector< VkPipelineColorBlendAttachmentState > getColorBlendingDescriptors() const
Returns the VkPipelineColorBlendAttachmentState descriptors of the color attachments of this subpass.
Definition: Subpass.h:79
Subpass(VkPipelineBindPoint bindPoint=VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, const BA &... boundAttachments)
Creates a Subpass with the specified attachments.
Definition: Subpass.h:40
Generic runtime exception thrown by Vulkan-related functions.
Definition: VulkanException.h:13