mirror of
https://github.com/antopilo/Nuake.git
synced 2026-01-06 06:09:52 +03:00
Started automatic sync + transition for render pass
This commit is contained in:
@@ -211,6 +211,17 @@ std::vector<std::string> RenderPass::GetInputs()
|
||||
return InputNames;
|
||||
}
|
||||
|
||||
std::vector<TextureAttachment> RenderPass::GetInputAttachments()
|
||||
{
|
||||
std::vector<TextureAttachment> 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<TextureAttachment> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace Nuake
|
||||
|
||||
void AddInput(const std::string& name);
|
||||
std::vector<std::string> GetInputs();
|
||||
std::vector<TextureAttachment> GetInputAttachments();
|
||||
TextureAttachment& GetDepthAttachment() { return DepthAttachment; }
|
||||
|
||||
void SetInput(const std::string& name, TextureAttachment attachment);
|
||||
@@ -112,7 +113,7 @@ namespace Nuake
|
||||
private:
|
||||
bool Built;
|
||||
std::vector<RenderPass> RenderPasses;
|
||||
|
||||
TextureAttachment FinalOutput;
|
||||
public:
|
||||
RenderPipeline();
|
||||
~RenderPipeline() = default;
|
||||
|
||||
@@ -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>(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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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> 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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user