Lugdunum  0.1.0
Pipeline.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 
8 
9 namespace lug {
10 namespace Graphics {
11 namespace Vulkan {
12 namespace API {
13 
14 static VkAccessFlags getImageSrcAccessMask(VkImageLayout oldLayout) {
15  switch (oldLayout) {
16  case VK_IMAGE_LAYOUT_UNDEFINED:
17  return 0;
18  case VK_IMAGE_LAYOUT_PREINITIALIZED:
19  return VK_ACCESS_HOST_WRITE_BIT;
20  case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
21  return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
22  case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
23  return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
24  case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
25  return VK_ACCESS_TRANSFER_READ_BIT;
26  case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
27  return VK_ACCESS_TRANSFER_WRITE_BIT;
28  case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
29  return VK_ACCESS_SHADER_READ_BIT;
30  default:
31  // Not handled
32  return 0;
33  }
34 }
35 
36 static VkAccessFlags getImageDstAccessMask(VkImageLayout newLayout) {
37  switch (newLayout) {
38  case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
39  return VK_ACCESS_TRANSFER_WRITE_BIT;
40  case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
41  return VK_ACCESS_TRANSFER_READ_BIT;
42  case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
43  return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
44  case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
45  return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
46  case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
47  return VK_ACCESS_SHADER_READ_BIT;
48  default:
49  // Not handled
50  return 0;
51  }
52 }
53 
54 static void setupMemoryBarriers(
55  std::vector<VkMemoryBarrier>& vkMemoryBarriers,
56  const std::vector<CommandBuffer::CmdPipelineBarrier::MemoryBarrier>& memoryBarriers
57 ) {
58  vkMemoryBarriers.resize(memoryBarriers.size());
59  for (uint8_t i = 0; i < memoryBarriers.size(); ++i) {
60  vkMemoryBarriers[i].sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
61  vkMemoryBarriers[i].pNext = nullptr;
62  vkMemoryBarriers[i].srcAccessMask = memoryBarriers[i].srcAccessMask;
63  vkMemoryBarriers[i].dstAccessMask = memoryBarriers[i].dstAccessMask;
64  }
65 }
66 
67 static void setupBufferBarriers(
68  std::vector<VkBufferMemoryBarrier>& vkBufferMemoryBarriers,
69  const std::vector<CommandBuffer::CmdPipelineBarrier::BufferMemoryBarrier>& bufferMemoryBarriers
70 ) {
71  vkBufferMemoryBarriers.resize(bufferMemoryBarriers.size());
72  for (uint8_t i = 0; i < bufferMemoryBarriers.size(); ++i){
73  vkBufferMemoryBarriers[i].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
74  vkBufferMemoryBarriers[i].pNext = nullptr;
75  vkBufferMemoryBarriers[i].srcAccessMask = bufferMemoryBarriers[i].srcAccessMask;
76  vkBufferMemoryBarriers[i].dstAccessMask = bufferMemoryBarriers[i].dstAccessMask;
77  vkBufferMemoryBarriers[i].srcQueueFamilyIndex = bufferMemoryBarriers[i].srcQueueFamilyIndex;
78  vkBufferMemoryBarriers[i].dstQueueFamilyIndex = bufferMemoryBarriers[i].dstQueueFamilyIndex;
79  vkBufferMemoryBarriers[i].buffer = static_cast<VkBuffer>(*bufferMemoryBarriers[i].buffer);
80  vkBufferMemoryBarriers[i].offset = bufferMemoryBarriers[i].offset;
81  vkBufferMemoryBarriers[i].size = bufferMemoryBarriers[i].size;
82  }
83 }
84 
85 static void setupImageBarriers(
86  std::vector<VkImageMemoryBarrier>& vkImageMemoryBarriers,
87  const std::vector<CommandBuffer::CmdPipelineBarrier::ImageMemoryBarrier>& imageMemoryBarriers
88 ) {
89  vkImageMemoryBarriers.resize(imageMemoryBarriers.size());
90  for (uint8_t i = 0; i < imageMemoryBarriers.size(); ++i){
91  vkImageMemoryBarriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
92  vkImageMemoryBarriers[i].pNext = nullptr;
93  vkImageMemoryBarriers[i].srcAccessMask = imageMemoryBarriers[i].srcAccessMask;
94  vkImageMemoryBarriers[i].dstAccessMask = imageMemoryBarriers[i].dstAccessMask;
95  vkImageMemoryBarriers[i].oldLayout = imageMemoryBarriers[i].oldLayout;
96  vkImageMemoryBarriers[i].newLayout = imageMemoryBarriers[i].newLayout;
97  vkImageMemoryBarriers[i].srcQueueFamilyIndex = imageMemoryBarriers[i].srcQueueFamilyIndex;
98  vkImageMemoryBarriers[i].dstQueueFamilyIndex = imageMemoryBarriers[i].dstQueueFamilyIndex;
99  vkImageMemoryBarriers[i].image = static_cast<VkImage>(*imageMemoryBarriers[i].image);
100  vkImageMemoryBarriers[i].subresourceRange.aspectMask = imageMemoryBarriers[i].subresourceRange.aspectMask;
101  vkImageMemoryBarriers[i].subresourceRange.baseMipLevel = imageMemoryBarriers[i].subresourceRange.baseMipLevel;
102  vkImageMemoryBarriers[i].subresourceRange.levelCount = imageMemoryBarriers[i].subresourceRange.levelCount;
103  vkImageMemoryBarriers[i].subresourceRange.baseArrayLayer = imageMemoryBarriers[i].subresourceRange.baseArrayLayer;
104  vkImageMemoryBarriers[i].subresourceRange.layerCount = imageMemoryBarriers[i].subresourceRange.layerCount;
105 
106  if (vkImageMemoryBarriers[i].srcAccessMask == 0xFFFFFFFF) {
107  vkImageMemoryBarriers[i].srcAccessMask = getImageSrcAccessMask(vkImageMemoryBarriers[i].oldLayout);
108  }
109  if (vkImageMemoryBarriers[i].dstAccessMask == 0xFFFFFFFF) {
110  vkImageMemoryBarriers[i].dstAccessMask = getImageDstAccessMask(vkImageMemoryBarriers[i].newLayout);
111  }
112 
113  if (vkImageMemoryBarriers[i].srcAccessMask == 0 &&
114  vkImageMemoryBarriers[i].newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
115  vkImageMemoryBarriers[i].srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
116  }
117  }
118 }
119 
121  const CmdPipelineBarrier& parameters,
122  VkDependencyFlags dependencyFlags,
123  VkPipelineStageFlags srcStageMask,
124  VkPipelineStageFlags dstStageMask
125 ) const {
126 
127  std::vector<VkMemoryBarrier> vkMemoryBarriers;
128  std::vector<VkBufferMemoryBarrier> vkBufferMemoryBarriers;
129  std::vector<VkImageMemoryBarrier> vkImageMemoryBarriers;
130 
131  setupMemoryBarriers(vkMemoryBarriers, parameters.memoryBarriers);
132  setupBufferBarriers(vkBufferMemoryBarriers, parameters.bufferMemoryBarriers);
133  setupImageBarriers(vkImageMemoryBarriers, parameters.imageMemoryBarriers);
134 
135  vkCmdPipelineBarrier(
137  srcStageMask,
138  dstStageMask,
139  dependencyFlags,
140  static_cast<uint32_t>(vkMemoryBarriers.size()),
141  vkMemoryBarriers.data(),
142  static_cast<uint32_t>(vkBufferMemoryBarriers.size()),
143  vkBufferMemoryBarriers.data(),
144  static_cast<uint32_t>(vkImageMemoryBarriers.size()),
145  vkImageMemoryBarriers.data()
146  );
147 }
148 
149 void CommandBuffer::bindPipeline(const API::GraphicsPipeline& pipeline, VkPipelineBindPoint pipelineBindPoint) const {
150  vkCmdBindPipeline(
152  pipelineBindPoint,
153  static_cast<VkPipeline>(pipeline)
154  );
155 }
156 
158  const std::vector<const API::Buffer*>& buffers,
159  const std::vector<VkDeviceSize>& offsets,
160  uint32_t firstBinding
161 ) const {
162 
163  // Build a vector of VkBuffer from the API::Buffer
164  std::vector<VkBuffer> vkBuffers(buffers.size());
165  std::transform(
166  std::begin(buffers), std::end(buffers), std::begin(vkBuffers),
167  [](const API::Buffer* buffer){ return static_cast<VkBuffer>(*buffer); }
168  );
169 
170  vkCmdBindVertexBuffers(
172  firstBinding,
173  static_cast<uint32_t>(vkBuffers.size()),
174  vkBuffers.data(),
175  offsets.data()
176  );
177 }
178 
179 void CommandBuffer::bindIndexBuffer(const API::Buffer& buffer, VkIndexType indexType, VkDeviceSize offset) const {
180  vkCmdBindIndexBuffer(
182  static_cast<VkBuffer>(buffer),
183  offset,
184  indexType
185  );
186 }
187 
188 void CommandBuffer::setViewport(const std::vector<VkViewport>& viewports, uint32_t firstViewport) const {
189  vkCmdSetViewport(
191  firstViewport,
192  static_cast<uint32_t>(viewports.size()),
193  viewports.data()
194  );
195 }
196 
197 void CommandBuffer::setScissor(const std::vector<VkRect2D>& scissors, uint32_t firstScissor) const {
198  vkCmdSetScissor(
200  firstScissor,
201  static_cast<uint32_t>(scissors.size()),
202  scissors.data()
203  );
204 }
205 
206 void CommandBuffer::setBlendConstants(const float blendConstants[4]) const {
207  vkCmdSetBlendConstants(_commandBuffer, blendConstants);
208 }
209 
210 void CommandBuffer::pushConstants(const CmdPushConstants& parameters) const {
211  vkCmdPushConstants(
213  parameters.layout,
214  parameters.stageFlags,
215  parameters.offset,
216  parameters.size,
217  parameters.values
218  );
219 }
220 
221 } // API
222 } // Vulkan
223 } // Graphics
224 } // lug
static void setupMemoryBarriers(std::vector< VkMemoryBarrier > &vkMemoryBarriers, const std::vector< CommandBuffer::CmdPipelineBarrier::MemoryBarrier > &memoryBarriers)
Definition: Pipeline.cpp:54
VkShaderStageFlags stageFlags
Definition: Pipeline.inl:51
uint32_t offset
Definition: Pipeline.inl:52
std::vector< ImageMemoryBarrier > imageMemoryBarriers
Definition: Pipeline.inl:45
std::vector< MemoryBarrier > memoryBarriers
Definition: Pipeline.inl:44
VkPipelineLayout layout
Definition: Pipeline.inl:50
static VkAccessFlags getImageDstAccessMask(VkImageLayout newLayout)
Definition: Pipeline.cpp:36
void setBlendConstants(const float blendConstants[4]) const
void pipelineBarrier(const CmdPipelineBarrier &parameters, VkDependencyFlags dependencyFlags=VK_DEPENDENCY_BY_REGION_BIT, VkPipelineStageFlags srcStageMask=VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VkPipelineStageFlags dstStageMask=VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) const
const void * values
Definition: Pipeline.inl:54
static void setupBufferBarriers(std::vector< VkBufferMemoryBarrier > &vkBufferMemoryBarriers, const std::vector< CommandBuffer::CmdPipelineBarrier::BufferMemoryBarrier > &bufferMemoryBarriers)
Definition: Pipeline.cpp:67
void bindPipeline(const API::GraphicsPipeline &pipeline, VkPipelineBindPoint pipelineBindPoint=VK_PIPELINE_BIND_POINT_GRAPHICS) const
void bindIndexBuffer(const API::Buffer &buffer, VkIndexType indexType, VkDeviceSize offset=0) const
std::vector< BufferMemoryBarrier > bufferMemoryBarriers
Definition: Pipeline.inl:46
void setScissor(const std::vector< VkRect2D > &scissors, uint32_t firstScissor=0) const
void setViewport(const std::vector< VkViewport > &viewports, uint32_t firstViewport=0) const
void bindVertexBuffers(const std::vector< const API::Buffer *> &buffers, const std::vector< VkDeviceSize > &offsets, uint32_t firstBinding=0) const
void pushConstants(const CmdPushConstants &parameters) const
static VkAccessFlags getImageSrcAccessMask(VkImageLayout oldLayout)
Definition: Pipeline.cpp:14
uint32_t size
Definition: Pipeline.inl:53
static void setupImageBarriers(std::vector< VkImageMemoryBarrier > &vkImageMemoryBarriers, const std::vector< CommandBuffer::CmdPipelineBarrier::ImageMemoryBarrier > &imageMemoryBarriers)
Definition: Pipeline.cpp:85