Swapchain code cleanup
Use references instead of pointers
This commit is contained in:
parent
372cab5779
commit
dcec337fa9
12 changed files with 65 additions and 85 deletions
|
|
@ -111,10 +111,9 @@ void VulkanRaytracingSample::setupFrameBuffer()
|
||||||
frameBufferCreateInfo.layers = 1;
|
frameBufferCreateInfo.layers = 1;
|
||||||
|
|
||||||
// Create frame buffers for every swap chain image
|
// Create frame buffers for every swap chain image
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.images.size());
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||||
{
|
attachments[0] = swapChain.imageViews[i];
|
||||||
attachments[0] = swapChain.buffers[i].view;
|
|
||||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
|
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ void VulkanSwapChain::setContext(VkInstance instance, VkPhysicalDevice physicalD
|
||||||
this->device = device;
|
this->device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanSwapChain::create(uint32_t *width, uint32_t *height, bool vsync, bool fullscreen)
|
void VulkanSwapChain::create(uint32_t& width, uint32_t& height, bool vsync, bool fullscreen)
|
||||||
{
|
{
|
||||||
assert(physicalDevice);
|
assert(physicalDevice);
|
||||||
assert(device);
|
assert(device);
|
||||||
|
|
@ -221,7 +221,24 @@ void VulkanSwapChain::create(uint32_t *width, uint32_t *height, bool vsync, bool
|
||||||
VkSurfaceCapabilitiesKHR surfCaps;
|
VkSurfaceCapabilitiesKHR surfCaps;
|
||||||
VK_CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps));
|
VK_CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfCaps));
|
||||||
|
|
||||||
// Get available present modes
|
VkExtent2D swapchainExtent = {};
|
||||||
|
// If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain
|
||||||
|
if (surfCaps.currentExtent.width == (uint32_t)-1)
|
||||||
|
{
|
||||||
|
// If the surface size is undefined, the size is set to the size of the images requested
|
||||||
|
swapchainExtent.width = width;
|
||||||
|
swapchainExtent.height = height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the surface size is defined, the swap chain size must match
|
||||||
|
swapchainExtent = surfCaps.currentExtent;
|
||||||
|
width = surfCaps.currentExtent.width;
|
||||||
|
height = surfCaps.currentExtent.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Select a present mode for the swapchain
|
||||||
uint32_t presentModeCount;
|
uint32_t presentModeCount;
|
||||||
VK_CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL));
|
VK_CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL));
|
||||||
assert(presentModeCount > 0);
|
assert(presentModeCount > 0);
|
||||||
|
|
@ -229,26 +246,6 @@ void VulkanSwapChain::create(uint32_t *width, uint32_t *height, bool vsync, bool
|
||||||
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
|
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
|
||||||
VK_CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data()));
|
VK_CHECK_RESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data()));
|
||||||
|
|
||||||
VkExtent2D swapchainExtent = {};
|
|
||||||
// If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain
|
|
||||||
if (surfCaps.currentExtent.width == (uint32_t)-1)
|
|
||||||
{
|
|
||||||
// If the surface size is undefined, the size is set to
|
|
||||||
// the size of the images requested.
|
|
||||||
swapchainExtent.width = *width;
|
|
||||||
swapchainExtent.height = *height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the surface size is defined, the swap chain size must match
|
|
||||||
swapchainExtent = surfCaps.currentExtent;
|
|
||||||
*width = surfCaps.currentExtent.width;
|
|
||||||
*height = surfCaps.currentExtent.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Select a present mode for the swapchain
|
|
||||||
|
|
||||||
// The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec
|
// The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec
|
||||||
// This mode waits for the vertical blank ("v-sync")
|
// This mode waits for the vertical blank ("v-sync")
|
||||||
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
|
@ -348,25 +345,23 @@ void VulkanSwapChain::create(uint32_t *width, uint32_t *height, bool vsync, bool
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain));
|
VK_CHECK_RESULT(vkCreateSwapchainKHR(device, &swapchainCI, nullptr, &swapChain));
|
||||||
|
|
||||||
// If an existing swap chain is re-created, destroy the old swap chain
|
// If an existing swap chain is re-created, destroy the old swap chain and the ressources owned by the application (image views, images are owned by the swap chain)
|
||||||
// This also cleans up all the presentable images
|
if (oldSwapchain != VK_NULL_HANDLE) {
|
||||||
if (oldSwapchain != VK_NULL_HANDLE)
|
for (auto i = 0; i < images.size(); i++) {
|
||||||
{
|
vkDestroyImageView(device, imageViews[i], nullptr);
|
||||||
for (uint32_t i = 0; i < imageCount; i++)
|
|
||||||
{
|
|
||||||
vkDestroyImageView(device, buffers[i].view, nullptr);
|
|
||||||
}
|
}
|
||||||
vkDestroySwapchainKHR(device, oldSwapchain, nullptr);
|
vkDestroySwapchainKHR(device, oldSwapchain, nullptr);
|
||||||
}
|
}
|
||||||
VK_CHECK_RESULT(vkGetSwapchainImagesKHR(device, swapChain, &imageCount, NULL));
|
uint32_t imageCount{ 0 };
|
||||||
|
VK_CHECK_RESULT(vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr));
|
||||||
|
|
||||||
// Get the swap chain images
|
// Get the swap chain images
|
||||||
images.resize(imageCount);
|
images.resize(imageCount);
|
||||||
VK_CHECK_RESULT(vkGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data()));
|
VK_CHECK_RESULT(vkGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data()));
|
||||||
|
|
||||||
// Get the swap chain buffers containing the image and imageview
|
// Get the swap chain buffers containing the image and imageview
|
||||||
buffers.resize(imageCount);
|
imageViews.resize(imageCount);
|
||||||
for (uint32_t i = 0; i < imageCount; i++)
|
for (auto i = 0; i < images.size(); i++)
|
||||||
{
|
{
|
||||||
VkImageViewCreateInfo colorAttachmentView = {};
|
VkImageViewCreateInfo colorAttachmentView = {};
|
||||||
colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
|
@ -385,20 +380,16 @@ void VulkanSwapChain::create(uint32_t *width, uint32_t *height, bool vsync, bool
|
||||||
colorAttachmentView.subresourceRange.layerCount = 1;
|
colorAttachmentView.subresourceRange.layerCount = 1;
|
||||||
colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
colorAttachmentView.flags = 0;
|
colorAttachmentView.flags = 0;
|
||||||
|
colorAttachmentView.image = images[i];
|
||||||
buffers[i].image = images[i];
|
VK_CHECK_RESULT(vkCreateImageView(device, &colorAttachmentView, nullptr, &imageViews[i]));
|
||||||
|
|
||||||
colorAttachmentView.image = buffers[i].image;
|
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateImageView(device, &colorAttachmentView, nullptr, &buffers[i].view));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult VulkanSwapChain::acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t *imageIndex)
|
VkResult VulkanSwapChain::acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t& imageIndex)
|
||||||
{
|
{
|
||||||
// By setting timeout to UINT64_MAX we will always wait until the next image has been acquired or an actual error is thrown
|
// By setting timeout to UINT64_MAX we will always wait until the next image has been acquired or an actual error is thrown
|
||||||
// With that we don't have to handle VK_NOT_READY
|
// With that we don't have to handle VK_NOT_READY
|
||||||
return vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, presentCompleteSemaphore, (VkFence)nullptr, imageIndex);
|
return vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, presentCompleteSemaphore, (VkFence)nullptr, &imageIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult VulkanSwapChain::queuePresent(VkQueue queue, uint32_t imageIndex, VkSemaphore waitSemaphore)
|
VkResult VulkanSwapChain::queuePresent(VkQueue queue, uint32_t imageIndex, VkSemaphore waitSemaphore)
|
||||||
|
|
@ -421,16 +412,13 @@ VkResult VulkanSwapChain::queuePresent(VkQueue queue, uint32_t imageIndex, VkSem
|
||||||
|
|
||||||
void VulkanSwapChain::cleanup()
|
void VulkanSwapChain::cleanup()
|
||||||
{
|
{
|
||||||
if (swapChain != VK_NULL_HANDLE)
|
if (swapChain != VK_NULL_HANDLE) {
|
||||||
{
|
for (auto i = 0; i < images.size(); i++) {
|
||||||
for (uint32_t i = 0; i < imageCount; i++)
|
vkDestroyImageView(device, imageViews[i], nullptr);
|
||||||
{
|
|
||||||
vkDestroyImageView(device, buffers[i].view, nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (surface != VK_NULL_HANDLE)
|
|
||||||
{
|
|
||||||
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
||||||
|
}
|
||||||
|
if (surface != VK_NULL_HANDLE) {
|
||||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||||
}
|
}
|
||||||
surface = VK_NULL_HANDLE;
|
surface = VK_NULL_HANDLE;
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,6 @@
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _SwapChainBuffers {
|
|
||||||
VkImage image{ VK_NULL_HANDLE };
|
|
||||||
VkImageView view{ VK_NULL_HANDLE };
|
|
||||||
} SwapChainBuffer;
|
|
||||||
|
|
||||||
class VulkanSwapChain
|
class VulkanSwapChain
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -43,9 +38,8 @@ public:
|
||||||
VkFormat colorFormat{};
|
VkFormat colorFormat{};
|
||||||
VkColorSpaceKHR colorSpace{};
|
VkColorSpaceKHR colorSpace{};
|
||||||
VkSwapchainKHR swapChain{ VK_NULL_HANDLE };
|
VkSwapchainKHR swapChain{ VK_NULL_HANDLE };
|
||||||
uint32_t imageCount;
|
|
||||||
std::vector<VkImage> images{};
|
std::vector<VkImage> images{};
|
||||||
std::vector<SwapChainBuffer> buffers{};
|
std::vector<VkImageView> imageViews{};
|
||||||
uint32_t queueNodeIndex{ UINT32_MAX };
|
uint32_t queueNodeIndex{ UINT32_MAX };
|
||||||
|
|
||||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||||
|
|
@ -79,7 +73,7 @@ public:
|
||||||
* @param height Pointer to the height of the swapchain (may be adjusted to fit the requirements of the swapchain)
|
* @param height Pointer to the height of the swapchain (may be adjusted to fit the requirements of the swapchain)
|
||||||
* @param vsync (Optional, default = false) Can be used to force vsync-ed rendering (by using VK_PRESENT_MODE_FIFO_KHR as presentation mode)
|
* @param vsync (Optional, default = false) Can be used to force vsync-ed rendering (by using VK_PRESENT_MODE_FIFO_KHR as presentation mode)
|
||||||
*/
|
*/
|
||||||
void create(uint32_t* width, uint32_t* height, bool vsync = false, bool fullscreen = false);
|
void create(uint32_t& width, uint32_t& height, bool vsync = false, bool fullscreen = false);
|
||||||
/**
|
/**
|
||||||
* Acquires the next image in the swap chain
|
* Acquires the next image in the swap chain
|
||||||
*
|
*
|
||||||
|
|
@ -90,7 +84,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return VkResult of the image acquisition
|
* @return VkResult of the image acquisition
|
||||||
*/
|
*/
|
||||||
VkResult acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t* imageIndex);
|
VkResult acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t& imageIndex);
|
||||||
/**
|
/**
|
||||||
* Queue an image for presentation
|
* Queue an image for presentation
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ std::string VulkanExampleBase::getWindowTitle() const
|
||||||
void VulkanExampleBase::createCommandBuffers()
|
void VulkanExampleBase::createCommandBuffers()
|
||||||
{
|
{
|
||||||
// Create one command buffer for each swap chain image
|
// Create one command buffer for each swap chain image
|
||||||
drawCmdBuffers.resize(swapChain.imageCount);
|
drawCmdBuffers.resize(swapChain.images.size());
|
||||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, drawCmdBuffers.data()));
|
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, drawCmdBuffers.data()));
|
||||||
}
|
}
|
||||||
|
|
@ -751,7 +751,7 @@ void VulkanExampleBase::drawUI(const VkCommandBuffer commandBuffer)
|
||||||
void VulkanExampleBase::prepareFrame()
|
void VulkanExampleBase::prepareFrame()
|
||||||
{
|
{
|
||||||
// Acquire the next image from the swap chain
|
// Acquire the next image from the swap chain
|
||||||
VkResult result = swapChain.acquireNextImage(semaphores.presentComplete, ¤tBuffer);
|
VkResult result = swapChain.acquireNextImage(semaphores.presentComplete, currentBuffer);
|
||||||
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE)
|
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE)
|
||||||
// SRS - If no longer optimal (VK_SUBOPTIMAL_KHR), wait until submitFrame() in case number of swapchain images will change on resize
|
// SRS - If no longer optimal (VK_SUBOPTIMAL_KHR), wait until submitFrame() in case number of swapchain images will change on resize
|
||||||
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
|
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
|
||||||
|
|
@ -3077,11 +3077,11 @@ void VulkanExampleBase::setupDepthStencil()
|
||||||
void VulkanExampleBase::setupFrameBuffer()
|
void VulkanExampleBase::setupFrameBuffer()
|
||||||
{
|
{
|
||||||
// Create frame buffers for every swap chain image
|
// Create frame buffers for every swap chain image
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.images.size());
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
||||||
{
|
{
|
||||||
const VkImageView attachments[2] = {
|
const VkImageView attachments[2] = {
|
||||||
swapChain.buffers[i].view,
|
swapChain.imageViews[i],
|
||||||
// Depth/Stencil attachment is the same for all frame buffers
|
// Depth/Stencil attachment is the same for all frame buffers
|
||||||
depthStencil.view
|
depthStencil.view
|
||||||
};
|
};
|
||||||
|
|
@ -3290,7 +3290,7 @@ void VulkanExampleBase::createSurface()
|
||||||
|
|
||||||
void VulkanExampleBase::createSwapChain()
|
void VulkanExampleBase::createSwapChain()
|
||||||
{
|
{
|
||||||
swapChain.create(&width, &height, settings.vsync, settings.fullscreen);
|
swapChain.create(width, height, settings.vsync, settings.fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanExampleBase::OnUpdateUIOverlay(vks::UIOverlay *overlay) {}
|
void VulkanExampleBase::OnUpdateUIOverlay(vks::UIOverlay *overlay) {}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ public:
|
||||||
// This set of barriers prepares the color and depth images for output
|
// This set of barriers prepares the color and depth images for output
|
||||||
vks::tools::insertImageMemoryBarrier(
|
vks::tools::insertImageMemoryBarrier(
|
||||||
drawCmdBuffers[i],
|
drawCmdBuffers[i],
|
||||||
swapChain.buffers[i].image,
|
swapChain.images[i],
|
||||||
0,
|
0,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
|
@ -126,7 +126,7 @@ public:
|
||||||
// New structures are used to define the attachments used in dynamic rendering
|
// New structures are used to define the attachments used in dynamic rendering
|
||||||
VkRenderingAttachmentInfoKHR colorAttachment{};
|
VkRenderingAttachmentInfoKHR colorAttachment{};
|
||||||
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||||
colorAttachment.imageView = swapChain.buffers[i].view;
|
colorAttachment.imageView = swapChain.imageViews[i];
|
||||||
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
|
@ -173,7 +173,7 @@ public:
|
||||||
// This set of barriers prepares the color image for presentation, we don't need to care for the depth image
|
// This set of barriers prepares the color image for presentation, we don't need to care for the depth image
|
||||||
vks::tools::insertImageMemoryBarrier(
|
vks::tools::insertImageMemoryBarrier(
|
||||||
drawCmdBuffers[i],
|
drawCmdBuffers[i],
|
||||||
swapChain.buffers[i].image,
|
swapChain.images[i],
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
0,
|
0,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ public:
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.imageCount);
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
||||||
{
|
{
|
||||||
views[0] = swapChain.buffers[i].view;
|
views[0] = swapChain.imageViews[i];
|
||||||
views[1] = attachments[i].color.view;
|
views[1] = attachments[i].color.view;
|
||||||
views[2] = attachments[i].depth.view;
|
views[2] = attachments[i].depth.view;
|
||||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i]));
|
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i]));
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ public:
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.imageCount);
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
||||||
{
|
{
|
||||||
attachments[1] = swapChain.buffers[i].view;
|
attachments[1] = swapChain.imageViews[i];
|
||||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
|
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -268,11 +268,11 @@ public:
|
||||||
for (int32_t i = 0; i < drawCmdBuffers.size(); ++i)
|
for (int32_t i = 0; i < drawCmdBuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));
|
VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));
|
||||||
|
|
||||||
// Transition color and depth images for drawing
|
// Transition color and depth images for drawing
|
||||||
vks::tools::insertImageMemoryBarrier(
|
vks::tools::insertImageMemoryBarrier(
|
||||||
drawCmdBuffers[i],
|
drawCmdBuffers[i],
|
||||||
swapChain.buffers[i].image,
|
swapChain.images[i],
|
||||||
0,
|
0,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
|
@ -294,7 +294,7 @@ public:
|
||||||
// New structures are used to define the attachments used in dynamic rendering
|
// New structures are used to define the attachments used in dynamic rendering
|
||||||
VkRenderingAttachmentInfoKHR colorAttachment{};
|
VkRenderingAttachmentInfoKHR colorAttachment{};
|
||||||
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||||
colorAttachment.imageView = swapChain.buffers[i].view;
|
colorAttachment.imageView = swapChain.imageViews[i];
|
||||||
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
|
@ -385,7 +385,7 @@ public:
|
||||||
// Transition color image for presentation
|
// Transition color image for presentation
|
||||||
vks::tools::insertImageMemoryBarrier(
|
vks::tools::insertImageMemoryBarrier(
|
||||||
drawCmdBuffers[i],
|
drawCmdBuffers[i],
|
||||||
swapChain.buffers[i].image,
|
swapChain.images[i],
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
0,
|
0,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ public:
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.imageCount);
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
||||||
{
|
{
|
||||||
attachments[0] = swapChain.buffers[i].view;
|
attachments[0] = swapChain.imageViews[i];
|
||||||
attachments[1] = this->attachments.position.view;
|
attachments[1] = this->attachments.position.view;
|
||||||
attachments[2] = this->attachments.normal.view;
|
attachments[2] = this->attachments.normal.view;
|
||||||
attachments[3] = this->attachments.albedo.view;
|
attachments[3] = this->attachments.albedo.view;
|
||||||
|
|
|
||||||
|
|
@ -510,7 +510,7 @@ public:
|
||||||
{
|
{
|
||||||
std::array<VkImageView, 2> attachments{};
|
std::array<VkImageView, 2> attachments{};
|
||||||
// Color attachment is the view of the swapchain image
|
// Color attachment is the view of the swapchain image
|
||||||
attachments[0] = swapChain.buffers[i].view;
|
attachments[0] = swapChain.imageViews[i];
|
||||||
// Depth/Stencil attachment is the same for all frame buffers due to how depth works with current GPUs
|
// Depth/Stencil attachment is the same for all frame buffers due to how depth works with current GPUs
|
||||||
attachments[1] = depthStencil.view;
|
attachments[1] = depthStencil.view;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -705,13 +705,13 @@ public:
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffer, &cmdBufInfo));
|
VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffer, &cmdBufInfo));
|
||||||
|
|
||||||
// With dynamic rendering we need to explicitly add layout transitions by using barriers, this set of barriers prepares the color and depth images for output
|
// With dynamic rendering we need to explicitly add layout transitions by using barriers, this set of barriers prepares the color and depth images for output
|
||||||
vks::tools::insertImageMemoryBarrier(commandBuffer, swapChain.buffers[imageIndex].image, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
vks::tools::insertImageMemoryBarrier(commandBuffer, swapChain.images[imageIndex], 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||||
vks::tools::insertImageMemoryBarrier(commandBuffer, depthStencil.image, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1 });
|
vks::tools::insertImageMemoryBarrier(commandBuffer, depthStencil.image, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1 });
|
||||||
|
|
||||||
// New structures are used to define the attachments used in dynamic rendering
|
// New structures are used to define the attachments used in dynamic rendering
|
||||||
// Color attachment
|
// Color attachment
|
||||||
VkRenderingAttachmentInfo colorAttachment{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
|
VkRenderingAttachmentInfo colorAttachment{ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
|
||||||
colorAttachment.imageView = swapChain.buffers[imageIndex].view;
|
colorAttachment.imageView = swapChain.imageViews[imageIndex];
|
||||||
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
|
@ -755,7 +755,7 @@ public:
|
||||||
vkCmdEndRendering(commandBuffer);
|
vkCmdEndRendering(commandBuffer);
|
||||||
|
|
||||||
// This barrier prepares the color image for presentation, we don't need to care for the depth image
|
// This barrier prepares the color image for presentation, we don't need to care for the depth image
|
||||||
vks::tools::insertImageMemoryBarrier(commandBuffer, swapChain.buffers[imageIndex].image, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_NONE, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
vks::tools::insertImageMemoryBarrier(commandBuffer, swapChain.images[imageIndex], VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_NONE, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||||
VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer));
|
VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer));
|
||||||
|
|
||||||
// Submit the command buffer to the graphics queue
|
// Submit the command buffer to the graphics queue
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Vulkan Example - Variable rate shading
|
* Vulkan Example - Variable rate shading
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2020-2024 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
@ -91,10 +91,9 @@ void VulkanExample::setupFrameBuffer()
|
||||||
frameBufferCreateInfo.layers = 1;
|
frameBufferCreateInfo.layers = 1;
|
||||||
|
|
||||||
// Create frame buffers for every swap chain image
|
// Create frame buffers for every swap chain image
|
||||||
frameBuffers.resize(swapChain.imageCount);
|
frameBuffers.resize(swapChain.images.size());
|
||||||
for (uint32_t i = 0; i < frameBuffers.size(); i++)
|
for (uint32_t i = 0; i < frameBuffers.size(); i++) {
|
||||||
{
|
attachments[0] = swapChain.imageViews[i];
|
||||||
attachments[0] = swapChain.buffers[i].view;
|
|
||||||
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
|
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue