diff --git a/KaguEngine/extern/glfw b/KaguEngine/extern/glfw index e7ea71b..506c11b 160000 --- a/KaguEngine/extern/glfw +++ b/KaguEngine/extern/glfw @@ -1 +1 @@ -Subproject commit e7ea71be039836da3a98cea55ae5569cb5eb885c +Subproject commit 506c11ba43b901dbcc4d90449f46de67cf000af4 diff --git a/KaguEngine/src/App.cpp b/KaguEngine/src/App.cpp index ac33265..ee59afa 100644 --- a/KaguEngine/src/App.cpp +++ b/KaguEngine/src/App.cpp @@ -51,13 +51,15 @@ void App::run() { RenderSystem renderSystem{ m_Device, - m_Renderer.getSwapChainRenderPass(), + m_Renderer.getOffscreenFormat(), + m_Renderer.getOffscreenDepthFormat(), m_GlobalSetLayout->getDescriptorSetLayout(), // set = 0 (UBO) m_MaterialSetLayout->getDescriptorSetLayout() // set = 1 (textures) }; PointLightSystem pointLightSystem{ m_Device, - m_Renderer.getSwapChainRenderPass(), + m_Renderer.getOffscreenFormat(), + m_Renderer.getOffscreenDepthFormat(), m_GlobalSetLayout->getDescriptorSetLayout() }; Camera camera{}; @@ -118,7 +120,7 @@ void App::run() { m_Renderer.endOffscreenRenderPass(commandBuffer); // ImGui rendering - m_Renderer.transitionOffscreenImageForImGui(); + m_Renderer.transitionOffscreenImageForImGui(commandBuffer); imGuiContext.render(m_Renderer); // Present the image @@ -200,6 +202,7 @@ void App::loadGameObjects() { for (int i = 0; i < lightColors.size(); i++) { auto pointLight = Entity::makePointLight(0.2f); pointLight.color = lightColors[i]; + pointLight.name = "Point Light " + std::to_string(i + 1); auto rotateLight = glm::rotate( glm::mat4(1.f), static_cast(i) * glm::two_pi() / static_cast(lightColors.size()), diff --git a/KaguEngine/src/Device.cpp b/KaguEngine/src/Device.cpp index 0373585..420ca8d 100644 --- a/KaguEngine/src/Device.cpp +++ b/KaguEngine/src/Device.cpp @@ -77,7 +77,7 @@ void Device::createInstance() { appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1); appInfo.pEngineName = "Kagu Engine"; appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); - appInfo.apiVersion = VK_API_VERSION_1_0; + appInfo.apiVersion = VK_API_VERSION_1_3; VkInstanceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; @@ -139,9 +139,14 @@ void Device::pickPhysicalDevice() { int Device::rateDeviceSuitability(const VkPhysicalDevice device) const { VkPhysicalDeviceProperties supportedProperties; - VkPhysicalDeviceFeatures supportedFeatures; vkGetPhysicalDeviceProperties(device, &supportedProperties); - vkGetPhysicalDeviceFeatures(device, &supportedFeatures); + + VkPhysicalDeviceVulkan13Features features13{}; + features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + VkPhysicalDeviceFeatures2 features2{}; + features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + features2.pNext = &features13; + vkGetPhysicalDeviceFeatures2(device, &features2); const QueueFamilyIndices indices = findQueueFamilies(device); @@ -161,7 +166,7 @@ int Device::rateDeviceSuitability(const VkPhysicalDevice device) const { // Check for needed features, the engine can't work without them. if (!(indices.isComplete() && extensionsSupported && swapChainAdequate && - supportedFeatures.geometryShader && supportedFeatures.samplerAnisotropy)) { + features2.features.samplerAnisotropy && features13.dynamicRendering)) { return 0; } @@ -184,16 +189,23 @@ void Device::createLogicalDevice() { queueCreateInfos.push_back(queueCreateInfo); } - VkPhysicalDeviceFeatures deviceFeatures = {}; - deviceFeatures.samplerAnisotropy = VK_TRUE; + VkPhysicalDeviceVulkan13Features deviceFeatures13{}; + deviceFeatures13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + deviceFeatures13.dynamicRendering = VK_TRUE; + + VkPhysicalDeviceFeatures2 deviceFeatures2{}; + deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + deviceFeatures2.pNext = &deviceFeatures13; + deviceFeatures2.features.samplerAnisotropy = VK_TRUE; VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + createInfo.pNext = &deviceFeatures2; createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); createInfo.pQueueCreateInfos = queueCreateInfos.data(); - createInfo.pEnabledFeatures = &deviceFeatures; + createInfo.pEnabledFeatures = nullptr; // This must be null if pNext is used createInfo.enabledExtensionCount = static_cast(m_DeviceExtensions.size()); createInfo.ppEnabledExtensionNames = m_DeviceExtensions.data(); diff --git a/KaguEngine/src/ImGuiContext.cpp b/KaguEngine/src/ImGuiContext.cpp index c7daa77..011443b 100644 --- a/KaguEngine/src/ImGuiContext.cpp +++ b/KaguEngine/src/ImGuiContext.cpp @@ -154,7 +154,6 @@ void ImGuiContext::setupContext() const { init_info.Device = deviceRef.device(); init_info.QueueFamily = indices.graphicsFamily; init_info.Queue = deviceRef.graphicsQueue(); - init_info.RenderPass = swapChainRef.getRenderPass(); init_info.PipelineCache = VK_NULL_HANDLE; init_info.DescriptorPool = poolRef->getDescriptorPool(); init_info.Allocator = nullptr; @@ -162,6 +161,7 @@ void ImGuiContext::setupContext() const { init_info.MinImageCount = SwapChain::MAX_FRAMES_IN_FLIGHT; init_info.MSAASamples = deviceRef.getSampleCount(); init_info.ImageCount = SwapChain::MAX_FRAMES_IN_FLIGHT; + init_info.UseDynamicRendering = true; ImGui_ImplVulkan_Init(&init_info); ImGui_ImplVulkan_CreateFontsTexture(); } @@ -366,7 +366,8 @@ void ImGuiContext::renderSceneHierarchyPanel() { if (ImGui::TreeNodeEx("Scene", ImGuiTreeNodeFlags_DefaultOpen)) { for (auto& [id, entity] : entitiesRef) { - std::string name = entity.pointLight != nullptr ? std::string(ICON_FA_LIGHTBULB_O) + " Point Light " + std::to_string(id) : std::string(ICON_FA_CUBE) + " " + entity.name; + std::string name = entity.pointLight != nullptr ? std::string(ICON_FA_LIGHTBULB_O) + " " : std::string(ICON_FA_CUBE) + " "; + name += entity.name; bool is_selected = (m_SelectedEntityID == id); if (ImGui::Selectable(name.c_str(), is_selected)) { diff --git a/KaguEngine/src/Pipeline.cpp b/KaguEngine/src/Pipeline.cpp index 191a66c..7df66d9 100644 --- a/KaguEngine/src/Pipeline.cpp +++ b/KaguEngine/src/Pipeline.cpp @@ -49,8 +49,6 @@ void Pipeline::createGraphicsPipeline(const std::string &vertFilepath, const std const PipelineConfigInfo &configInfo) { assert(configInfo.pipelineLayout != VK_NULL_HANDLE && "Cannot create graphics pipeline: no pipelineLayout provided in configInfo"); - assert(configInfo.renderPass != VK_NULL_HANDLE && - "Cannot create graphics pipeline: no renderPass provided in configInfo"); const auto vertCode = readFile(vertFilepath); const auto fragCode = readFile(fragFilepath); @@ -83,8 +81,16 @@ void Pipeline::createGraphicsPipeline(const std::string &vertFilepath, const std vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data(); vertexInputInfo.pVertexBindingDescriptions = bindingDescriptions.data(); + VkPipelineRenderingCreateInfo renderingCreateInfo{}; + renderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + renderingCreateInfo.colorAttachmentCount = 1; + renderingCreateInfo.pColorAttachmentFormats = &configInfo.colorAttachmentFormat; + renderingCreateInfo.depthAttachmentFormat = configInfo.depthAttachmentFormat; + renderingCreateInfo.stencilAttachmentFormat = configInfo.depthAttachmentFormat; + VkGraphicsPipelineCreateInfo pipelineInfo{}; pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineInfo.pNext = &renderingCreateInfo; pipelineInfo.stageCount = 2; pipelineInfo.pStages = shaderStages; pipelineInfo.pVertexInputState = &vertexInputInfo; @@ -97,8 +103,8 @@ void Pipeline::createGraphicsPipeline(const std::string &vertFilepath, const std pipelineInfo.pDynamicState = &configInfo.dynamicStateInfo; pipelineInfo.layout = configInfo.pipelineLayout; - pipelineInfo.renderPass = configInfo.renderPass; - pipelineInfo.subpass = configInfo.subpass; + pipelineInfo.renderPass = VK_NULL_HANDLE; + pipelineInfo.subpass = 0; pipelineInfo.basePipelineIndex = -1; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; diff --git a/KaguEngine/src/Pipeline.ixx b/KaguEngine/src/Pipeline.ixx index 48a5df6..a4aac25 100644 --- a/KaguEngine/src/Pipeline.ixx +++ b/KaguEngine/src/Pipeline.ixx @@ -29,8 +29,8 @@ struct PipelineConfigInfo { std::vector dynamicStateEnables; VkPipelineDynamicStateCreateInfo dynamicStateInfo; VkPipelineLayout pipelineLayout = nullptr; - VkRenderPass renderPass = nullptr; - uint32_t subpass = 0; + VkFormat colorAttachmentFormat; + VkFormat depthAttachmentFormat; }; class Pipeline { diff --git a/KaguEngine/src/Renderer.cpp b/KaguEngine/src/Renderer.cpp index 71ccbf0..856bc29 100644 --- a/KaguEngine/src/Renderer.cpp +++ b/KaguEngine/src/Renderer.cpp @@ -18,6 +18,40 @@ import KaguEngine.Window; namespace KaguEngine { +namespace { // Anonymous namespace for internal helpers +void cmdTransitionImageLayout( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout oldLayout, + VkImageLayout newLayout, + VkImageSubresourceRange subresourceRange, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask) { + + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange = subresourceRange; + barrier.srcAccessMask = srcAccessMask; + barrier.dstAccessMask = dstAccessMask; + + vkCmdPipelineBarrier( + commandBuffer, + srcStageMask, + dstStageMask, + 0, + 0, nullptr, + 0, nullptr, + 1, &barrier); +} +} + Renderer::Renderer(Window &window, Device &device) : windowRef{window}, deviceRef{device} { m_currentImageIndex = 0; recreateSwapChain(); @@ -119,21 +153,47 @@ void Renderer::beginSwapChainRenderPass(const VkCommandBuffer commandBuffer) con assert(commandBuffer == getCurrentCommandBuffer() && "Can't begin render pass on command buffer from a different frame"); - VkRenderPassBeginInfo renderPassInfo{}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassInfo.renderPass = m_SwapChain->getRenderPass(); - renderPassInfo.framebuffer = m_SwapChain->getFrameBuffer(m_currentImageIndex); + VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + cmdTransitionImageLayout( + commandBuffer, + m_SwapChain->getImage(m_currentImageIndex), + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + subresourceRange, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + + VkRenderingAttachmentInfo colorAttachment{}; + colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + colorAttachment.imageView = m_SwapChain->getMultisampleColorImageView(m_currentImageIndex); + colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; + colorAttachment.resolveImageView = m_SwapChain->getImageView(m_currentImageIndex); + colorAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorAttachment.clearValue.color = {0.1f, 0.1f, 0.15f, 1.0f}; - renderPassInfo.renderArea.offset = {0, 0}; - renderPassInfo.renderArea.extent = m_SwapChain->getSwapChainExtent(); + VkRenderingAttachmentInfo depthAttachment{}; + depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + depthAttachment.imageView = m_SwapChain->getDepthImageView(m_currentImageIndex); + depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depthAttachment.clearValue.depthStencil = {1.0f, 0}; - std::array clearValues{}; - clearValues[0].color = {0.1f, 0.1f, 0.15f, 1.0f}; - clearValues[1].depthStencil = {1.0f, 0}; - renderPassInfo.clearValueCount = static_cast(clearValues.size()); - renderPassInfo.pClearValues = clearValues.data(); + VkRenderingInfo renderingInfo{}; + renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + renderingInfo.renderArea = {{0, 0}, m_SwapChain->getSwapChainExtent()}; + renderingInfo.layerCount = 1; + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &colorAttachment; + renderingInfo.pDepthAttachment = &depthAttachment; + renderingInfo.pStencilAttachment = nullptr; - vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBeginRendering(commandBuffer, &renderingInfo); VkViewport viewport{}; viewport.x = 0.0f; @@ -151,7 +211,20 @@ void Renderer::endSwapChainRenderPass(const VkCommandBuffer commandBuffer) const assert(m_isFrameStarted && "Can't call endSwapChainRenderPass if frame is not in progress"); assert(commandBuffer == getCurrentCommandBuffer() && "Can't end render pass on command buffer from a different frame"); - vkCmdEndRenderPass(commandBuffer); + + vkCmdEndRendering(commandBuffer); + + VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + cmdTransitionImageLayout( + commandBuffer, + m_SwapChain->getImage(m_currentImageIndex), + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + subresourceRange, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + 0); } void Renderer::createOffscreenResources() { @@ -221,6 +294,7 @@ void Renderer::createOffscreenResources() { } // Create depth image + m_offscreenDepthFormat = m_SwapChain->findDepthFormat(); VkImageCreateInfo imageInfo{}; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.imageType = VK_IMAGE_TYPE_2D; @@ -229,7 +303,7 @@ void Renderer::createOffscreenResources() { imageInfo.extent.depth = 1; imageInfo.mipLevels = 1; imageInfo.arrayLayers = 1; - imageInfo.format = m_SwapChain->findDepthFormat(); + imageInfo.format = m_offscreenDepthFormat; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -243,7 +317,7 @@ void Renderer::createOffscreenResources() { viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.image = m_offscreenDepthImage; viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = m_SwapChain->findDepthFormat(); + viewInfo.format = m_offscreenDepthFormat; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; viewInfo.subresourceRange.baseMipLevel = 0; viewInfo.subresourceRange.levelCount = 1; @@ -254,12 +328,19 @@ void Renderer::createOffscreenResources() { throw std::runtime_error("failed to create texture image view!"); } - transitionImageLayout(m_offscreenImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - transitionImageLayout(m_offscreenResolveImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - m_offscreenCurrentLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + // Initial layout transition + auto cmd = deviceRef.beginSingleTimeCommands(); + VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + cmdTransitionImageLayout( + cmd, + m_offscreenResolveImage, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, VK_ACCESS_SHADER_READ_BIT); + deviceRef.endSingleTimeCommands(cmd); - createOffscreenRenderPass(); - createOffscreenFramebuffer(); + m_offscreenCurrentLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; createOffscreenDescriptorSet(); } @@ -279,14 +360,6 @@ void Renderer::cleanupOffscreenResources() { vkDestroyDescriptorSetLayout(device, m_offscreenDescriptorSetLayout, nullptr); m_offscreenDescriptorSetLayout = VK_NULL_HANDLE; } - if (m_offscreenFramebuffer) { - vkDestroyFramebuffer(device, m_offscreenFramebuffer, nullptr); - m_offscreenFramebuffer = VK_NULL_HANDLE; - } - if (m_offscreenRenderPass) { - vkDestroyRenderPass(device, m_offscreenRenderPass, nullptr); - m_offscreenRenderPass = VK_NULL_HANDLE; - } if (m_offscreenImageView) { vkDestroyImageView(device, m_offscreenImageView, nullptr); m_offscreenImageView = VK_NULL_HANDLE; @@ -329,98 +402,6 @@ void Renderer::cleanupOffscreenResources() { } } -void Renderer::createOffscreenRenderPass() { - VkAttachmentDescription colorAttachment{}; - colorAttachment.format = m_offscreenFormat; - colorAttachment.samples = deviceRef.getSampleCount(); - colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkAttachmentDescription depthAttachment{}; - depthAttachment.format = m_SwapChain->findDepthFormat(); - depthAttachment.samples = deviceRef.getSampleCount(); - depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentDescription colorAttachmentResolve = {}; - colorAttachmentResolve.format = m_offscreenFormat; - colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT; - colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkAttachmentReference colorAttachmentRef{}; - colorAttachmentRef.attachment = 0; - colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference depthAttachmentRef{}; - depthAttachmentRef.attachment = 1; - depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference colorAttachmentResolveRef = {}; - colorAttachmentResolveRef.attachment = 2; - colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorAttachmentRef; - subpass.pDepthStencilAttachment = &depthAttachmentRef; - subpass.pResolveAttachments = &colorAttachmentResolveRef; - - // Subpass dependency for layout transitions - VkSubpassDependency dependency{}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.srcAccessMask = 0; - dependency.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - std::array attachments = {colorAttachment, depthAttachment, colorAttachmentResolve}; - - VkRenderPassCreateInfo renderPassInfo{}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo.attachmentCount = static_cast(attachments.size()); - renderPassInfo.pAttachments = attachments.data(); - renderPassInfo.subpassCount = 1; - renderPassInfo.pSubpasses = &subpass; - renderPassInfo.dependencyCount = 1; - renderPassInfo.pDependencies = &dependency; - - if (vkCreateRenderPass(deviceRef.device(), &renderPassInfo, nullptr, &m_offscreenRenderPass) != VK_SUCCESS) { - throw std::runtime_error("failed to create offscreen render pass!"); - } -} - -void Renderer::createOffscreenFramebuffer() { - const std::array attachments = {m_offscreenImageView, m_offscreenDepthView, m_offscreenResolveImageView}; - - VkFramebufferCreateInfo framebufferInfo{}; - framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = m_offscreenRenderPass; - framebufferInfo.attachmentCount = static_cast(attachments.size()); - framebufferInfo.pAttachments = attachments.data(); - framebufferInfo.width = m_offscreenExtent.width; - framebufferInfo.height = m_offscreenExtent.height; - framebufferInfo.layers = 1; - - if (vkCreateFramebuffer(deviceRef.device(), &framebufferInfo, nullptr, &m_offscreenFramebuffer) != VK_SUCCESS) { - throw std::runtime_error("failed to create offscreen framebuffer!"); - } -} - void Renderer::createOffscreenDescriptorSet() { const auto device = deviceRef.device(); @@ -484,26 +465,49 @@ void Renderer::createOffscreenDescriptorSet() { void Renderer::beginOffscreenRenderPass(VkCommandBuffer commandBuffer) { if (m_offscreenCurrentLayout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - transitionImageLayout(m_offscreenImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - transitionImageLayout(m_offscreenResolveImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + cmdTransitionImageLayout( + commandBuffer, + m_offscreenResolveImage, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + subresourceRange, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); m_offscreenCurrentLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } - VkRenderPassBeginInfo renderPassInfo{}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassInfo.renderPass = m_offscreenRenderPass; - renderPassInfo.framebuffer = m_offscreenFramebuffer; - renderPassInfo.renderArea.offset = {0, 0}; - renderPassInfo.renderArea.extent = m_offscreenExtent; + VkRenderingAttachmentInfo colorAttachment{}; + colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + colorAttachment.imageView = m_offscreenImageView; + colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; + colorAttachment.resolveImageView = m_offscreenResolveImageView; + colorAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorAttachment.clearValue.color = {0.1f, 0.1f, 0.15f, 1.0f}; + + VkRenderingAttachmentInfo depthAttachment{}; + depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + depthAttachment.imageView = m_offscreenDepthView; + depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + depthAttachment.clearValue.depthStencil = {1.0f, 0}; - std::array clearValues{}; - clearValues[0].color = {0.1f, 0.1f, 0.15f, 1.0f}; - clearValues[1].depthStencil = {1.0f, 0}; - clearValues[2].color = {0.0f, 0.0f, 0.0f, 0.0f}; - renderPassInfo.clearValueCount = 3; - renderPassInfo.pClearValues = clearValues.data(); + VkRenderingInfo renderingInfo{}; + renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + renderingInfo.renderArea = {{0, 0}, m_offscreenExtent}; + renderingInfo.layerCount = 1; + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &colorAttachment; + renderingInfo.pDepthAttachment = &depthAttachment; + renderingInfo.pStencilAttachment = nullptr; - vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBeginRendering(commandBuffer, &renderingInfo); VkViewport viewport{}; viewport.x = 0.0f; @@ -518,82 +522,24 @@ void Renderer::beginOffscreenRenderPass(VkCommandBuffer commandBuffer) { } void Renderer::endOffscreenRenderPass(VkCommandBuffer commandBuffer) const { - vkCmdEndRenderPass(commandBuffer); + vkCmdEndRendering(commandBuffer); } -void Renderer::transitionOffscreenImageForImGui() { +void Renderer::transitionOffscreenImageForImGui(VkCommandBuffer commandBuffer) { if (m_offscreenCurrentLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - transitionImageLayout(m_offscreenResolveImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + cmdTransitionImageLayout( + commandBuffer, + m_offscreenResolveImage, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT); m_offscreenCurrentLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } } -void Renderer::transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) const { - VkCommandBuffer commandBuffer = deviceRef.beginSingleTimeCommands(); - - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.oldLayout = oldLayout; - barrier.newLayout = newLayout; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = image; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - barrier.subresourceRange.baseMipLevel = 0; - barrier.subresourceRange.levelCount = 1; - barrier.subresourceRange.baseArrayLayer = 0; - barrier.subresourceRange.layerCount = 1; - - VkPipelineStageFlags sourceStage; - VkPipelineStageFlags destinationStage; - - if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - } - else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - } - else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - } - else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - } - else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - } - else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - barrier.srcAccessMask = 0; - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - } - else { - throw std::invalid_argument("Unsupported layout transition!"); - } - - vkCmdPipelineBarrier( - commandBuffer, - sourceStage, destinationStage, - 0, 0, nullptr, 0, nullptr, 1, &barrier - ); - - deviceRef.endSingleTimeCommands(commandBuffer); -} - } // Namespace KaguEngine \ No newline at end of file diff --git a/KaguEngine/src/Renderer.ixx b/KaguEngine/src/Renderer.ixx index aea092d..8c2833a 100644 --- a/KaguEngine/src/Renderer.ixx +++ b/KaguEngine/src/Renderer.ixx @@ -25,7 +25,6 @@ public: Renderer(const Renderer &) = delete; Renderer &operator=(const Renderer &) = delete; - [[nodiscard]] VkRenderPass getSwapChainRenderPass() const { return m_SwapChain->getRenderPass(); } [[nodiscard]] float getAspectRatio() const { return m_SwapChain->extentAspectRatio(); } [[nodiscard]] bool isFrameInProgress() const { return m_isFrameStarted; } @@ -47,10 +46,12 @@ public: // Off screen render pass void beginOffscreenRenderPass(VkCommandBuffer commandBuffer); void endOffscreenRenderPass(VkCommandBuffer commandBuffer) const; - void transitionOffscreenImageForImGui(); + void transitionOffscreenImageForImGui(VkCommandBuffer commandBuffer); [[nodiscard]] VkDescriptorSet getOffscreenImGuiDescriptorSet() const { return m_offscreenImGuiDescriptorSet; } [[nodiscard]] VkExtent2D getOffscreenExtent() const { return m_offscreenExtent; } + [[nodiscard]] VkFormat getOffscreenFormat() const { return m_offscreenFormat; } + [[nodiscard]] VkFormat getOffscreenDepthFormat() const { return m_offscreenDepthFormat; } std::unique_ptr& getSwapChain() { return m_SwapChain; } @@ -68,15 +69,14 @@ private: int m_currentFrameIndex{0}; bool m_isFrameStarted{false}; - VkFramebuffer m_offscreenFramebuffer = VK_NULL_HANDLE; - VkRenderPass m_offscreenRenderPass = VK_NULL_HANDLE; - VkSampler m_offscreenSampler = VK_NULL_HANDLE; VkDescriptorSet m_offscreenImGuiDescriptorSet = VK_NULL_HANDLE; VkDescriptorPool m_offscreenDescriptorPool = VK_NULL_HANDLE; VkImageLayout m_offscreenCurrentLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkDescriptorSetLayout m_offscreenDescriptorSetLayout = VK_NULL_HANDLE; VkFormat m_offscreenFormat = VK_FORMAT_B8G8R8A8_UNORM; + VkFormat m_offscreenDepthFormat; VkExtent2D m_offscreenExtent{}; + VkSampler m_offscreenSampler = VK_NULL_HANDLE; // Multi sampled color image VkImage m_offscreenImage = VK_NULL_HANDLE; @@ -94,10 +94,7 @@ private: void createOffscreenResources(); void cleanupOffscreenResources(); - void createOffscreenRenderPass(); - void createOffscreenFramebuffer(); void createOffscreenDescriptorSet(); - void transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) const; }; } // Namespace KaguEngine \ No newline at end of file diff --git a/KaguEngine/src/SwapChain.cpp b/KaguEngine/src/SwapChain.cpp index 0f4d603..5942c1b 100644 --- a/KaguEngine/src/SwapChain.cpp +++ b/KaguEngine/src/SwapChain.cpp @@ -26,10 +26,8 @@ SwapChain::SwapChain(Device &deviceRef, const VkExtent2D windowExtent, const std void SwapChain::init() { createSwapChain(); createImageViews(); - createRenderPass(); createDepthResources(); createColorResources(); - createFramebuffers(); createSyncObjects(); } @@ -60,18 +58,6 @@ SwapChain::~SwapChain() { m_DepthImages.clear(); m_DepthImageMemories.clear(); - // Destroy framebuffers - for (const auto framebuffer: m_SwapChainFramebuffers) { - vkDestroyFramebuffer(deviceRef.device(), framebuffer, nullptr); - } - m_SwapChainFramebuffers.clear(); - - // Destroy render pass - if (m_RenderPass != nullptr) { - vkDestroyRenderPass(deviceRef.device(), m_RenderPass, nullptr); - m_RenderPass = nullptr; - } - // Destroy the swapchain if (m_SwapChain != nullptr) { vkDestroySwapchainKHR(deviceRef.device(), m_SwapChain, nullptr); @@ -233,103 +219,6 @@ void SwapChain::createImageViews() { } } -void SwapChain::createRenderPass() { - VkAttachmentDescription colorAttachment = {}; - colorAttachment.format = getSwapChainImageFormat(); - colorAttachment.samples = deviceRef.getSampleCount(); - colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentDescription depthAttachment{}; - depthAttachment.format = findDepthFormat(); - depthAttachment.samples = deviceRef.getSampleCount(); - depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentDescription colorAttachmentResolve = {}; - colorAttachmentResolve.format = getSwapChainImageFormat(); - colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT; - colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentReference colorAttachmentRef = {}; - colorAttachmentRef.attachment = 0; - colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference depthAttachmentRef = {}; - depthAttachmentRef.attachment = 1; - depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference colorAttachmentResolveRef = {}; - colorAttachmentResolveRef.attachment = 2; - colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorAttachmentRef; - subpass.pDepthStencilAttachment = &depthAttachmentRef; - subpass.pResolveAttachments = &colorAttachmentResolveRef; - - VkSubpassDependency dependency = {}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.srcAccessMask = 0; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - - std::array attachments = {colorAttachment, depthAttachment, colorAttachmentResolve}; - VkRenderPassCreateInfo renderPassInfo = {}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo.attachmentCount = static_cast(attachments.size()); - renderPassInfo.pAttachments = attachments.data(); - renderPassInfo.subpassCount = 1; - renderPassInfo.pSubpasses = &subpass; - renderPassInfo.dependencyCount = 1; - renderPassInfo.pDependencies = &dependency; - - if (vkCreateRenderPass(deviceRef.device(), &renderPassInfo, nullptr, &m_RenderPass) != VK_SUCCESS) { - throw std::runtime_error("Failed to create render pass!"); - } -} - -void SwapChain::createFramebuffers() { - m_SwapChainFramebuffers.resize(imageCount()); - for (size_t i = 0; i < imageCount(); i++) { - std::array attachments = { - m_MultisampleColorImageViews[i], - m_DepthImageViews[i], - m_SwapChainImageViews[i] - }; - - VkFramebufferCreateInfo framebufferInfo = {}; - framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = m_RenderPass; - framebufferInfo.attachmentCount = static_cast(attachments.size()); - framebufferInfo.pAttachments = attachments.data(); - framebufferInfo.width = m_SwapChainExtent.width; - framebufferInfo.height = m_SwapChainExtent.height; - framebufferInfo.layers = 1; - - if (vkCreateFramebuffer(deviceRef.device(), &framebufferInfo, nullptr, &m_SwapChainFramebuffers[i]) != VK_SUCCESS) { - throw std::runtime_error("failed to create framebuffer!"); - } - } -} - void SwapChain::createDepthResources() { const VkFormat depthFormat = findDepthFormat(); m_SwapChainDepthFormat = depthFormat; diff --git a/KaguEngine/src/SwapChain.ixx b/KaguEngine/src/SwapChain.ixx index 17c6cc7..e43972e 100644 --- a/KaguEngine/src/SwapChain.ixx +++ b/KaguEngine/src/SwapChain.ixx @@ -24,9 +24,10 @@ public: SwapChain(const SwapChain &) = delete; SwapChain &operator=(const SwapChain &) = delete; - [[nodiscard]] VkFramebuffer getFrameBuffer(const int index) const { return m_SwapChainFramebuffers[index]; } - [[nodiscard]] VkRenderPass getRenderPass() const { return m_RenderPass; } [[nodiscard]] VkImageView getImageView(const int index) const { return m_SwapChainImageViews[index]; } + [[nodiscard]] VkImage getImage(const int index) const { return m_SwapChainImages[index]; } + [[nodiscard]] VkImageView getDepthImageView(const int index) const { return m_DepthImageViews[index]; } + [[nodiscard]] VkImageView getMultisampleColorImageView(const int index) const { return m_MultisampleColorImageViews[index]; } [[nodiscard]] size_t imageCount() const { return m_SwapChainImages.size(); } [[nodiscard]] VkFormat getSwapChainImageFormat() const { return m_SwapChainImageFormat; } [[nodiscard]] VkExtent2D getSwapChainExtent() const { return m_SwapChainExtent; } @@ -53,8 +54,6 @@ private: void createImageViews(); void createDepthResources(); void createColorResources(); - void createRenderPass(); - void createFramebuffers(); void createSyncObjects(); // Helper functions @@ -67,9 +66,6 @@ private: VkFormat m_SwapChainDepthFormat; VkExtent2D m_SwapChainExtent; - std::vector m_SwapChainFramebuffers; - VkRenderPass m_RenderPass; - std::vector m_DepthImages; std::vector m_DepthImageMemories; std::vector m_DepthImageViews; diff --git a/KaguEngine/src/systems/PointLightSystem.cpp b/KaguEngine/src/systems/PointLightSystem.cpp index 78af114..1c0cc16 100644 --- a/KaguEngine/src/systems/PointLightSystem.cpp +++ b/KaguEngine/src/systems/PointLightSystem.cpp @@ -26,10 +26,10 @@ struct PointLightPushConstants { float radius; }; -PointLightSystem::PointLightSystem(Device &device, const VkRenderPass renderPass, +PointLightSystem::PointLightSystem(Device &device, const VkFormat colorFormat, const VkFormat depthFormat, const VkDescriptorSetLayout globalSetLayout) : m_Device{device} { createPipelineLayout(globalSetLayout); - createPipeline(renderPass); + createPipeline(colorFormat, depthFormat); } PointLightSystem::~PointLightSystem() { @@ -55,7 +55,7 @@ void PointLightSystem::createPipelineLayout(const VkDescriptorSetLayout globalSe } } -void PointLightSystem::createPipeline(const VkRenderPass renderPass) { +void PointLightSystem::createPipeline(const VkFormat colorFormat, const VkFormat depthFormat) { assert(m_pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout"); PipelineConfigInfo pipelineConfig{}; @@ -64,8 +64,10 @@ void PointLightSystem::createPipeline(const VkRenderPass renderPass) { Pipeline::enableMSAA(pipelineConfig, m_Device.getSampleCount()); pipelineConfig.attributeDescriptions.clear(); pipelineConfig.bindingDescriptions.clear(); - pipelineConfig.renderPass = renderPass; pipelineConfig.pipelineLayout = m_pipelineLayout; + pipelineConfig.colorAttachmentFormat = colorFormat; + pipelineConfig.depthAttachmentFormat = depthFormat; + m_Pipeline = std::make_unique(m_Device, "assets/shaders/point_light.vert.spv", "assets/shaders/point_light.frag.spv", pipelineConfig); diff --git a/KaguEngine/src/systems/PointLightSystem.ixx b/KaguEngine/src/systems/PointLightSystem.ixx index 551a5ba..629ac47 100644 --- a/KaguEngine/src/systems/PointLightSystem.ixx +++ b/KaguEngine/src/systems/PointLightSystem.ixx @@ -1,11 +1,6 @@ module; // libs -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#include -#include - #include export module KaguEngine.System.PointLight; @@ -22,7 +17,7 @@ export namespace KaguEngine { class PointLightSystem { public: - PointLightSystem(Device &device, VkRenderPass renderPass, VkDescriptorSetLayout globalSetLayout); + PointLightSystem(Device &device, VkFormat colorFormat, VkFormat depthFormat, VkDescriptorSetLayout globalSetLayout); ~PointLightSystem(); PointLightSystem(const PointLightSystem &) = delete; @@ -33,7 +28,7 @@ public: private: void createPipelineLayout(VkDescriptorSetLayout globalSetLayout); - void createPipeline(VkRenderPass renderPass); + void createPipeline(VkFormat colorFormat, VkFormat depthFormat); Device &m_Device; diff --git a/KaguEngine/src/systems/RenderSystem.cpp b/KaguEngine/src/systems/RenderSystem.cpp index 332007d..6c8f2af 100644 --- a/KaguEngine/src/systems/RenderSystem.cpp +++ b/KaguEngine/src/systems/RenderSystem.cpp @@ -28,13 +28,14 @@ struct SimplePushConstantData { RenderSystem::RenderSystem( Device &device, - const VkRenderPass renderPass, + const VkFormat colorFormat, + const VkFormat depthFormat, const VkDescriptorSetLayout globalSetLayout, const VkDescriptorSetLayout materialSetLayout ) : m_Device{device} { createPipelineLayout(globalSetLayout, materialSetLayout); - createPipeline(renderPass); + createPipeline(colorFormat, depthFormat); } RenderSystem::~RenderSystem() { @@ -65,15 +66,18 @@ void RenderSystem::createPipelineLayout(const VkDescriptorSetLayout globalSetLay } } -void RenderSystem::createPipeline(const VkRenderPass renderPass) { +void RenderSystem::createPipeline(const VkFormat colorFormat, const VkFormat depthFormat) { assert(m_pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout"); PipelineConfigInfo pipelineConfig{}; Pipeline::defaultPipelineConfigInfo(pipelineConfig); Pipeline::enableAlphaBlending(pipelineConfig); Pipeline::enableMSAA(pipelineConfig, m_Device.getSampleCount()); - pipelineConfig.renderPass = renderPass; + pipelineConfig.pipelineLayout = m_pipelineLayout; + pipelineConfig.colorAttachmentFormat = colorFormat; + pipelineConfig.depthAttachmentFormat = depthFormat; + m_Pipeline = std::make_unique( m_Device, "assets/shaders/simple_shader.vert.spv", diff --git a/KaguEngine/src/systems/RenderSystem.ixx b/KaguEngine/src/systems/RenderSystem.ixx index 761e638..2339332 100644 --- a/KaguEngine/src/systems/RenderSystem.ixx +++ b/KaguEngine/src/systems/RenderSystem.ixx @@ -20,26 +20,26 @@ import KaguEngine.Pipeline; export namespace KaguEngine { -class RenderSystem { -public: - RenderSystem(Device &device, VkRenderPass renderPass, - VkDescriptorSetLayout globalSetLayout, - VkDescriptorSetLayout materialSetLayout); - ~RenderSystem(); + class RenderSystem { + public: + RenderSystem(Device &device, VkFormat colorFormat, VkFormat depthFormat, + VkDescriptorSetLayout globalSetLayout, + VkDescriptorSetLayout materialSetLayout); + ~RenderSystem(); - RenderSystem(const RenderSystem &) = delete; - RenderSystem &operator=(const RenderSystem &) = delete; + RenderSystem(const RenderSystem &) = delete; + RenderSystem &operator=(const RenderSystem &) = delete; - void renderGameObjects(const FrameInfo &frameInfo) const; + void renderGameObjects(const FrameInfo &frameInfo) const; -private: - void createPipelineLayout(VkDescriptorSetLayout globalSetLayout, VkDescriptorSetLayout materialSetLayout); - void createPipeline(VkRenderPass renderPass); + private: + void createPipelineLayout(VkDescriptorSetLayout globalSetLayout, VkDescriptorSetLayout materialSetLayout); + void createPipeline(VkFormat colorFormat, VkFormat depthFormat); - Device &m_Device; + Device &m_Device; - std::unique_ptr m_Pipeline; - VkPipelineLayout m_pipelineLayout; -}; + std::unique_ptr m_Pipeline; + VkPipelineLayout m_pipelineLayout; + }; } // Namespace KaguEngine \ No newline at end of file