15 if (!bFrameStarted)
return;
18 if (m_inGeometryPass)
return;
19 if (skyboxPipeline == VK_NULL_HANDLE || !m_skyboxDescriptorsWritten)
22 m_activeCustomFormat = 0;
23 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS,
26 if (CurrentFrameIndex < skyboxDescriptorSets.size()) {
27 vkCmdBindDescriptorSets(
28 command, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLay, 0, 1,
29 &skyboxDescriptorSets[CurrentFrameIndex], 0,
nullptr);
36 if (!bFrameStarted)
return;
40 VkPipeline restoreTo =
41 (m_inGeometryPass && m_gbufferPipeline != VK_NULL_HANDLE)
42 ? m_gbufferPipeline : pipeline;
43 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, restoreTo);
49 if (!m_inGeometryPass && m_textureDescriptorsWritten &&
50 CurrentFrameIndex < descriptorSets.size()) {
51 vkCmdBindDescriptorSets(
52 command, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLay, 0, 1,
53 &descriptorSets[CurrentFrameIndex], 0,
nullptr);
58bool VulkanRenderer::CreateGraphicsPipeline() {
63 simpleShader->
compile(
"assets/shaders/default_shader");
68 VkPipelineShaderStageCreateInfo shaderStages[] = {
72 std::vector<VkDynamicState> dynamicStates = {
73 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
75 VkPipelineDynamicStateCreateInfo dynamicState{};
77 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
78 dynamicState.dynamicStateCount =
79 static_cast<uint32_t
>(dynamicStates.size());
80 dynamicState.pDynamicStates = dynamicStates.data();
83 VkVertexInputBindingDescription bindingDescription{};
84 bindingDescription.binding = 0;
85 bindingDescription.stride =
sizeof(
Vertex);
86 bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
88 std::array<VkVertexInputAttributeDescription, 7> attributeDescs{};
91 attributeDescs[0].binding = 0;
92 attributeDescs[0].location = 0;
93 attributeDescs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
94 attributeDescs[0].offset = offsetof(
Vertex, px);
97 attributeDescs[1].binding = 0;
98 attributeDescs[1].location = 1;
99 attributeDescs[1].format = VK_FORMAT_R32G32B32_SFLOAT;
100 attributeDescs[1].offset = offsetof(
Vertex, nx);
103 attributeDescs[2].binding = 0;
104 attributeDescs[2].location = 2;
105 attributeDescs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
106 attributeDescs[2].offset = offsetof(
Vertex, tx);
109 attributeDescs[3].binding = 0;
110 attributeDescs[3].location = 3;
111 attributeDescs[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
112 attributeDescs[3].offset = offsetof(
Vertex, r);
115 attributeDescs[4].binding = 0;
116 attributeDescs[4].location = 4;
117 attributeDescs[4].format = VK_FORMAT_R32G32_SFLOAT;
118 attributeDescs[4].offset = offsetof(
Vertex, u);
121 attributeDescs[5].binding = 0;
122 attributeDescs[5].location = 5;
123 attributeDescs[5].format = VK_FORMAT_R32G32B32A32_SINT;
124 attributeDescs[5].offset = offsetof(
Vertex, boneIDs);
127 attributeDescs[6].binding = 0;
128 attributeDescs[6].location = 6;
129 attributeDescs[6].format = VK_FORMAT_R32G32B32A32_SFLOAT;
130 attributeDescs[6].offset = offsetof(
Vertex, boneWeights);
132 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
133 vertexInputInfo.sType =
134 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
135 vertexInputInfo.vertexBindingDescriptionCount = 1;
136 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
137 vertexInputInfo.vertexAttributeDescriptionCount =
138 static_cast<uint32_t
>(attributeDescs.size());
139 vertexInputInfo.pVertexAttributeDescriptions = attributeDescs.data();
142 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo{};
143 inputAssemblyInfo.sType =
144 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
145 inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
146 inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
149 VkPipelineViewportStateCreateInfo viewportInfo{};
151 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
152 viewportInfo.viewportCount = 1;
153 viewportInfo.scissorCount = 1;
156 VkPipelineRasterizationStateCreateInfo rasterizer{};
158 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
159 rasterizer.depthClampEnable = VK_FALSE;
160 rasterizer.rasterizerDiscardEnable = VK_FALSE;
161 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
162 rasterizer.lineWidth = 1.0f;
163 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
164 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
165 rasterizer.depthBiasEnable = VK_FALSE;
168 VkPipelineMultisampleStateCreateInfo msaa{};
170 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
171 msaa.sampleShadingEnable = VK_FALSE;
172 msaa.rasterizationSamples = m_msaaSamples;
175 VkPipelineDepthStencilStateCreateInfo depthStencil{};
177 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
178 depthStencil.depthTestEnable = VK_TRUE;
179 depthStencil.depthWriteEnable = VK_TRUE;
180 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
181 depthStencil.depthBoundsTestEnable = VK_FALSE;
182 depthStencil.stencilTestEnable = VK_FALSE;
185 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
186 colorBlendAttachment.blendEnable = VK_TRUE;
187 colorBlendAttachment.colorWriteMask =
188 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
189 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
190 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
191 colorBlendAttachment.dstColorBlendFactor =
192 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
193 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
194 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
195 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
196 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
198 VkPipelineColorBlendStateCreateInfo colorBlendInfo{};
199 colorBlendInfo.sType =
200 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
201 colorBlendInfo.logicOpEnable = VK_FALSE;
202 colorBlendInfo.attachmentCount = 1;
203 colorBlendInfo.pAttachments = &colorBlendAttachment;
207 VkPushConstantRange pushConstantRange{};
208 pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
209 pushConstantRange.offset = 0;
210 pushConstantRange.size = 128;
215 std::array<VkDescriptorSetLayout, 4> setLayouts = {
216 descriptorSetLayout, boneDescriptorSetLayout,
217 m_lightUBODescriptorSetLayout, m_shadowSamplerDescriptorSetLayout
220 VkPipelineLayoutCreateInfo layoutInfo{};
221 layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
222 layoutInfo.setLayoutCount =
static_cast<uint32_t
>(setLayouts.size());
223 layoutInfo.pSetLayouts = setLayouts.data();
224 layoutInfo.pushConstantRangeCount = 1;
225 layoutInfo.pPushConstantRanges = &pushConstantRange;
227 result = vkCreatePipelineLayout(device, &layoutInfo,
nullptr,
229 if (result != VK_SUCCESS)
233 VkGraphicsPipelineCreateInfo pipelineInfo{};
234 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
235 pipelineInfo.stageCount = 2;
236 pipelineInfo.pStages = shaderStages;
237 pipelineInfo.pVertexInputState = &vertexInputInfo;
238 pipelineInfo.pInputAssemblyState = &inputAssemblyInfo;
239 pipelineInfo.pViewportState = &viewportInfo;
240 pipelineInfo.pRasterizationState = &rasterizer;
241 pipelineInfo.pMultisampleState = &msaa;
242 pipelineInfo.pDepthStencilState = &depthStencil;
243 pipelineInfo.pColorBlendState = &colorBlendInfo;
244 pipelineInfo.pDynamicState = &dynamicState;
245 pipelineInfo.layout = pipelineLay;
246 pipelineInfo.subpass = 0;
247 pipelineInfo.renderPass = (
m_deferredEnabled && m_forwardRenderPass != VK_NULL_HANDLE)
248 ? m_forwardRenderPass : renderPass;
249 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
250 pipelineInfo.basePipelineIndex = -1;
252 result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1,
253 &pipelineInfo,
nullptr, &pipeline);
254 if (result != VK_SUCCESS)
255 SLEAK_ERROR(
"Failed to create graphics pipeline!!");
262bool VulkanRenderer::CreateRenderPass() {
263 const bool msaaEnabled = (m_msaaSamples != VK_SAMPLE_COUNT_1_BIT);
266 VkAttachmentDescription colorAttachment{};
267 colorAttachment.format = scImageFormat;
268 colorAttachment.samples = m_msaaSamples;
269 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
270 colorAttachment.storeOp = msaaEnabled ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
271 colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
272 colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
273 colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
274 colorAttachment.finalLayout = msaaEnabled ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
276 VkAttachmentReference colorRef{};
277 colorRef.attachment = 0;
278 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
281 VkAttachmentDescription depthAttachment{};
282 depthAttachment.format = depthFormat;
283 depthAttachment.samples = m_msaaSamples;
284 depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
285 depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
286 depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
287 depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
288 depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
289 depthAttachment.finalLayout =
290 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
292 VkAttachmentReference depthRef{};
293 depthRef.attachment = 1;
294 depthRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
297 VkAttachmentDescription resolveAttachment{};
298 VkAttachmentReference resolveRef{};
300 resolveAttachment.format = scImageFormat;
301 resolveAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
302 resolveAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
303 resolveAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
304 resolveAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
305 resolveAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
306 resolveAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
307 resolveAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
309 resolveRef.attachment = 2;
310 resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
314 VkSubpassDescription subpass{};
315 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
316 subpass.colorAttachmentCount = 1;
317 subpass.pColorAttachments = &colorRef;
318 subpass.pDepthStencilAttachment = &depthRef;
319 subpass.pResolveAttachments = msaaEnabled ? &resolveRef :
nullptr;
322 VkSubpassDependency dependency{};
323 dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
324 dependency.dstSubpass = 0;
325 dependency.srcStageMask =
326 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
327 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
328 dependency.srcAccessMask = 0;
329 dependency.dstStageMask =
330 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
331 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
332 dependency.dstAccessMask =
333 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
334 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
337 std::vector<VkAttachmentDescription> attachments = {
338 colorAttachment, depthAttachment};
340 attachments.push_back(resolveAttachment);
342 VkRenderPassCreateInfo renderInfo{};
343 renderInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
344 renderInfo.attachmentCount =
345 static_cast<uint32_t
>(attachments.size());
346 renderInfo.pAttachments = attachments.data();
347 renderInfo.subpassCount = 1;
348 renderInfo.pSubpasses = &subpass;
349 renderInfo.dependencyCount = 1;
350 renderInfo.pDependencies = &dependency;
352 if (vkCreateRenderPass(device, &renderInfo,
nullptr, &renderPass) !=
361bool VulkanRenderer::CreateFrameBuffer() {
362 swapChainFramebuffers.resize(swapChainImageViews.size());
363 const bool msaaEnabled = (m_msaaSamples != VK_SAMPLE_COUNT_1_BIT);
365 for (
size_t i = 0; i < swapChainImageViews.size(); i++) {
366 std::vector<VkImageView> attachments;
369 attachments = {m_msaaColorImageView, depthImageView, swapChainImageViews[i]};
372 attachments = {swapChainImageViews[i], depthImageView};
375 VkFramebufferCreateInfo info{};
376 info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
377 info.renderPass = renderPass;
378 info.attachmentCount =
379 static_cast<uint32_t
>(attachments.size());
380 info.pAttachments = attachments.data();
382 info.width = scExtent.width;
383 info.height = scExtent.height;
385 if (vkCreateFramebuffer(device, &info,
nullptr,
386 &swapChainFramebuffers[i]) != VK_SUCCESS)
393bool VulkanRenderer::CreateSkyboxPipeline() {
395 skyboxShader =
new VulkanShader(device);
396 if (!skyboxShader->compile(
"assets/shaders/skybox")) {
397 SLEAK_ERROR(
"VulkanRenderer: Failed to compile skybox shaders");
399 skyboxShader =
nullptr;
404 uint32_t imageCount =
405 static_cast<uint32_t
>(swapChainImages.size());
407 VkDescriptorPoolSize poolSize{};
408 poolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
409 poolSize.descriptorCount = imageCount;
411 VkDescriptorPoolCreateInfo poolInfo{};
412 poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
413 poolInfo.poolSizeCount = 1;
414 poolInfo.pPoolSizes = &poolSize;
415 poolInfo.maxSets = imageCount;
417 if (vkCreateDescriptorPool(device, &poolInfo,
nullptr,
418 &skyboxDescriptorPool) != VK_SUCCESS) {
419 SLEAK_ERROR(
"VulkanRenderer: Failed to create skybox descriptor pool");
423 std::vector<VkDescriptorSetLayout> layouts(imageCount,
424 descriptorSetLayout);
426 VkDescriptorSetAllocateInfo allocInfo{};
427 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
428 allocInfo.descriptorPool = skyboxDescriptorPool;
429 allocInfo.descriptorSetCount = imageCount;
430 allocInfo.pSetLayouts = layouts.data();
432 skyboxDescriptorSets.resize(imageCount);
433 if (vkAllocateDescriptorSets(device, &allocInfo,
434 skyboxDescriptorSets.data()) !=
436 SLEAK_ERROR(
"VulkanRenderer: Failed to allocate skybox descriptor sets");
442 VkPipelineShaderStageCreateInfo shaderStages[] = {
443 skyboxShader->GetVertexInfo(), skyboxShader->GetFragInfo()};
445 std::vector<VkDynamicState> dynamicStates = {
446 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
448 VkPipelineDynamicStateCreateInfo dynamicState{};
450 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
451 dynamicState.dynamicStateCount =
452 static_cast<uint32_t
>(dynamicStates.size());
453 dynamicState.pDynamicStates = dynamicStates.data();
456 VkVertexInputBindingDescription bindingDescription{};
457 bindingDescription.binding = 0;
458 bindingDescription.stride =
sizeof(
Vertex);
459 bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
461 std::array<VkVertexInputAttributeDescription, 7> attributeDescs{};
462 attributeDescs[0].binding = 0;
463 attributeDescs[0].location = 0;
464 attributeDescs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
465 attributeDescs[0].offset = offsetof(
Vertex, px);
467 attributeDescs[1].binding = 0;
468 attributeDescs[1].location = 1;
469 attributeDescs[1].format = VK_FORMAT_R32G32B32_SFLOAT;
470 attributeDescs[1].offset = offsetof(
Vertex, nx);
472 attributeDescs[2].binding = 0;
473 attributeDescs[2].location = 2;
474 attributeDescs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
475 attributeDescs[2].offset = offsetof(
Vertex, tx);
477 attributeDescs[3].binding = 0;
478 attributeDescs[3].location = 3;
479 attributeDescs[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
480 attributeDescs[3].offset = offsetof(
Vertex, r);
482 attributeDescs[4].binding = 0;
483 attributeDescs[4].location = 4;
484 attributeDescs[4].format = VK_FORMAT_R32G32_SFLOAT;
485 attributeDescs[4].offset = offsetof(
Vertex, u);
487 attributeDescs[5].binding = 0;
488 attributeDescs[5].location = 5;
489 attributeDescs[5].format = VK_FORMAT_R32G32B32A32_SINT;
490 attributeDescs[5].offset = offsetof(
Vertex, boneIDs);
492 attributeDescs[6].binding = 0;
493 attributeDescs[6].location = 6;
494 attributeDescs[6].format = VK_FORMAT_R32G32B32A32_SFLOAT;
495 attributeDescs[6].offset = offsetof(
Vertex, boneWeights);
497 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
498 vertexInputInfo.sType =
499 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
500 vertexInputInfo.vertexBindingDescriptionCount = 1;
501 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
502 vertexInputInfo.vertexAttributeDescriptionCount =
503 static_cast<uint32_t
>(attributeDescs.size());
504 vertexInputInfo.pVertexAttributeDescriptions = attributeDescs.data();
506 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo{};
507 inputAssemblyInfo.sType =
508 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
509 inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
510 inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
512 VkPipelineViewportStateCreateInfo viewportInfo{};
514 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
515 viewportInfo.viewportCount = 1;
516 viewportInfo.scissorCount = 1;
518 VkPipelineRasterizationStateCreateInfo rasterizer{};
520 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
521 rasterizer.depthClampEnable = VK_FALSE;
522 rasterizer.rasterizerDiscardEnable = VK_FALSE;
523 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
524 rasterizer.lineWidth = 1.0f;
525 rasterizer.cullMode = VK_CULL_MODE_NONE;
526 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
527 rasterizer.depthBiasEnable = VK_FALSE;
529 VkPipelineMultisampleStateCreateInfo msaa{};
531 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
532 msaa.sampleShadingEnable = VK_FALSE;
533 msaa.rasterizationSamples = m_msaaSamples;
536 VkPipelineDepthStencilStateCreateInfo depthStencil{};
538 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
539 depthStencil.depthTestEnable = VK_TRUE;
540 depthStencil.depthWriteEnable = VK_FALSE;
541 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
542 depthStencil.depthBoundsTestEnable = VK_FALSE;
543 depthStencil.stencilTestEnable = VK_FALSE;
545 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
546 colorBlendAttachment.blendEnable = VK_FALSE;
547 colorBlendAttachment.colorWriteMask =
548 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
549 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
551 VkPipelineColorBlendStateCreateInfo colorBlendInfo{};
552 colorBlendInfo.sType =
553 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
554 colorBlendInfo.logicOpEnable = VK_FALSE;
555 colorBlendInfo.attachmentCount = 1;
556 colorBlendInfo.pAttachments = &colorBlendAttachment;
558 VkGraphicsPipelineCreateInfo pipelineInfo{};
559 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
560 pipelineInfo.stageCount = 2;
561 pipelineInfo.pStages = shaderStages;
562 pipelineInfo.pVertexInputState = &vertexInputInfo;
563 pipelineInfo.pInputAssemblyState = &inputAssemblyInfo;
564 pipelineInfo.pViewportState = &viewportInfo;
565 pipelineInfo.pRasterizationState = &rasterizer;
566 pipelineInfo.pMultisampleState = &msaa;
567 pipelineInfo.pDepthStencilState = &depthStencil;
568 pipelineInfo.pColorBlendState = &colorBlendInfo;
569 pipelineInfo.pDynamicState = &dynamicState;
570 pipelineInfo.layout = pipelineLay;
571 pipelineInfo.subpass = 0;
572 pipelineInfo.renderPass = (
m_deferredEnabled && m_forwardRenderPass != VK_NULL_HANDLE)
573 ? m_forwardRenderPass : renderPass;
574 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
575 pipelineInfo.basePipelineIndex = -1;
577 VkResult result = vkCreateGraphicsPipelines(
578 device, VK_NULL_HANDLE, 1, &pipelineInfo,
nullptr, &skyboxPipeline);
579 if (result != VK_SUCCESS) {
580 SLEAK_ERROR(
"VulkanRenderer: Failed to create skybox pipeline!");
584 SLEAK_INFO(
"VulkanRenderer: Skybox pipeline created successfully");
590bool VulkanRenderer::CreateDebugLinePipeline() {
591 if (debugLinePipeline != VK_NULL_HANDLE)
return true;
593 debugLineShader =
new VulkanShader(device);
594 if (!debugLineShader->compile(
"assets/shaders/debug_line")) {
595 SLEAK_ERROR(
"VulkanRenderer: Failed to compile debug line shaders");
596 delete debugLineShader;
597 debugLineShader =
nullptr;
601 VkPipelineShaderStageCreateInfo shaderStages[] = {
602 debugLineShader->GetVertexInfo(), debugLineShader->GetFragInfo()};
604 std::vector<VkDynamicState> dynamicStates = {
605 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
607 VkPipelineDynamicStateCreateInfo dynamicState{};
609 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
610 dynamicState.dynamicStateCount =
611 static_cast<uint32_t
>(dynamicStates.size());
612 dynamicState.pDynamicStates = dynamicStates.data();
614 VkVertexInputBindingDescription bindingDescription{};
615 bindingDescription.binding = 0;
616 bindingDescription.stride =
sizeof(
Vertex);
617 bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
619 std::array<VkVertexInputAttributeDescription, 7> attributeDescs{};
620 attributeDescs[0] = {0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(
Vertex, px)};
621 attributeDescs[1] = {1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(
Vertex, nx)};
622 attributeDescs[2] = {2, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(
Vertex, tx)};
623 attributeDescs[3] = {3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(
Vertex, r)};
624 attributeDescs[4] = {4, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(
Vertex, u)};
625 attributeDescs[5] = {5, 0, VK_FORMAT_R32G32B32A32_SINT, offsetof(
Vertex, boneIDs)};
626 attributeDescs[6] = {6, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(
Vertex, boneWeights)};
628 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
629 vertexInputInfo.sType =
630 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
631 vertexInputInfo.vertexBindingDescriptionCount = 1;
632 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
633 vertexInputInfo.vertexAttributeDescriptionCount =
634 static_cast<uint32_t
>(attributeDescs.size());
635 vertexInputInfo.pVertexAttributeDescriptions = attributeDescs.data();
637 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo{};
638 inputAssemblyInfo.sType =
639 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
640 inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
641 inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
643 VkPipelineViewportStateCreateInfo viewportInfo{};
645 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
646 viewportInfo.viewportCount = 1;
647 viewportInfo.scissorCount = 1;
649 VkPipelineRasterizationStateCreateInfo rasterizer{};
651 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
652 rasterizer.depthClampEnable = VK_FALSE;
653 rasterizer.rasterizerDiscardEnable = VK_FALSE;
654 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
655 rasterizer.lineWidth = 1.0f;
656 rasterizer.cullMode = VK_CULL_MODE_NONE;
657 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
658 rasterizer.depthBiasEnable = VK_FALSE;
660 VkPipelineMultisampleStateCreateInfo msaa{};
662 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
663 msaa.sampleShadingEnable = VK_FALSE;
664 msaa.rasterizationSamples = m_msaaSamples;
666 VkPipelineDepthStencilStateCreateInfo depthStencil{};
668 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
669 depthStencil.depthTestEnable = VK_TRUE;
670 depthStencil.depthWriteEnable = VK_TRUE;
671 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
672 depthStencil.depthBoundsTestEnable = VK_FALSE;
673 depthStencil.stencilTestEnable = VK_FALSE;
675 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
676 colorBlendAttachment.blendEnable = VK_FALSE;
677 colorBlendAttachment.colorWriteMask =
678 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
679 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
681 VkPipelineColorBlendStateCreateInfo colorBlendInfo{};
682 colorBlendInfo.sType =
683 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
684 colorBlendInfo.logicOpEnable = VK_FALSE;
685 colorBlendInfo.attachmentCount = 1;
686 colorBlendInfo.pAttachments = &colorBlendAttachment;
688 VkGraphicsPipelineCreateInfo pipelineInfo{};
689 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
690 pipelineInfo.stageCount = 2;
691 pipelineInfo.pStages = shaderStages;
692 pipelineInfo.pVertexInputState = &vertexInputInfo;
693 pipelineInfo.pInputAssemblyState = &inputAssemblyInfo;
694 pipelineInfo.pViewportState = &viewportInfo;
695 pipelineInfo.pRasterizationState = &rasterizer;
696 pipelineInfo.pMultisampleState = &msaa;
697 pipelineInfo.pDepthStencilState = &depthStencil;
698 pipelineInfo.pColorBlendState = &colorBlendInfo;
699 pipelineInfo.pDynamicState = &dynamicState;
700 pipelineInfo.layout = pipelineLay;
701 pipelineInfo.subpass = 0;
702 pipelineInfo.renderPass = (
m_deferredEnabled && m_forwardRenderPass != VK_NULL_HANDLE)
703 ? m_forwardRenderPass : renderPass;
704 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
705 pipelineInfo.basePipelineIndex = -1;
707 VkResult result = vkCreateGraphicsPipelines(
708 device, VK_NULL_HANDLE, 1, &pipelineInfo,
nullptr, &debugLinePipeline);
709 if (result != VK_SUCCESS) {
710 SLEAK_ERROR(
"VulkanRenderer: Failed to create debug line pipeline!");
714 SLEAK_INFO(
"VulkanRenderer: Debug line pipeline created successfully");
734 return VK_FORMAT_R32G32B32_SFLOAT;
744 CustomFormatPipelines& pipes = m_customFormatPipelines[format];
747 VkVertexInputBindingDescription bindingDescription{};
748 bindingDescription.binding = 0;
749 bindingDescription.stride = desc->
stride;
750 bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
752 std::vector<VkVertexInputAttributeDescription> attributeDescs;
753 attributeDescs.reserve(desc->
attributes.size());
755 attributeDescs.push_back({attr.location, 0,
759 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
760 vertexInputInfo.sType =
761 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
762 vertexInputInfo.vertexBindingDescriptionCount = 1;
763 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
764 vertexInputInfo.vertexAttributeDescriptionCount =
765 static_cast<uint32_t
>(attributeDescs.size());
766 vertexInputInfo.pVertexAttributeDescriptions = attributeDescs.data();
768 std::vector<VkDynamicState> dynamicStates = {
769 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
771 VkPipelineDynamicStateCreateInfo dynamicState{};
772 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
773 dynamicState.dynamicStateCount =
static_cast<uint32_t
>(dynamicStates.size());
774 dynamicState.pDynamicStates = dynamicStates.data();
777 if (pipes.main == VK_NULL_HANDLE && !pipes.mainFailed) {
779 SLEAK_ERROR(
"VulkanRenderer: Vertex format {} has no main shader stem", format);
780 pipes.mainFailed =
true;
782 const std::string stemPath =
"assets/shaders/" + desc->
shaderStem;
783 auto* shader =
new VulkanShader(device);
784 if (!shader->compile(stemPath)) {
785 SLEAK_ERROR(
"VulkanRenderer: Failed to compile '{}' for vertex format {}",
787 pipes.mainFailed =
true;
790 VkPipelineShaderStageCreateInfo shaderStages[] = {
791 shader->GetVertexInfo(), shader->GetFragInfo()};
793 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo{};
794 inputAssemblyInfo.sType =
795 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
796 inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
797 inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
799 VkPipelineViewportStateCreateInfo viewportInfo{};
800 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
801 viewportInfo.viewportCount = 1;
802 viewportInfo.scissorCount = 1;
804 VkPipelineRasterizationStateCreateInfo rasterizer{};
806 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
807 rasterizer.depthClampEnable = VK_FALSE;
808 rasterizer.rasterizerDiscardEnable = VK_FALSE;
809 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
810 rasterizer.lineWidth = 1.0f;
811 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
812 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
813 rasterizer.depthBiasEnable = VK_FALSE;
815 VkPipelineMultisampleStateCreateInfo msaa{};
816 msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
817 msaa.sampleShadingEnable = VK_FALSE;
818 msaa.rasterizationSamples = m_msaaSamples;
820 VkPipelineDepthStencilStateCreateInfo depthStencil{};
822 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
823 depthStencil.depthTestEnable = VK_TRUE;
824 depthStencil.depthWriteEnable = VK_TRUE;
825 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
826 depthStencil.depthBoundsTestEnable = VK_FALSE;
827 depthStencil.stencilTestEnable = VK_FALSE;
829 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
830 colorBlendAttachment.blendEnable = VK_TRUE;
831 colorBlendAttachment.colorWriteMask =
832 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
833 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
834 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
835 colorBlendAttachment.dstColorBlendFactor =
836 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
837 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
838 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
839 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
840 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
842 VkPipelineColorBlendStateCreateInfo colorBlendInfo{};
843 colorBlendInfo.sType =
844 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
845 colorBlendInfo.logicOpEnable = VK_FALSE;
846 colorBlendInfo.attachmentCount = 1;
847 colorBlendInfo.pAttachments = &colorBlendAttachment;
849 VkGraphicsPipelineCreateInfo pipelineInfo{};
850 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
851 pipelineInfo.stageCount = 2;
852 pipelineInfo.pStages = shaderStages;
853 pipelineInfo.pVertexInputState = &vertexInputInfo;
854 pipelineInfo.pInputAssemblyState = &inputAssemblyInfo;
855 pipelineInfo.pViewportState = &viewportInfo;
856 pipelineInfo.pRasterizationState = &rasterizer;
857 pipelineInfo.pMultisampleState = &msaa;
858 pipelineInfo.pDepthStencilState = &depthStencil;
859 pipelineInfo.pColorBlendState = &colorBlendInfo;
860 pipelineInfo.pDynamicState = &dynamicState;
861 pipelineInfo.layout = pipelineLay;
862 pipelineInfo.subpass = 0;
863 pipelineInfo.renderPass =
865 ? m_forwardRenderPass : renderPass;
866 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
867 pipelineInfo.basePipelineIndex = -1;
869 VkResult result = vkCreateGraphicsPipelines(
870 device, VK_NULL_HANDLE, 1, &pipelineInfo,
nullptr, &pipes.main);
873 if (result != VK_SUCCESS) {
874 SLEAK_ERROR(
"VulkanRenderer: Failed to create main pipeline for vertex format {}",
876 pipes.main = VK_NULL_HANDLE;
877 pipes.mainFailed =
true;
879 SLEAK_INFO(
"VulkanRenderer: Custom format {} main pipeline created", format);
886 if (pipes.shadow == VK_NULL_HANDLE && !pipes.shadowFailed &&
888 m_shadowRenderPass != VK_NULL_HANDLE && m_shadowShader) {
889 const std::string shadowPath =
891 auto* shadowShader =
new VulkanShader(device);
892 if (!shadowShader->compileVertexOnly(shadowPath)) {
893 SLEAK_ERROR(
"VulkanRenderer: Failed to compile '{}' for vertex format {}",
895 pipes.shadowFailed =
true;
898 VkPipelineShaderStageCreateInfo shaderStage = shadowShader->GetVertexInfo();
900 VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
901 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
902 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
903 inputAssembly.primitiveRestartEnable = VK_FALSE;
905 VkPipelineViewportStateCreateInfo viewportState{};
906 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
907 viewportState.viewportCount = 1;
908 viewportState.scissorCount = 1;
910 VkPipelineRasterizationStateCreateInfo rasterizer{};
911 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
912 rasterizer.depthClampEnable = VK_FALSE;
913 rasterizer.rasterizerDiscardEnable = VK_FALSE;
914 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
915 rasterizer.lineWidth = 1.0f;
916 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
917 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
918 rasterizer.depthBiasEnable = VK_TRUE;
919 rasterizer.depthBiasConstantFactor = 1.25f;
920 rasterizer.depthBiasSlopeFactor = 1.75f;
921 rasterizer.depthBiasClamp = 0.0f;
923 VkPipelineMultisampleStateCreateInfo msaa{};
924 msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
925 msaa.sampleShadingEnable = VK_FALSE;
926 msaa.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
928 VkPipelineDepthStencilStateCreateInfo depthStencil{};
929 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
930 depthStencil.depthTestEnable = VK_TRUE;
931 depthStencil.depthWriteEnable = VK_TRUE;
932 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
933 depthStencil.depthBoundsTestEnable = VK_FALSE;
934 depthStencil.stencilTestEnable = VK_FALSE;
936 VkPipelineColorBlendStateCreateInfo colorBlendInfo{};
937 colorBlendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
938 colorBlendInfo.logicOpEnable = VK_FALSE;
939 colorBlendInfo.attachmentCount = 0;
941 VkGraphicsPipelineCreateInfo pipelineInfo{};
942 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
943 pipelineInfo.stageCount = 1;
944 pipelineInfo.pStages = &shaderStage;
945 pipelineInfo.pVertexInputState = &vertexInputInfo;
946 pipelineInfo.pInputAssemblyState = &inputAssembly;
947 pipelineInfo.pViewportState = &viewportState;
948 pipelineInfo.pRasterizationState = &rasterizer;
949 pipelineInfo.pMultisampleState = &msaa;
950 pipelineInfo.pDepthStencilState = &depthStencil;
951 pipelineInfo.pColorBlendState = &colorBlendInfo;
952 pipelineInfo.pDynamicState = &dynamicState;
953 pipelineInfo.layout = pipelineLay;
954 pipelineInfo.renderPass = m_shadowRenderPass;
955 pipelineInfo.subpass = 0;
956 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
957 pipelineInfo.basePipelineIndex = -1;
959 VkResult result = vkCreateGraphicsPipelines(
960 device, VK_NULL_HANDLE, 1, &pipelineInfo,
nullptr, &pipes.shadow);
963 if (result != VK_SUCCESS) {
964 SLEAK_ERROR(
"VulkanRenderer: Failed to create shadow pipeline for vertex format {}",
966 pipes.shadow = VK_NULL_HANDLE;
967 pipes.shadowFailed =
true;
969 SLEAK_INFO(
"VulkanRenderer: Custom format {} shadow pipeline created", format);
975 if (pipes.gbuffer == VK_NULL_HANDLE && !pipes.gbufferFailed &&
977 m_gbufferRenderPass != VK_NULL_HANDLE) {
978 const std::string gbufVertPath =
980 auto* gbufShader =
new VulkanShader(device);
981 if (!gbufShader->compile(gbufVertPath,
"assets/shaders/gbuffer.frag.spv")) {
982 SLEAK_ERROR(
"VulkanRenderer: Failed to compile '{}' for vertex format {}",
983 gbufVertPath, format);
984 pipes.gbufferFailed =
true;
987 VkPipelineShaderStageCreateInfo gbufStages[] = {
988 gbufShader->GetVertexInfo(), gbufShader->GetFragInfo()};
990 VkPipelineInputAssemblyStateCreateInfo ia{};
991 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
992 ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
993 ia.primitiveRestartEnable = VK_FALSE;
995 VkPipelineViewportStateCreateInfo vp{};
996 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
997 vp.viewportCount = 1;
1000 VkPipelineRasterizationStateCreateInfo rs{};
1001 rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1002 rs.polygonMode = VK_POLYGON_MODE_FILL;
1003 rs.lineWidth = 1.0f;
1004 rs.cullMode = VK_CULL_MODE_BACK_BIT;
1005 rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1007 VkPipelineMultisampleStateCreateInfo ms{};
1008 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
1009 ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1011 VkPipelineDepthStencilStateCreateInfo ds{};
1012 ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
1013 ds.depthTestEnable = VK_TRUE;
1014 ds.depthWriteEnable = VK_TRUE;
1015 ds.depthCompareOp = VK_COMPARE_OP_LESS;
1017 VkPipelineColorBlendAttachmentState opaqueBlend{};
1018 opaqueBlend.blendEnable = VK_FALSE;
1019 opaqueBlend.colorWriteMask =
1020 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
1021 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1022 std::array<VkPipelineColorBlendAttachmentState, GBUFFER_COUNT> gbAtts;
1023 gbAtts.fill(opaqueBlend);
1025 VkPipelineColorBlendStateCreateInfo cb{};
1026 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
1027 cb.attachmentCount =
static_cast<uint32_t
>(gbAtts.size());
1028 cb.pAttachments = gbAtts.data();
1030 VkGraphicsPipelineCreateInfo gbPipeInfo{};
1031 gbPipeInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1032 gbPipeInfo.stageCount = 2;
1033 gbPipeInfo.pStages = gbufStages;
1034 gbPipeInfo.pVertexInputState = &vertexInputInfo;
1035 gbPipeInfo.pInputAssemblyState = &ia;
1036 gbPipeInfo.pViewportState = &vp;
1037 gbPipeInfo.pRasterizationState = &rs;
1038 gbPipeInfo.pMultisampleState = &ms;
1039 gbPipeInfo.pDepthStencilState = &ds;
1040 gbPipeInfo.pColorBlendState = &cb;
1041 gbPipeInfo.pDynamicState = &dynamicState;
1044 gbPipeInfo.layout = m_gbufferGeomLayout;
1045 gbPipeInfo.renderPass = m_gbufferRenderPass;
1046 gbPipeInfo.subpass = 0;
1048 VkResult gbResult = vkCreateGraphicsPipelines(
1049 device, VK_NULL_HANDLE, 1, &gbPipeInfo,
nullptr, &pipes.gbuffer);
1052 if (gbResult != VK_SUCCESS) {
1053 SLEAK_ERROR(
"VulkanRenderer: Failed to create GBuffer pipeline for vertex format {}",
1055 pipes.gbuffer = VK_NULL_HANDLE;
1056 pipes.gbufferFailed =
true;
1058 SLEAK_INFO(
"VulkanRenderer: Custom format {} GBuffer pipeline created", format);
1065 if (pipes.transparent == VK_NULL_HANDLE && !pipes.transparentFailed &&
1067 const std::string transparentPath =
1069 auto* transparentShader =
new VulkanShader(device);
1070 if (!transparentShader->compile(transparentPath)) {
1071 SLEAK_ERROR(
"VulkanRenderer: Failed to compile '{}' for vertex format {}",
1072 transparentPath, format);
1073 pipes.transparentFailed =
true;
1074 delete transparentShader;
1076 VkPipelineShaderStageCreateInfo trStages[] = {
1077 transparentShader->GetVertexInfo(),
1078 transparentShader->GetFragInfo()};
1080 VkPipelineInputAssemblyStateCreateInfo ia{};
1081 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
1082 ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1083 ia.primitiveRestartEnable = VK_FALSE;
1085 VkPipelineViewportStateCreateInfo vp{};
1086 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
1087 vp.viewportCount = 1;
1088 vp.scissorCount = 1;
1090 VkPipelineRasterizationStateCreateInfo rs{};
1091 rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1092 rs.depthClampEnable = VK_FALSE;
1093 rs.rasterizerDiscardEnable = VK_FALSE;
1094 rs.polygonMode = VK_POLYGON_MODE_FILL;
1095 rs.lineWidth = 1.0f;
1097 rs.cullMode = VK_CULL_MODE_NONE;
1098 rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1099 rs.depthBiasEnable = VK_FALSE;
1101 VkPipelineMultisampleStateCreateInfo ms{};
1102 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
1103 ms.sampleShadingEnable = VK_FALSE;
1106 ms.rasterizationSamples =
1108 ? VK_SAMPLE_COUNT_1_BIT
1111 VkPipelineDepthStencilStateCreateInfo ds{};
1112 ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
1113 ds.depthTestEnable = VK_TRUE;
1114 ds.depthWriteEnable = VK_TRUE;
1115 ds.depthCompareOp = VK_COMPARE_OP_LESS;
1116 ds.depthBoundsTestEnable = VK_FALSE;
1117 ds.stencilTestEnable = VK_FALSE;
1119 VkPipelineColorBlendAttachmentState blendAtt{};
1120 blendAtt.blendEnable = VK_TRUE;
1121 blendAtt.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
1122 blendAtt.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
1123 blendAtt.colorBlendOp = VK_BLEND_OP_ADD;
1124 blendAtt.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
1125 blendAtt.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
1126 blendAtt.alphaBlendOp = VK_BLEND_OP_ADD;
1127 blendAtt.colorWriteMask =
1128 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
1129 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1131 VkPipelineColorBlendStateCreateInfo cb{};
1132 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
1133 cb.logicOpEnable = VK_FALSE;
1134 cb.attachmentCount = 1;
1135 cb.pAttachments = &blendAtt;
1137 VkGraphicsPipelineCreateInfo trPipeInfo{};
1138 trPipeInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1139 trPipeInfo.stageCount = 2;
1140 trPipeInfo.pStages = trStages;
1141 trPipeInfo.pVertexInputState = &vertexInputInfo;
1142 trPipeInfo.pInputAssemblyState = &ia;
1143 trPipeInfo.pViewportState = &vp;
1144 trPipeInfo.pRasterizationState = &rs;
1145 trPipeInfo.pMultisampleState = &ms;
1146 trPipeInfo.pDepthStencilState = &ds;
1147 trPipeInfo.pColorBlendState = &cb;
1148 trPipeInfo.pDynamicState = &dynamicState;
1149 trPipeInfo.layout = pipelineLay;
1150 trPipeInfo.subpass = 0;
1151 trPipeInfo.renderPass =
1153 ? m_forwardRenderPass
1155 trPipeInfo.basePipelineHandle = VK_NULL_HANDLE;
1156 trPipeInfo.basePipelineIndex = -1;
1158 VkResult trResult = vkCreateGraphicsPipelines(
1159 device, VK_NULL_HANDLE, 1, &trPipeInfo,
nullptr, &pipes.transparent);
1160 delete transparentShader;
1162 if (trResult != VK_SUCCESS) {
1163 SLEAK_ERROR(
"VulkanRenderer: Failed to create transparent pipeline for vertex format {}",
1165 pipes.transparent = VK_NULL_HANDLE;
1166 pipes.transparentFailed =
true;
1168 SLEAK_INFO(
"VulkanRenderer: Custom format {} transparent pipeline created", format);
1173 return pipes.main != VK_NULL_HANDLE;
1179 if (!bFrameStarted)
return;
1180 if (format == 0)
return;
1181 if (m_activeCustomFormat == format)
return;
1182 m_activeCustomFormat = format;
1183 m_customFormatUnbound =
false;
1185 if (!CreateCustomFormatPipelines(format)) {
1186 m_customFormatUnbound =
true;
1189 const CustomFormatPipelines& pipes = m_customFormatPipelines[format];
1192 if (m_shadowPassActive) {
1193 target = pipes.shadow;
1194 }
else if (m_inGeometryPass) {
1195 target = pipes.gbuffer;
1196 }
else if (m_inForwardTransparentPass) {
1197 target = pipes.transparent;
1199 target = pipes.main;
1204 if (target == VK_NULL_HANDLE) {
1205 m_customFormatUnbound =
true;
1209 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, target);
1215 if (!bFrameStarted)
return;
1216 if (m_activeCustomFormat == 0)
return;
1217 m_activeCustomFormat = 0;
1218 m_customFormatUnbound =
false;
1220 if (m_shadowPassActive) {
1221 if (m_shadowPipeline != VK_NULL_HANDLE) {
1222 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS,
1225 }
else if (m_inGeometryPass && m_gbufferPipeline != VK_NULL_HANDLE) {
1226 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS,
1229 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1234 if (!m_inGeometryPass && m_textureDescriptorsWritten &&
1235 CurrentFrameIndex < descriptorSets.size()) {
1236 vkCmdBindDescriptorSets(command, VK_PIPELINE_BIND_POINT_GRAPHICS,
1238 &descriptorSets[CurrentFrameIndex], 0,
nullptr);
1244void VulkanRenderer::DestroyCustomFormatPipelines() {
1245 for (
auto& entry : m_customFormatPipelines) {
1246 CustomFormatPipelines& pipes = entry.second;
1247 if (pipes.main) vkDestroyPipeline(device, pipes.main,
nullptr);
1248 if (pipes.shadow) vkDestroyPipeline(device, pipes.shadow,
nullptr);
1249 if (pipes.gbuffer) vkDestroyPipeline(device, pipes.gbuffer,
nullptr);
1250 if (pipes.transparent)
1251 vkDestroyPipeline(device, pipes.transparent,
nullptr);
1253 m_customFormatPipelines.clear();
1254 m_activeCustomFormat = 0;
1261 if (!bFrameStarted)
return;
1262 if (debugLinePipeline == VK_NULL_HANDLE) {
1263 if (!CreateDebugLinePipeline())
return;
1265 m_activeCustomFormat = 0;
1266 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS,
1273 if (!bFrameStarted)
return;
1277 VkPipeline restoreTo =
1278 (m_inGeometryPass && m_gbufferPipeline != VK_NULL_HANDLE)
1279 ? m_gbufferPipeline : pipeline;
1280 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, restoreTo);
1286 if (!m_inGeometryPass && m_textureDescriptorsWritten &&
1287 CurrentFrameIndex < descriptorSets.size()) {
1288 vkCmdBindDescriptorSets(
1289 command, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLay, 0, 1,
1290 &descriptorSets[CurrentFrameIndex], 0,
nullptr);
1295bool VulkanRenderer::CreateSkinnedPipeline() {
1298 if (!skinnedShader->
compile(
"assets/shaders/skinned_shader")) {
1299 SLEAK_ERROR(
"VulkanRenderer: Failed to compile skinned shaders");
1300 delete skinnedShader;
1301 skinnedShader =
nullptr;
1306 VkPipelineShaderStageCreateInfo shaderStages[] = {
1309 std::vector<VkDynamicState> dynamicStates = {
1310 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
1312 VkPipelineDynamicStateCreateInfo dynamicState{};
1313 dynamicState.sType =
1314 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1315 dynamicState.dynamicStateCount =
1316 static_cast<uint32_t
>(dynamicStates.size());
1317 dynamicState.pDynamicStates = dynamicStates.data();
1320 VkVertexInputBindingDescription bindingDescription{};
1321 bindingDescription.binding = 0;
1322 bindingDescription.stride =
sizeof(
Vertex);
1323 bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1325 std::array<VkVertexInputAttributeDescription, 7> attributeDescs{};
1326 attributeDescs[0].binding = 0;
1327 attributeDescs[0].location = 0;
1328 attributeDescs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
1329 attributeDescs[0].offset = offsetof(
Vertex, px);
1331 attributeDescs[1].binding = 0;
1332 attributeDescs[1].location = 1;
1333 attributeDescs[1].format = VK_FORMAT_R32G32B32_SFLOAT;
1334 attributeDescs[1].offset = offsetof(
Vertex, nx);
1336 attributeDescs[2].binding = 0;
1337 attributeDescs[2].location = 2;
1338 attributeDescs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
1339 attributeDescs[2].offset = offsetof(
Vertex, tx);
1341 attributeDescs[3].binding = 0;
1342 attributeDescs[3].location = 3;
1343 attributeDescs[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
1344 attributeDescs[3].offset = offsetof(
Vertex, r);
1346 attributeDescs[4].binding = 0;
1347 attributeDescs[4].location = 4;
1348 attributeDescs[4].format = VK_FORMAT_R32G32_SFLOAT;
1349 attributeDescs[4].offset = offsetof(
Vertex, u);
1351 attributeDescs[5].binding = 0;
1352 attributeDescs[5].location = 5;
1353 attributeDescs[5].format = VK_FORMAT_R32G32B32A32_SINT;
1354 attributeDescs[5].offset = offsetof(
Vertex, boneIDs);
1356 attributeDescs[6].binding = 0;
1357 attributeDescs[6].location = 6;
1358 attributeDescs[6].format = VK_FORMAT_R32G32B32A32_SFLOAT;
1359 attributeDescs[6].offset = offsetof(
Vertex, boneWeights);
1361 VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
1362 vertexInputInfo.sType =
1363 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
1364 vertexInputInfo.vertexBindingDescriptionCount = 1;
1365 vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
1366 vertexInputInfo.vertexAttributeDescriptionCount =
1367 static_cast<uint32_t
>(attributeDescs.size());
1368 vertexInputInfo.pVertexAttributeDescriptions = attributeDescs.data();
1370 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo{};
1371 inputAssemblyInfo.sType =
1372 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
1373 inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1374 inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
1376 VkPipelineViewportStateCreateInfo viewportInfo{};
1377 viewportInfo.sType =
1378 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
1379 viewportInfo.viewportCount = 1;
1380 viewportInfo.scissorCount = 1;
1382 VkPipelineRasterizationStateCreateInfo rasterizer{};
1384 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1385 rasterizer.depthClampEnable = VK_FALSE;
1386 rasterizer.rasterizerDiscardEnable = VK_FALSE;
1387 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
1388 rasterizer.lineWidth = 1.0f;
1389 rasterizer.cullMode = VK_CULL_MODE_NONE;
1390 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1391 rasterizer.depthBiasEnable = VK_FALSE;
1393 VkPipelineMultisampleStateCreateInfo msaa{};
1395 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
1396 msaa.sampleShadingEnable = VK_FALSE;
1400 msaa.rasterizationSamples = (
m_deferredEnabled && m_forwardRenderPass != VK_NULL_HANDLE)
1401 ? VK_SAMPLE_COUNT_1_BIT : m_msaaSamples;
1404 VkPipelineDepthStencilStateCreateInfo depthStencil{};
1405 depthStencil.sType =
1406 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
1407 depthStencil.depthTestEnable = VK_TRUE;
1408 depthStencil.depthWriteEnable = VK_TRUE;
1409 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
1410 depthStencil.depthBoundsTestEnable = VK_FALSE;
1411 depthStencil.stencilTestEnable = VK_FALSE;
1413 VkPipelineColorBlendAttachmentState colorBlendAttachment{};
1414 colorBlendAttachment.blendEnable = VK_FALSE;
1415 colorBlendAttachment.colorWriteMask =
1416 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
1417 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1419 VkPipelineColorBlendStateCreateInfo colorBlendInfo{};
1420 colorBlendInfo.sType =
1421 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
1422 colorBlendInfo.logicOpEnable = VK_FALSE;
1423 colorBlendInfo.attachmentCount = 1;
1424 colorBlendInfo.pAttachments = &colorBlendAttachment;
1426 VkGraphicsPipelineCreateInfo pipelineInfo{};
1427 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1428 pipelineInfo.stageCount = 2;
1429 pipelineInfo.pStages = shaderStages;
1430 pipelineInfo.pVertexInputState = &vertexInputInfo;
1431 pipelineInfo.pInputAssemblyState = &inputAssemblyInfo;
1432 pipelineInfo.pViewportState = &viewportInfo;
1433 pipelineInfo.pRasterizationState = &rasterizer;
1434 pipelineInfo.pMultisampleState = &msaa;
1435 pipelineInfo.pDepthStencilState = &depthStencil;
1436 pipelineInfo.pColorBlendState = &colorBlendInfo;
1437 pipelineInfo.pDynamicState = &dynamicState;
1438 pipelineInfo.layout = pipelineLay;
1439 pipelineInfo.subpass = 0;
1440 pipelineInfo.renderPass = (
m_deferredEnabled && m_forwardRenderPass != VK_NULL_HANDLE)
1441 ? m_forwardRenderPass : renderPass;
1442 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
1443 pipelineInfo.basePipelineIndex = -1;
1445 VkResult result = vkCreateGraphicsPipelines(
1446 device, VK_NULL_HANDLE, 1, &pipelineInfo,
nullptr, &skinnedPipeline);
1447 if (result != VK_SUCCESS) {
1448 SLEAK_ERROR(
"VulkanRenderer: Failed to create skinned pipeline!");
1452 SLEAK_INFO(
"VulkanRenderer: Skinned pipeline created successfully");
1459 if (!bFrameStarted)
return;
1461 if (m_inGeometryPass) {
1463 if (m_skinnedGbufferPipeline == VK_NULL_HANDLE)
1464 CreateSkinnedGbufferPipeline();
1465 if (m_skinnedGbufferPipeline != VK_NULL_HANDLE)
1466 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS,
1467 m_skinnedGbufferPipeline);
1472 if (skinnedPipeline == VK_NULL_HANDLE) {
1473 if (!CreateSkinnedPipeline())
return;
1475 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, skinnedPipeline);
1481 if (!bFrameStarted)
return;
1483 if (m_inGeometryPass) {
1485 if (m_gbufferPipeline != VK_NULL_HANDLE)
1486 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, m_gbufferPipeline);
1490 vkCmdBindPipeline(command, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
#define SLEAK_RETURN_ERR(...)
virtual void EndDebugLinePass() override
Restores the previous pipeline and descriptor set after debug line draws.
virtual void EndSkinnedPass() override
Restores the previous pipeline after skinned draws.
virtual void EndCustomFormatPass() override
Restores the previous pipeline and descriptor set after custom-format draws.
virtual void EndSkyboxPass() override
Restores the previous pipeline and descriptor set after the skybox draw.
virtual void BeginDebugLinePass() override
Binds the debug line pipeline for the current frame.
virtual void BeginSkinnedPass() override
Binds the skinned pipeline matching the currently active render pass.
virtual void BeginSkyboxPass() override
Binds the skybox pipeline and its descriptor set for the current frame.
virtual void BeginCustomFormatPass(VertexFormatHandle format) override
Binds the custom-format pipeline matching the currently active render pass.
Vulkan vertex+fragment shader pair, loaded from precompiled SPIR-V modules.
VkPipelineShaderStageCreateInfo GetFragInfo()
VkPipelineShaderStageCreateInfo GetVertexInfo()
virtual bool compile(const std::string &shaderPath) override
Loads the combined-path convention's .vert.spv/.frag.spv pair.
Backend-facing rendering layer shared by the four graphics backends.
static VkFormat ToVkVertexFormat(VertexAttribFormat format)
Translates a registry attribute format into its Vulkan vertex format.
Root namespace for everything the engine exposes.
uint32_t VertexFormatHandle
std::string transparentShaderStem
std::string gbufferShaderStem
std::string shadowShaderStem
std::vector< VertexAttribute > attributes