Vulkan/RenderTarget: Change interface to better suit needs

Former-commit-id: cc61462eca9a4b73821eb0c9bd10b74366e5a6ce [formerly 8e64df958d6b9ccd61b9df22456cd566947fcb0b]
Former-commit-id: 750ea64ee603b0c52058eb93045310db4977dfdb
This commit is contained in:
Lynix 2016-07-08 17:59:43 +02:00
parent 8d3680f4b9
commit f1c5f8d0b7
3 changed files with 232 additions and 236 deletions

View File

@ -12,6 +12,7 @@
#include <Nazara/Vulkan/Config.hpp>
#include <Nazara/Vulkan/VkFrameBuffer.hpp>
#include <Nazara/Vulkan/VkRenderPass.hpp>
#include <Nazara/Vulkan/VkSemaphore.hpp>
#include <unordered_map>
#include <vulkan/vulkan.h>
@ -29,11 +30,19 @@ namespace Nz
RenderTarget(RenderTarget&&) = delete; ///TOOD?
virtual ~RenderTarget();
virtual bool Acquire(const Vk::Framebuffer** framebuffer) const = 0;
virtual bool Acquire(UInt32* imageIndex) const = 0;
virtual void BuildPreRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer) = 0;
virtual void BuildPostRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer) = 0;
virtual const Vk::Framebuffer& GetFrameBuffer(UInt32 imageIndex) const = 0;
virtual UInt32 GetFramebufferCount() const = 0;
const Vk::RenderPass& GetRenderPass() const { return m_renderPass; }
virtual void Present() = 0;
const Vk::Semaphore& GetRenderSemaphore() const { return m_imageReadySemaphore; }
virtual void Present(UInt32 imageIndex) = 0;
RenderTarget& operator=(const RenderTarget&) = delete;
RenderTarget& operator=(RenderTarget&&) = delete; ///TOOD?
@ -44,6 +53,7 @@ namespace Nz
protected:
Vk::RenderPass m_renderPass;
Vk::Semaphore m_imageReadySemaphore;
};
}

View File

@ -17,7 +17,6 @@
#include <Nazara/Vulkan/VkCommandPool.hpp>
#include <Nazara/Vulkan/VkDevice.hpp>
#include <Nazara/Vulkan/VkFramebuffer.hpp>
#include <Nazara/Vulkan/VkSemaphore.hpp>
#include <Nazara/Vulkan/VkSurface.hpp>
#include <Nazara/Vulkan/VkSwapchain.hpp>
#include <Nazara/Utility/Window.hpp>
@ -35,7 +34,14 @@ namespace Nz
RenderWindow(RenderWindow&&) = delete; ///TODO
virtual ~RenderWindow();
bool Acquire(const Vk::Framebuffer** framebuffer) const override;
bool Acquire(UInt32* index) const override;
void BuildPreRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer) override;
void BuildPostRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer) override;
const Vk::Framebuffer& GetFrameBuffer(UInt32 imageIndex) const override;
UInt32 GetFramebufferCount() const;
bool Create(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default);
bool Create(WindowHandle handle);
@ -45,7 +51,7 @@ namespace Nz
const Vk::Surface& GetSurface() const;
const Vk::Swapchain& GetSwapchain() const;
void Present() override;
void Present(UInt32 imageIndex) override;
bool IsValid() const;
@ -59,25 +65,20 @@ namespace Nz
void OnWindowDestroy() override;
void OnWindowResized() override;
bool SetupRenderPass(VkFormat colorFormat, VkFormat depthFormat);
struct ImageData
{
Vk::CommandBuffer drawToPresentCmd;
Vk::CommandBuffer presentToDrawCmd;
Vk::Framebuffer frameBuffer;
};
bool SetupCommandBuffers();
bool SetupRenderPass();
bool SetupSwapchain();
Clock m_clock;
VkFormat m_colorFormat;
VkFormat m_depthFormat;
VkColorSpaceKHR m_colorSpace;
VkPhysicalDevice m_forcedPhysicalDevice;
std::vector<ImageData> m_images;
Vk::CommandPool m_cmdPool;
std::vector<Vk::Framebuffer> m_frameBuffers;
Vk::DeviceHandle m_device;
Vk::Queue m_presentQueue;
Vk::Semaphore m_imageReadySemaphore;
Vk::Surface m_surface;
Vk::Swapchain m_swapchain;
mutable UInt32 m_lastImageAcquired;
UInt32 m_presentableFamilyQueue;
};
}

