I am building a graphics renderer using Vulkan in C++. I am facing an issue where I have implemented subpass rendering, but nothing is being rendered to the screen. No validation errors are being recorded. Can you help diagnose the issue?

Here is the code to create the renderpass if it is helpful:

void Renderer::CreateRenderPass()
{
    vk::AttachmentDescription positionAttachment{};
    positionAttachment.format = vk::Format::eR16G16B16A16Sfloat; // High precision format
    positionAttachment.samples = vk::SampleCountFlagBits::e1;
    positionAttachment.loadOp = vk::AttachmentLoadOp::eClear;
    positionAttachment.storeOp = vk::AttachmentStoreOp::eStore;
    positionAttachment.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
    positionAttachment.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
    positionAttachment.initialLayout = vk::ImageLayout::eUndefined;
    positionAttachment.finalLayout = vk::ImageLayout::eShaderReadOnlyOptimal;

    vk::AttachmentDescription normalAttachment = positionAttachment;
    normalAttachment.format = vk::Format::eR16G16B16A16Sfloat;

    vk::AttachmentDescription albedoAttachment = positionAttachment;
    albedoAttachment.format = swapChainImageFormat; // Assuming albedo might use swap chain format

    vk::AttachmentDescription depthAttachment = positionAttachment;
    depthAttachment.format = FindDepthFormat(*GetPhysicalDevice());
    depthAttachment.samples = msaaSamples;
    depthAttachment.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;

    vk::AttachmentDescription colorAttachmentResolve{};
    colorAttachmentResolve.format = swapChainImageFormat;
    colorAttachmentResolve.samples = vk::SampleCountFlagBits::e1;
    colorAttachmentResolve.loadOp = vk::AttachmentLoadOp::eDontCare; // Shouldn’t clear resolve attachment
    colorAttachmentResolve.storeOp = vk::AttachmentStoreOp::eStore;
    colorAttachmentResolve.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
    colorAttachmentResolve.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
    colorAttachmentResolve.initialLayout = vk::ImageLayout::eUndefined;
    colorAttachmentResolve.finalLayout = vk::ImageLayout::ePresentSrcKHR;

    std::array<vk::AttachmentDescription, 5> attachments = {
        positionAttachment, normalAttachment, albedoAttachment, depthAttachment, colorAttachmentResolve
    };

    vk::AttachmentReference positionAttachmentRef{};
    positionAttachmentRef.attachment = 0;
    positionAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal;

    vk::AttachmentReference normalAttachmentRef{};
    normalAttachmentRef.attachment = 1;
    normalAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal;

    vk::AttachmentReference albedoAttachmentRef{};
    albedoAttachmentRef.attachment = 2;
    albedoAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal;

    vk::AttachmentReference depthAttachmentRef{};
    depthAttachmentRef.attachment = 3;
    depthAttachmentRef.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal;

    vk::AttachmentReference colorAttachmentResolveRef{};
    colorAttachmentResolveRef.attachment = 4;
    colorAttachmentResolveRef.layout = vk::ImageLayout::eColorAttachmentOptimal;

    std::array<vk::AttachmentReference, 3> colorAttachments = {
        positionAttachmentRef, normalAttachmentRef, albedoAttachmentRef
    };

    // Input attachments for the lighting pass
    std::array<vk::AttachmentReference, 3> inputAttachments = {
        vk::AttachmentReference{0, vk::ImageLayout::eShaderReadOnlyOptimal},
        vk::AttachmentReference{1, vk::ImageLayout::eShaderReadOnlyOptimal},
        vk::AttachmentReference{2, vk::ImageLayout::eShaderReadOnlyOptimal}
    };

    // Geometry pass subpass: writes to color and depth attachments
    vk::SubpassDescription geometryPass{};
    geometryPass.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
    geometryPass.colorAttachmentCount = static_cast<uint32_t>(colorAttachments.size());
    geometryPass.pColorAttachments = colorAttachments.data();
    geometryPass.pDepthStencilAttachment = &depthAttachmentRef;

    // Lighting pass subpass: reads from input attachments
    vk::AttachmentReference colorAttachmentFinalRef{};
    colorAttachmentFinalRef.attachment = 4;
    colorAttachmentFinalRef.layout = vk::ImageLayout::eColorAttachmentOptimal;

    vk::SubpassDescription lightingPass{};
    lightingPass.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
    lightingPass.inputAttachmentCount = static_cast<uint32_t>(inputAttachments.size());
    lightingPass.pInputAttachments = inputAttachments.data();
    lightingPass.colorAttachmentCount = 1;
    lightingPass.pColorAttachments = &colorAttachmentFinalRef;

    std::array<vk::SubpassDescription, 2> subpasses = { geometryPass, lightingPass };

    // Define subpass dependencies
    vk::SubpassDependency externalToGeometryDependency{};
    externalToGeometryDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
    externalToGeometryDependency.dstSubpass = 0;
    externalToGeometryDependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
    externalToGeometryDependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
    externalToGeometryDependency.srcAccessMask = {};
    externalToGeometryDependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;

    vk::SubpassDependency geometryToLightingDependency{};
    geometryToLightingDependency.srcSubpass = 0;
    geometryToLightingDependency.dstSubpass = 1;
    geometryToLightingDependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
    geometryToLightingDependency.dstStageMask = vk::PipelineStageFlagBits::eFragmentShader;
    geometryToLightingDependency.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
    geometryToLightingDependency.dstAccessMask = vk::AccessFlagBits::eShaderRead;
    geometryToLightingDependency.dependencyFlags = vk::DependencyFlagBits::eByRegion;

    vk::SubpassDependency geometryToLightingDepthDependency{};
    geometryToLightingDepthDependency.srcSubpass = 0;
    geometryToLightingDepthDependency.dstSubpass = 1;
    geometryToLightingDepthDependency.srcStageMask = vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
    geometryToLightingDepthDependency.dstStageMask = vk::PipelineStageFlagBits::eFragmentShader;
    geometryToLightingDepthDependency.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite;
    geometryToLightingDepthDependency.dstAccessMask = vk::AccessFlagBits::eShaderRead;
    geometryToLightingDepthDependency.dependencyFlags = vk::DependencyFlagBits::eByRegion;

    std::array<vk::SubpassDependency, 3> dependencies = {
        externalToGeometryDependency,
        geometryToLightingDependency,
        geometryToLightingDepthDependency
    };

    vk::RenderPassCreateInfo renderPassInfo{};
    renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
    renderPassInfo.pAttachments = attachments.data();
    renderPassInfo.subpassCount = static_cast<uint32_t>(subpasses.size());
    renderPassInfo.pSubpasses = subpasses.data();
    renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
    renderPassInfo.pDependencies = dependencies.data();

    if (device.createRenderPass(&renderPassInfo, nullptr, &renderPass) != vk::Result::eSuccess)
    {
        throw std::runtime_error("Failed to create render pass.");
    }
}