From b40b0045b9b1f73e0fe05190ddd6ec74e9d19c51 Mon Sep 17 00:00:00 2001 From: antopilo Date: Wed, 8 Jan 2025 21:19:23 -0500 Subject: [PATCH] Started automatic sync + transition for render pass --- .../Vulkan/Pipeline/RenderPipeline.cpp | 84 +++++++++++++++++++ .../Vulkan/Pipeline/RenderPipeline.h | 3 +- .../Rendering/Vulkan/VulkanSceneRenderer.cpp | 9 +- Resources/Shaders/Vulkan/triangle.frag | 13 ++- 4 files changed, 99 insertions(+), 10 deletions(-) diff --git a/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.cpp b/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.cpp index cbdd5045..ee0b8043 100644 --- a/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.cpp +++ b/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.cpp @@ -211,6 +211,17 @@ std::vector RenderPass::GetInputs() return InputNames; } +std::vector RenderPass::GetInputAttachments() +{ + std::vector inputAttachments; + inputAttachments.reserve(Inputs.size()); + for (auto& [name, attachment] : Inputs) + { + inputAttachments.push_back(attachment); + } + return inputAttachments; +} + void RenderPass::SetInput(const std::string& name, TextureAttachment attachment) { Inputs[name] = attachment; @@ -361,12 +372,85 @@ void RenderPipeline::Execute(PassRenderContext& ctx) return; } + std::vector transitionedInputs; for (auto& pass : RenderPasses) { + for (auto& input : pass.GetInputAttachments()) + { + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + + // Handle old and new layouts based on attachment type + barrier.oldLayout = input.Format != ImageFormat::D32F ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + // Access masks for color or depth-stencil attachments + if (input.Format != ImageFormat::D32F) { + barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + } + else { + barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + + // Include stencil aspect if applicable + //if (input.HasStencilComponent()) { + // barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + //} + } + + // Destination access mask is always for shaders reading + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + + // No queue family ownership transfer in this case + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + + // Set the image and subresource range + barrier.image = input.Image->GetImage(); + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = 1; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = 1; + + // Choose appropriate source pipeline stage for color or depth-stencil + VkPipelineStageFlags srcStage = (input.Format != ImageFormat::D32F) + ? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT + : (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); + + // Insert the pipeline barrier + vkCmdPipelineBarrier( + ctx.commandBuffer, + srcStage, // Source stage + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // Destination stage + 0, + 0, nullptr, + 0, nullptr, + 1, &barrier + ); + + transitionedInputs.push_back(input); + } + pass.ClearAttachments(ctx); pass.TransitionAttachments(ctx); pass.Render(ctx); pass.UntransitionAttachments(ctx); + + // Sync the attachments + + } + + for (auto& transitionedOutputs : transitionedInputs) + { + if (transitionedOutputs.Format == ImageFormat::D32F) + { + //VulkanUtil::TransitionImage(ctx.commandBuffer, transitionedOutputs.Image->GetImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + } + else + { + VulkanUtil::TransitionImage(ctx.commandBuffer, transitionedOutputs.Image->GetImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); + } } } diff --git a/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.h b/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.h index cd0dc3c5..bc23325b 100644 --- a/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.h +++ b/Nuake/src/Rendering/Vulkan/Pipeline/RenderPipeline.h @@ -84,6 +84,7 @@ namespace Nuake void AddInput(const std::string& name); std::vector GetInputs(); + std::vector GetInputAttachments(); TextureAttachment& GetDepthAttachment() { return DepthAttachment; } void SetInput(const std::string& name, TextureAttachment attachment); @@ -112,7 +113,7 @@ namespace Nuake private: bool Built; std::vector RenderPasses; - + TextureAttachment FinalOutput; public: RenderPipeline(); ~RenderPipeline() = default; diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp index 8cebc1ab..77b59baa 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp @@ -80,7 +80,7 @@ void VkSceneRenderer::EndScene() auto& cmd = Context.CommandBuffer; auto& albedo = GBufferPipeline.GetRenderPass("GBuffer").GetAttachment("Albedo"); - VulkanUtil::TransitionImage(cmd, albedo.Image->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + VulkanUtil::TransitionImage(cmd, albedo.Image->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); VulkanUtil::TransitionImage(cmd, vk.DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VulkanUtil::CopyImageToImage(cmd, albedo.Image->GetImage(), vk.GetDrawImage()->GetImage(), albedo.Image->GetSize(), vk.DrawImage->GetSize()); VulkanUtil::TransitionImage(cmd, vk.DrawImage->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); @@ -349,13 +349,12 @@ void VkSceneRenderer::CreatePipelines() shadingPass.SetPushConstant(modelPushConstant); shadingPass.AddAttachment("Output", ImageFormat::RGBA16F); shadingPass.AddAttachment("DepthShading", ImageFormat::D32F, ImageUsage::Depth); - shadingPass.AddInput("Albedo"); - shadingPass.AddInput("Normal"); - shadingPass.AddInput("Material"); - shadingPass.AddInput("Depth"); + shadingPass.AddInput("Albedo"); // We need to sync those + shadingPass.SetPreRender([](PassRenderContext& ctx) {}); shadingPass.SetRender([](PassRenderContext& ctx) {}); + GBufferPipeline.Build(); } diff --git a/Resources/Shaders/Vulkan/triangle.frag b/Resources/Shaders/Vulkan/triangle.frag index 519ab49f..5ee697ee 100644 --- a/Resources/Shaders/Vulkan/triangle.frag +++ b/Resources/Shaders/Vulkan/triangle.frag @@ -15,7 +15,13 @@ struct Material float metalnessValue; float roughnessValue; float aoValue; + int albedoTextureId; + int normalTextureId; + int metalnessTextureId; + int roughnessTextureId; + int aoTextureId; }; + [[vk::binding(0, 5)]] StructuredBuffer material; @@ -68,16 +74,15 @@ PSOutput main(PSInput input) float4 albedoColor = float4(inMaterial.albedo.xyz, 1.0f); if(inMaterial.hasAlbedo == 1) { - float4 testTexture = textures[pushConstants.modelIndex].Sample(mySampler, input.UV); - float4 albedoTextureSample = albedo.Sample(mySampler, input.UV); + float4 albedoSample = textures[inMaterial.albedoTextureId].Sample(mySampler, input.UV); // Alpha cutout? - if(albedoTextureSample.a < 0.001f) + if(albedoSample.a < 0.001f) { discard; } - albedoColor.xyz = testTexture.xyz * albedoTextureSample.xyz; + albedoColor.xyz = albedoSample.xyz; } output.oColor0 = albedoColor;