VEX Engine
Retro looking game engine made in vulkan mostly because i wanted to understand it better.
Loading...
Searching...
No Matches
Pipeline.cpp
1#include "Pipeline.hpp"
2#include <fstream>
3#include <vulkan/vulkan_core.h>
4
5#include "uniforms.hpp"
6
7namespace vex {
9
10 VulkanPipeline::~VulkanPipeline() {
11 if (m_pipeline != VK_NULL_HANDLE) {
12 vkDestroyPipeline(m_r_context.device, m_pipeline, nullptr);
13 }
14 if (m_layout != VK_NULL_HANDLE) {
15 vkDestroyPipelineLayout(m_r_context.device, m_layout, nullptr);
16 }
17 }
18
19 std::vector<char> VulkanPipeline::readFile(const std::string& filename) {
20 log("Reading shader...");
21
22 std::string realPath = "./" + filename;
23
24 std::ifstream file(realPath, std::ios::ate | std::ios::binary);
25 if (!file.is_open()) {
26 throw_error("Failed to open shader file: " + realPath);
27 }
28 size_t fileSize = file.tellg();
29 std::vector<char> buffer(fileSize);
30 file.seekg(0);
31 file.read(buffer.data(), fileSize);
32 return buffer;
33 }
34
35 void VulkanPipeline::updateViewport(glm::uvec2 resolution) {
36 m_currentRenderResolution = resolution;
37 }
38
40 const std::string& vertShaderPath,
41 const std::string& fragShaderPath,
42 const VkVertexInputBindingDescription& bindingDescription,
43 const std::vector<VkVertexInputAttributeDescription>& attributeDescriptions
44 ) {
45 auto vertShaderCode = readFile(vertShaderPath);
46 auto fragShaderCode = readFile(fragShaderPath);
47
48 log("Creating shader modules...");
49 auto createShaderModule = [&](const std::vector<char>& code) {
50 VkShaderModuleCreateInfo createInfo{};
51 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
52 createInfo.codeSize = code.size();
53 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
54
55 VkShaderModule shaderModule;
56 if (vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
57 throw_error("Failed to create shader module");
58 }
59 return shaderModule;
60 };
61
62 VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
63 VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
64
65 log("Defining shader stages...");
66 VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
67 vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
68 vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
69 vertShaderStageInfo.module = vertShaderModule;
70 vertShaderStageInfo.pName = "main";
71
72 VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
73 fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
74 fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
75 fragShaderStageInfo.module = fragShaderModule;
76 fragShaderStageInfo.pName = "main";
77
78 VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
79
80 log("Creating vertex input state...");
81 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
82 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
83 vertexInputInfo.vertexBindingDescriptionCount = 1;
84 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
85 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
86 vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
87
88 log("Creating pipeline state...");
89 VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
90 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
91 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
92 inputAssembly.primitiveRestartEnable = VK_FALSE;
93
94 VkViewport viewport{};
95 viewport.x = 0.0f;
96 viewport.y = 0.0f;
97 viewport.width = static_cast<float>(m_r_context.currentRenderResolution.x);
98 viewport.height = static_cast<float>(m_r_context.currentRenderResolution.y);
99 viewport.minDepth = 0.0f;
100 viewport.maxDepth = 1.0f;
101
102 VkRect2D scissor{};
103 scissor.offset = {0, 0};
104 scissor.extent = {m_currentRenderResolution.x, m_currentRenderResolution.y};
105
106 log("Creating viewport state...");
107 VkPipelineViewportStateCreateInfo viewportState{};
108 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
109 viewportState.viewportCount = 1;
110 viewportState.pViewports = &viewport;
111 viewportState.scissorCount = 1;
112 viewportState.pScissors = &scissor;
113
114 log("Creating resterazer...");
115 VkPipelineRasterizationStateCreateInfo rasterizer{};
116 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
117 rasterizer.depthClampEnable = VK_FALSE;
118 rasterizer.rasterizerDiscardEnable = VK_FALSE;
119 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
120 rasterizer.lineWidth = 1.0f;
121 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
122 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
123 rasterizer.depthBiasEnable = VK_FALSE;
124
125 log("Creating multisampling...");
126 VkPipelineMultisampleStateCreateInfo multisampling{};
127 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
128 multisampling.sampleShadingEnable = VK_FALSE;
129 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
130
131 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
132 colorBlendAttachment.colorWriteMask =
133 VK_COLOR_COMPONENT_R_BIT |
134 VK_COLOR_COMPONENT_G_BIT |
135 VK_COLOR_COMPONENT_B_BIT |
136 VK_COLOR_COMPONENT_A_BIT;
137 colorBlendAttachment.blendEnable = VK_FALSE;
138 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
139 colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
140 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
141 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
142 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
143 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
144
145 VkPipelineColorBlendStateCreateInfo colorBlending{};
146 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
147 colorBlending.logicOpEnable = VK_FALSE;
148 colorBlending.attachmentCount = 1;
149 colorBlending.pAttachments = &colorBlendAttachment;
150
151 log("Creating Pipeline layout...");
152 VkPushConstantRange pushConstantRange{};
153 pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
154 pushConstantRange.offset = 0;
155 pushConstantRange.size = sizeof(PushConstants);
156
157 VkDescriptorSetLayout textureLayout = m_r_context.supportsBindlessTextures
158 ? m_r_context.bindlessDescriptorSetLayout
159 : m_r_context.textureDescriptorSetLayout;
160
161 std::array<VkDescriptorSetLayout, 2> setLayouts = {
162 m_r_context.uboDescriptorSetLayout,
163 textureLayout
164 };
165
166 VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
167 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
168 pipelineLayoutInfo.setLayoutCount = setLayouts.size();
169 pipelineLayoutInfo.pSetLayouts = setLayouts.data();
170 pipelineLayoutInfo.pushConstantRangeCount = 1;
171 pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
172
173 log("Creating pipeline layout with %d descriptor sets", setLayouts.size());
174 if (vkCreatePipelineLayout(m_r_context.device, &pipelineLayoutInfo, nullptr, &m_layout) != VK_SUCCESS) {
175 throw_error("Failed to create pipeline layout!");
176 }
177
178 VkPipelineDepthStencilStateCreateInfo depthStencil{};
179 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
180 depthStencil.depthTestEnable = VK_TRUE;
181 depthStencil.depthWriteEnable = VK_TRUE;
182 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
183 depthStencil.depthBoundsTestEnable = VK_FALSE;
184 depthStencil.minDepthBounds = 0.0f;
185 depthStencil.maxDepthBounds = 1.0f;
186 depthStencil.stencilTestEnable = VK_FALSE;
187
188 std::vector<VkDynamicState> dynamicStates = {
189 VK_DYNAMIC_STATE_VIEWPORT,
190 VK_DYNAMIC_STATE_SCISSOR
191 };
192
193 VkPipelineDynamicStateCreateInfo dynamicState{};
194 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
195 dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
196 dynamicState.pDynamicStates = dynamicStates.data();
197
198 VkPipelineRenderingCreateInfo renderingCreateInfo{};
199 renderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
200 renderingCreateInfo.colorAttachmentCount = 1;
201 renderingCreateInfo.pColorAttachmentFormats = &m_r_context.swapchainImageFormat;
202 renderingCreateInfo.depthAttachmentFormat = m_r_context.depthFormat;
203
204 log("Creating Graphics pipeline...");
205 VkGraphicsPipelineCreateInfo pipelineInfo{};
206 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
207 pipelineInfo.stageCount = 2;
208 pipelineInfo.pStages = shaderStages;
209 pipelineInfo.pVertexInputState = &vertexInputInfo;
210 pipelineInfo.pInputAssemblyState = &inputAssembly;
211 pipelineInfo.pViewportState = &viewportState;
212 pipelineInfo.pRasterizationState = &rasterizer;
213 pipelineInfo.pMultisampleState = &multisampling;
214 pipelineInfo.pColorBlendState = &colorBlending;
215 pipelineInfo.pDepthStencilState = &depthStencil;
216 pipelineInfo.pDynamicState = &dynamicState;
217 pipelineInfo.layout = m_layout;
218 pipelineInfo.pNext = &renderingCreateInfo;
219
220 if (vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_pipeline) != VK_SUCCESS) {
221 throw_error("Failed to create graphics pipeline");
222 }
223
224 log("Cleanup shader modules...");
225 vkDestroyShaderModule(m_r_context.device, vertShaderModule, nullptr);
226 vkDestroyShaderModule(m_r_context.device, fragShaderModule, nullptr);
227 }
228
230 const std::string& vertShaderPath,
231 const std::string& fragShaderPath,
232 const VkVertexInputBindingDescription& bindingDescription,
233 const std::vector<VkVertexInputAttributeDescription>& attributeDescriptions
234 ) {
235 auto vertShaderCode = readFile(vertShaderPath);
236 auto fragShaderCode = readFile(fragShaderPath);
237
238 log("Creating shader modules...");
239 auto createShaderModule = [&](const std::vector<char>& code) {
240 VkShaderModuleCreateInfo createInfo{};
241 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
242 createInfo.codeSize = code.size();
243 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
244
245 VkShaderModule shaderModule;
246 if (vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
247 throw_error("Failed to create shader module");
248 }
249 return shaderModule;
250 };
251
252 VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
253 VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
254
255 log("Defining shader stages...");
256 VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
257 vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
258 vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
259 vertShaderStageInfo.module = vertShaderModule;
260 vertShaderStageInfo.pName = "main";
261
262 VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
263 fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
264 fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
265 fragShaderStageInfo.module = fragShaderModule;
266 fragShaderStageInfo.pName = "main";
267
268 VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
269
270 log("Creating vertex input state...");
271 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
272 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
273 vertexInputInfo.vertexBindingDescriptionCount = 1;
274 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
275 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
276 vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
277
278 log("Creating pipeline state...");
279 VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
280 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
281 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
282 inputAssembly.primitiveRestartEnable = VK_FALSE;
283
284 VkViewport viewport{};
285 viewport.x = 0.0f;
286 viewport.y = 0.0f;
287 viewport.width = static_cast<float>(m_r_context.currentRenderResolution.x);
288 viewport.height = static_cast<float>(m_r_context.currentRenderResolution.y);
289 viewport.minDepth = 0.0f;
290 viewport.maxDepth = 1.0f;
291
292 VkRect2D scissor{};
293 scissor.offset = {0, 0};
294 scissor.extent = {m_currentRenderResolution.x, m_currentRenderResolution.y};
295
296 log("Creating viewport state...");
297 VkPipelineViewportStateCreateInfo viewportState{};
298 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
299 viewportState.viewportCount = 1;
300 viewportState.pViewports = &viewport;
301 viewportState.scissorCount = 1;
302 viewportState.pScissors = &scissor;
303
304 log("Creating resterazer...");
305 VkPipelineRasterizationStateCreateInfo rasterizer{};
306 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
307 rasterizer.depthClampEnable = VK_FALSE;
308 rasterizer.rasterizerDiscardEnable = VK_FALSE;
309 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
310 rasterizer.lineWidth = 1.0f;
311 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
312 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
313 rasterizer.depthBiasEnable = VK_FALSE;
314
315 log("Creating multisampling...");
316 VkPipelineMultisampleStateCreateInfo multisampling{};
317 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
318 multisampling.sampleShadingEnable = VK_FALSE;
319 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
320
321 VkPipelineColorBlendAttachmentState accumBlend{};
322 accumBlend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
323 accumBlend.blendEnable = VK_TRUE;
324 accumBlend.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
325 accumBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
326 accumBlend.colorBlendOp = VK_BLEND_OP_ADD;
327 accumBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
328 accumBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
329 accumBlend.alphaBlendOp = VK_BLEND_OP_ADD;
330
331 VkPipelineColorBlendAttachmentState revealBlend{};
332 revealBlend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT;
333 revealBlend.blendEnable = VK_TRUE;
334 revealBlend.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
335 revealBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
336 revealBlend.colorBlendOp = VK_BLEND_OP_ADD;
337 revealBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
338 revealBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
339 revealBlend.alphaBlendOp = VK_BLEND_OP_ADD;
340
341 VkPipelineColorBlendAttachmentState colorBlendAttachments[] = { accumBlend, revealBlend };
342
343 VkPipelineColorBlendStateCreateInfo colorBlending{};
344 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
345 colorBlending.logicOpEnable = VK_FALSE;
346 colorBlending.attachmentCount = 2;
347 colorBlending.pAttachments = colorBlendAttachments;
348
349 log("Creating Pipeline layout...");
350 VkPushConstantRange pushConstantRange{};
351 pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
352 pushConstantRange.offset = 0;
353 pushConstantRange.size = sizeof(PushConstants);
354
355 VkDescriptorSetLayout textureLayout = m_r_context.supportsBindlessTextures
356 ? m_r_context.bindlessDescriptorSetLayout
357 : m_r_context.textureDescriptorSetLayout;
358
359 std::array<VkDescriptorSetLayout, 2> setLayouts = {
360 m_r_context.uboDescriptorSetLayout,
361 textureLayout
362 };
363
364 VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
365 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
366 pipelineLayoutInfo.setLayoutCount = setLayouts.size();
367 pipelineLayoutInfo.pSetLayouts = setLayouts.data();
368 pipelineLayoutInfo.pushConstantRangeCount = 1;
369 pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
370
371 log("Creating pipeline layout with %d descriptor sets", setLayouts.size());
372 if (vkCreatePipelineLayout(m_r_context.device, &pipelineLayoutInfo, nullptr, &m_layout) != VK_SUCCESS) {
373 throw_error("Failed to create pipeline layout!");
374 }
375
376 VkPipelineDepthStencilStateCreateInfo depthStencil{};
377 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
378 depthStencil.depthTestEnable = VK_TRUE;
379 depthStencil.depthWriteEnable = VK_FALSE;
380 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
381 depthStencil.depthBoundsTestEnable = VK_FALSE;
382 depthStencil.minDepthBounds = 0.0f;
383 depthStencil.maxDepthBounds = 1.0f;
384 depthStencil.stencilTestEnable = VK_FALSE;
385
386 std::vector<VkDynamicState> dynamicStates = {
387 VK_DYNAMIC_STATE_VIEWPORT,
388 VK_DYNAMIC_STATE_SCISSOR
389 };
390
391 VkPipelineDynamicStateCreateInfo dynamicState{};
392 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
393 dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
394 dynamicState.pDynamicStates = dynamicStates.data();
395
396 VkFormat transFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8_UNORM };
397 VkPipelineRenderingCreateInfo renderingCreateInfo{};
398 renderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
399 renderingCreateInfo.colorAttachmentCount = 2;
400 renderingCreateInfo.pColorAttachmentFormats = transFormats;
401 renderingCreateInfo.depthAttachmentFormat = m_r_context.depthFormat;
402
403 log("Creating Graphics pipeline...");
404 VkGraphicsPipelineCreateInfo pipelineInfo{};
405 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
406 pipelineInfo.stageCount = 2;
407 pipelineInfo.pStages = shaderStages;
408 pipelineInfo.pVertexInputState = &vertexInputInfo;
409 pipelineInfo.pInputAssemblyState = &inputAssembly;
410 pipelineInfo.pViewportState = &viewportState;
411 pipelineInfo.pRasterizationState = &rasterizer;
412 pipelineInfo.pMultisampleState = &multisampling;
413 pipelineInfo.pColorBlendState = &colorBlending;
414 pipelineInfo.pDepthStencilState = &depthStencil;
415 pipelineInfo.pDynamicState = &dynamicState;
416 pipelineInfo.layout = m_layout;
417 pipelineInfo.pNext = &renderingCreateInfo;
418
419 if (vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_pipeline) != VK_SUCCESS) {
420 throw_error("Failed to create graphics pipeline");
421 }
422
423 log("Cleanup shader modules...");
424 vkDestroyShaderModule(m_r_context.device, vertShaderModule, nullptr);
425 vkDestroyShaderModule(m_r_context.device, fragShaderModule, nullptr);
426 }
427
429 const std::string& vertShaderPath,
430 const std::string& fragShaderPath,
431 const VkVertexInputBindingDescription& bindingDescription,
432 const std::vector<VkVertexInputAttributeDescription>& attributeDescriptions
433 ) {
434 auto vertShaderCode = readFile(vertShaderPath);
435 auto fragShaderCode = readFile(fragShaderPath);
436
437 log("Creating shader modules...");
438 auto createShaderModule = [&](const std::vector<char>& code) {
439 VkShaderModuleCreateInfo createInfo{};
440 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
441 createInfo.codeSize = code.size();
442 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
443
444 VkShaderModule shaderModule;
445 if (vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
446 throw_error("Failed to create shader module");
447 }
448 return shaderModule;
449 };
450
451 VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
452 VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
453
454 log("Defining shader stages...");
455 VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
456 vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
457 vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
458 vertShaderStageInfo.module = vertShaderModule;
459 vertShaderStageInfo.pName = "main";
460
461 VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
462 fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
463 fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
464 fragShaderStageInfo.module = fragShaderModule;
465 fragShaderStageInfo.pName = "main";
466
467 VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
468
469 log("Creating vertex input state...");
470 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
471 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
472 vertexInputInfo.vertexBindingDescriptionCount = 1;
473 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
474 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
475 vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
476
477 log("Creating pipeline state...");
478 VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
479 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
480 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
481 inputAssembly.primitiveRestartEnable = VK_FALSE;
482
483 VkViewport viewport{};
484 viewport.x = 0.0f;
485 viewport.y = 0.0f;
486 viewport.width = static_cast<float>(m_r_context.currentRenderResolution.x);
487 viewport.height = static_cast<float>(m_r_context.currentRenderResolution.y);
488 viewport.minDepth = 0.0f;
489 viewport.maxDepth = 1.0f;
490
491 VkRect2D scissor{};
492 scissor.offset = {0, 0};
493 scissor.extent = {m_currentRenderResolution.x, m_currentRenderResolution.y};
494
495 log("Creating viewport state...");
496 VkPipelineViewportStateCreateInfo viewportState{};
497 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
498 viewportState.viewportCount = 1;
499 viewportState.pViewports = &viewport;
500 viewportState.scissorCount = 1;
501 viewportState.pScissors = &scissor;
502
503 log("Creating resterazer...");
504 VkPipelineRasterizationStateCreateInfo rasterizer{};
505 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
506 rasterizer.depthClampEnable = VK_FALSE;
507 rasterizer.rasterizerDiscardEnable = VK_FALSE;
508 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
509 rasterizer.lineWidth = 1.0f;
510 rasterizer.cullMode = VK_CULL_MODE_NONE;
511 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
512 rasterizer.depthBiasEnable = VK_FALSE;
513
514 log("Creating multisampling...");
515 VkPipelineMultisampleStateCreateInfo multisampling{};
516 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
517 multisampling.sampleShadingEnable = VK_FALSE;
518 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
519
520 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
521 colorBlendAttachment.colorWriteMask =
522 VK_COLOR_COMPONENT_R_BIT |
523 VK_COLOR_COMPONENT_G_BIT |
524 VK_COLOR_COMPONENT_B_BIT |
525 VK_COLOR_COMPONENT_A_BIT;
526 colorBlendAttachment.blendEnable = VK_FALSE;
527 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
528 colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
529 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
530 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
531 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
532 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
533
534 VkPipelineColorBlendStateCreateInfo colorBlending{};
535 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
536 colorBlending.logicOpEnable = VK_FALSE;
537 colorBlending.attachmentCount = 1;
538 colorBlending.pAttachments = &colorBlendAttachment;
539
540 log("Creating Pipeline layout...");
541 VkPushConstantRange pushConstantRange{};
542 pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
543 pushConstantRange.offset = 0;
544 pushConstantRange.size = sizeof(PushConstants);
545
546 VkDescriptorSetLayout textureLayout = m_r_context.supportsBindlessTextures
547 ? m_r_context.bindlessDescriptorSetLayout
548 : m_r_context.textureDescriptorSetLayout;
549
550 std::array<VkDescriptorSetLayout, 2> setLayouts = {
551 m_r_context.uboDescriptorSetLayout,
552 textureLayout
553 };
554
555 VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
556 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
557 pipelineLayoutInfo.setLayoutCount = setLayouts.size();
558 pipelineLayoutInfo.pSetLayouts = setLayouts.data();
559 pipelineLayoutInfo.pushConstantRangeCount = 1;
560 pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
561
562 log("Creating pipeline layout with %d descriptor sets", setLayouts.size());
563 if (vkCreatePipelineLayout(m_r_context.device, &pipelineLayoutInfo, nullptr, &m_layout) != VK_SUCCESS) {
564 throw_error("Failed to create pipeline layout!");
565 }
566
567 VkPipelineDepthStencilStateCreateInfo depthStencil{};
568 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
569 depthStencil.depthTestEnable = VK_TRUE;
570 depthStencil.depthWriteEnable = VK_TRUE;
571 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
572 depthStencil.depthBoundsTestEnable = VK_FALSE;
573 depthStencil.minDepthBounds = 0.0f;
574 depthStencil.maxDepthBounds = 1.0f;
575 depthStencil.stencilTestEnable = VK_FALSE;
576
577 std::vector<VkDynamicState> dynamicStates = {
578 VK_DYNAMIC_STATE_VIEWPORT,
579 VK_DYNAMIC_STATE_SCISSOR
580 };
581
582 VkPipelineDynamicStateCreateInfo dynamicState{};
583 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
584 dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
585 dynamicState.pDynamicStates = dynamicStates.data();
586
587 VkPipelineRenderingCreateInfo renderingCreateInfo{};
588 renderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
589 renderingCreateInfo.colorAttachmentCount = 1;
590 renderingCreateInfo.pColorAttachmentFormats = &m_r_context.swapchainImageFormat;
591 renderingCreateInfo.depthAttachmentFormat = m_r_context.depthFormat;
592
593 log("Creating Graphics pipeline...");
594 VkGraphicsPipelineCreateInfo pipelineInfo{};
595 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
596 pipelineInfo.stageCount = 2;
597 pipelineInfo.pStages = shaderStages;
598 pipelineInfo.pVertexInputState = &vertexInputInfo;
599 pipelineInfo.pInputAssemblyState = &inputAssembly;
600 pipelineInfo.pViewportState = &viewportState;
601 pipelineInfo.pRasterizationState = &rasterizer;
602 pipelineInfo.pMultisampleState = &multisampling;
603 pipelineInfo.pColorBlendState = &colorBlending;
604 pipelineInfo.pDepthStencilState = &depthStencil;
605 pipelineInfo.pDynamicState = &dynamicState;
606 pipelineInfo.layout = m_layout;
607 pipelineInfo.pNext = &renderingCreateInfo;
608
609 if (vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_pipeline) != VK_SUCCESS) {
610 throw_error("Failed to create graphics pipeline");
611 }
612
613 log("Cleanup shader modules...");
614 vkDestroyShaderModule(m_r_context.device, vertShaderModule, nullptr);
615 vkDestroyShaderModule(m_r_context.device, fragShaderModule, nullptr);
616 }
617
618 void VulkanPipeline::createSpritePipeline(const std::string& vertPath, const std::string& fragPath, bool isTransparent, bool isInstanced) {
619 auto vertShaderCode = readFile(vertPath);
620 auto fragShaderCode = readFile(fragPath);
621
622 auto createShaderModule = [&](const std::vector<char>& code) {
623 VkShaderModuleCreateInfo createInfo{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
624 createInfo.codeSize = code.size();
625 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
626 VkShaderModule mod;
627 vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &mod);
628 return mod;
629 };
630 VkShaderModule vertMod = createShaderModule(vertShaderCode);
631 VkShaderModule fragMod = createShaderModule(fragShaderCode);
632
633 VkPipelineShaderStageCreateInfo stages[] = {
634 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, VK_SHADER_STAGE_VERTEX_BIT, vertMod, "main", nullptr},
635 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, VK_SHADER_STAGE_FRAGMENT_BIT, fragMod, "main", nullptr}
636 };
637
638 VkPipelineVertexInputStateCreateInfo vertexInputInfo{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
639 vertexInputInfo.vertexBindingDescriptionCount = 0;
640 vertexInputInfo.pVertexBindingDescriptions = nullptr;
641 vertexInputInfo.vertexAttributeDescriptionCount = 0;
642 vertexInputInfo.pVertexAttributeDescriptions = nullptr;
643
644 VkPipelineInputAssemblyStateCreateInfo inputAssembly{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
645 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
646 inputAssembly.primitiveRestartEnable = VK_FALSE;
647
648 VkViewport viewport{0, 0, (float)m_r_context.currentRenderResolution.x, (float)m_r_context.currentRenderResolution.y, 0.0f, 1.0f};
649 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
650 VkPipelineViewportStateCreateInfo viewportState{VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, nullptr, 0, 1, &viewport, 1, &scissor};
651
652 VkPipelineRasterizationStateCreateInfo rasterizer{VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO};
653 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
654 rasterizer.cullMode = VK_CULL_MODE_NONE;
655 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
656 rasterizer.lineWidth = 1.0f;
657 rasterizer.depthClampEnable = VK_FALSE;
658 rasterizer.rasterizerDiscardEnable = VK_FALSE;
659 rasterizer.depthBiasEnable = VK_FALSE;
660
661 VkPipelineMultisampleStateCreateInfo multisampling{VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};
662 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
663 multisampling.sampleShadingEnable = VK_FALSE;
664
665 VkPipelineColorBlendAttachmentState accumBlend{};
666 accumBlend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
667
668 VkPipelineColorBlendAttachmentState revealBlend{};
669 revealBlend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT;
670
671 VkPipelineColorBlendStateCreateInfo colorBlending{VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
672 colorBlending.logicOpEnable = VK_FALSE;
673
674 VkPipelineColorBlendAttachmentState transAttachments[2];
675
676 if (isTransparent) {
677 accumBlend.blendEnable = VK_TRUE;
678 accumBlend.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
679 accumBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
680 accumBlend.colorBlendOp = VK_BLEND_OP_ADD;
681 accumBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
682 accumBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
683 accumBlend.alphaBlendOp = VK_BLEND_OP_ADD;
684
685 revealBlend.blendEnable = VK_TRUE;
686 revealBlend.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
687 revealBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
688 revealBlend.colorBlendOp = VK_BLEND_OP_ADD;
689 revealBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
690 revealBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
691 revealBlend.alphaBlendOp = VK_BLEND_OP_ADD;
692
693 transAttachments[0] = accumBlend;
694 transAttachments[1] = revealBlend;
695
696 colorBlending.attachmentCount = 2;
697 colorBlending.pAttachments = transAttachments;
698 } else {
699 accumBlend.blendEnable = VK_FALSE;
700 accumBlend.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
701 accumBlend.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
702 accumBlend.colorBlendOp = VK_BLEND_OP_ADD;
703 accumBlend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
704 accumBlend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
705 accumBlend.alphaBlendOp = VK_BLEND_OP_ADD;
706 colorBlending.attachmentCount = 1;
707 colorBlending.pAttachments = &accumBlend;
708 }
709
710 VkPipelineDepthStencilStateCreateInfo depthStencil{VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
711 depthStencil.depthTestEnable = VK_TRUE;
712 depthStencil.depthWriteEnable = isTransparent ? VK_FALSE : VK_TRUE;
713 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
714 depthStencil.depthBoundsTestEnable = VK_FALSE;
715 depthStencil.stencilTestEnable = VK_FALSE;
716 depthStencil.minDepthBounds = 0.0f;
717 depthStencil.maxDepthBounds = 1.0f;
718
719 std::vector<VkDynamicState> dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
720 VkPipelineDynamicStateCreateInfo dynamicState{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, (uint32_t)dynamicStates.size(), dynamicStates.data()};
721
722 std::vector<VkDescriptorSetLayout> setLayouts = { m_r_context.uboDescriptorSetLayout };
723
724 if (m_r_context.supportsBindlessTextures) {
725 setLayouts.push_back(m_r_context.bindlessDescriptorSetLayout);
726 } else {
727 setLayouts.push_back(m_r_context.textureDescriptorSetLayout);
728 }
729
730 if (isInstanced) {
731 setLayouts.push_back(m_r_context.particleDescriptorSetLayout);
732 }
733
734 VkPushConstantRange pushConstantRange{};
735 pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
736 pushConstantRange.offset = 0;
737 pushConstantRange.size = isInstanced ? 0 : 48;
738
739 VkPipelineLayoutCreateInfo layoutInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
740 layoutInfo.setLayoutCount = setLayouts.size();
741 layoutInfo.pSetLayouts = setLayouts.data();
742 layoutInfo.pushConstantRangeCount = isInstanced ? 0 : 1;
743 layoutInfo.pPushConstantRanges = isInstanced ? nullptr : &pushConstantRange;
744
745 vkCreatePipelineLayout(m_r_context.device, &layoutInfo, nullptr, &m_layout);
746
747 VkFormat transFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8_UNORM };
748 VkPipelineRenderingCreateInfo renderInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO};
749 renderInfo.colorAttachmentCount = isTransparent ? 2 : 1;
750 renderInfo.pColorAttachmentFormats = isTransparent ? transFormats : &m_r_context.swapchainImageFormat;
751 renderInfo.depthAttachmentFormat = m_r_context.depthFormat;
752
753 VkGraphicsPipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
754 pipelineInfo.pNext = &renderInfo;
755 pipelineInfo.stageCount = 2;
756 pipelineInfo.pStages = stages;
757 pipelineInfo.pVertexInputState = &vertexInputInfo;
758 pipelineInfo.pInputAssemblyState = &inputAssembly;
759 pipelineInfo.pViewportState = &viewportState;
760 pipelineInfo.pRasterizationState = &rasterizer;
761 pipelineInfo.pMultisampleState = &multisampling;
762 pipelineInfo.pColorBlendState = &colorBlending;
763 pipelineInfo.pDepthStencilState = &depthStencil;
764 pipelineInfo.pDynamicState = &dynamicState;
765 pipelineInfo.layout = m_layout;
766 pipelineInfo.subpass = 0;
767 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
768
769 vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_pipeline);
770
771 vkDestroyShaderModule(m_r_context.device, vertMod, nullptr);
772 vkDestroyShaderModule(m_r_context.device, fragMod, nullptr);
773 }
774
776 const std::string& vertShaderPath,
777 const std::string& fragShaderPath,
778 const VkVertexInputBindingDescription& bindingDesc,
779 const std::vector<VkVertexInputAttributeDescription>& attrDesc)
780 {
781 auto vertShaderCode = readFile(vertShaderPath);
782 auto fragShaderCode = readFile(fragShaderPath);
783
784 auto createShaderModule = [&](const std::vector<char>& code) {
785 VkShaderModuleCreateInfo createInfo{};
786 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
787 createInfo.codeSize = code.size();
788 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
789
790 VkShaderModule shaderModule;
791 if (vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
792 throw_error("Failed to create UI shader module");
793 }
794 return shaderModule;
795 };
796
797 VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
798 VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
799
800 VkPipelineShaderStageCreateInfo vertStage{};
801 vertStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
802 vertStage.stage = VK_SHADER_STAGE_VERTEX_BIT;
803 vertStage.module = vertShaderModule;
804 vertStage.pName = "main";
805
806 VkPipelineShaderStageCreateInfo fragStage{};
807 fragStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
808 fragStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
809 fragStage.module = fragShaderModule;
810 fragStage.pName = "main";
811
812 VkPipelineShaderStageCreateInfo shaderStages[] = { vertStage, fragStage };
813
814 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
815 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
816 vertexInputInfo.vertexBindingDescriptionCount = 1;
817 vertexInputInfo.pVertexBindingDescriptions = &bindingDesc;
818 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attrDesc.size());
819 vertexInputInfo.pVertexAttributeDescriptions = attrDesc.data();
820
821 VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
822 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
823 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
824 inputAssembly.primitiveRestartEnable = VK_FALSE;
825
826 VkPipelineViewportStateCreateInfo viewportState{};
827 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
828 viewportState.viewportCount = 1;
829 viewportState.scissorCount = 1;
830
831 VkPipelineRasterizationStateCreateInfo rasterizer{};
832 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
833 rasterizer.depthClampEnable = VK_FALSE;
834 rasterizer.rasterizerDiscardEnable = VK_FALSE;
835 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
836 rasterizer.lineWidth = 1.0f;
837 rasterizer.cullMode = VK_CULL_MODE_NONE;
838 rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
839 rasterizer.depthBiasEnable = VK_FALSE;
840
841 VkPipelineMultisampleStateCreateInfo multisampling{};
842 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
843 multisampling.sampleShadingEnable = VK_FALSE;
844 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
845
846 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
847 colorBlendAttachment.colorWriteMask =
848 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
849 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
850 colorBlendAttachment.blendEnable = VK_TRUE;
851 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
852 colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
853 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
854 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
855 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
856 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
857
858 VkPipelineColorBlendStateCreateInfo colorBlending{};
859 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
860 colorBlending.logicOpEnable = VK_FALSE;
861 colorBlending.attachmentCount = 1;
862 colorBlending.pAttachments = &colorBlendAttachment;
863
864 VkPipelineDepthStencilStateCreateInfo depthStencil{};
865 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
866 depthStencil.depthTestEnable = VK_FALSE;
867 depthStencil.depthWriteEnable = VK_FALSE;
868 depthStencil.stencilTestEnable= VK_FALSE;
869
870 std::vector<VkDynamicState> dynamicStates = {
871 VK_DYNAMIC_STATE_VIEWPORT,
872 VK_DYNAMIC_STATE_SCISSOR
873 };
874 VkPipelineDynamicStateCreateInfo dynamicState{};
875 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
876 dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
877 dynamicState.pDynamicStates = dynamicStates.data();
878
879 VkPushConstantRange pushConstantRange{};
880 pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
881 pushConstantRange.offset = 0;
882 pushConstantRange.size = sizeof(UIPushConstants);
883
884 VkDescriptorSetLayout textureLayout = m_r_context.supportsBindlessTextures
885 ? m_r_context.bindlessDescriptorSetLayout
886 : m_r_context.textureDescriptorSetLayout;
887
888 std::array<VkDescriptorSetLayout, 2> setLayouts = {
889 m_r_context.uboDescriptorSetLayout,
890 textureLayout
891 };
892
893 VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
894 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
895 pipelineLayoutInfo.setLayoutCount = setLayouts.size();
896 pipelineLayoutInfo.pSetLayouts = setLayouts.data();
897 pipelineLayoutInfo.pushConstantRangeCount = 1;
898 pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
899
900 if (vkCreatePipelineLayout(m_r_context.device, &pipelineLayoutInfo,
901 nullptr, &m_layout) != VK_SUCCESS) {
902 throw_error("Failed to create UI pipeline layout!");
903 }
904
905 VkPipelineRenderingCreateInfo renderingCreateInfo{};
906 renderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
907 renderingCreateInfo.colorAttachmentCount = 1;
908 renderingCreateInfo.pColorAttachmentFormats = &m_r_context.swapchainImageFormat;
909 renderingCreateInfo.depthAttachmentFormat = m_r_context.depthFormat;
910
911 VkGraphicsPipelineCreateInfo pipelineInfo{};
912 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
913 pipelineInfo.stageCount = 2;
914 pipelineInfo.pStages = shaderStages;
915 pipelineInfo.pVertexInputState = &vertexInputInfo;
916 pipelineInfo.pInputAssemblyState = &inputAssembly;
917 pipelineInfo.pViewportState = &viewportState;
918 pipelineInfo.pRasterizationState = &rasterizer;
919 pipelineInfo.pMultisampleState = &multisampling;
920 pipelineInfo.pColorBlendState = &colorBlending;
921 pipelineInfo.pDepthStencilState = &depthStencil;
922 pipelineInfo.pDynamicState = &dynamicState;
923 pipelineInfo.layout = m_layout;
924 pipelineInfo.pNext = &renderingCreateInfo;
925
926 if (vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1,
927 &pipelineInfo, nullptr, &m_pipeline) != VK_SUCCESS) {
928 throw_error("Failed to create UI graphics pipeline");
929 }
930
931 vkDestroyShaderModule(m_r_context.device, vertShaderModule, nullptr);
932 vkDestroyShaderModule(m_r_context.device, fragShaderModule, nullptr);
933 }
934
935 void VulkanPipeline::createFullscreenPipeline(const std::string& vertPath, const std::string& fragPath) {
936 auto vertShaderCode = readFile(vertPath);
937 auto fragShaderCode = readFile(fragPath);
938
939 auto createShaderModule = [&](const std::vector<char>& code) {
940 VkShaderModuleCreateInfo createInfo{};
941 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
942 createInfo.codeSize = code.size();
943 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
944
945 VkShaderModule shaderModule;
946 if (vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
947 throw_error("Failed to create UI shader module");
948 }
949 return shaderModule;
950 };
951
952 VkShaderModule vertModule = createShaderModule(vertShaderCode);
953 VkShaderModule fragModule = createShaderModule(fragShaderCode);
954
955 VkPipelineShaderStageCreateInfo vertStage{};
956 vertStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
957 vertStage.stage = VK_SHADER_STAGE_VERTEX_BIT;
958 vertStage.module = vertModule;
959 vertStage.pName = "main";
960
961 VkPipelineShaderStageCreateInfo fragStage{};
962 fragStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
963 fragStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
964 fragStage.module = fragModule;
965 fragStage.pName = "main";
966
967 VkPipelineShaderStageCreateInfo stages[] = { vertStage, fragStage };
968
969 VkPipelineVertexInputStateCreateInfo vertexInputInfo{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
970
971 VkPipelineInputAssemblyStateCreateInfo inputAssembly{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
972 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
973
974 VkPipelineViewportStateCreateInfo viewportState{VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
975 viewportState.viewportCount = 1;
976 viewportState.scissorCount = 1;
977
978 VkPipelineRasterizationStateCreateInfo rasterizer{VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO};
979 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
980 rasterizer.lineWidth = 1.0f;
981 rasterizer.cullMode = VK_CULL_MODE_NONE;
982 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
983
984 VkPipelineMultisampleStateCreateInfo multisampling{VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};
985 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
986
987 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
988 colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
989 colorBlendAttachment.blendEnable = VK_FALSE;
990
991 VkPipelineColorBlendStateCreateInfo colorBlending{VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
992 colorBlending.attachmentCount = 1;
993 colorBlending.pAttachments = &colorBlendAttachment;
994
995 std::array<VkDescriptorSetLayout, 2> setLayouts = {
996 m_r_context.uboDescriptorSetLayout,
997 m_r_context.screenDescriptorSetLayout
998 };
999
1000 VkPipelineLayoutCreateInfo pipelineLayoutInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
1001 pipelineLayoutInfo.setLayoutCount = setLayouts.size();
1002 pipelineLayoutInfo.pSetLayouts = setLayouts.data();
1003
1004 if (vkCreatePipelineLayout(m_r_context.device, &pipelineLayoutInfo, nullptr, &m_layout) != VK_SUCCESS) {
1005 throw_error("Failed to create fullscreen layout");
1006 }
1007
1008 VkPipelineDepthStencilStateCreateInfo depthStencil{VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
1009 depthStencil.depthTestEnable = VK_FALSE;
1010 depthStencil.depthWriteEnable = VK_FALSE;
1011
1012 std::vector<VkDynamicState> dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
1013 VkPipelineDynamicStateCreateInfo dynamicState{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO};
1014 dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
1015 dynamicState.pDynamicStates = dynamicStates.data();
1016
1017 VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO};
1018 renderingCreateInfo.colorAttachmentCount = 1;
1019 renderingCreateInfo.pColorAttachmentFormats = &m_r_context.swapchainImageFormat;
1020
1021 VkGraphicsPipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
1022 pipelineInfo.pNext = &renderingCreateInfo;
1023 pipelineInfo.stageCount = 2;
1024 pipelineInfo.pStages = stages;
1025 pipelineInfo.pVertexInputState = &vertexInputInfo;
1026 pipelineInfo.pInputAssemblyState = &inputAssembly;
1027 pipelineInfo.pViewportState = &viewportState;
1028 pipelineInfo.pRasterizationState = &rasterizer;
1029 pipelineInfo.pMultisampleState = &multisampling;
1030 pipelineInfo.pColorBlendState = &colorBlending;
1031 pipelineInfo.pDepthStencilState = &depthStencil;
1032 pipelineInfo.pDynamicState = &dynamicState;
1033 pipelineInfo.layout = m_layout;
1034
1035 if (vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_pipeline) != VK_SUCCESS) {
1036 throw_error("Failed to create fullscreen pipeline");
1037 }
1038
1039 vkDestroyShaderModule(m_r_context.device, vertModule, nullptr);
1040 vkDestroyShaderModule(m_r_context.device, fragModule, nullptr);
1041 }
1042
1043 #if DEBUG
1044 void VulkanPipeline::createDebugPipeline(const std::string& vertShaderPath, const std::string& fragShaderPath) {
1045 log("Creating Debug Pipeline...");
1046
1047 auto vertShaderCode = readFile(vertShaderPath);
1048 auto fragShaderCode = readFile(fragShaderPath);
1049
1050 auto createShaderModule = [&](const std::vector<char>& code) {
1051 VkShaderModuleCreateInfo createInfo{};
1052 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1053 createInfo.codeSize = code.size();
1054 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
1055 VkShaderModule shaderModule;
1056 if (vkCreateShaderModule(m_r_context.device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
1057 throw_error("Failed to create debug shader module");
1058 }
1059 return shaderModule;
1060 };
1061
1062 VkShaderModule vertModule = createShaderModule(vertShaderCode);
1063 VkShaderModule fragModule = createShaderModule(fragShaderCode);
1064
1065 VkPipelineShaderStageCreateInfo vertStage{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
1066 vertStage.stage = VK_SHADER_STAGE_VERTEX_BIT;
1067 vertStage.module = vertModule;
1068 vertStage.pName = "main";
1069
1070 VkPipelineShaderStageCreateInfo fragStage{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
1071 fragStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
1072 fragStage.module = fragModule;
1073 fragStage.pName = "main";
1074
1075 VkPipelineShaderStageCreateInfo shaderStages[] = { vertStage, fragStage };
1076
1077 VkVertexInputBindingDescription bindingDesc{};
1078 bindingDesc.binding = 0;
1079 bindingDesc.stride = sizeof(float) * 7;
1080 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1081
1082 std::vector<VkVertexInputAttributeDescription> attrDesc(2);
1083
1084 attrDesc[0].binding = 0;
1085 attrDesc[0].location = 0;
1086 attrDesc[0].format = VK_FORMAT_R32G32B32_SFLOAT;
1087 attrDesc[0].offset = 0;
1088
1089 attrDesc[1].binding = 0;
1090 attrDesc[1].location = 1;
1091 attrDesc[1].format = VK_FORMAT_R32G32B32A32_SFLOAT;
1092 attrDesc[1].offset = sizeof(float) * 3;
1093
1094 VkPipelineVertexInputStateCreateInfo vertexInputInfo{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
1095 vertexInputInfo.vertexBindingDescriptionCount = 1;
1096 vertexInputInfo.pVertexBindingDescriptions = &bindingDesc;
1097 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attrDesc.size());
1098 vertexInputInfo.pVertexAttributeDescriptions = attrDesc.data();
1099
1100 VkPipelineInputAssemblyStateCreateInfo inputAssembly{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
1101 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1102 inputAssembly.primitiveRestartEnable = VK_FALSE;
1103
1104 VkPipelineViewportStateCreateInfo viewportState{VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
1105 viewportState.viewportCount = 1;
1106 viewportState.scissorCount = 1;
1107
1108 VkPipelineRasterizationStateCreateInfo rasterizer{VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO};
1109 rasterizer.depthClampEnable = VK_FALSE;
1110 rasterizer.rasterizerDiscardEnable = VK_FALSE;
1111 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
1112 rasterizer.lineWidth = 1.0f;
1113 rasterizer.cullMode = VK_CULL_MODE_NONE;
1114 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1115 rasterizer.depthBiasEnable = VK_FALSE;
1116
1117 VkPipelineMultisampleStateCreateInfo multisampling{VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};
1118 multisampling.sampleShadingEnable = VK_FALSE;
1119 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1120
1121 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
1122 colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1123 colorBlendAttachment.blendEnable = VK_FALSE;
1124
1125 VkPipelineColorBlendStateCreateInfo colorBlending{VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
1126 colorBlending.logicOpEnable = VK_FALSE;
1127 colorBlending.attachmentCount = 1;
1128 colorBlending.pAttachments = &colorBlendAttachment;
1129
1130 VkPipelineDepthStencilStateCreateInfo depthStencil{VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
1131 depthStencil.depthTestEnable = VK_TRUE;
1132 depthStencil.depthWriteEnable = VK_TRUE;
1133 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
1134 depthStencil.stencilTestEnable = VK_FALSE;
1135
1136 std::vector<VkDynamicState> dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
1137 VkPipelineDynamicStateCreateInfo dynamicState{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO};
1138 dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
1139 dynamicState.pDynamicStates = dynamicStates.data();
1140
1141 VkPipelineLayoutCreateInfo pipelineLayoutInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
1142 pipelineLayoutInfo.setLayoutCount = 1;
1143 pipelineLayoutInfo.pSetLayouts = &m_r_context.uboDescriptorSetLayout;
1144
1145 if (vkCreatePipelineLayout(m_r_context.device, &pipelineLayoutInfo, nullptr, &m_layout) != VK_SUCCESS) {
1146 throw_error("Failed to create debug pipeline layout");
1147 }
1148
1149 VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO};
1150 renderingCreateInfo.colorAttachmentCount = 1;
1151 renderingCreateInfo.pColorAttachmentFormats = &m_r_context.swapchainImageFormat;
1152 renderingCreateInfo.depthAttachmentFormat = m_r_context.depthFormat;
1153
1154 VkGraphicsPipelineCreateInfo pipelineInfo{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
1155 pipelineInfo.pNext = &renderingCreateInfo;
1156 pipelineInfo.stageCount = 2;
1157 pipelineInfo.pStages = shaderStages;
1158 pipelineInfo.pVertexInputState = &vertexInputInfo;
1159 pipelineInfo.pInputAssemblyState = &inputAssembly;
1160 pipelineInfo.pViewportState = &viewportState;
1161 pipelineInfo.pRasterizationState = &rasterizer;
1162 pipelineInfo.pMultisampleState = &multisampling;
1163 pipelineInfo.pColorBlendState = &colorBlending;
1164 pipelineInfo.pDepthStencilState = &depthStencil;
1165 pipelineInfo.pDynamicState = &dynamicState;
1166 pipelineInfo.layout = m_layout;
1167 pipelineInfo.subpass = 0;
1168 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
1169
1170 if (vkCreateGraphicsPipelines(m_r_context.device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &m_pipeline) != VK_SUCCESS) {
1171 throw_error("Failed to create debug graphics pipeline");
1172 }
1173
1174 vkDestroyShaderModule(m_r_context.device, vertModule, nullptr);
1175 vkDestroyShaderModule(m_r_context.device, fragModule, nullptr);
1176
1177 log("Debug Pipeline created successfully.");
1178 }
1179 #endif
1180}
This file defines VulkanPipeline Class.
void createMaskedPipeline(const std::string &vertShaderPath, const std::string &fragShaderPath, const VkVertexInputBindingDescription &bindingDescription, const std::vector< VkVertexInputAttributeDescription > &attributeDescriptions)
Creates a Masked Graphics Pipeline (Alpha Cutout).
Definition Pipeline.cpp:428
void createUIPipeline(const std::string &vertShaderPath, const std::string &fragShaderPath, const VkVertexInputBindingDescription &bindingDesc, const std::vector< VkVertexInputAttributeDescription > &attrDesc)
Creates a UI Pipeline.
Definition Pipeline.cpp:775
std::vector< char > readFile(const std::string &filename)
Reads a file and returns its contents as a vector of characters.
Definition Pipeline.cpp:19
VulkanPipeline(VulkanContext &r_context)
Constructor for VulkanPipeline.
Definition Pipeline.cpp:8
VulkanContext & m_r_context
Creates a debug VkPipeline.
Definition Pipeline.hpp:121
void updateViewport(glm::uvec2 resolution)
Updates viewport to new resolution.
Definition Pipeline.cpp:35
void createSpritePipeline(const std::string &vertPath, const std::string &fragPath, bool isTransparent, bool isInstanced)
Creates a Sprite Graphics Pipeline (used for Billboards and Particles).
Definition Pipeline.cpp:618
void createGraphicsPipeline(const std::string &vertShaderPath, const std::string &fragShaderPath, const VkVertexInputBindingDescription &bindingDescription, const std::vector< VkVertexInputAttributeDescription > &attributeDescriptions)
Creates a standard Opaque Graphics Pipeline.
Definition Pipeline.cpp:39
void createFullscreenPipeline(const std::string &vertPath, const std::string &fragPath)
Creates a Fullscreen Quad Pipeline.
Definition Pipeline.cpp:935
void createTransparentPipeline(const std::string &vertShaderPath, const std::string &fragShaderPath, const VkVertexInputBindingDescription &bindingDescription, const std::vector< VkVertexInputAttributeDescription > &attributeDescriptions)
Creates a Transparent Graphics Pipeline.
Definition Pipeline.cpp:229
void VEX_EXPORT throw_error(const std::string &msg)
Throws an error or terminates the application.
void VEX_EXPORT log(const char *fmt,...)
Logs a formatted message.
Push constants, holds model information.
Definition uniforms.hpp:53
Push constants for UI rendering.
Definition UIVertex.hpp:23
Struct holding all vulkan data, like device, surface, swapchain, images, views, and more.
Definition context.hpp:26
This file defines uniforms and pushconstant for rendering meshes.