5 #define VMA_IMPLEMENTATION 15 #include <ThirdParty/glm/glm/gtc/matrix_transform.hpp> 18 #include <ThirdParty/EASTL-master/include/EASTL/shared_ptr.h> 24 static void check_vk_result(VkResult err) {
25 if (err != VK_SUCCESS) {
26 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(err).c_str() +
"] ImGui vulkan call failed";
27 std::cout << s.c_str() << std::endl;
31 VulkanRenderer::VulkanRenderer() noexcept
34 setClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));
37 VulkanRenderer::~VulkanRenderer()
39 vkWaitForFences(vulkanLogicalDevice_->GetDevice(),
40 static_cast<uint32_t
>(drawingFinishedFences_.size()),
41 drawingFinishedFences_.data(),
42 VK_TRUE, eastl::numeric_limits<uint64_t>::max());
44 vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
46 vkResetCommandPool(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
47 vkResetCommandPool(vulkanLogicalDevice_->GetDevice(), computeCommandPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
49 vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
53 DestroyGBufferRenderPipeline();
54 DestroyCompositingPipeline();
57 DestroyDecriptorPool();
58 DestroyFramebuffers();
60 DestroyAttachmentImages();
62 DestroyVmaAllocator();
63 DestroyGraphicsCommandPool();
64 DestroyComputeCommandPool();
65 DestroySwapChainImageViews();
67 DestroyLogicalDevice();
71 void VulkanRenderer::InitializeRenderer()
73 InitializeRenderer(Engine::GetEngine().lock()->GetWindow<VulkanWindow>());
76 void VulkanRenderer::InitializeRenderer(eastl::weak_ptr<VulkanWindow> window)
81 this->window = window;
83 swapChain = VK_NULL_HANDLE;
87 surface = window.lock()->CreateSurface(vulkanInstance_->GetInstance());
91 CreateLogicalDevice();
96 CreateSwapChainImageViews();
98 CreateGraphicsCommandPool();
99 CreateComputeCommandPool();
101 CreateVmaAllocator();
105 CreateAttachmentImages();
109 CreateFramebuffers();
111 CreateDescriptorPool();
117 CreateCompositingPipeline();
119 CreateGBufferRenderPipeline();
121 GenerateCommandBuffers();
129 VulkanTexture::InitTextureSystem(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get(), vmaAllocator_, graphicsCommandPool);
131 VulkanMesh::InitMeshes(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get(), graphicsCommandPool);
133 VulkanMaterial::InitMaterialData(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get(), vmaAllocator_);
174 void VulkanRenderer::Resized()
179 void VulkanRenderer::RecreateSwapChain()
181 vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
183 DestroyFramebuffers();
185 DestroyCompositingPipeline();
186 DestroyGBufferRenderPipeline();
187 vulkanSpriteRenderer->Clean();
188 vulkanDebugRenderer->Clean();
189 vulkanStaticMeshRenderer->Clean();
190 vulkanSkeletalMeshRenderer->Clean();
195 DestroyAttachmentImages();
197 DestroySwapChainImageViews();
201 GetSwapChainImages();
202 CreateSwapChainImageViews();
204 CreateAttachmentImages();
206 CreateFramebuffers();
208 CreateCompositingPipeline();
209 CreateGBufferRenderPipeline();
211 vulkanSpriteRenderer->Recreate();
212 vulkanDebugRenderer->Recreate();
213 vulkanStaticMeshRenderer->Recreate();
214 vulkanSkeletalMeshRenderer->Recreate();
218 GenerateCommandBuffers();
224 void VulkanRenderer::setClearColor(glm::vec4 color)
226 clearValue.color = { color.x,color.y,color.z,color.w };
229 VkRenderPass VulkanRenderer::GetRenderPass()
const 234 VkRenderPass VulkanRenderer::GetGBufferRenderPass()
const 239 VmaAllocator VulkanRenderer::GetVmaAllocator()
const 241 return vmaAllocator_;
244 VkCommandPool VulkanRenderer::GetGraphicsCommandPool()
const 246 return graphicsCommandPool;
249 VkCommandPool VulkanRenderer::GetComputeCommandPool()
const 251 return computeCommandPool;
254 VkExtent2D VulkanRenderer::GetSwapChainExtent()
const 256 return swapChainImageExtent;
259 void VulkanRenderer::RendererBegin()
261 RendererBegin(glm::mat4(), glm::perspective(75.f,
262 static_cast<float>(swapChainImageExtent.width) / static_cast<float>(swapChainImageExtent.height),
266 void VulkanRenderer::RendererBegin(
const glm::mat4x4 & view,
const glm::mat4x4 & projection)
270 VkResult res = vkAcquireNextImageKHR(vulkanLogicalDevice_->GetDevice(), swapChain, eastl::numeric_limits<uint64_t>::max(), imageAvailableSemaphores_[(currentImage + 1) % imageAvailableSemaphores_.size()], VK_NULL_HANDLE, &imageIndex);
272 if (res == VK_ERROR_OUT_OF_DATE_KHR) {
275 else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
276 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to aquire next swap chain image";
277 std::cout << s.c_str() << std::endl;
281 currentBuffer_ = primaryRenderCommandBuffers_[imageIndex];
282 currentComputeBuffer_ = primaryComputeCommandBuffers_[imageIndex];
283 this->prevImage = this->currentImage;
284 this->currentImage = imageIndex;
287 VkFence fences[] = { drawingFinishedFences_[currentImage], computeFinishedFences_[currentImage] };
288 vkWaitForFences(vulkanLogicalDevice_->GetDevice(), 2, fences,
true, eastl::numeric_limits<uint64_t>::max());
289 vkResetFences(vulkanLogicalDevice_->GetDevice(), 2, fences);
298 VkResult res = vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
299 if (res != VK_SUCCESS) {
300 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Queue wait idle failed";
301 std::cout << s.c_str() << std::endl;
306 ImGui_ImplGlfwVulkan_NewFrame();
309 vulkanSpriteRenderer->StartRender(spriteRenderCommandBuffers_[imageIndex], view, projection);
310 vulkanDebugRenderer->StartRender(debugRenderCommandBuffers_[imageIndex], view, projection);
311 vulkanStaticMeshRenderer->StartRender(view, projection);
312 vulkanSkeletalMeshRenderer->StartRender(view, projection);
314 glm::vec3 camPos = Engine::GetEngine().lock()->GetCamera().lock()->GetPosition();
315 scene.viewPos = glm::vec4(camPos.x, camPos.y, camPos.z, 1.f);
334 void VulkanRenderer::Render(
const glm::mat4x4 & modelMatrix, eastl::shared_ptr<Model> model,
const glm::vec4 & mainColor)
336 eastl::vector<eastl::shared_ptr<Mesh>> meshes = model->GetModelMeshes();
338 for (
size_t i = 0, size = meshes.size(); i < size; i++) {
339 if (meshes[i] ==
nullptr)
344 eastl::shared_ptr<VulkanMaterial> material =
345 eastl::dynamic_pointer_cast<VulkanMaterial, Material>(model->GetMeshMaterial(meshes[i]));
347 bool isAnimated = eastl::dynamic_pointer_cast<VulkanMesh, Mesh>(meshes[i])->IsAnimated();
348 size_t currentAnimationIndex = model->GetCurrentAnimationIndex();
351 currentAnimationIndex == -1 ||
352 model->GetSkeleton() ==
nullptr) {
353 vulkanStaticMeshRenderer->RenderMesh(modelMatrix,
354 eastl::dynamic_pointer_cast<VulkanMesh, Mesh>(meshes[i]), material, mainColor);
357 vulkanSkeletalMeshRenderer->RenderMesh(modelMatrix,
358 static_cast<VulkanMesh*>(meshes[i].
get()),
359 material.get(), model->GetSkeleton().get(), model->GetCurrentAnimationIndex(), model->GetAnimationTime(),
360 model->GetSkeleton()->GetAnimationTicksPerSecond(model->GetCurrentAnimationIndex()),
361 model->GetAnimationDuration(), model->IsLooping(), mainColor);
366 void VulkanRenderer::RenderSprite(eastl::weak_ptr<Texture> texture, glm::mat4 modelMatrix)
368 eastl::weak_ptr<VulkanTexture> vulkanTexture;
370 vulkanTexture = eastl::dynamic_pointer_cast<VulkanTexture, Texture>(texture.lock());
372 vulkanSpriteRenderer->RenderSprite(vulkanTexture, modelMatrix);
375 void VulkanRenderer::RenderLine(glm::vec3 start, glm::vec3 end, glm::vec4 color)
377 vulkanDebugRenderer->RenderLine(start, end, color);
380 void VulkanRenderer::RendererEnd()
382 VkCommandBufferBeginInfo beginInfo = {};
383 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
384 beginInfo.pInheritanceInfo =
nullptr;
387 vkBeginCommandBuffer(currentComputeBuffer_, &beginInfo);
391 vkEndCommandBuffer(currentComputeBuffer_);
393 VkSubmitInfo computeSubmitInfo = {};
394 computeSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
396 computeSubmitInfo.waitSemaphoreCount = 0;
397 computeSubmitInfo.pWaitSemaphores =
nullptr;
398 computeSubmitInfo.pWaitDstStageMask =
nullptr;
399 computeSubmitInfo.commandBufferCount = 1;
400 computeSubmitInfo.pCommandBuffers = ¤tComputeBuffer_;
401 computeSubmitInfo.signalSemaphoreCount = 1;
402 VkSemaphore computeSignalSemaphores[] = { computeFinishedSemaphores_[currentImage] };
403 computeSubmitInfo.pSignalSemaphores = computeSignalSemaphores;
405 VkResult res = vkQueueSubmit(vulkanLogicalDevice_->GetComputeQueue(), 1, &computeSubmitInfo, computeFinishedFences_[currentImage]);
406 if (res != VK_SUCCESS) {
407 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to submit compute commands";
408 std::cout << s.c_str() << std::endl;
412 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
413 beginInfo.pInheritanceInfo =
nullptr;
416 vkBeginCommandBuffer(currentBuffer_, &beginInfo);
418 eastl::array<VkClearValue, static_cast<int>(GBufferAttachments::ATTACHMENT_COUNT)> gbufferClearValues = {};
419 gbufferClearValues[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].color = clearValue.color;
420 gbufferClearValues[static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].color = { 0.f,0.f,0.f,0.f };
421 gbufferClearValues[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].color = { 0.f,0.f,0.f,0.f };
422 gbufferClearValues[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].depthStencil = { 1.0f,0 };
424 VkRenderPassBeginInfo renderPassInfo = {};
425 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
426 renderPassInfo.renderPass = gBufferPass;
427 renderPassInfo.framebuffer = gBufferFrameBuffer;
428 renderPassInfo.renderArea.offset = { 0,0 };
429 renderPassInfo.renderArea.extent = swapChainImageExtent;
430 renderPassInfo.clearValueCount =
static_cast<uint32_t
>(gbufferClearValues.size());
431 renderPassInfo.pClearValues = gbufferClearValues.data();
433 vkCmdBeginRenderPass(currentBuffer_, &renderPassInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
444 vulkanStaticMeshRenderer->FinishRender(0, graphicsCommandPool, (staticMeshCommandBuffers_[currentImage]));
455 vulkanSkeletalMeshRenderer->FinishRender(0, graphicsCommandPool, (skeletalMeshCommandBuffers_[currentImage]));
458 vkCmdExecuteCommands(currentBuffer_, 1, &staticMeshCommandBuffers_[currentImage]);
460 vkCmdExecuteCommands(currentBuffer_, 1, &skeletalMeshCommandBuffers_[currentImage]);
462 vkCmdEndRenderPass(currentBuffer_);
464 eastl::array<VkClearValue, static_cast<int>(RenderPassAttachments::ATTACHMENT_COUNT)> renderClearValues = {};
465 renderClearValues[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].color = clearValue.color;
466 renderClearValues[static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].color = { 0.f,0.f,0.f,0.f };
468 renderClearValues[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].color = clearValue.color;
470 renderClearValues[static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].color = clearValue.color;
473 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
474 renderPassInfo.renderPass = renderPass;
475 renderPassInfo.framebuffer = framebuffers[currentImage];
476 renderPassInfo.renderArea.offset = { 0,0 };
477 renderPassInfo.renderArea.extent = swapChainImageExtent;
478 renderPassInfo.clearValueCount =
static_cast<uint32_t
>(renderClearValues.size());
479 renderPassInfo.pClearValues = renderClearValues.data();
481 vkCmdBeginRenderPass(currentBuffer_, &renderPassInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
483 StartSecondaryCommandBufferRecording(imguiCommandBuffers_[currentImage],
484 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
485 renderPass, static_cast<int>(RenderSubPasses::IMGUI_PASS), framebuffers[currentImage]);
487 ImGui_ImplGlfwVulkan_Render(imguiCommandBuffers_[currentImage]);
488 EndSecondaryCommandBufferRecording(imguiCommandBuffers_[currentImage]);
490 vulkanSpriteRenderer->FinishRender();
491 vulkanDebugRenderer->FinishRender();
493 if (lightDataRestructured)
495 if (lightDataChanged)
498 scene.lightCount = activeLights;
499 sceneDataBuffer->UpdateBuffer(&scene, 0, static_cast<uint32_t>(
sizeof(scene)));
501 uint32_t size =
static_cast<uint32_t
>(staticMeshShadowCommandBuffers_[currentImage].size());
503 if (size < static_cast<uint32_t>(activeLights)) {
504 staticMeshShadowCommandBuffers_[currentImage].resize(activeLights);
505 GenerateSecondaryCommandBuffers(staticMeshShadowCommandBuffers_[currentImage].data() +
sizeof(VkCommandBuffer)*size,
506 static_cast<uint32_t>(staticMeshShadowCommandBuffers_[currentImage].size()) - size);
509 size =
static_cast<uint32_t
>(skeletalMeshShadowCommandBuffers_[currentImage].size());
511 if (size < static_cast<uint32_t>(activeLights)) {
512 skeletalMeshShadowCommandBuffers_[currentImage].resize(activeLights);
513 GenerateSecondaryCommandBuffers(skeletalMeshShadowCommandBuffers_[currentImage].data() +
sizeof(VkCommandBuffer)*size,
514 static_cast<uint32_t>(skeletalMeshShadowCommandBuffers_[currentImage].size()) - size);
517 size =
static_cast<uint32_t
>(gBufferShadowCommandBuffers_[currentImage].size());
519 if (size < static_cast<uint32_t>(activeLights)) {
520 gBufferShadowCommandBuffers_[currentImage].resize(activeLights);
521 GenerateSecondaryCommandBuffers(gBufferShadowCommandBuffers_[currentImage].data() +
sizeof(VkCommandBuffer)*size,
522 static_cast<uint32_t>(gBufferShadowCommandBuffers_[currentImage].size()) - size);
526 VkRect2D scissor = { 0,0,swapChainImageExtent };
527 VkViewport viewport = { 0.f,0.f,
static_cast<float>(swapChainImageExtent.width),static_cast<float>(swapChainImageExtent.height),-1.f,1.f };
529 VkDescriptorSet sceneDescriptorSet = GetLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1);
530 if (sceneDescriptorSet == VK_NULL_HANDLE) {
531 sceneDescriptorSet = CreateLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1, gBufferRenderPipeline_->GetDescriptorSetLayout(1));
534 for (
int i = 0; i < activeLights; ++i) {
535 if (!(lightData[i].position.w == 0.f && lightData[i].direction == glm::vec4(0.f))) {
546 vulkanStaticMeshRenderer->RenderShadows(0, graphicsCommandPool, (staticMeshShadowCommandBuffers_[currentImage][i]), static_cast<uint32_t>(i *
sizeof(
Light)));
558 vulkanSkeletalMeshRenderer->RenderShadows(0, graphicsCommandPool, (skeletalMeshShadowCommandBuffers_[currentImage][i]), static_cast<uint32_t>(i *
sizeof(
Light)));
561 StartSecondaryCommandBufferRecording(gBufferShadowCommandBuffers_[currentImage][i],
562 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
563 renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS), framebuffers[currentImage]);
565 vkCmdBindPipeline(gBufferShadowCommandBuffers_[currentImage][i], VK_PIPELINE_BIND_POINT_GRAPHICS, gBufferRenderPipeline_->GetPipeline());
567 vkCmdSetScissor(gBufferShadowCommandBuffers_[currentImage][i], 0, 1, &scissor);
569 VkDescriptorSet descriptors[] = { gBufferAttachmentDescriptorSet_ };
571 vkCmdBindDescriptorSets(gBufferShadowCommandBuffers_[currentImage][i],
572 VK_PIPELINE_BIND_POINT_GRAPHICS,
573 gBufferRenderPipeline_->GetPipelineLayout(),
578 uint32_t dynamicOffset[] = {
static_cast<uint32_t
>(i *
sizeof(
Light)) };
580 vkCmdBindDescriptorSets(gBufferShadowCommandBuffers_[currentImage][i],
581 VK_PIPELINE_BIND_POINT_GRAPHICS,
582 gBufferRenderPipeline_->GetPipelineLayout(),
588 VkDeviceSize offsets[] = { 0 };
590 vkCmdBindVertexBuffers(gBufferShadowCommandBuffers_[currentImage][i], 0, 1, &vertexBuffer_, offsets);
592 vkCmdDraw(gBufferShadowCommandBuffers_[currentImage][i], 6, 1, 0, 0);
594 EndSecondaryCommandBufferRecording(gBufferShadowCommandBuffers_[currentImage][i]);
597 StartSecondaryCommandBufferRecording(clearStencilCommandBuffers_[currentImage],
598 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
599 renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS), framebuffers[currentImage]);
601 VkClearValue clearValue = {};
602 clearValue.depthStencil = { 0.f,0 };
604 VkClearAttachment stencilAttachment = {};
605 stencilAttachment.colorAttachment =
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT);
606 stencilAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
607 stencilAttachment.clearValue = clearValue;
609 VkClearRect clearRect = {};
610 clearRect.baseArrayLayer = 0;
611 clearRect.layerCount = 1;
612 clearRect.rect.offset = { 0,0 };
613 clearRect.rect.extent = swapChainImageExtent;
615 vkCmdClearAttachments(clearStencilCommandBuffers_[currentImage], 1, &stencilAttachment, 1, &clearRect);
617 EndSecondaryCommandBufferRecording(clearStencilCommandBuffers_[currentImage]);
621 vkCmdNextSubpass(currentBuffer_, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
623 vkCmdExecuteCommands(currentBuffer_, 1, &spriteRenderCommandBuffers_[currentImage]);
625 vkCmdExecuteCommands(currentBuffer_, 1, &debugRenderCommandBuffers_[currentImage]);
627 for (
int i = 0; i < activeLights; ++i) {
628 vkCmdExecuteCommands(currentBuffer_, 1, &(clearStencilCommandBuffers_[currentImage]));
630 if (!(lightData[i].position.w == 0.f && lightData[i].direction == glm::vec4(0.f))) {
631 vkCmdExecuteCommands(currentBuffer_, 1, &(staticMeshShadowCommandBuffers_[currentImage][i]));
632 vkCmdExecuteCommands(currentBuffer_, 1, &(skeletalMeshShadowCommandBuffers_[currentImage][i]));
634 vkCmdExecuteCommands(currentBuffer_, 1, &(gBufferShadowCommandBuffers_[currentImage][i]));
637 vkCmdNextSubpass(currentBuffer_, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
639 vkCmdExecuteCommands(currentBuffer_, 1, &imguiCommandBuffers_[currentImage]);
641 vkCmdNextSubpass(currentBuffer_, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
643 vkCmdExecuteCommands(currentBuffer_, 1, &compositeCommandBuffer_);
645 vkCmdEndRenderPass(currentBuffer_);
647 res = vkEndCommandBuffer(currentBuffer_);
648 if (res != VK_SUCCESS) {
649 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to record primary command buffer";
650 std::cout << s.c_str() << std::endl;
654 VkSubmitInfo submitInfo = {};
655 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
656 VkSemaphore waitSemaphores[] = {
657 imageAvailableSemaphores_[(prevImage + 1) % imageAvailableSemaphores_.size()],
658 computeFinishedSemaphores_[currentImage] };
659 VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
660 submitInfo.waitSemaphoreCount = 2;
661 submitInfo.pWaitSemaphores = waitSemaphores;
662 submitInfo.pWaitDstStageMask = waitStages;
663 submitInfo.commandBufferCount = 1;
664 submitInfo.pCommandBuffers = ¤tBuffer_;
665 VkSemaphore signalSemaphors[] = { renderFinishedSemaphores_[currentImage] };
666 submitInfo.signalSemaphoreCount = 1;
667 submitInfo.pSignalSemaphores = signalSemaphors;
669 res = vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, drawingFinishedFences_[currentImage]);
670 if (res != VK_SUCCESS) {
671 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Submitting command buffer to queue failed";
672 std::cout << s.c_str() << std::endl;
676 VkPresentInfoKHR presentInfo = {};
677 presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
678 presentInfo.waitSemaphoreCount = 1;
679 presentInfo.pWaitSemaphores = signalSemaphors;
681 VkSwapchainKHR swapChains[] = { swapChain };
682 presentInfo.swapchainCount = 1;
683 presentInfo.pSwapchains = swapChains;
684 presentInfo.pImageIndices = ¤tImage;
685 presentInfo.pResults =
nullptr;
687 res = vkQueuePresentKHR(vulkanLogicalDevice_->GetPresentQueue(), &presentInfo);
688 if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) {
691 else if (res != VK_SUCCESS) {
692 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to present swap chain image";
693 std::cout << s.c_str() << std::endl;
702 void VulkanRenderer::CreateLight(eastl::string name,
LightType lightType,
703 glm::vec3 position, glm::vec3 direction, glm::vec3 color,
704 float radius,
float attunuation,
float coneInnerAngle,
float coneOuterAngle)
709 info.type = lightType;
713 info.light.position = glm::vec4(position.x, position.y, position.z, 0.f);
714 info.light.direction = glm::vec4(0.f);
715 info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
716 info.light.radius = radius;
717 info.light.attunuation = attunuation;
718 info.light.coneInnerAngle = coneInnerAngle;
719 info.light.coneOuterAngle = coneOuterAngle;
722 info.light.position = glm::vec4(position.x, position.y, position.z, 0.f);
723 info.light.direction = glm::vec4(-direction.x, -direction.y, direction.z, 0.f);
724 info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
725 info.light.radius = radius;
726 info.light.attunuation = attunuation;
727 info.light.coneInnerAngle = coneInnerAngle;
728 info.light.coneOuterAngle = coneOuterAngle;
731 info.light.position = glm::vec4(position.x, position.y, position.z, 1.f);
732 info.light.direction = glm::vec4(-direction.x, -direction.y, direction.z, 0.f);
733 info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
734 info.light.radius = radius;
735 info.light.attunuation = attunuation;
736 info.light.coneInnerAngle = 2.f*glm::pi<float>();
737 info.light.coneOuterAngle = 2.f*glm::pi<float>();
740 info.light.position = glm::vec4(position.x, position.y, position.z, 1.f);
741 info.light.direction = glm::vec4(-direction.x, -direction.y, direction.z, 0.f);
742 info.light.color = glm::vec4(color.x, color.y, color.z, 1.f);
743 info.light.radius = radius;
744 info.light.attunuation = attunuation;
745 info.light.coneInnerAngle = coneInnerAngle;
746 info.light.coneOuterAngle = coneOuterAngle;
752 lightDataRestructured =
true;
754 scene.lightCount = activeLights;
757 void VulkanRenderer::SetLightType(eastl::string name,
LightType lightType)
759 eastl::map<eastl::string, LightInfo>::iterator it = lights.find(name);
761 if (it == lights.end())
764 LightInfo info = it->second;
766 if (info.type == lightType)
769 if (info.type == LightType::LIGHT_NONEXISTENT) {
770 info.type = lightType;
772 lightDataRestructured =
true;
775 if (lightType == LightType::LIGHT_NONEXISTENT) {
776 info.type = lightType;
778 lightDataRestructured =
true;
782 info.type = lightType;
786 info.light.position.w = 0.f;
787 info.light.direction = glm::vec4(0.f);
790 info.light.position.w = 0.f;
793 info.light.position.w = 1.f;
794 info.light.coneInnerAngle = 2.f * glm::pi<float>();
795 info.light.coneOuterAngle = 2.f * glm::pi<float>();
798 info.light.position.w = 1.f;
799 info.light.coneInnerAngle = 0.f;
800 info.light.coneOuterAngle = 0.f;
806 if (lightDataRestructured ==
false)
807 lightData[info.lightDataIndex] = info.light;
809 lightDataChanged =
true;
812 LightType VulkanRenderer::GetLightType(eastl::string name)
814 if (lights.count(name) > 0)
815 return lights[name].type;
817 return LightType::LIGHT_NONEXISTENT;
820 void VulkanRenderer::SetLightPosition(eastl::string name, glm::vec3 position)
822 if (lights.count(name) <= 0)
825 LightInfo info = lights[name];
827 info.light.position.x = position.x;
828 info.light.position.y = position.y;
829 info.light.position.z = position.z;
832 lightData[info.lightDataIndex] = info.light;
833 lightDataChanged =
true;
839 glm::vec3 VulkanRenderer::GetLightPosition(eastl::string name)
841 if (lights.count(name) <= 0)
842 return glm::vec3(0.f);
844 LightInfo info = lights[name];
846 return glm::vec3(info.light.position.x, info.light.position.y, info.light.position.z);
849 void VulkanRenderer::SetLightDirection(eastl::string name, glm::vec3 direction)
851 if (lights.count(name) <= 0)
854 LightInfo info = lights[name];
858 info.light.direction.x = -direction.x;
859 info.light.direction.y = -direction.y;
860 info.light.direction.z = direction.z;
862 lightData[info.lightDataIndex] = info.light;
863 lightDataChanged =
true;
869 glm::vec3 VulkanRenderer::GetLightDirection(eastl::string name)
872 if (lights.count(name) <= 0)
873 return glm::vec3(0.f);
875 LightInfo info = lights[name];
877 return glm::vec3(info.light.direction.x, info.light.direction.y, info.light.direction.z);
880 void VulkanRenderer::SetLightColor(eastl::string name, glm::vec3 color)
882 if (lights.count(name) <= 0)
885 LightInfo info = lights[name];
887 info.light.color.x = color.x;
888 info.light.color.y = color.y;
889 info.light.color.z = color.z;
892 lightData[info.lightDataIndex] = info.light;
893 lightDataChanged =
true;
899 glm::vec3 VulkanRenderer::GetLightColor(eastl::string name)
901 if (lights.count(name) <= 0)
902 return glm::vec3(0.f);
904 LightInfo info = lights[name];
906 return glm::vec3(info.light.color.x, info.light.color.y, info.light.color.z);
909 void VulkanRenderer::SetLightRadius(eastl::string name,
float radius)
911 if (lights.count(name) <= 0)
914 LightInfo info = lights[name];
915 info.light.radius = radius;
918 lightData[info.lightDataIndex] = info.light;
919 lightDataChanged =
true;
925 float VulkanRenderer::GetLightRadius(eastl::string name)
927 if (lights.count(name) == 0)
930 return lights[name].light.radius;
933 void VulkanRenderer::SetLightConeInnerAngle(eastl::string name,
float angle)
935 if (lights.count(name) <= 0)
938 LightInfo info = lights[name];
939 info.light.coneInnerAngle = angle;
942 lightData[info.lightDataIndex] = info.light;
943 lightDataChanged =
true;
949 float VulkanRenderer::GetLightConeInnerAngle(eastl::string name)
951 if (lights.count(name) == 0)
954 return lights[name].light.coneInnerAngle;
957 void VulkanRenderer::SetLightConeOuterAngle(eastl::string name,
float angle)
959 if (lights.count(name) <= 0)
962 LightInfo info = lights[name];
963 info.light.coneOuterAngle = angle;
966 lightData[info.lightDataIndex] = info.light;
967 lightDataChanged =
true;
973 float VulkanRenderer::GetLightConeOuterAngle(eastl::string name)
975 if (lights.count(name) == 0)
978 return lights[name].light.coneOuterAngle;
981 VkDescriptorSetLayout VulkanRenderer::CreateLightDescriptorSetLayout()
984 eastl::array<VkDescriptorSetLayoutBinding, 2> descriptorSetBindings;
986 descriptorSetBindings[0] = {};
987 descriptorSetBindings[0].binding = 0;
988 descriptorSetBindings[0].descriptorCount = 1;
989 descriptorSetBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
990 descriptorSetBindings[0].pImmutableSamplers =
nullptr;
991 descriptorSetBindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT;
993 descriptorSetBindings[1] = {};
994 descriptorSetBindings[1].binding = 1;
995 descriptorSetBindings[1].descriptorCount = 1;
996 descriptorSetBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
997 descriptorSetBindings[1].pImmutableSamplers =
nullptr;
998 descriptorSetBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT;
1000 VkDescriptorSetLayoutCreateInfo info = {};
1001 info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1002 info.bindingCount =
static_cast<uint32_t
>(descriptorSetBindings.size());
1003 info.pBindings = descriptorSetBindings.data();
1006 VkDescriptorSetLayout layout;
1007 vkCreateDescriptorSetLayout(vulkanLogicalDevice_->GetDevice(), &info,
nullptr, &layout);
1012 VkDescriptorSet VulkanRenderer::CreateLightDescriptorSet(
size_t threadID,
size_t pipelineID,
size_t set, VkDescriptorSetLayout layout)
1014 if (lightDescriptorSets_.size() <= pipelineID) {
1015 lightDescriptorSets_.resize(pipelineID + 1);
1017 if (lightDescriptorSets_[pipelineID].size() <=
set) {
1018 lightDescriptorSets_[pipelineID].resize(
set + 1);
1021 if (lightDescriptorSets_[pipelineID][
set].size() <= threadID) {
1022 lightDescriptorSets_[pipelineID][
set].resize(threadID + 1, VK_NULL_HANDLE);
1025 if (threadID >= vulkanDescriptorPools_.size())
1026 return VK_NULL_HANDLE;
1028 VkDescriptorSetLayout layouts[] = { layout };
1029 vulkanDescriptorPools_[threadID]->AllocateDescriptorSet(1, layouts, &lightDescriptorSets_[pipelineID][
set][threadID]);
1031 vulkanDescriptorPools_[threadID]->DescriptorSetBindToBuffer(lightDescriptorSets_[pipelineID][
set][threadID], lightBuffer->GetBuffer(),
1032 0,
static_cast<uint32_t
>(
sizeof(
Light)), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1);
1034 vulkanDescriptorPools_[threadID]->DescriptorSetBindToBuffer(lightDescriptorSets_[pipelineID][
set][threadID], sceneDataBuffer->GetBuffer(),
1035 0,
static_cast<uint32_t
>(
sizeof(SceneInfo)), 1, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
1037 return lightDescriptorSets_[pipelineID][
set][threadID];
1040 VkDescriptorSet VulkanRenderer::GetLightDescriptorSet(
size_t threadID,
size_t pipelineID,
size_t set)
1042 if (pipelineID >= lightDescriptorSets_.size())
1043 return VK_NULL_HANDLE;
1044 if (
set >= lightDescriptorSets_[pipelineID].size())
1045 return VK_NULL_HANDLE;
1046 if (threadID >= lightDescriptorSets_[pipelineID][
set].size())
1047 return VK_NULL_HANDLE;
1048 return lightDescriptorSets_[pipelineID][
set][threadID];
1051 VkFramebuffer VulkanRenderer::GetFrameBuffer()
1053 return framebuffers[currentImage];
1056 VulkanDescriptorPool* VulkanRenderer::GetDescriptorPool(
size_t thread)
1058 if (thread >= vulkanDescriptorPools_.size())
1060 return vulkanDescriptorPools_[thread].get();
1063 size_t VulkanRenderer::GetThreadCount()
1065 return threads.size() + 1;
1068 void VulkanRenderer::CreateInstance()
1070 vulkanInstance_ = eastl::make_unique<VulkanInstance>(enableValidationLayers, DebugLevel::LEVEL_WARNINGS);
1073 void VulkanRenderer::FindPhysicalDevice()
1075 requiredFeatures = {};
1076 requiredFeatures.depthBiasClamp = 1.f;
1077 requiredFeatures.depthBounds = 1.f;
1078 requiredFeatures.depthClamp = 1.f;
1079 requiredFeatures.fillModeNonSolid = 1.f;
1080 requiredFeatures.samplerAnisotropy = 1.f;
1081 requiredFeatures.wideLines = 1.f;
1082 requiredFeatures.largePoints = 1.f;
1083 requiredFeatures.variableMultisampleRate = 1.f;
1084 requiredFeatures.geometryShader = 1.f;
1087 VulkanDeviceQueueRequestedFamilies_t requestedQueueFamilies = {};
1088 requestedQueueFamilies.graphics =
true;
1089 requestedQueueFamilies.compute =
true;
1090 requestedQueueFamilies.present =
true;
1092 vulkanPhysicalDevice_ = eastl::unique_ptr<VulkanPhysicalDevice>(VulkanPhysicalDevice::GetBestPhysicalDevice(
1093 vulkanInstance_.get(), surface, { VK_KHR_SWAPCHAIN_EXTENSION_NAME }, requiredFeatures,
1094 {}, requestedQueueFamilies,
true));
1097 void VulkanRenderer::CreateLogicalDevice()
1099 vulkanLogicalDevice_ = eastl::unique_ptr<VulkanLogicalDevice>(
new VulkanLogicalDevice(
1100 vulkanPhysicalDevice_.get(),
1101 enableValidationLayers,
1102 { VK_KHR_SWAPCHAIN_EXTENSION_NAME },
1107 void VulkanRenderer::CreateSwapChain()
1109 VulkanSwapChainSupportDetails_t details = vulkanPhysicalDevice_->GetSwapChainSupportDetails();
1111 VkSurfaceFormatKHR surfaceFormat = vulkanPhysicalDevice_->ChooseSwapSurfaceFormat(details.formats);
1112 VkPresentModeKHR presentMode = vulkanPhysicalDevice_->ChooseSwapPresentMode(details.presentModes);
1113 VkExtent2D extent = vulkanPhysicalDevice_->ChooseSwapExtent(details.capabilities, window.lock()->GetDisplayWidth(), window.lock()->GetDisplayHeight());
1115 uint32_t imageCount = details.capabilities.minImageCount + 1;
1116 if (details.capabilities.maxImageCount > 0 && imageCount > details.capabilities.maxImageCount) {
1117 imageCount = details.capabilities.maxImageCount;
1120 VkSwapchainCreateInfoKHR createInfo = {};
1121 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
1122 createInfo.surface = surface;
1123 createInfo.minImageCount = imageCount;
1124 createInfo.imageFormat = surfaceFormat.format;
1125 createInfo.imageColorSpace = surfaceFormat.colorSpace;
1126 createInfo.imageExtent = extent;
1127 createInfo.imageArrayLayers = 1;
1128 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1130 VulkanDeviceQueueFamilies_t queueFamilies = vulkanPhysicalDevice_->GetQueueFamilies();
1131 uint32_t queueFamilyIndices[] = { (uint32_t)queueFamilies.graphics, (uint32_t)queueFamilies.present };
1133 if (queueFamilies.graphics != queueFamilies.present) {
1134 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
1135 createInfo.queueFamilyIndexCount = 2;
1136 createInfo.pQueueFamilyIndices = queueFamilyIndices;
1139 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
1140 createInfo.queueFamilyIndexCount = 0;
1141 createInfo.pQueueFamilyIndices =
nullptr;
1144 createInfo.preTransform = details.capabilities.currentTransform;
1145 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
1146 createInfo.presentMode = presentMode;
1147 createInfo.clipped = VK_TRUE;
1148 createInfo.oldSwapchain = VK_NULL_HANDLE;
1150 VkResult res = vkCreateSwapchainKHR(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &swapChain);
1152 if (res != VK_SUCCESS) {
1153 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create new swapchain";
1154 std::cout << s.c_str() << std::endl;
1157 swapChainImageFormat = surfaceFormat.format;
1158 swapChainImageExtent = extent;
1161 void VulkanRenderer::GetSwapChainImages()
1164 vkGetSwapchainImagesKHR(vulkanLogicalDevice_->GetDevice(), swapChain, &imageCount,
nullptr);
1165 swapChainImages.resize(imageCount);
1166 vkGetSwapchainImagesKHR(vulkanLogicalDevice_->GetDevice(), swapChain, &imageCount, swapChainImages.data());
1169 void VulkanRenderer::CreateSwapChainImageViews()
1171 swapChainImageViews.resize(swapChainImages.size());
1172 for (
int i = 0; i < static_cast<int>(swapChainImages.size()); ++i) {
1173 VkImageViewCreateInfo createInfo = {};
1174 createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1175 createInfo.image = swapChainImages[i];
1176 createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1177 createInfo.format = swapChainImageFormat;
1178 createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
1179 createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
1180 createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
1181 createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
1182 createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1183 createInfo.subresourceRange.baseMipLevel = 0;
1184 createInfo.subresourceRange.levelCount = 1;
1185 createInfo.subresourceRange.baseArrayLayer = 0;
1186 createInfo.subresourceRange.layerCount = 1;
1188 VkResult res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &swapChainImageViews[i]);
1190 if (res != VK_SUCCESS) {
1191 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Image view creation creation failed";
1192 std::cout << s.c_str() << std::endl;
1197 void VulkanRenderer::CreateGraphicsCommandPool()
1199 VkCommandPoolCreateInfo createInfo = {};
1200 createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1201 createInfo.queueFamilyIndex = vulkanPhysicalDevice_->GetQueueFamilies().graphics;
1202 createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1204 VkResult res = vkCreateCommandPool(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &graphicsCommandPool);
1205 if (res != VK_SUCCESS) {
1206 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Graphics command pool creation failed";
1207 std::cout << s.c_str() << std::endl;
1211 void VulkanRenderer::CreateComputeCommandPool()
1213 VkCommandPoolCreateInfo createInfo = {};
1214 createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1215 createInfo.queueFamilyIndex = vulkanPhysicalDevice_->GetQueueFamilies().compute;
1216 createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1218 VkResult res = vkCreateCommandPool(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &computeCommandPool);
1219 if (res != VK_SUCCESS) {
1220 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Graphics command pool creation failed";
1221 std::cout << s.c_str() << std::endl;
1225 void VulkanRenderer::CreateVmaAllocator()
1227 VmaAllocatorCreateInfo createInfo = {};
1228 createInfo.physicalDevice = vulkanPhysicalDevice_->GetPhysicalDevice();
1229 createInfo.device = vulkanLogicalDevice_->GetDevice();
1230 createInfo.preferredLargeHeapBlockSize = 64 * 1024 * 1024;
1231 createInfo.pAllocationCallbacks =
nullptr;
1232 createInfo.pDeviceMemoryCallbacks =
nullptr;
1233 createInfo.frameInUseCount = imageCount;
1234 createInfo.pHeapSizeLimit =
nullptr;
1235 createInfo.pVulkanFunctions =
nullptr;
1237 VkResult res = vmaCreateAllocator(&createInfo, &vmaAllocator_);
1238 if (res != VK_SUCCESS) {
1239 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create vulkan memory allocator";
1240 std::cout << s.c_str() << std::endl;
1244 void VulkanRenderer::CreateDepthImage()
1246 VkFormat depthFormat = FindSupportedDepthFormat({ VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
1247 VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
1249 this->depthImageFormat = depthFormat;
1251 VkImageCreateInfo imageCreateInfo = {};
1252 imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1253 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1254 imageCreateInfo.extent.width = swapChainImageExtent.width;
1255 imageCreateInfo.extent.height = swapChainImageExtent.height;
1256 imageCreateInfo.extent.depth = 1;
1257 imageCreateInfo.mipLevels = 1;
1258 imageCreateInfo.arrayLayers = 1;
1259 imageCreateInfo.format = depthFormat;
1260 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1261 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1262 imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1263 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1264 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1266 VmaAllocationCreateInfo allocInfo = {};
1267 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1269 VkResult res = vmaCreateImage(vmaAllocator_, &imageCreateInfo, &allocInfo, &depthImage, &depthImageAllocation, &depthImageAllocationInfo);
1270 if (res != VK_SUCCESS) {
1271 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create depth image";
1272 std::cout << s.c_str() << std::endl;
1275 VkImageViewCreateInfo viewCreateInfo = {};
1276 viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1277 viewCreateInfo.image = depthImage;
1278 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1279 viewCreateInfo.format = depthFormat;
1280 viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1281 viewCreateInfo.subresourceRange.baseArrayLayer = 0;
1282 viewCreateInfo.subresourceRange.baseMipLevel = 0;
1283 viewCreateInfo.subresourceRange.layerCount = 1;
1284 viewCreateInfo.subresourceRange.levelCount = 1;
1286 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &viewCreateInfo,
nullptr, &depthImageView);
1287 if (res != VK_SUCCESS) {
1288 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create depth image view";
1289 std::cout << s.c_str() << std::endl;
1292 VkCommandBufferAllocateInfo commandBufferInfo = {};
1293 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1294 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1295 commandBufferInfo.commandPool = graphicsCommandPool;
1296 commandBufferInfo.commandBufferCount = 1;
1298 VkCommandBuffer commandBuffer;
1299 vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &commandBufferInfo, &commandBuffer);
1301 VkCommandBufferBeginInfo beginInfo = {};
1302 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1303 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1305 vkBeginCommandBuffer(commandBuffer, &beginInfo);
1307 VkImageMemoryBarrier barrier = {};
1308 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1309 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1310 barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1311 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1312 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1313 barrier.image = depthImage;
1314 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1315 barrier.subresourceRange.baseArrayLayer = 0;
1316 barrier.subresourceRange.baseMipLevel = 0;
1317 barrier.subresourceRange.layerCount = 1;
1318 barrier.subresourceRange.levelCount = 1;
1320 if (depthFormat == VK_FORMAT_D32_SFLOAT_S8_UINT || depthFormat == VK_FORMAT_D24_UNORM_S8_UINT)
1321 barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
1323 barrier.srcAccessMask = 0;
1324 barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1326 vkCmdPipelineBarrier(
1328 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
1335 vkEndCommandBuffer(commandBuffer);
1337 VkSubmitInfo submitInfo = {};
1338 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1339 submitInfo.commandBufferCount = 1;
1340 submitInfo.pCommandBuffers = &commandBuffer;
1342 vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
1343 vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
1344 vkFreeCommandBuffers(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, 1, &commandBuffer);
1348 void VulkanRenderer::CreateAttachmentImages()
1350 VkImageCreateInfo imguiImageCreateInfo = {};
1351 imguiImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1352 imguiImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1353 imguiImageCreateInfo.extent.width = swapChainImageExtent.width;
1354 imguiImageCreateInfo.extent.height = swapChainImageExtent.height;
1355 imguiImageCreateInfo.extent.depth = 1;
1356 imguiImageCreateInfo.mipLevels = 1;
1357 imguiImageCreateInfo.arrayLayers = 1;
1358 imguiImageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1359 imguiImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1360 imguiImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1361 imguiImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1362 imguiImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1363 imguiImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1365 VmaAllocationCreateInfo allocInfo = {};
1366 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1368 VkResult res = vmaCreateImage(vmaAllocator_, &imguiImageCreateInfo, &allocInfo, &imguiImage, &imguiImageAllocation, &imguiImageAllocationInfo);
1369 if (res != VK_SUCCESS) {
1370 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create imgui image";
1371 std::cout << s.c_str() << std::endl;
1374 VkImageViewCreateInfo imguiViewCreateInfo = {};
1375 imguiViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1376 imguiViewCreateInfo.image = imguiImage;
1377 imguiViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1378 imguiViewCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1379 imguiViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1380 imguiViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1381 imguiViewCreateInfo.subresourceRange.baseMipLevel = 0;
1382 imguiViewCreateInfo.subresourceRange.layerCount = 1;
1383 imguiViewCreateInfo.subresourceRange.levelCount = 1;
1385 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &imguiViewCreateInfo,
nullptr, &imguiImageView);
1386 if (res != VK_SUCCESS) {
1387 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create imgui image view";
1388 std::cout << s.c_str() << std::endl;
1391 VkImageCreateInfo renderImageCreateInfo = {};
1392 renderImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1393 renderImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1394 renderImageCreateInfo.extent.width = swapChainImageExtent.width;
1395 renderImageCreateInfo.extent.height = swapChainImageExtent.height;
1396 renderImageCreateInfo.extent.depth = 1;
1397 renderImageCreateInfo.mipLevels = 1;
1398 renderImageCreateInfo.arrayLayers = 1;
1399 renderImageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1400 renderImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1401 renderImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1402 renderImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1403 renderImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1404 renderImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1407 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1409 res = vmaCreateImage(vmaAllocator_, &renderImageCreateInfo, &allocInfo, &renderImage, &renderImageAllocation, &renderImageAllocationInfo);
1410 if (res != VK_SUCCESS) {
1411 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create render image";
1412 std::cout << s.c_str() << std::endl;
1415 VkImageViewCreateInfo renderViewCreateInfo = {};
1416 renderViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1417 renderViewCreateInfo.image = renderImage;
1418 renderViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1419 renderViewCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1420 renderViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1421 renderViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1422 renderViewCreateInfo.subresourceRange.baseMipLevel = 0;
1423 renderViewCreateInfo.subresourceRange.layerCount = 1;
1424 renderViewCreateInfo.subresourceRange.levelCount = 1;
1426 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &renderViewCreateInfo,
nullptr, &renderImageView);
1427 if (res != VK_SUCCESS) {
1428 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create render image view";
1429 std::cout << s.c_str() << std::endl;
1432 VkImageCreateInfo albedoImageCreateInfo = {};
1433 albedoImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1434 albedoImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1435 albedoImageCreateInfo.extent.width = swapChainImageExtent.width;
1436 albedoImageCreateInfo.extent.height = swapChainImageExtent.height;
1437 albedoImageCreateInfo.extent.depth = 1;
1438 albedoImageCreateInfo.mipLevels = 1;
1439 albedoImageCreateInfo.arrayLayers = 1;
1440 albedoImageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
1441 albedoImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1442 albedoImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1443 albedoImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1444 albedoImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1445 albedoImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1448 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1450 res = vmaCreateImage(vmaAllocator_, &albedoImageCreateInfo, &allocInfo, &albedoImage, &albedoImageAllocation, &albedoImageAllocationInfo);
1451 if (res != VK_SUCCESS) {
1452 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create albedo image";
1453 std::cout << s.c_str() << std::endl;
1456 VkImageViewCreateInfo albedoViewCreateInfo = {};
1457 albedoViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1458 albedoViewCreateInfo.image = albedoImage;
1459 albedoViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1460 albedoViewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
1461 albedoViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1462 albedoViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1463 albedoViewCreateInfo.subresourceRange.baseMipLevel = 0;
1464 albedoViewCreateInfo.subresourceRange.layerCount = 1;
1465 albedoViewCreateInfo.subresourceRange.levelCount = 1;
1467 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &albedoViewCreateInfo,
nullptr, &albedoImageView);
1468 if (res != VK_SUCCESS) {
1469 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create albedo image view";
1470 std::cout << s.c_str() << std::endl;
1473 VkImageCreateInfo positionImageCreateInfo = {};
1474 positionImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1475 positionImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1476 positionImageCreateInfo.extent.width = swapChainImageExtent.width;
1477 positionImageCreateInfo.extent.height = swapChainImageExtent.height;
1478 positionImageCreateInfo.extent.depth = 1;
1479 positionImageCreateInfo.mipLevels = 1;
1480 positionImageCreateInfo.arrayLayers = 1;
1481 positionImageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1482 positionImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1483 positionImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1484 positionImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1485 positionImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1486 positionImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1489 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1491 res = vmaCreateImage(vmaAllocator_, &positionImageCreateInfo, &allocInfo, &positionImage, &positionImageAllocation, &positionImageAllocationInfo);
1492 if (res != VK_SUCCESS) {
1493 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create position image";
1494 std::cout << s.c_str() << std::endl;
1497 VkImageViewCreateInfo positionViewCreateInfo = {};
1498 positionViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1499 positionViewCreateInfo.image = positionImage;
1500 positionViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1501 positionViewCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1502 positionViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1503 positionViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1504 positionViewCreateInfo.subresourceRange.baseMipLevel = 0;
1505 positionViewCreateInfo.subresourceRange.layerCount = 1;
1506 positionViewCreateInfo.subresourceRange.levelCount = 1;
1508 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &positionViewCreateInfo,
nullptr, &positionImageView);
1509 if (res != VK_SUCCESS) {
1510 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create position image view";
1511 std::cout << s.c_str() << std::endl;
1514 VkImageCreateInfo normalImageCreateInfo = {};
1515 normalImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1516 normalImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1517 normalImageCreateInfo.extent.width = swapChainImageExtent.width;
1518 normalImageCreateInfo.extent.height = swapChainImageExtent.height;
1519 normalImageCreateInfo.extent.depth = 1;
1520 normalImageCreateInfo.mipLevels = 1;
1521 normalImageCreateInfo.arrayLayers = 1;
1522 normalImageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1523 normalImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1524 normalImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1525 normalImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1526 normalImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1527 normalImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1530 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1532 res = vmaCreateImage(vmaAllocator_, &normalImageCreateInfo, &allocInfo, &normalImage, &normalImageAllocation, &normalImageAllocationInfo);
1533 if (res != VK_SUCCESS) {
1534 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create normal image";
1535 std::cout << s.c_str() << std::endl;
1538 VkImageViewCreateInfo normalViewCreateInfo = {};
1539 normalViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1540 normalViewCreateInfo.image = normalImage;
1541 normalViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1542 normalViewCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
1543 normalViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1544 normalViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1545 normalViewCreateInfo.subresourceRange.baseMipLevel = 0;
1546 normalViewCreateInfo.subresourceRange.layerCount = 1;
1547 normalViewCreateInfo.subresourceRange.levelCount = 1;
1549 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &normalViewCreateInfo,
nullptr, &normalImageView);
1550 if (res != VK_SUCCESS) {
1551 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create normal image view";
1552 std::cout << s.c_str() << std::endl;
1556 VkImageCreateInfo ssaoImageCreateInfo = {};
1557 ssaoImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1558 ssaoImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1559 ssaoImageCreateInfo.extent.width = swapChainImageExtent.width;
1560 ssaoImageCreateInfo.extent.height = swapChainImageExtent.height;
1561 ssaoImageCreateInfo.extent.depth = 1;
1562 ssaoImageCreateInfo.mipLevels = 1;
1563 ssaoImageCreateInfo.arrayLayers = 1;
1564 ssaoImageCreateInfo.format = VK_FORMAT_R16_UNORM;
1565 ssaoImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1566 ssaoImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1567 ssaoImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1568 ssaoImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1569 ssaoImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1572 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1574 res = vmaCreateImage(vmaAllocator_, &ssaoImageCreateInfo, &allocInfo, &ssaoImage, &ssaoImageAllocation, &ssaoImageAllocationInfo);
1575 if (res != VK_SUCCESS) {
1576 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create ssao image";
1577 std::cout << s.c_str() << std::endl;
1580 VkImageViewCreateInfo ssaoViewCreateInfo = {};
1581 ssaoViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1582 ssaoViewCreateInfo.image = ssaoImage;
1583 ssaoViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1584 ssaoViewCreateInfo.format = VK_FORMAT_R16_UNORM;
1585 ssaoViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1586 ssaoViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1587 ssaoViewCreateInfo.subresourceRange.baseMipLevel = 0;
1588 ssaoViewCreateInfo.subresourceRange.layerCount = 1;
1589 ssaoViewCreateInfo.subresourceRange.levelCount = 1;
1591 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &ssaoViewCreateInfo,
nullptr, &ssaoImageView);
1592 if (res != VK_SUCCESS) {
1593 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create ssao image view";
1594 std::cout << s.c_str() << std::endl;
1597 VkImageCreateInfo ssaoBlurImageCreateInfo = {};
1598 ssaoBlurImageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1599 ssaoBlurImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1600 ssaoBlurImageCreateInfo.extent.width = swapChainImageExtent.width;
1601 ssaoBlurImageCreateInfo.extent.height = swapChainImageExtent.height;
1602 ssaoBlurImageCreateInfo.extent.depth = 1;
1603 ssaoBlurImageCreateInfo.mipLevels = 1;
1604 ssaoBlurImageCreateInfo.arrayLayers = 1;
1605 ssaoBlurImageCreateInfo.format = VK_FORMAT_R16_UNORM;
1606 ssaoBlurImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1607 ssaoBlurImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1608 ssaoBlurImageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1609 ssaoBlurImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1610 ssaoBlurImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1613 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
1615 res = vmaCreateImage(vmaAllocator_, &ssaoBlurImageCreateInfo, &allocInfo, &ssaoBlurImage, &ssaoBlurImageAllocation, &ssaoBlurImageAllocationInfo);
1616 if (res != VK_SUCCESS) {
1617 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create ssaoBlur image";
1618 std::cout << s.c_str() << std::endl;
1621 VkImageViewCreateInfo ssaoBlurViewCreateInfo = {};
1622 ssaoBlurViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1623 ssaoBlurViewCreateInfo.image = ssaoBlurImage;
1624 ssaoBlurViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1625 ssaoBlurViewCreateInfo.format = VK_FORMAT_R16_UNORM;
1626 ssaoBlurViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1627 ssaoBlurViewCreateInfo.subresourceRange.baseArrayLayer = 0;
1628 ssaoBlurViewCreateInfo.subresourceRange.baseMipLevel = 0;
1629 ssaoBlurViewCreateInfo.subresourceRange.layerCount = 1;
1630 ssaoBlurViewCreateInfo.subresourceRange.levelCount = 1;
1632 res = vkCreateImageView(vulkanLogicalDevice_->GetDevice(), &ssaoBlurViewCreateInfo,
nullptr, &ssaoBlurImageView);
1633 if (res != VK_SUCCESS) {
1634 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Failed to create ssaoBlur image view";
1635 std::cout << s.c_str() << std::endl;
1640 void VulkanRenderer::CreateRenderPass()
1643 gBufferPassAttachments.resize(static_cast<size_t>(GBufferAttachments::ATTACHMENT_COUNT));
1645 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].flags = 0;
1646 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].format = depthImageFormat;
1647 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1648 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1649 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1650 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1651 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1652 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1653 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1655 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].flags = 0;
1656 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].format = VK_FORMAT_R8G8B8A8_UNORM;
1657 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1658 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1659 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1660 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1661 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1662 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1663 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1665 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].flags = 0;
1666 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1667 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1668 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1669 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1670 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1671 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1672 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1673 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1675 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].flags = 0;
1676 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1677 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1678 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1679 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1680 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1681 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1682 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1683 gBufferPassAttachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1687 ssaoPassAttachments.resize(static_cast<size_t>(SsaoAttachments::ATTACHMENT_COUNT));
1689 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].flags = 0;
1690 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].format = VK_FORMAT_R16_UNORM;
1691 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1692 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1693 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1694 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1695 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1696 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1697 ssaoPassAttachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1699 renderPassAttachments.resize(static_cast<int>(RenderPassAttachments::ATTACHMENT_COUNT));
1701 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].flags = 0;
1702 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].format = VK_FORMAT_B8G8R8A8_UNORM;
1703 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1704 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1705 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1706 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1707 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1708 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1709 renderPassAttachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1711 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].flags = 0;
1712 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].format = depthImageFormat;
1713 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1714 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1715 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1716 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1717 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1718 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1719 renderPassAttachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1721 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].flags = 0;
1722 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].format = VK_FORMAT_R16_UNORM;
1723 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1724 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1725 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1726 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1727 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1728 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1729 renderPassAttachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1731 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].flags = 0;
1732 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].format = VK_FORMAT_R8G8B8A8_UNORM;
1733 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1734 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1735 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1736 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1737 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1738 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1739 renderPassAttachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1741 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].flags = 0;
1742 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1743 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1744 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1745 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1746 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1747 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1748 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1749 renderPassAttachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1751 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].flags = 0;
1752 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].format = VK_FORMAT_R16G16B16A16_SFLOAT;
1753 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1754 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1755 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1756 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1757 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1758 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1759 renderPassAttachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1761 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].flags = 0;
1762 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].format = VK_FORMAT_B8G8R8A8_UNORM;
1763 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1764 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1765 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1766 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1767 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1768 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1769 renderPassAttachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1771 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].flags = 0;
1772 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].format = VK_FORMAT_B8G8R8A8_UNORM;
1773 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].samples = VK_SAMPLE_COUNT_1_BIT;
1774 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1775 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1776 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1777 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1778 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1779 renderPassAttachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1782 gBufferPassSubPasses.resize(static_cast<int>(GBufferSubPasses::SUBPASS_COUNT));
1784 VkAttachmentReference gBufferDepthReference = {};
1785 gBufferDepthReference.attachment =
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT);
1786 gBufferDepthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1788 VkAttachmentReference gBufferAttachments[] = {
1790 static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT),
1791 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1794 static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT),
1795 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1798 static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT),
1799 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1803 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].flags = 0;
1804 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1805 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].inputAttachmentCount = 0;
1806 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pInputAttachments =
nullptr;
1807 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].colorAttachmentCount = 3;
1808 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pColorAttachments = gBufferAttachments;
1809 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pResolveAttachments =
nullptr;
1810 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pDepthStencilAttachment = &gBufferDepthReference;
1811 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].preserveAttachmentCount = 0;
1812 gBufferPassSubPasses[
static_cast<int>(GBufferSubPasses::G_BUFFER_PASS)].pPreserveAttachments =
nullptr;
1814 eastl::vector<VkSubpassDependency> gbufferDependencies = {
1816 VK_SUBPASS_EXTERNAL,
1817 static_cast<int>(GBufferSubPasses::G_BUFFER_PASS),
1818 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1819 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1820 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1821 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
1822 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1823 VK_DEPENDENCY_BY_REGION_BIT
1826 static_cast<int>(GBufferSubPasses::G_BUFFER_PASS),
1827 VK_SUBPASS_EXTERNAL,
1828 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1829 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1830 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
1831 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1832 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1833 VK_DEPENDENCY_BY_REGION_BIT
1837 VkRenderPassCreateInfo gbufferPassCreateInfo = {};
1838 gbufferPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1839 gbufferPassCreateInfo.attachmentCount =
static_cast<uint32_t
>(gBufferPassAttachments.size());
1840 gbufferPassCreateInfo.pAttachments = gBufferPassAttachments.data();
1841 gbufferPassCreateInfo.dependencyCount =
static_cast<uint32_t
>(gbufferDependencies.size());
1842 gbufferPassCreateInfo.pDependencies = gbufferDependencies.data();
1843 gbufferPassCreateInfo.subpassCount =
static_cast<uint32_t
>(gBufferPassSubPasses.size());
1844 gbufferPassCreateInfo.pSubpasses = gBufferPassSubPasses.data();
1845 gbufferPassCreateInfo.flags = 0;
1847 vkCreateRenderPass(vulkanLogicalDevice_->GetDevice(), &gbufferPassCreateInfo,
nullptr, &gBufferPass);
1849 ssaoPassSubPasses.resize(static_cast<int>(SsaoSubPasses::SUBPASS_COUNT));
1851 VkAttachmentReference ssaoReference = {};
1852 ssaoReference.attachment =
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT);
1853 ssaoReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1855 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].flags = 0;
1856 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1857 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].inputAttachmentCount = 0;
1858 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].pInputAttachments =
nullptr;
1859 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].colorAttachmentCount = 1;
1860 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].pColorAttachments = &ssaoReference;
1861 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].pResolveAttachments =
nullptr;
1862 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].pDepthStencilAttachment =
nullptr;
1863 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].preserveAttachmentCount = 0;
1864 ssaoPassSubPasses[
static_cast<int>(SsaoSubPasses::SSAO_PASS)].pPreserveAttachments =
nullptr;
1866 eastl::vector<VkSubpassDependency> ssaoDependencies = {
1868 VK_SUBPASS_EXTERNAL,
1869 static_cast<int>(SsaoSubPasses::SSAO_PASS),
1870 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1871 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1872 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1873 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1874 VK_DEPENDENCY_BY_REGION_BIT
1877 static_cast<int>(SsaoSubPasses::SSAO_PASS),
1878 VK_SUBPASS_EXTERNAL,
1879 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1880 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1881 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1882 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1883 VK_DEPENDENCY_BY_REGION_BIT
1887 VkRenderPassCreateInfo ssaoPassCreateInfo = {};
1888 ssaoPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1889 ssaoPassCreateInfo.attachmentCount =
static_cast<uint32_t
>(ssaoPassAttachments.size());
1890 ssaoPassCreateInfo.pAttachments = ssaoPassAttachments.data();
1891 ssaoPassCreateInfo.dependencyCount =
static_cast<uint32_t
>(ssaoDependencies.size());
1892 ssaoPassCreateInfo.pDependencies = ssaoDependencies.data();
1893 ssaoPassCreateInfo.subpassCount =
static_cast<uint32_t
>(ssaoPassSubPasses.size());
1894 ssaoPassCreateInfo.pSubpasses = ssaoPassSubPasses.data();
1895 ssaoPassCreateInfo.flags = 0;
1897 vkCreateRenderPass(vulkanLogicalDevice_->GetDevice(), &ssaoPassCreateInfo,
nullptr, &ssaoPass);
1899 renderPassSubPasses.resize(static_cast<int>(RenderSubPasses::SUBPASS_COUNT));
1901 VkAttachmentReference ssaoBlurReference = {};
1902 ssaoBlurReference.attachment =
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT);
1903 ssaoBlurReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1905 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].flags = 0;
1906 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1907 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].inputAttachmentCount = 0;
1908 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pInputAttachments =
nullptr;
1909 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].colorAttachmentCount = 1;
1910 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pColorAttachments = &ssaoBlurReference;
1911 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pResolveAttachments =
nullptr;
1912 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pDepthStencilAttachment =
nullptr;
1913 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].preserveAttachmentCount = 0;
1914 renderPassSubPasses[
static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS)].pPreserveAttachments =
nullptr;
1916 VkAttachmentReference renderDepthReference = {};
1917 renderDepthReference.attachment =
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT);
1918 renderDepthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
1920 VkAttachmentReference gBufferInputs[] = {
1922 static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT),
1923 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1926 static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT),
1927 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1930 static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT),
1931 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1935 VkAttachmentReference renderReference = {};
1936 renderReference.attachment =
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT);
1937 renderReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1939 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].flags = 0;
1940 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1941 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].inputAttachmentCount = 3;
1942 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].pInputAttachments = gBufferInputs;
1943 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].colorAttachmentCount = 1;
1944 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].pColorAttachments = &renderReference;
1945 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].pResolveAttachments =
nullptr;
1946 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].pDepthStencilAttachment = &renderDepthReference;
1947 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].preserveAttachmentCount = 0;
1948 renderPassSubPasses[
static_cast<int>(RenderSubPasses::RENDER_PASS)].pPreserveAttachments =
nullptr;
1950 VkAttachmentReference imguiReference = {};
1951 imguiReference.attachment =
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT);
1952 imguiReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1954 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].flags = 0;
1955 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1956 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].inputAttachmentCount = 0;
1957 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].pInputAttachments =
nullptr;
1958 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].colorAttachmentCount = 1;
1959 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].pColorAttachments = &imguiReference;
1960 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].pResolveAttachments =
nullptr;
1961 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].pDepthStencilAttachment =
nullptr;
1962 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].preserveAttachmentCount = 0;
1963 renderPassSubPasses[
static_cast<int>(RenderSubPasses::IMGUI_PASS)].pPreserveAttachments =
nullptr;
1965 VkAttachmentReference compositeInputs[] = {
1967 static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT),
1968 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1972 static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT),
1973 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1977 VkAttachmentReference compositeReference = {};
1978 compositeReference.attachment =
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT);
1979 compositeReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1981 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].flags = 0;
1982 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1983 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].inputAttachmentCount = 2;
1984 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pInputAttachments = compositeInputs;
1985 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].colorAttachmentCount = 1;
1986 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pColorAttachments = &compositeReference;
1987 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pResolveAttachments =
nullptr;
1988 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pDepthStencilAttachment =
nullptr;
1989 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].preserveAttachmentCount = 0;
1990 renderPassSubPasses[
static_cast<int>(RenderSubPasses::COMPOSITE_PASS)].pPreserveAttachments =
nullptr;
1994 eastl::vector<VkSubpassDependency> dependecies = {
1996 VK_SUBPASS_EXTERNAL,
1997 static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS),
1998 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1999 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2000 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2001 VK_ACCESS_SHADER_READ_BIT,
2002 VK_DEPENDENCY_BY_REGION_BIT
2006 static_cast<int>(RenderSubPasses::SSAO_BLUR_PASS),
2007 static_cast<int>(RenderSubPasses::RENDER_PASS),
2008 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2009 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2010 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2011 VK_ACCESS_SHADER_READ_BIT,
2012 VK_DEPENDENCY_BY_REGION_BIT
2016 static_cast<int>(RenderSubPasses::RENDER_PASS),
2017 static_cast<int>(RenderSubPasses::COMPOSITE_PASS),
2018 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2019 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2020 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2021 VK_ACCESS_SHADER_READ_BIT,
2022 VK_DEPENDENCY_BY_REGION_BIT
2026 static_cast<int>(RenderSubPasses::IMGUI_PASS),
2027 static_cast<int>(RenderSubPasses::COMPOSITE_PASS),
2028 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2029 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2030 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2031 VK_ACCESS_SHADER_READ_BIT,
2032 VK_DEPENDENCY_BY_REGION_BIT
2036 static_cast<int>(RenderSubPasses::COMPOSITE_PASS),
2037 VK_SUBPASS_EXTERNAL,
2038 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2039 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2040 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
2041 VK_ACCESS_SHADER_READ_BIT,
2042 VK_DEPENDENCY_BY_REGION_BIT
2046 VkRenderPassCreateInfo createInfo = {};
2047 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
2048 createInfo.flags = 0;
2049 createInfo.attachmentCount =
static_cast<uint32_t
>(renderPassAttachments.size());
2050 createInfo.pAttachments = renderPassAttachments.data();
2051 createInfo.subpassCount =
static_cast<uint32_t
>(renderPassSubPasses.size());
2052 createInfo.pSubpasses = renderPassSubPasses.data();
2053 createInfo.dependencyCount =
static_cast<uint32_t
>(dependecies.size());
2054 createInfo.pDependencies = dependecies.data();
2056 VkResult res = vkCreateRenderPass(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &renderPass);
2059 void VulkanRenderer::CreateFramebuffers()
2061 framebuffers.resize(swapChainImageViews.size());
2063 for (
int i = 0; i < framebuffers.size(); ++i) {
2064 eastl::vector<VkImageView> attachments(static_cast<int>(RenderPassAttachments::ATTACHMENT_COUNT));
2065 attachments[
static_cast<int>(RenderPassAttachments::COLOR_ATTACHMENT)] = swapChainImageViews[i];
2066 attachments[
static_cast<int>(RenderPassAttachments::DEPTH_ATTACHMENT)] = depthImageView;
2067 attachments[
static_cast<int>(RenderPassAttachments::IMGUI_ATTACHMENT)] = imguiImageView;
2068 attachments[
static_cast<int>(RenderPassAttachments::RENDER_ATTACHMENT)] = renderImageView;
2069 attachments[
static_cast<int>(RenderPassAttachments::ALBEDO_ATTACHMENT)] = albedoImageView;
2070 attachments[
static_cast<int>(RenderPassAttachments::POSITION_ATTACHMENT)] = positionImageView;
2071 attachments[
static_cast<int>(RenderPassAttachments::NORMAL_ATTACHMENT)] = normalImageView;
2072 attachments[
static_cast<int>(RenderPassAttachments::SSAO_BLUR_ATTACHMENT)] = ssaoBlurImageView;
2074 VkFramebufferCreateInfo createInfo = {};
2075 createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2076 createInfo.renderPass = renderPass;
2077 createInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
2078 createInfo.pAttachments = attachments.data();
2079 createInfo.width = swapChainImageExtent.width;
2080 createInfo.height = swapChainImageExtent.height;
2081 createInfo.layers = 1;
2083 VkResult res = vkCreateFramebuffer(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &framebuffers[i]);
2084 if (res != VK_SUCCESS) {
2085 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Framebuffer creation failed";
2086 std::cout << s.c_str() << std::endl;
2089 eastl::vector<VkImageView> attachments(static_cast<int>(GBufferAttachments::ATTACHMENT_COUNT));
2090 attachments[
static_cast<int>(GBufferAttachments::DEPTH_ATTACHMENT)] = depthImageView;
2091 attachments[
static_cast<int>(GBufferAttachments::ALBEDO_ATTACHMENT)] = albedoImageView;
2092 attachments[
static_cast<int>(GBufferAttachments::POSITION_ATTACHMENT)] = positionImageView;
2093 attachments[
static_cast<int>(GBufferAttachments::NORMAL_ATTACHMENT)] = normalImageView;
2095 VkFramebufferCreateInfo createInfo = {};
2096 createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2097 createInfo.renderPass = gBufferPass;
2098 createInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
2099 createInfo.pAttachments = attachments.data();
2100 createInfo.width = swapChainImageExtent.width;
2101 createInfo.height = swapChainImageExtent.height;
2102 createInfo.layers = 1;
2104 VkResult res = vkCreateFramebuffer(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &gBufferFrameBuffer);
2105 if (res != VK_SUCCESS) {
2106 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Framebuffer creation failed";
2107 std::cout << s.c_str() << std::endl;
2110 attachments.resize(static_cast<int>(SsaoAttachments::ATTACHMENT_COUNT));
2111 attachments[
static_cast<int>(SsaoAttachments::SSAO_ATTACHMENT)] = ssaoImageView;
2114 createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
2115 createInfo.renderPass = ssaoPass;
2116 createInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
2117 createInfo.pAttachments = attachments.data();
2118 createInfo.width = swapChainImageExtent.width;
2119 createInfo.height = swapChainImageExtent.height;
2120 createInfo.layers = 1;
2122 res = vkCreateFramebuffer(vulkanLogicalDevice_->GetDevice(), &createInfo,
nullptr, &ssaoFrameBuffer);
2123 if (res != VK_SUCCESS) {
2124 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Framebuffer creation failed";
2125 std::cout << s.c_str() << std::endl;
2129 void VulkanRenderer::GenerateCommandBuffers()
2131 primaryRenderCommandBuffers_.resize(framebuffers.size());
2133 VkCommandBufferAllocateInfo allocInfo = {};
2134 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2135 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2136 allocInfo.commandPool = graphicsCommandPool;
2137 allocInfo.commandBufferCount =
static_cast<uint32_t
>(primaryRenderCommandBuffers_.size());
2139 vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, primaryRenderCommandBuffers_.data());
2141 primaryComputeCommandBuffers_.resize(framebuffers.size());
2143 allocInfo.commandPool = computeCommandPool;
2144 vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, primaryComputeCommandBuffers_.data());
2146 imguiCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2147 spriteRenderCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2148 debugRenderCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2149 staticMeshCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2150 skeletalMeshCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2151 clearStencilCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2153 staticMeshShadowCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2154 skeletalMeshShadowCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2155 gBufferShadowCommandBuffers_.resize(primaryRenderCommandBuffers_.size());
2157 GenerateSecondaryCommandBuffers(imguiCommandBuffers_.data(),
static_cast<uint32_t
>(imguiCommandBuffers_.size()));
2159 GenerateSecondaryCommandBuffers(&compositeCommandBuffer_, 1);
2161 GenerateSecondaryCommandBuffers(&gBufferRenderCommandBuffer_, 1);
2163 GenerateSecondaryCommandBuffers(spriteRenderCommandBuffers_.data(),
static_cast<uint32_t
>(spriteRenderCommandBuffers_.size()));
2165 GenerateSecondaryCommandBuffers(debugRenderCommandBuffers_.data(),
static_cast<uint32_t
>(debugRenderCommandBuffers_.size()));
2167 GenerateSecondaryCommandBuffers(clearStencilCommandBuffers_.data(),
static_cast<uint32_t
>(clearStencilCommandBuffers_.size()));
2169 GenerateSecondaryCommandBuffers(staticMeshCommandBuffers_.data(),
static_cast<uint32_t
>(staticMeshCommandBuffers_.size()));
2171 GenerateSecondaryCommandBuffers(skeletalMeshCommandBuffers_.data(),
static_cast<uint32_t
>(skeletalMeshCommandBuffers_.size()));
2173 StartSecondaryCommandBufferRecording(compositeCommandBuffer_,
2174 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
2175 renderPass, static_cast<int>(RenderSubPasses::COMPOSITE_PASS), VK_NULL_HANDLE);
2177 vkCmdBindPipeline(compositeCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, compositingPipeline_->GetPipeline());
2179 VkRect2D scissor = { 0,0,swapChainImageExtent };
2180 VkViewport viewport = { 0.f,0.f,
static_cast<float>(swapChainImageExtent.width),static_cast<float>(swapChainImageExtent.height),-1.f,1.f };
2182 vkCmdSetScissor(compositeCommandBuffer_, 0, 1, &scissor);
2184 VkDescriptorSet descriptors[] = { CompositingAttachmentDescriptorSet_ };
2186 vkCmdBindDescriptorSets(compositeCommandBuffer_,
2187 VK_PIPELINE_BIND_POINT_GRAPHICS,
2188 compositingPipeline_->GetPipelineLayout(),
2193 VkDeviceSize offsets[] = { 0 };
2195 vkCmdBindVertexBuffers(compositeCommandBuffer_, 0, 1, &vertexBuffer_, offsets);
2197 vkCmdDraw(compositeCommandBuffer_, 6, 1, 0, 0);
2199 EndSecondaryCommandBufferRecording(compositeCommandBuffer_);
2201 StartSecondaryCommandBufferRecording(gBufferRenderCommandBuffer_,
2202 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
2203 renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS), VK_NULL_HANDLE);
2205 vkCmdBindPipeline(gBufferRenderCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, gBufferRenderPipeline_->GetPipeline());
2207 vkCmdSetScissor(gBufferRenderCommandBuffer_, 0, 1, &scissor);
2209 descriptors[0] = gBufferAttachmentDescriptorSet_;
2211 vkCmdBindDescriptorSets(gBufferRenderCommandBuffer_,
2212 VK_PIPELINE_BIND_POINT_GRAPHICS,
2213 gBufferRenderPipeline_->GetPipelineLayout(),
2218 VkDescriptorSet sceneDescriptorSet = GetLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1);
2219 if (sceneDescriptorSet == VK_NULL_HANDLE) {
2220 sceneDescriptorSet = CreateLightDescriptorSet(0, gBufferRenderPipeline_->GetPipelineId(), 1, gBufferRenderPipeline_->GetDescriptorSetLayout(1));
2223 uint32_t dynamicOffset[] = { 0 };
2225 vkCmdBindDescriptorSets(gBufferRenderCommandBuffer_,
2226 VK_PIPELINE_BIND_POINT_GRAPHICS,
2227 gBufferRenderPipeline_->GetPipelineLayout(),
2229 &sceneDescriptorSet,
2232 vkCmdBindVertexBuffers(gBufferRenderCommandBuffer_, 0, 1, &vertexBuffer_, offsets);
2234 vkCmdDraw(gBufferRenderCommandBuffer_, 6, 1, 0, 0);
2236 EndSecondaryCommandBufferRecording(gBufferRenderCommandBuffer_);
2240 void VulkanRenderer::CreateDescriptorPool()
2242 if (vulkanDescriptorPools_.size() == 0)
2243 vulkanDescriptorPools_.resize(1);
2244 vulkanDescriptorPools_[0] = eastl::shared_ptr<VulkanDescriptorPool>(
new VulkanDescriptorPool(vulkanLogicalDevice_.get()));
2246 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLER, 1000);
2247 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000);
2248 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000);
2249 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000);
2250 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000);
2251 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000);
2252 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2000);
2253 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000);
2254 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000);
2255 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000);
2256 vulkanDescriptorPools_[0]->AddPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000);
2258 vulkanDescriptorPools_[0]->Compile(11 * 1000);
2261 void VulkanRenderer::InitImGui()
2263 vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
2265 ImGui_ImplGlfwVulkan_Init_Data initData = {};
2266 initData.allocator =
nullptr;
2267 initData.gpu = vulkanPhysicalDevice_->GetPhysicalDevice();
2268 initData.device = vulkanLogicalDevice_->GetDevice();
2269 initData.graphics_queue = vulkanLogicalDevice_->GetGraphicsQueue();
2270 initData.descriptor_pool = vulkanDescriptorPools_[0]->GetPool();
2271 initData.pipeline_cache = VK_NULL_HANDLE;
2272 initData.check_vk_result = check_vk_result;
2273 initData.render_pass = renderPass;
2274 initData.sub_pass =
static_cast<int>(RenderSubPasses::IMGUI_PASS);
2275 ImGui_ImplGlfwVulkan_Init(window.lock()->GetGLFWWindow().lock().get(), &initData);
2277 VkCommandBuffer commandBuffer;
2279 VkCommandBufferAllocateInfo allocInfo = {};
2280 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2281 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2282 allocInfo.commandPool = graphicsCommandPool;
2283 allocInfo.commandBufferCount = 1;
2285 vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, &commandBuffer);
2287 VkCommandBufferBeginInfo beginInfo = {};
2288 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2289 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2291 vkBeginCommandBuffer(commandBuffer, &beginInfo);
2293 ImGui_ImplGlfwVulkan_CreateFontsTexture(commandBuffer);
2295 vkEndCommandBuffer(commandBuffer);
2297 VkSubmitInfo submitInfo = {};
2298 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2299 submitInfo.commandBufferCount = 1;
2300 submitInfo.pCommandBuffers = &commandBuffer;
2302 vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
2304 vkDeviceWaitIdle(vulkanLogicalDevice_->GetDevice());
2306 ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects();
2310 void VulkanRenderer::CreateSemaphores()
2312 imageAvailableSemaphores_.resize(framebuffers.size());
2313 renderFinishedSemaphores_.resize(framebuffers.size());
2314 computeFinishedSemaphores_.resize(framebuffers.size());
2316 drawingFinishedFences_.resize(framebuffers.size());
2317 computeFinishedFences_.resize(framebuffers.size());
2319 VkSemaphoreCreateInfo semaphoreInfo = {};
2320 semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2321 for (
size_t i = 0, size = framebuffers.size(); i < size; ++i) {
2322 VkResult res = vkCreateSemaphore(vulkanLogicalDevice_->GetDevice(), &semaphoreInfo,
nullptr, &imageAvailableSemaphores_[i]);
2323 if (res != VK_SUCCESS) {
2324 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Semaphore 'image available' creation failed";
2325 debug_error(
"VulkanRenderer",
"CreateSemaphores", s);
2327 res = vkCreateSemaphore(vulkanLogicalDevice_->GetDevice(), &semaphoreInfo,
nullptr, &renderFinishedSemaphores_[i]);
2328 if (res != VK_SUCCESS) {
2329 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Semaphore 'render finished' creation failed";
2330 debug_error(
"VulkanRenderer",
"CreateSemaphores", s);
2332 res = vkCreateSemaphore(vulkanLogicalDevice_->GetDevice(), &semaphoreInfo,
nullptr, &computeFinishedSemaphores_[i]);
2333 if (res != VK_SUCCESS) {
2334 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Semaphore 'compute finished' creation failed";
2335 debug_error(
"VulkanRenderer",
"CreateSemaphores", s);
2338 VkFenceCreateInfo fenceInfo = {};
2339 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2340 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2342 res = vkCreateFence(vulkanLogicalDevice_->GetDevice(), &fenceInfo,
nullptr, &drawingFinishedFences_[i]);
2343 if (res != VK_SUCCESS) {
2344 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Fence 'drawing finished' creation failed";
2345 debug_error(
"VulkanRenderer",
"CreateSemaphores", s);
2348 res = vkCreateFence(vulkanLogicalDevice_->GetDevice(), &fenceInfo,
nullptr, &computeFinishedFences_[i]);
2349 if (res != VK_SUCCESS) {
2350 eastl::string s = eastl::string(
"[ERROR] [CODE:") + std::to_string(res).c_str() +
"] Fence 'compute finished' creation failed";
2351 debug_error(
"VulkanRenderer",
"CreateSemaphores", s);
2358 void VulkanRenderer::CreateCompositingPipeline()
2360 compositingPipeline_ = eastl::unique_ptr<VulkanPipeline>(
new VulkanPipeline(vulkanLogicalDevice_.get(),
this));
2362 compositingPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER,
"Composite.vert.spv");
2363 compositingPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER,
"Composite.frag.spv");
2365 compositingPipeline_->CreateDescriptorSet();
2366 compositingPipeline_->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2367 compositingPipeline_->AddDescriptorSetBinding(0, 1, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2369 compositingPipeline_->AddVertexInputBindingDescription(0,
sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
2370 compositingPipeline_->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
2372 compositingPipeline_->SetRasterizerSettings(0, 0, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_NONE);
2374 compositingPipeline_->SetRenderPassInfo(renderPass, static_cast<int>(RenderSubPasses::COMPOSITE_PASS));
2376 compositingPipeline_->CreateColorBlendAttachment();
2378 compositingPipeline_->Compile();
2380 VkDescriptorSetLayout layouts[] = { compositingPipeline_->GetDescriptorSetLayout(0) };
2381 vulkanDescriptorPools_[0]->AllocateDescriptorSet(1, layouts, &CompositingAttachmentDescriptorSet_);
2383 vulkanDescriptorPools_[0]->DescriptorSetBindToImage(CompositingAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, renderImageView, VK_NULL_HANDLE, 0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2384 vulkanDescriptorPools_[0]->DescriptorSetBindToImage(CompositingAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imguiImageView, VK_NULL_HANDLE, 1, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2386 VkBufferCreateInfo vertexBufferInfo = {};
2387 vertexBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2388 vertexBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2389 vertexBufferInfo.size =
sizeof(glm::vec4) * 6;
2390 vertexBufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2392 VmaAllocationCreateInfo vertexBufferAllocInfo = {};
2393 vertexBufferAllocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
2395 vmaCreateBuffer(vmaAllocator_, &vertexBufferInfo, &vertexBufferAllocInfo, &vertexBuffer_, &vertexBufferAllocation_,
nullptr);
2397 VkBufferCreateInfo stagingBufferInfo = {};
2398 stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2399 stagingBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2400 stagingBufferInfo.size =
sizeof(glm::vec4) * 6;
2401 stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
2403 VmaAllocationCreateInfo stagingBufferAllocInfo = {};
2404 stagingBufferAllocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
2406 VkBuffer stagingBuffer;
2407 VmaAllocation stagingBufferAllocation;
2408 VmaAllocationInfo stagingBufferAllocationInfo;
2410 vmaCreateBuffer(vmaAllocator_, &stagingBufferInfo, &stagingBufferAllocInfo, &stagingBuffer, &stagingBufferAllocation, &stagingBufferAllocationInfo);
2414 vkMapMemory(vulkanLogicalDevice_->GetDevice(), stagingBufferAllocationInfo.deviceMemory, stagingBufferAllocationInfo.offset, stagingBufferAllocationInfo.size, 0, &location);
2416 eastl::vector<glm::vec4> coords = {
2417 { -1.f,1.f, 0.f, 0.f },
2418 { 1.f,1.f, 1.f, 0.f },
2419 { -1.f,-1.f, 0.f, 1.f },
2420 { -1.f,-1.f, 0.f, 1.f },
2421 { 1.f,1.f, 1.f, 0.f },
2422 { 1.f,-1.f, 1.f, 1.f }
2425 memcpy(location, coords.data(),
sizeof(glm::vec4) * 6);
2427 vkUnmapMemory(vulkanLogicalDevice_->GetDevice(), stagingBufferAllocationInfo.deviceMemory);
2429 VkCommandBufferAllocateInfo cmdAllocInfo = {};
2430 cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2431 cmdAllocInfo.commandPool = graphicsCommandPool;
2432 cmdAllocInfo.commandBufferCount = 1;
2433 cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2435 VkCommandBuffer cmdBuffer;
2437 vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &cmdAllocInfo, &cmdBuffer);
2439 VkCommandBufferBeginInfo cmdBeginInfo = {};
2440 cmdBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2441 cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2443 vkBeginCommandBuffer(cmdBuffer, &cmdBeginInfo);
2445 VkBufferCopy copyRegion = {};
2446 copyRegion.srcOffset = 0;
2447 copyRegion.dstOffset = 0;
2448 copyRegion.size =
sizeof(glm::vec4) * 6;
2449 vkCmdCopyBuffer(cmdBuffer, stagingBuffer, vertexBuffer_, 1, ©Region);
2451 vkEndCommandBuffer(cmdBuffer);
2453 VkSubmitInfo submitInfo = {};
2454 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2455 submitInfo.commandBufferCount = 1;
2456 submitInfo.pCommandBuffers = &cmdBuffer;
2458 vkQueueSubmit(vulkanLogicalDevice_->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
2459 vkQueueWaitIdle(vulkanLogicalDevice_->GetGraphicsQueue());
2461 vmaDestroyBuffer(vmaAllocator_, stagingBuffer, stagingBufferAllocation);
2465 void VulkanRenderer::CreateGBufferRenderPipeline()
2467 gBufferRenderPipeline_ = eastl::unique_ptr<VulkanPipeline>(
new VulkanPipeline(vulkanLogicalDevice_.get(),
this));
2469 gBufferRenderPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER,
"G-BufferRender.vert.spv");
2470 gBufferRenderPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER,
"G-BufferRender.frag.spv");
2472 gBufferRenderPipeline_->CreateDescriptorSet();
2473 gBufferRenderPipeline_->AddDescriptorSetLayout(CreateLightDescriptorSetLayout());
2475 gBufferRenderPipeline_->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2476 gBufferRenderPipeline_->AddDescriptorSetBinding(0, 1, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2477 gBufferRenderPipeline_->AddDescriptorSetBinding(0, 2, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2479 gBufferRenderPipeline_->AddVertexInputBindingDescription(0,
sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
2480 gBufferRenderPipeline_->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
2482 gBufferRenderPipeline_->SetRasterizerSettings(0, 0, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_NONE);
2484 gBufferRenderPipeline_->SetRenderPassInfo(renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS));
2486 gBufferRenderPipeline_->CreateColorBlendAttachment(VK_TRUE, 15U,
2487 VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD);
2489 VkStencilOpState front = {};
2490 front.failOp = VK_STENCIL_OP_KEEP;
2491 front.passOp = VK_STENCIL_OP_KEEP;
2492 front.depthFailOp = VK_STENCIL_OP_KEEP;
2493 front.compareOp = VK_COMPARE_OP_EQUAL;
2494 front.reference = 0;
2495 front.compareMask = 0xff;
2496 front.writeMask = 0xff;
2498 VkStencilOpState back = {};
2499 back.failOp = VK_STENCIL_OP_KEEP;
2500 back.passOp = VK_STENCIL_OP_KEEP;
2501 back.depthFailOp = VK_STENCIL_OP_KEEP;
2502 back.compareOp = VK_COMPARE_OP_EQUAL;
2504 back.compareMask = 0xff;
2505 back.writeMask = 0xff;
2507 gBufferRenderPipeline_->SetDepthStencilState(VK_TRUE, VK_FALSE, VK_COMPARE_OP_LESS, 0U, 0U, 1.f, VK_TRUE, front, back);
2509 gBufferRenderPipeline_->Compile();
2511 VkDescriptorSetLayout layouts[] = { gBufferRenderPipeline_->GetDescriptorSetLayout(0) };
2512 vulkanDescriptorPools_[0]->AllocateDescriptorSet(1, layouts, &gBufferAttachmentDescriptorSet_);
2514 vulkanDescriptorPools_[0]->DescriptorSetBindToImage(gBufferAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, albedoImageView, VK_NULL_HANDLE,
2515 0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2516 vulkanDescriptorPools_[0]->DescriptorSetBindToImage(gBufferAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, positionImageView, VK_NULL_HANDLE,
2517 1, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2518 vulkanDescriptorPools_[0]->DescriptorSetBindToImage(gBufferAttachmentDescriptorSet_, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, normalImageView, VK_NULL_HANDLE,
2519 2, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1);
2521 sceneDataBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(
2522 vulkanLogicalDevice_.get(), vmaAllocator_,
static_cast<uint32_t
>(
sizeof(SceneInfo)),
2523 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
false, graphicsCommandPool));
2525 lightBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(
2526 vulkanLogicalDevice_.get(), vmaAllocator_,
static_cast<uint32_t
>(
sizeof(
Light)*lightData.size()),
2527 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
false, graphicsCommandPool));
2529 ambientLightPipeline_ = eastl::unique_ptr<VulkanPipeline>(
new VulkanPipeline(vulkanLogicalDevice_.get(),
this));
2531 ambientLightPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER,
"G-BufferRender.vert.spv");
2532 ambientLightPipeline_->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER,
"G-BufferRender.frag.spv");
2534 ambientLightPipeline_->CreateDescriptorSet();
2535 ambientLightPipeline_->AddDescriptorSetLayout(CreateLightDescriptorSetLayout());
2537 ambientLightPipeline_->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2538 ambientLightPipeline_->AddDescriptorSetBinding(0, 1, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2539 ambientLightPipeline_->AddDescriptorSetBinding(0, 2, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
2541 ambientLightPipeline_->AddVertexInputBindingDescription(0,
sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
2542 ambientLightPipeline_->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
2544 ambientLightPipeline_->SetRasterizerSettings(0, 0, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_NONE);
2546 ambientLightPipeline_->SetRenderPassInfo(renderPass, static_cast<int>(RenderSubPasses::RENDER_PASS));
2548 ambientLightPipeline_->CreateColorBlendAttachment(VK_TRUE, 15U,
2549 VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD);
2551 ambientLightPipeline_->SetDepthStencilState(VK_TRUE, VK_FALSE, VK_COMPARE_OP_LESS, 0U, 0U, 1.f, VK_FALSE, front, back);
2553 ambientLightPipeline_->Compile();
2556 void VulkanRenderer::CreateRenderers()
2558 vulkanSpriteRenderer = eastl::unique_ptr<VulkanSpriteRenderer>(
new VulkanSpriteRenderer(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2559 vulkanDebugRenderer = eastl::unique_ptr<VulkanDebugRenderer>(
new VulkanDebugRenderer(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2560 vulkanStaticMeshRenderer = eastl::unique_ptr<VulkanStaticMeshRenderer>(
new VulkanStaticMeshRenderer(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2561 vulkanSkeletalMeshRenderer = eastl::unique_ptr<VulkanSkeletalMeshRenderer>(
new VulkanSkeletalMeshRenderer(
this, vulkanLogicalDevice_.get(), vulkanDescriptorPools_[0].get()));
2564 void VulkanRenderer::AllocateThreads()
2566 int threadCount = std::thread::hardware_concurrency() - 1;
2567 threads.resize(threadCount);
2568 vulkanDescriptorPools_.resize(threadCount + 1);
2570 for (
size_t i = 0, size = threads.size(); i < size; ++i) {
2571 threads[i] =
new ThreadInfo;
2573 VkCommandPoolCreateInfo info = {};
2574 info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2575 info.queueFamilyIndex = vulkanPhysicalDevice_->GetQueueFamilies().graphics;
2577 vkCreateCommandPool(vulkanLogicalDevice_->GetDevice(), &info,
nullptr, &(threads[i]->commandPool));
2579 vulkanDescriptorPools_[i + 1] = eastl::shared_ptr<VulkanDescriptorPool>(
new VulkanDescriptorPool(vulkanLogicalDevice_.get()));
2581 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLER, 1000);
2582 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000);
2583 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000);
2584 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000);
2585 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000);
2586 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000);
2587 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2000);
2588 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000);
2589 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000);
2590 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000);
2591 vulkanDescriptorPools_[i + 1]->AddPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000);
2593 vulkanDescriptorPools_[i + 1]->Compile(11 * 1000);
2595 threads[i]->threadId = i + 1;
2599 void VulkanRenderer::DestroyInstance()
2601 vkDestroySurfaceKHR(vulkanInstance_->GetInstance(), surface,
nullptr);
2602 vulkanInstance_.reset();
2605 void VulkanRenderer::DestroyLogicalDevice()
2607 vulkanLogicalDevice_.reset();
2610 void VulkanRenderer::DestroySwapChain()
2612 vkDestroySwapchainKHR(vulkanLogicalDevice_->GetDevice(), swapChain,
nullptr);
2615 void VulkanRenderer::DestroySwapChainImageViews()
2617 for (
int i = 0; i < static_cast<int>(swapChainImageViews.size()); ++i) {
2618 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), swapChainImageViews[i],
nullptr);
2622 void VulkanRenderer::DestroyGraphicsCommandPool()
2624 vkDestroyCommandPool(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool,
nullptr);
2627 void VulkanRenderer::DestroyComputeCommandPool()
2629 vkDestroyCommandPool(vulkanLogicalDevice_->GetDevice(), computeCommandPool,
nullptr);
2632 void VulkanRenderer::DestroyVmaAllocator()
2634 vmaDestroyAllocator(vmaAllocator_);
2637 void VulkanRenderer::DestroyDepthImage()
2639 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), depthImageView,
nullptr);
2641 vmaDestroyImage(vmaAllocator_, depthImage, depthImageAllocation);
2644 void VulkanRenderer::DestroyAttachmentImages()
2646 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), imguiImageView,
nullptr);
2648 vmaDestroyImage(vmaAllocator_, imguiImage, imguiImageAllocation);
2650 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), renderImageView,
nullptr);
2652 vmaDestroyImage(vmaAllocator_, renderImage, renderImageAllocation);
2654 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), albedoImageView,
nullptr);
2656 vmaDestroyImage(vmaAllocator_, albedoImage, albedoImageAllocation);
2658 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), positionImageView,
nullptr);
2660 vmaDestroyImage(vmaAllocator_, positionImage, positionImageAllocation);
2662 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), normalImageView,
nullptr);
2664 vmaDestroyImage(vmaAllocator_, normalImage, normalImageAllocation);
2666 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), ssaoImageView,
nullptr);
2668 vmaDestroyImage(vmaAllocator_, ssaoImage, ssaoImageAllocation);
2670 vkDestroyImageView(vulkanLogicalDevice_->GetDevice(), ssaoBlurImageView,
nullptr);
2672 vmaDestroyImage(vmaAllocator_, ssaoBlurImage, ssaoBlurImageAllocation);
2676 void VulkanRenderer::DestroyRenderPass()
2678 vkDestroyRenderPass(vulkanLogicalDevice_->GetDevice(), gBufferPass,
nullptr);
2679 vkDestroyRenderPass(vulkanLogicalDevice_->GetDevice(), ssaoPass,
nullptr);
2680 vkDestroyRenderPass(vulkanLogicalDevice_->GetDevice(), renderPass,
nullptr);
2683 void VulkanRenderer::DestroyFramebuffers()
2685 for (
int i = 0; i < framebuffers.size(); ++i) {
2686 vkDestroyFramebuffer(vulkanLogicalDevice_->GetDevice(), framebuffers[i],
nullptr);
2688 vkDestroyFramebuffer(vulkanLogicalDevice_->GetDevice(), gBufferFrameBuffer,
nullptr);
2689 vkDestroyFramebuffer(vulkanLogicalDevice_->GetDevice(), ssaoFrameBuffer,
nullptr);
2693 void VulkanRenderer::DestroyDecriptorPool()
2695 for (
size_t i = 0, size = vulkanDescriptorPools_.size(); i < size; ++i) {
2696 vulkanDescriptorPools_[i].reset();
2700 void VulkanRenderer::DestroyImGui()
const 2702 ImGui_ImplGlfwVulkan_Shutdown();
2705 void VulkanRenderer::DestroySemaphores()
2707 for (
size_t i = 0, size = imageAvailableSemaphores_.size(); i < size; ++i) {
2708 vkDestroySemaphore(vulkanLogicalDevice_->GetDevice(), imageAvailableSemaphores_[i],
nullptr);
2709 vkDestroySemaphore(vulkanLogicalDevice_->GetDevice(), renderFinishedSemaphores_[i],
nullptr);
2710 vkDestroySemaphore(vulkanLogicalDevice_->GetDevice(), computeFinishedSemaphores_[i],
nullptr);
2712 vkDestroyFence(vulkanLogicalDevice_->GetDevice(), drawingFinishedFences_[i],
nullptr);
2713 vkDestroyFence(vulkanLogicalDevice_->GetDevice(), computeFinishedFences_[i],
nullptr);
2718 void VulkanRenderer::DestroyCompositingPipeline()
2720 compositingPipeline_.reset();
2721 vmaDestroyBuffer(vmaAllocator_, vertexBuffer_, vertexBufferAllocation_);
2724 void VulkanRenderer::DestroyGBufferRenderPipeline()
2726 gBufferRenderPipeline_.reset();
2727 ambientLightPipeline_.reset();
2729 sceneDataBuffer.reset();
2730 lightBuffer.reset();
2733 void VulkanRenderer::DestroyRenderers()
2735 vulkanSpriteRenderer.reset();
2736 vulkanDebugRenderer.reset();
2737 vulkanStaticMeshRenderer.reset();
2738 vulkanSkeletalMeshRenderer.reset();
2741 void VulkanRenderer::DestroyThreads()
2743 for (
size_t i = 0, size = threads.size(); i < size; ++i) {
2744 if (threads[i]->thread.joinable())
2745 threads[i]->thread.join();
2746 vkDestroyCommandPool(vulkanLogicalDevice_->GetDevice(), threads[i]->commandPool,
nullptr);
2751 VkFormat VulkanRenderer::FindSupportedDepthFormat(
const eastl::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
2753 if (!vulkanPhysicalDevice_)
2754 return VK_FORMAT_UNDEFINED;
2755 for (VkFormat format : candidates) {
2756 VkFormatProperties props;
2757 vkGetPhysicalDeviceFormatProperties(vulkanPhysicalDevice_->GetPhysicalDevice(), format, &props);
2758 if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures&features) == features) {
2761 else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures&features) == features) {
2765 return VK_FORMAT_UNDEFINED;
2768 void VulkanRenderer::GenerateSecondaryCommandBuffers(VkCommandBuffer * buffers, uint32_t count)
2770 VkCommandBufferAllocateInfo allocInfo = {};
2771 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2772 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
2773 allocInfo.commandPool = graphicsCommandPool;
2774 allocInfo.commandBufferCount = count;
2776 vkAllocateCommandBuffers(vulkanLogicalDevice_->GetDevice(), &allocInfo, buffers);
2779 void VulkanRenderer::DestroySecondaryCommandBuffers(VkCommandBuffer * buffers, uint32_t count)
2781 vkFreeCommandBuffers(vulkanLogicalDevice_->GetDevice(), graphicsCommandPool, count, buffers);
2784 void VulkanRenderer::RestructureLights()
2786 eastl::array<Light, 1024> tempData = lightData;
2788 eastl::map<eastl::string, LightInfo>::iterator it = lights.begin();
2789 eastl::map<eastl::string, LightInfo>::iterator end = lights.end();
2790 for (
size_t location = 0; it != end; ++it) {
2791 if (it->second.active) {
2792 lightData[location] = it->second.light;
2793 it->second.lightDataIndex = location;
2795 activeLights =
static_cast<int>(location);
2799 lightDataRestructured =
false;
2800 lightDataChanged =
true;
2803 void VulkanRenderer::UpdateLightData()
2805 lightBuffer->UpdateBuffer(lightData.data(), 0,
static_cast<uint32_t
>(
sizeof(
Light)*lightData.size()));
2807 if (activeLights != scene.lightCount) {
2808 scene.lightCount = activeLights;
2811 lightDataChanged =
false;
2814 VulkanRenderer::ThreadInfo * VulkanRenderer::GetFreeThread()
2816 for (
size_t i = 0, size = threads.size(); i < size; ++i) {
2817 if (threads[i]->initialized ==
false)
2820 auto status = threads[i]->future.wait_for(std::chrono::milliseconds(0));
2822 if (status == std::future_status::ready) {
2823 if (threads[i]->thread.joinable())
2824 threads[i]->thread.join();
2825 threads[i]->initialized =
false;
2832 void VulkanRenderer::JoinAllThreads()
2834 for (
size_t i = 0, size = threads.size(); i < size; ++i) {
2835 if (threads[i]->thread.joinable())
2836 threads[i]->thread.join();
2840 void VulkanRenderer::ResetCommandPools()
2842 for (
size_t i = 0, size = threads.size(); i < size; ++i) {
2843 vkResetCommandPool(vulkanLogicalDevice_->GetDevice(), threads[i]->commandPool, 0);
2847 void VulkanRenderer::StartSecondaryCommandBufferRecording(VkCommandBuffer buffer, VkCommandBufferUsageFlags flags, VkRenderPass renderPass, uint32_t subPass, VkFramebuffer framebuffer)
const 2849 VkCommandBufferInheritanceInfo inheritence = {};
2850 inheritence.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
2851 inheritence.occlusionQueryEnable = VK_FALSE;
2852 inheritence.renderPass = renderPass;
2853 inheritence.subpass = subPass;
2854 inheritence.framebuffer = framebuffer;
2856 VkCommandBufferBeginInfo info = {};
2857 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2859 info.pInheritanceInfo = &inheritence;
2861 vkBeginCommandBuffer(buffer, &info);
2864 void VulkanRenderer::EndSecondaryCommandBufferRecording(VkCommandBuffer buffer)
const 2866 vkEndCommandBuffer(buffer);
#define debug_error(debug_class, function, value)
This functions logs a debug error to the log and console. This does not halt the program! ...
enum ENGINE_API LightType
Enum containing the different types of lights that can be created.