View File

@ -39,42 +39,77 @@ namespace Nz
OnWindowDestroy();
}
bool RenderWindow::Acquire(const Vk::Framebuffer** framebuffer) const
bool RenderWindow::Acquire(UInt32* imageIndex) const
{
UInt32 imageIndex;
if (!m_swapchain.AcquireNextImage(std::numeric_limits<UInt64>::max(), m_imageReadySemaphore, VK_NULL_HANDLE, &imageIndex))
if (!m_swapchain.AcquireNextImage(std::numeric_limits<UInt64>::max(), m_imageReadySemaphore, VK_NULL_HANDLE, imageIndex))
{
NazaraError("Failed to acquire next image");
return false;
}
VkSemaphore waitSemaphore = m_imageReadySemaphore;
VkCommandBuffer barrierBuffer = m_images[imageIndex].presentToDrawCmd;
VkSubmitInfo submitInfo = {
VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType
nullptr, // const void* pNext
1, // uint32_t waitSemaphoreCount
&waitSemaphore, // const VkSemaphore* pWaitSemaphores
nullptr, // const VkPipelineStageFlags* pWaitDstStageMask
1, // uint32_t commandBufferCount
&barrierBuffer, // const VkCommandBuffer* pCommandBuffers
0, // uint32_t signalSemaphoreCount
nullptr // const VkSemaphore* pSignalSemaphores
};
if (!m_presentQueue.Submit(1, &submitInfo))
{
NazaraError("Failed to submit memory barrier");
return false;
return true;
}
m_lastImageAcquired = imageIndex;
void RenderWindow::BuildPreRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer)
{
VkImageSubresourceRange imageRange = {
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0, // uint32_t baseMipLevel
1, // uint32_t levelCount
0, // uint32_t baseArrayLayer
1 // uint32_t layerCount
};
if (framebuffer)
*framebuffer = &m_images[imageIndex].frameBuffer;
VkImageMemoryBarrier presentToDrawBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
nullptr, // const void* pNext
0, // VkAccessFlags srcAccessMask
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
m_swapchain.GetBuffer(imageIndex).image, // VkImage image
imageRange // VkImageSubresourceRange subresourceRange
};
return true;
commandBuffer.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, presentToDrawBarrier);
}
void RenderWindow::BuildPostRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer)
{
VkImageSubresourceRange imageRange = {
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0, // uint32_t baseMipLevel
1, // uint32_t levelCount
0, // uint32_t baseArrayLayer
1 // uint32_t layerCount
};
VkImageMemoryBarrier drawToPresentBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
nullptr, // const void* pNext
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
0, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
m_swapchain.GetBuffer(imageIndex).image, // VkImage image
imageRange // VkImageSubresourceRange subresourceRange
};
commandBuffer.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, drawToPresentBarrier);
}
const Vk::Framebuffer& RenderWindow::GetFrameBuffer(UInt32 imageIndex) const
{
return m_frameBuffers[imageIndex];
}
UInt32 RenderWindow::GetFramebufferCount() const
{
return static_cast<UInt32>(m_frameBuffers.size());
}
bool RenderWindow::Create(VideoMode mode, const String& title, UInt32 style)
@ -107,9 +142,11 @@ namespace Nz
return m_swapchain;
}
void RenderWindow::Present()
void RenderWindow::Present(UInt32 imageIndex)
{
m_presentQueue.Present(m_swapchain, m_lastImageAcquired);
NazaraAssert(imageIndex < m_frameBuffers.size(), "Invalid image index");
m_presentQueue.Present(m_swapchain, imageIndex);
}
bool RenderWindow::IsValid() const
@ -156,14 +193,149 @@ namespace Nz
return false;
}
VkFormat colorFormat;
if (surfaceFormats.size() == 1 && surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
m_colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
else
colorFormat = surfaceFormats[0].format;
m_colorFormat = surfaceFormats[0].format;
VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace;
m_colorSpace = surfaceFormats[0].colorSpace;
m_depthFormat = VK_FORMAT_MAX_ENUM;
if (!SetupSwapchain())
{
NazaraError("Failed to create swapchain");
return false;
}
if (!SetupRenderPass())
{
NazaraError("Failed to create render pass");
return false;
}
UInt32 imageCount = m_swapchain.GetBufferCount();
// Framebuffers
m_frameBuffers.resize(imageCount);
for (UInt32 i = 0; i < imageCount; ++i)
{
std::array<VkImageView, 2> attachments = {m_swapchain.GetBuffer(i).view, VK_NULL_HANDLE};
VkFramebufferCreateInfo frameBufferCreate = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0, // VkFramebufferCreateFlags flags;
m_renderPass, // VkRenderPass renderPass;
(attachments[1] != VK_NULL_HANDLE) ? 2U : 1U, // uint32_t attachmentCount;
attachments.data(), // const VkImageView* pAttachments;
GetWidth(), // uint32_t width;
GetHeight(), // uint32_t height;
1U // uint32_t layers;
};
if (!m_frameBuffers[i].Create(m_device, frameBufferCreate))
{
NazaraError("Failed to create framebuffer for image #" + String::Number(i));
return false;
}
}
m_imageReadySemaphore.Create(m_device);
m_clock.Restart();
return true;
}
void RenderWindow::OnWindowDestroy()
{
m_frameBuffers.clear();
m_renderPass.Destroy();
m_swapchain.Destroy();
m_surface.Destroy();
}
void RenderWindow::OnWindowResized()
{
OnRenderTargetSizeChange(this);
}
bool RenderWindow::SetupCommandBuffers()
{
return false;
}
bool RenderWindow::SetupRenderPass()
{
std::array<VkAttachmentDescription, 2> attachments = {
{
{
0, // VkAttachmentDescriptionFlags flags;
m_colorFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
},
{
0, // VkAttachmentDescriptionFlags flags;
m_depthFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
},
}
};
VkAttachmentReference colorReference = {
0, // uint32_t attachment;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
VkAttachmentReference depthReference = {
1, // uint32_t attachment;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
VkSubpassDescription subpass = {
0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
0U, // uint32_t inputAttachmentCount;
nullptr, // const VkAttachmentReference* pInputAttachments;
1U, // uint32_t colorAttachmentCount;
&colorReference, // const VkAttachmentReference* pColorAttachments;
nullptr, // const VkAttachmentReference* pResolveAttachments;
(m_depthFormat != VK_FORMAT_MAX_ENUM) ? &depthReference : nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
0U, // uint32_t preserveAttachmentCount;
nullptr // const uint32_t* pPreserveAttachments;
};
VkRenderPassCreateInfo createInfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0, // VkRenderPassCreateFlags flags;
(m_depthFormat != VK_FORMAT_MAX_ENUM) ? 2U : 1U, // uint32_t attachmentCount;
attachments.data(), // const VkAttachmentDescription* pAttachments;
1U, // uint32_t subpassCount;
&subpass, // const VkSubpassDescription* pSubpasses;
0U, // uint32_t dependencyCount;
nullptr // const VkSubpassDependency* pDependencies;
};
return m_renderPass.Create(m_device, createInfo);
}
bool RenderWindow::SetupSwapchain()
{
VkSurfaceCapabilitiesKHR surfaceCapabilities;
if (!m_surface.GetCapabilities(m_forcedPhysicalDevice, &surfaceCapabilities))
{
@ -210,8 +382,8 @@ namespace Nz
0,
m_surface,
imageCount,
colorFormat,
colorSpace,
m_colorFormat,
m_colorSpace,
extent,
1,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
@ -230,193 +402,6 @@ namespace Nz
return false;
}
if (!SetupRenderPass(colorFormat, VK_FORMAT_MAX_ENUM))
{
NazaraError("Failed to create render pass");
return false;
}
if (!m_cmdPool.Create(m_device, m_presentableFamilyQueue))
{
NazaraError("Failed to create present command pool");
return false;
}
auto cmdBuffers = m_cmdPool.AllocateCommandBuffers(imageCount * 2, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
VkImageSubresourceRange imageRange = {
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0, // uint32_t baseMipLevel
1, // uint32_t levelCount
0, // uint32_t baseArrayLayer
1 // uint32_t layerCount
};
m_images.resize(imageCount);
for (UInt32 i = 0; i < imageCount; ++i)
{
ImageData& imageData = m_images[i];
imageData.presentToDrawCmd = std::move(cmdBuffers[i*2 + 0]);
imageData.drawToPresentCmd = std::move(cmdBuffers[i*2 + 1]);
VkImage image = m_swapchain.GetBuffer(i).image;
imageData.presentToDrawCmd.Begin(0);
{
VkImageMemoryBarrier presentToDrawBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
nullptr, // const void* pNext
VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
image, // VkImage image
imageRange // VkImageSubresourceRange subresourceRange
};
imageData.presentToDrawCmd.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, presentToDrawBarrier);
}
if (!imageData.presentToDrawCmd.End())
{
NazaraError("Failed to record present to draw barrier command buffer for image #" + String::Number(i));
return false;
}
imageData.drawToPresentCmd.Begin(0);
{
VkImageMemoryBarrier drawToPresentBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
nullptr, // const void* pNext
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
image, // VkImage image
imageRange // VkImageSubresourceRange subresourceRange
};
imageData.drawToPresentCmd.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, drawToPresentBarrier);
}
if (!imageData.drawToPresentCmd.End())
{
NazaraError("Failed to record draw to present barrier command buffer for image #" + String::Number(i));
return false;
}
// Framebuffer
std::array<VkImageView, 2> attachments = {m_swapchain.GetBuffer(i).view, VK_NULL_HANDLE};
VkFramebufferCreateInfo frameBufferCreate = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0, // VkFramebufferCreateFlags flags;
m_renderPass, // VkRenderPass renderPass;
(attachments[1] != VK_NULL_HANDLE) ? 2U : 1U, // uint32_t attachmentCount;
attachments.data(), // const VkImageView* pAttachments;
extent.width, // uint32_t width;
extent.height, // uint32_t height;
1U // uint32_t layers;
};
if (!imageData.frameBuffer.Create(m_device, frameBufferCreate))
{
NazaraError("Failed to create framebuffer for image #" + String::Number(i));
return false;
}
}
m_imageReadySemaphore.Create(m_device);
m_clock.Restart();
return true;
}
void RenderWindow::OnWindowDestroy()
{
m_images.clear();
m_renderPass.Destroy();
m_cmdPool.Destroy();
m_swapchain.Destroy();
m_surface.Destroy();
}
void RenderWindow::OnWindowResized()
{
OnRenderTargetSizeChange(this);
}
bool RenderWindow::SetupRenderPass(VkFormat colorFormat, VkFormat depthFormat)
{
std::array<VkAttachmentDescription, 2> attachments = {
{
{
0, // VkAttachmentDescriptionFlags flags;
colorFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
},
{
0, // VkAttachmentDescriptionFlags flags;
depthFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
},
}
};
VkAttachmentReference colorReference = {
0, // uint32_t attachment;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
VkAttachmentReference depthReference = {
1, // uint32_t attachment;
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
VkSubpassDescription subpass = {
0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
0U, // uint32_t inputAttachmentCount;
nullptr, // const VkAttachmentReference* pInputAttachments;
1U, // uint32_t colorAttachmentCount;
&colorReference, // const VkAttachmentReference* pColorAttachments;
nullptr, // const VkAttachmentReference* pResolveAttachments;
(depthFormat != VK_FORMAT_MAX_ENUM) ? &depthReference : nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
0U, // uint32_t preserveAttachmentCount;
nullptr // const uint32_t* pPreserveAttachments;
};
VkRenderPassCreateInfo createInfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
nullptr, // const void* pNext;
0, // VkRenderPassCreateFlags flags;
(depthFormat != VK_FORMAT_MAX_ENUM) ? 2U : 1U, // uint32_t attachmentCount;
attachments.data(), // const VkAttachmentDescription* pAttachments;
1U, // uint32_t subpassCount;
&subpass, // const VkSubpassDescription* pSubpasses;
0U, // uint32_t dependencyCount;
nullptr // const VkSubpassDependency* pDependencies;
};
return m_renderPass.Create(m_device, createInfo);
}
}