Lugdunum  0.1.0
RenderPass.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <vector>
5 
7 
8 namespace lug {
9 namespace Graphics {
10 namespace Vulkan {
11 namespace API {
12 namespace Builder {
13 
14 RenderPass::RenderPass(const API::Device& device) : _device{device} {}
15 
16 RenderPass::AttachmentIndex RenderPass::addAttachment(const VkAttachmentDescription& attachmentDescription) {
17  _attachments.push_back(attachmentDescription);
18  return &_attachments.back();
19 }
20 
22  const auto findIndexAttachment = [this](RenderPass::AttachmentIndex idx) {
23  if (idx == nullptr) {
24  return VK_ATTACHMENT_UNUSED;
25  }
26 
27  uint32_t i = 0;
28 
29  for (const auto& attachment : _attachments) {
30  if (&attachment == idx) {
31  break;
32  }
33 
34  ++i;
35  }
36 
37  return i;
38  };
39 
40  const auto transformAttachmentReference = [&findIndexAttachment](const RenderPass::AttachmentReference& reference){
41  return VkAttachmentReference{
42  findIndexAttachment(reference.attachment),
43  reference.layout
44  };
45  };
46 
47  SubpassResources resources{};
48 
49  resources.inputAttachments.resize(subpassDescription.inputAttachments.size());
50  std::transform(
51  std::begin(subpassDescription.inputAttachments), std::end(subpassDescription.inputAttachments), std::begin(resources.inputAttachments),
52  transformAttachmentReference
53  );
54 
55  resources.colorAttachments.resize(subpassDescription.colorAttachments.size());
56  std::transform(
57  std::begin(subpassDescription.colorAttachments), std::end(subpassDescription.colorAttachments), std::begin(resources.colorAttachments),
58  transformAttachmentReference
59  );
60 
61  resources.resolveAttachments.resize(subpassDescription.resolveAttachments.size());
62  std::transform(
63  std::begin(subpassDescription.resolveAttachments), std::end(subpassDescription.resolveAttachments), std::begin(resources.resolveAttachments),
64  transformAttachmentReference
65  );
66 
67  resources.depthStencilAttachment = transformAttachmentReference(subpassDescription.depthStencilAttachment);
68 
69  resources.preserveAttachments.resize(subpassDescription.preserveAttachments.size());
70  std::transform(
71  std::begin(subpassDescription.preserveAttachments), std::end(subpassDescription.preserveAttachments), std::begin(resources.preserveAttachments),
72  findIndexAttachment
73  );
74 
75  _subpassesResources.push_back(std::move(resources));
76 
77  const VkSubpassDescription vkSubpassDescription{
78  /* vkSubpassDescription.flags */ 0,
79  /* vkSubpassDescription.pipelineBindPoint */ subpassDescription.pipelineBindPoint,
80  /* vkSubpassDescription.inputAttachmentCount */ static_cast<uint32_t>(_subpassesResources.back().inputAttachments.size()),
81  /* vkSubpassDescription.pInputAttachments */ _subpassesResources.back().inputAttachments.data(),
82  /* vkSubpassDescription.colorAttachmentCount */ static_cast<uint32_t>(_subpassesResources.back().colorAttachments.size()),
83  /* vkSubpassDescription.pColorAttachments */ _subpassesResources.back().colorAttachments.data(),
84  /* vkSubpassDescription.pResolveAttachments */ _subpassesResources.back().resolveAttachments.data(),
85  /* vkSubpassDescription.pDepthStencilAttachment */ &_subpassesResources.back().depthStencilAttachment,
86  /* vkSubpassDescription.preserveAttachmentCount */ static_cast<uint32_t>(_subpassesResources.back().preserveAttachments.size()),
87  /* vkSubpassDescription.pPreserveAttachments */ _subpassesResources.back().preserveAttachments.data(),
88  };
89 
90  _subpasses.push_back(std::move(vkSubpassDescription));
91  return &_subpasses.back();
92 }
93 
95  const auto findIndexSubpass = [this](RenderPass::SubpassIndex idx) {
96  uint32_t i = 0;
97 
98  for (const auto& subpass : _subpasses) {
99  if (&subpass == idx) {
100  break;
101  }
102 
103  ++i;
104  }
105 
106  return i;
107  };
108 
109  const VkSubpassDependency vkSubpassDependency{
110  /* vkSubpassDependency.srcSubpass */ findIndexSubpass(subpassDependency.srcSubpass),
111  /* vkSubpassDependency.dstSubpass */ findIndexSubpass(subpassDependency.dstSubpass),
112  /* vkSubpassDependency.srcStageMask */ subpassDependency.srcStageMask,
113  /* vkSubpassDependency.dstStageMask */ subpassDependency.dstStageMask,
114  /* vkSubpassDependency.srcAccessMask */ subpassDependency.srcAccessMask,
115  /* vkSubpassDependency.dstAccessMask */ subpassDependency.dstAccessMask,
116  /* vkSubpassDependency.dependencyFlags */ subpassDependency.dependencyFlags
117  };
118 
119  _dependencies.push_back(std::move(vkSubpassDependency));
120 }
121 
122 bool RenderPass::build(API::RenderPass& renderPass, VkResult* returnResult) {
123  const std::vector<VkAttachmentDescription> attachments{std::cbegin(_attachments), std::cend(_attachments)};
124  const std::vector<VkSubpassDescription> subpasses{std::cbegin(_subpasses), std::cend(_subpasses)};
125  const std::vector<VkSubpassDependency> dependencies{std::cbegin(_dependencies), std::cend(_dependencies)};
126 
127  const VkRenderPassCreateInfo createInfo{
128  /* createInfo.sType */ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
129  /* createInfo.pNext */ nullptr,
130  /* createInfo.flags */ 0,
131  /* createInfo.attachmentCount */ static_cast<uint32_t>(attachments.size()),
132  /* createInfo.pAttachments */ attachments.data(),
133  /* createInfo.subpassCount */ static_cast<uint32_t>(subpasses.size()),
134  /* createInfo.pSubpasses */ subpasses.data(),
135  /* createInfo.dependencyCount */ static_cast<uint32_t>(dependencies.size()),
136  /* createInfo.pDependencies */ dependencies.data()
137  };
138 
139  // Create the render pass
140  VkRenderPass vkRenderPass{VK_NULL_HANDLE};
141  VkResult result = vkCreateRenderPass(static_cast<VkDevice>(_device), &createInfo, nullptr, &vkRenderPass);
142 
143  if (returnResult) {
144  *returnResult = result;
145  }
146 
147  if (result != VK_SUCCESS) {
148  return false;
149  }
150 
151  renderPass = API::RenderPass(vkRenderPass, &_device);
152 
153  return true;
154 }
155 
156 std::unique_ptr<API::RenderPass> RenderPass::build(VkResult* returnResult) {
157  std::unique_ptr<API::RenderPass> renderPass = std::make_unique<API::RenderPass>();
158  return build(*renderPass, returnResult) ? std::move(renderPass) : nullptr;
159 }
160 
161 } // Builder
162 } // API
163 } // Vulkan
164 } // Graphics
165 } // lug
bool build(API::RenderPass &instance, VkResult *returnResult=nullptr)
Definition: RenderPass.cpp:122
AttachmentIndex addAttachment(const VkAttachmentDescription &attachmentDescription)
Definition: RenderPass.cpp:16
std::list< VkSubpassDescription > _subpasses
Definition: RenderPass.hpp:78
std::list< VkAttachmentDescription > _attachments
Definition: RenderPass.hpp:77
SubpassIndex addSubpass(const SubpassDescription &subpassDescription)
Definition: RenderPass.cpp:21
const VkSubpassDescription * SubpassIndex
Definition: RenderPass.hpp:19
const VkAttachmentDescription * AttachmentIndex
Definition: RenderPass.hpp:18
void addSubpassDependency(const SubpassDependency &subpassDependency)
Definition: RenderPass.cpp:94
std::list< VkSubpassDependency > _dependencies
Definition: RenderPass.hpp:80
std::list< SubpassResources > _subpassesResources
Definition: RenderPass.hpp:79