Vulkan/RenderTarget: Change interface to better suit needs
Former-commit-id: cc61462eca9a4b73821eb0c9bd10b74366e5a6ce [formerly 8e64df958d6b9ccd61b9df22456cd566947fcb0b] Former-commit-id: 750ea64ee603b0c52058eb93045310db4977dfdb
This commit is contained in:
parent
8d3680f4b9
commit
f1c5f8d0b7
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue