Overte C++ Documentation
Pipelines.h
1 //
2 // Created by Bradley Austin Davis on 2018/10/29
3 // Copyright 2018 High Fidelity, Inc.
4 // Copyright 2021-2024 Overte e.V.
5 //
6 // Distributed under the Apache License, Version 2.0.
7 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
8 // SPDX-License-Identifier: Apache-2.0
9 //
10 // Contains parts of Vulkan Samples, Copyright (c) 2018, Sascha Willems, distributed on MIT License.
11 //
12 #pragma once
13 
14 #include "Context.h"
15 
16 namespace vks {
17  namespace pipelines {
18  struct PipelineRasterizationStateCreateInfo : public VkPipelineRasterizationStateCreateInfo {
19  using Parent = VkPipelineRasterizationStateCreateInfo;
20  PipelineRasterizationStateCreateInfo() : Parent {} {
21  sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
22  lineWidth = 1.0f;
23  cullMode = VK_CULL_MODE_BACK_BIT;
24  }
25  };
26 
27 
28  struct PipelineInputAssemblyStateCreateInfo : public VkPipelineInputAssemblyStateCreateInfo {
29  PipelineInputAssemblyStateCreateInfo() :
30  VkPipelineInputAssemblyStateCreateInfo {} {
31  sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
32  topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
33  }
34  };
35 
36  struct PipelineColorBlendAttachmentState : public VkPipelineColorBlendAttachmentState {
37  PipelineColorBlendAttachmentState() :
38  VkPipelineColorBlendAttachmentState {} {
39  colorWriteMask = vks::util::fullColorWriteMask();
40  }
41  };
42 
43  struct PipelineColorBlendStateCreateInfo : public VkPipelineColorBlendStateCreateInfo {
44  // Default to a single color attachment state with no blending
45  std::vector<PipelineColorBlendAttachmentState> blendAttachmentStates{ PipelineColorBlendAttachmentState() };
46 
47  PipelineColorBlendStateCreateInfo() :
48  VkPipelineColorBlendStateCreateInfo{} {
49  sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
50  }
51 
52  void update() {
53  this->attachmentCount = (uint32_t)blendAttachmentStates.size();
54  this->pAttachments = blendAttachmentStates.data();
55  }
56  };
57 
58  struct PipelineDynamicStateCreateInfo : public VkPipelineDynamicStateCreateInfo {
59  std::vector<VkDynamicState> dynamicStateEnables;
60 
61  PipelineDynamicStateCreateInfo() :
62  VkPipelineDynamicStateCreateInfo{} {
63  sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
64  dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
65  }
66 
67  void update() {
68  this->dynamicStateCount = (uint32_t)dynamicStateEnables.size();
69  this->pDynamicStates = dynamicStateEnables.data();
70  }
71  };
72 
73  struct PipelineVertexInputStateCreateInfo : public VkPipelineVertexInputStateCreateInfo {
74  std::vector<VkVertexInputBindingDescription> bindingDescriptions;
75  std::vector<VkVertexInputAttributeDescription> attributeDescriptions;
76 
77  PipelineVertexInputStateCreateInfo() :
78  VkPipelineVertexInputStateCreateInfo{} {
79  sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
80  }
81  void update() {
82  vertexAttributeDescriptionCount = (uint32_t)attributeDescriptions.size();
83  vertexBindingDescriptionCount = (uint32_t)bindingDescriptions.size();
84  pVertexBindingDescriptions = bindingDescriptions.data();
85  pVertexAttributeDescriptions = attributeDescriptions.data();
86  }
87  };
88 
89  struct PipelineViewportStateCreateInfo : public VkPipelineViewportStateCreateInfo {
90  std::vector<VkViewport> viewports;
91  std::vector<VkRect2D> scissors;
92  VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCI{};
93 
94  PipelineViewportStateCreateInfo() :
95  VkPipelineViewportStateCreateInfo{} {
96  sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
97  depthClipControlCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT;
98  depthClipControlCI.negativeOneToOne = true;
99  pNext = &depthClipControlCI;
100  }
101 
102  void update() {
103  if (viewports.empty()) {
104  viewportCount = 1;
105  pViewports = nullptr;
106  } else {
107  viewportCount = (uint32_t)viewports.size();
108  pViewports = viewports.data();
109  }
110 
111  if (scissors.empty()) {
112  scissorCount = 1;
113  pScissors = 0;
114  } else {
115  scissorCount = (uint32_t)scissors.size();
116  pScissors = scissors.data();
117  }
118  }
119  };
120 
121  struct PipelineDepthStencilStateCreateInfo : public VkPipelineDepthStencilStateCreateInfo {
122  explicit PipelineDepthStencilStateCreateInfo(bool depthEnable = true):
123  VkPipelineDepthStencilStateCreateInfo{} {
124  sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
125  if (depthEnable) {
126  depthTestEnable = VK_TRUE; //VKTODO
127  //depthTestEnable = VK_FALSE;
128  depthWriteEnable = VK_TRUE;
129  depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL; //VKTODO
130  //depthCompareOp = VK_COMPARE_OP_ALWAYS;
131  }
132  }
133  };
134  struct GraphicsPipelineBuilder {
135  private:
136  void init() {
137  pipelineCreateInfo.pRasterizationState = &rasterizationState;
138  pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
139  pipelineCreateInfo.pColorBlendState = &colorBlendState;
140  pipelineCreateInfo.pMultisampleState = &multisampleState;
141  pipelineCreateInfo.pViewportState = &viewportState;
142  pipelineCreateInfo.pDepthStencilState = &depthStencilState;
143  pipelineCreateInfo.pDynamicState = &dynamicState;
144  pipelineCreateInfo.pVertexInputState = &vertexInputState;
145  }
146  public:
147  GraphicsPipelineBuilder(const VkDevice& device, const VkPipelineLayout layout, const VkRenderPass& renderPass) :
148  device(device) {
149  pipelineCreateInfo.layout = layout;
150  pipelineCreateInfo.renderPass = renderPass;
151  multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
152  multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
153  init();
154  }
155 
156  GraphicsPipelineBuilder(const GraphicsPipelineBuilder& other) : GraphicsPipelineBuilder(other.device, other.layout, other.renderPass) {}
157 
158  GraphicsPipelineBuilder& operator=(const GraphicsPipelineBuilder& other) = delete;
159 
160  ~GraphicsPipelineBuilder() {
161  destroyShaderModules();
162  }
163 
164  const VkDevice& device;
165  VkPipelineCache pipelineCache{ VK_NULL_HANDLE }; // TODO: Add pipeline cache here
166  // TODO: is this initialized properly
167  VkRenderPass& renderPass { pipelineCreateInfo.renderPass };
168  VkPipelineLayout& layout { pipelineCreateInfo.layout };
169  // TODO: these need to be initialized
170  PipelineInputAssemblyStateCreateInfo inputAssemblyState;
171  PipelineRasterizationStateCreateInfo rasterizationState;
172  VkPipelineMultisampleStateCreateInfo multisampleState {};
173  PipelineDepthStencilStateCreateInfo depthStencilState;
174  PipelineViewportStateCreateInfo viewportState;
175  PipelineDynamicStateCreateInfo dynamicState;
176  PipelineColorBlendStateCreateInfo colorBlendState;
177  PipelineVertexInputStateCreateInfo vertexInputState;
178  std::vector<VkPipelineShaderStageCreateInfo> shaderStages {};
179 
180  VkGraphicsPipelineCreateInfo pipelineCreateInfo{};
181 
182  void update() {
183  pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
184  pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
185  pipelineCreateInfo.pStages = shaderStages.data();
186  dynamicState.update();
187  colorBlendState.update();
188  vertexInputState.update();
189  viewportState.update();
190  }
191 
192  void destroyShaderModules() {
193  for (const auto shaderStage : shaderStages) {
194  vkDestroyShaderModule(device, shaderStage.module, nullptr);
195  }
196  shaderStages.clear();
197  }
198 
199  VkPipeline create(const VkPipelineCache& cache) {
200  update();
201  VkPipeline vkPipeline;
202  VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, nullptr, &vkPipeline));
203  return vkPipeline;
204  }
205 
206  VkPipeline create() {
207  return create(pipelineCache);
208  }
209  };
210  }
211 } // namespace vks::pipelines