Disabled framebuffer caching by physical device
Swapchain is now capable of being recreated in a partially automatic manner (some effort is still required on the developer's side still) Windows are now allowed to be resizeable Updated main program to support resizable windows
This commit is contained in:
@@ -18,9 +18,10 @@ namespace basalt
|
|||||||
const std::initializer_list<VkPresentModeKHR> allowed_present_modes);
|
const std::initializer_list<VkPresentModeKHR> allowed_present_modes);
|
||||||
~Swapchain();
|
~Swapchain();
|
||||||
|
|
||||||
|
void recreate(VkRenderPass new_renderpass=VK_NULL_HANDLE);
|
||||||
|
|
||||||
void create_framebuffers(VkRenderPass render_pass);
|
void create_framebuffers(VkRenderPass render_pass);
|
||||||
void wait_and_reset(bool wait_all=VK_TRUE, u64 timeout=UINT64_MAX);
|
u32 wait_acquire_reset(bool wait_all=VK_TRUE, u64 timeout=UINT64_MAX, VkFence fence=VK_NULL_HANDLE);
|
||||||
u32 acquire_next_image(VkFence fence=VK_NULL_HANDLE, u64 timeout=UINT64_MAX);
|
|
||||||
|
|
||||||
basalt::darray<VkSemaphore> semaphores_image_available;
|
basalt::darray<VkSemaphore> semaphores_image_available;
|
||||||
basalt::darray<VkSemaphore> semaphores_render_finished;
|
basalt::darray<VkSemaphore> semaphores_render_finished;
|
||||||
@@ -36,5 +37,9 @@ namespace basalt
|
|||||||
u32 image_count = -1;
|
u32 image_count = -1;
|
||||||
u32 max_frames_in_flight = 2;
|
u32 max_frames_in_flight = 2;
|
||||||
u32 current_frame = 0;
|
u32 current_frame = 0;
|
||||||
|
bool framebuffers_created = false;
|
||||||
|
private:
|
||||||
|
void create (const std::initializer_list<VkSurfaceFormatKHR>& allowed_formats,
|
||||||
|
const std::initializer_list<VkPresentModeKHR> allowed_present_modes, VkSwapchainKHR prev_swapchain=VK_NULL_HANDLE);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -404,8 +404,6 @@ VkPresentModeKHR basalt::SwapchainSupportDetails::get_present_mode(const std::in
|
|||||||
|
|
||||||
VkExtent2D basalt::SwapchainSupportDetails::get_framebuffer_extent(basalt::Window& window)
|
VkExtent2D basalt::SwapchainSupportDetails::get_framebuffer_extent(basalt::Window& window)
|
||||||
{
|
{
|
||||||
if (this->surface_capabilities.currentExtent.width != -1)
|
|
||||||
return this->surface_capabilities.currentExtent;
|
|
||||||
i32 width, height;
|
i32 width, height;
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
VkExtent2D ext = {
|
VkExtent2D ext = {
|
||||||
|
|||||||
@@ -11,70 +11,10 @@ basalt::Swapchain::Swapchain(basalt::Device& device, basalt::Window& window,
|
|||||||
semaphores_render_finished(MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_ENGINE | MEMORY_TAG_ALIGN_ANY),
|
semaphores_render_finished(MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_ENGINE | MEMORY_TAG_ALIGN_ANY),
|
||||||
fences_in_flight(MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_ENGINE | MEMORY_TAG_ALIGN_ANY)
|
fences_in_flight(MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_ENGINE | MEMORY_TAG_ALIGN_ANY)
|
||||||
{
|
{
|
||||||
this->image_count = details.surface_capabilities.minImageCount + 1;
|
this->framebuffers_created = false;
|
||||||
BCLAMP(this->image_count, details.surface_capabilities.minImageCount, details.surface_capabilities.maxImageCount);
|
this->create(allowed_formats, allowed_present_modes, VK_NULL_HANDLE);
|
||||||
if (this->image_count == 0)
|
|
||||||
this->image_count = details.surface_capabilities.minImageCount + 1;
|
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR ci = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR};
|
|
||||||
ci.surface = window;
|
|
||||||
ci.minImageCount = this->image_count;
|
|
||||||
ci.imageFormat = details.get_surface_format(allowed_formats).format;
|
|
||||||
ci.imageColorSpace = details.get_surface_format(allowed_formats).colorSpace;
|
|
||||||
ci.imageExtent = details.get_framebuffer_extent(window);
|
|
||||||
ci.imageArrayLayers = 1;
|
|
||||||
ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
ci.presentMode = details.get_present_mode(allowed_present_modes);
|
|
||||||
ci.clipped = VK_TRUE;
|
|
||||||
ci.oldSwapchain = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
ci.preTransform = details.surface_capabilities.currentTransform;
|
|
||||||
ci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
|
||||||
u32 queue_family_indicies[] = { device.phys->indicies.graphics, device.phys->indicies.present };
|
|
||||||
if (device.phys->indicies.graphics == device.phys->indicies.present)
|
|
||||||
{
|
|
||||||
ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
ci.queueFamilyIndexCount = 0;
|
|
||||||
ci.pQueueFamilyIndices = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ci.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
|
||||||
ci.queueFamilyIndexCount = sizeof(queue_family_indicies)/sizeof(queue_family_indicies[0]);
|
|
||||||
ci.pQueueFamilyIndices = queue_family_indicies;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkResult err = VK_SUCCESS;
|
VkResult err = VK_SUCCESS;
|
||||||
this->swapchain_extent = ci.imageExtent;
|
|
||||||
VK_ASSERT(vkCreateSwapchainKHR(device, &ci, device.ctx->vk_alloc, &this->swapchain), "Failed to create swapchain\n\tAt %s:%d\n\tError %s\n");
|
|
||||||
|
|
||||||
u32 n_images = 0;
|
|
||||||
vkGetSwapchainImagesKHR(device, this->swapchain, &n_images, nullptr);
|
|
||||||
this->swapchain_images.resize(n_images);
|
|
||||||
vkGetSwapchainImagesKHR(device, this->swapchain, &n_images, this->swapchain_images.m_pdata);
|
|
||||||
this->swapchain_images.resize(n_images);
|
|
||||||
|
|
||||||
this->swapchain_image_views.reserve(n_images);
|
|
||||||
for (u32 i = 0; i < n_images; ++i)
|
|
||||||
{
|
|
||||||
VkImageViewCreateInfo view_ci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
|
||||||
view_ci.image = swapchain_images[i];
|
|
||||||
view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
view_ci.format = this->details.cached_format.format;
|
|
||||||
view_ci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
view_ci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
view_ci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
view_ci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
view_ci.subresourceRange.baseMipLevel = 0;
|
|
||||||
view_ci.subresourceRange.levelCount = 1;
|
|
||||||
view_ci.subresourceRange.baseArrayLayer = 0;
|
|
||||||
view_ci.subresourceRange.layerCount = 1;
|
|
||||||
|
|
||||||
VK_ASSERT(vkCreateImageView(device, &view_ci, device.ctx->vk_alloc, &swapchain_image_views[i]), "Failed to create image view\n\tAt %s:%d\n\tError %s\n\tImage index: %u\n", i);
|
|
||||||
}
|
|
||||||
swapchain_image_views.m_nelements = n_images;
|
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphore_ci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
|
VkSemaphoreCreateInfo semaphore_ci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
|
||||||
VkFenceCreateInfo fence_ci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
|
VkFenceCreateInfo fence_ci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
|
||||||
fence_ci.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
fence_ci.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
@@ -110,10 +50,28 @@ basalt::Swapchain::~Swapchain()
|
|||||||
vkDestroySwapchainKHR(*device, this->swapchain, device->ctx->vk_alloc);
|
vkDestroySwapchainKHR(*device, this->swapchain, device->ctx->vk_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void basalt::Swapchain::recreate(VkRenderPass new_renderpass)
|
||||||
|
{
|
||||||
|
swapchain_extent = details.get_framebuffer_extent(*window);
|
||||||
|
if (swapchain_extent.width == 0 || swapchain_extent.height == 0)
|
||||||
|
return;
|
||||||
|
vkDeviceWaitIdle(device->logical);
|
||||||
|
|
||||||
|
for (VkImageView& view : this->swapchain_image_views)
|
||||||
|
vkDestroyImageView(*this->device, view, this->device->ctx->vk_alloc);
|
||||||
|
vkDestroySwapchainKHR(*device, this->swapchain, device->ctx->vk_alloc);
|
||||||
|
|
||||||
|
// TODO: store the prefered format/present list and use them
|
||||||
|
this->create({ details.cached_format }, { details.cached_present_mode }, VK_NULL_HANDLE);
|
||||||
|
if (new_renderpass != VK_NULL_HANDLE)
|
||||||
|
this->create_framebuffers(new_renderpass);
|
||||||
|
}
|
||||||
|
|
||||||
void basalt::Swapchain::create_framebuffers(VkRenderPass render_pass)
|
void basalt::Swapchain::create_framebuffers(VkRenderPass render_pass)
|
||||||
{
|
{
|
||||||
if (framebuffers.m_nelements != 0)
|
if (framebuffers.m_nelements != 0 || framebuffers_created)
|
||||||
{
|
{
|
||||||
|
vkDeviceWaitIdle(*device);
|
||||||
for (VkFramebuffer& buffer : framebuffers)
|
for (VkFramebuffer& buffer : framebuffers)
|
||||||
vkDestroyFramebuffer(*device, buffer, device->ctx->vk_alloc);
|
vkDestroyFramebuffer(*device, buffer, device->ctx->vk_alloc);
|
||||||
}
|
}
|
||||||
@@ -133,17 +91,92 @@ void basalt::Swapchain::create_framebuffers(VkRenderPass render_pass)
|
|||||||
VK_ASSERT(vkCreateFramebuffer(*device, &ci, device->ctx->vk_alloc, framebuffers.m_pdata+i), "Failed to create framebuffer\n\tAt %s:%d\n\tError %s\n\tIndex: %llu\n", i);
|
VK_ASSERT(vkCreateFramebuffer(*device, &ci, device->ctx->vk_alloc, framebuffers.m_pdata+i), "Failed to create framebuffer\n\tAt %s:%d\n\tError %s\n\tIndex: %llu\n", i);
|
||||||
}
|
}
|
||||||
framebuffers.m_nelements = swapchain_image_views.m_nelements;
|
framebuffers.m_nelements = swapchain_image_views.m_nelements;
|
||||||
|
framebuffers_created = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void basalt::Swapchain::wait_and_reset(bool wait_all, u64 timeout)
|
u32 basalt::Swapchain::wait_acquire_reset(bool wait_all, u64 timeout, VkFence fence)
|
||||||
{
|
{
|
||||||
|
if (!framebuffers_created)
|
||||||
|
return - 1;
|
||||||
vkWaitForFences(device->logical, 1, &fences_in_flight.m_pdata[current_frame], wait_all, timeout);
|
vkWaitForFences(device->logical, 1, &fences_in_flight.m_pdata[current_frame], wait_all, timeout);
|
||||||
vkResetFences(device->logical, 1, &fences_in_flight.m_pdata[current_frame]);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 basalt::Swapchain::acquire_next_image(VkFence fence, u64 timeout)
|
|
||||||
{
|
|
||||||
u32 img = -1;
|
u32 img = -1;
|
||||||
vkAcquireNextImageKHR(device->logical, swapchain, timeout, semaphores_image_available[current_frame], fence, &img);
|
VkResult err = vkAcquireNextImageKHR(device->logical, swapchain, timeout, semaphores_image_available[current_frame], fence, &img);
|
||||||
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
|
{
|
||||||
|
framebuffers_created = false;
|
||||||
|
this->recreate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
BASSERT_FATAL(err == VK_SUCCESS, "Assertion %s failed\n\tFailed to acquire next image of swapchain\n\tAt %s:%d\n\tError %s\n\tSwapchain %p (%p)\n", string_VkResult(err), this, this->swapchain);
|
||||||
|
vkResetFences(device->logical, 1, &fences_in_flight.m_pdata[current_frame]);
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void basalt::Swapchain::create(const std::initializer_list<VkSurfaceFormatKHR>& allowed_formats,
|
||||||
|
const std::initializer_list<VkPresentModeKHR> allowed_present_modes, VkSwapchainKHR prev_swapchain)
|
||||||
|
{
|
||||||
|
this->image_count = details.surface_capabilities.minImageCount + 1;
|
||||||
|
BCLAMP(this->image_count, details.surface_capabilities.minImageCount, details.surface_capabilities.maxImageCount);
|
||||||
|
if (this->image_count == 0)
|
||||||
|
this->image_count = details.surface_capabilities.minImageCount + 1;
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR ci = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
|
||||||
|
ci.surface = *window;
|
||||||
|
ci.minImageCount = this->image_count;
|
||||||
|
ci.imageFormat = details.get_surface_format(allowed_formats).format;
|
||||||
|
ci.imageColorSpace = details.get_surface_format(allowed_formats).colorSpace;
|
||||||
|
ci.imageExtent = details.get_framebuffer_extent(*window);
|
||||||
|
ci.imageArrayLayers = 1;
|
||||||
|
ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
ci.presentMode = details.get_present_mode(allowed_present_modes);
|
||||||
|
ci.clipped = VK_TRUE;
|
||||||
|
ci.oldSwapchain = prev_swapchain;
|
||||||
|
|
||||||
|
ci.preTransform = details.surface_capabilities.currentTransform;
|
||||||
|
ci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
u32 queue_family_indicies[] = { device->phys->indicies.graphics, device->phys->indicies.present };
|
||||||
|
if (device->phys->indicies.graphics == device->phys->indicies.present)
|
||||||
|
{
|
||||||
|
ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
ci.queueFamilyIndexCount = 0;
|
||||||
|
ci.pQueueFamilyIndices = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ci.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
ci.queueFamilyIndexCount = sizeof(queue_family_indicies) / sizeof(queue_family_indicies[0]);
|
||||||
|
ci.pQueueFamilyIndices = queue_family_indicies;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult err = VK_SUCCESS;
|
||||||
|
this->swapchain_extent = ci.imageExtent;
|
||||||
|
VK_ASSERT(vkCreateSwapchainKHR(device->logical, &ci, device->ctx->vk_alloc, &this->swapchain), "Failed to create swapchain\n\tAt %s:%d\n\tError %s\n");
|
||||||
|
|
||||||
|
u32 n_images = 0;
|
||||||
|
vkGetSwapchainImagesKHR(device->logical, this->swapchain, &n_images, nullptr);
|
||||||
|
this->swapchain_images.resize(n_images);
|
||||||
|
vkGetSwapchainImagesKHR(device->logical, this->swapchain, &n_images, this->swapchain_images.m_pdata);
|
||||||
|
this->swapchain_images.resize(n_images);
|
||||||
|
|
||||||
|
this->swapchain_image_views.reserve(n_images);
|
||||||
|
for (u32 i = 0; i < n_images; ++i)
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo view_ci = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||||
|
view_ci.image = swapchain_images[i];
|
||||||
|
view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
view_ci.format = this->details.cached_format.format;
|
||||||
|
view_ci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
view_ci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
view_ci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
view_ci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
view_ci.subresourceRange.baseMipLevel = 0;
|
||||||
|
view_ci.subresourceRange.levelCount = 1;
|
||||||
|
view_ci.subresourceRange.baseArrayLayer = 0;
|
||||||
|
view_ci.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
VK_ASSERT(vkCreateImageView(device->logical, &view_ci, device->ctx->vk_alloc, &swapchain_image_views[i]), "Failed to create image view\n\tAt %s:%d\n\tError %s\n\tImage index: %u\n", i);
|
||||||
|
}
|
||||||
|
swapchain_image_views.m_nelements = n_images;
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ basalt::Window::Window(basalt::Context& ctx, uint16_t width, uint16_t height, co
|
|||||||
{
|
{
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
|
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
|
||||||
this->window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
this->window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||||||
VkResult err = VK_SUCCESS;
|
VkResult err = VK_SUCCESS;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "vulkan/basalt_command_buffer.h"
|
#include "vulkan/basalt_command_buffer.h"
|
||||||
#include "vulkan/basalt_swapchain.h"
|
#include "vulkan/basalt_swapchain.h"
|
||||||
|
|
||||||
|
void framebuffer_resized(GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
void application()
|
void application()
|
||||||
{
|
{
|
||||||
basalt::Context ctx("Basic",
|
basalt::Context ctx("Basic",
|
||||||
@@ -11,7 +13,10 @@ void application()
|
|||||||
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
|
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
|
||||||
}, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_ANY)
|
}, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_ANY)
|
||||||
);
|
);
|
||||||
basalt::Window window(ctx, 640, 480, "Hello Vulkan!");;
|
basalt::Window window(ctx, 640, 480, "Hello Vulkan!");
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_resized);
|
||||||
|
glfwSetWindowUserPointer(window, nullptr);
|
||||||
|
|
||||||
basalt::PhysicalDevice phy_dev = basalt::PhysicalDeviceSelector(ctx, window)
|
basalt::PhysicalDevice phy_dev = basalt::PhysicalDeviceSelector(ctx, window)
|
||||||
.prefer_types(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 2.0f, 0.0f)
|
.prefer_types(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 2.0f, 0.0f)
|
||||||
.prefer_types(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, 1.0f, 0.0f)
|
.prefer_types(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, 1.0f, 0.0f)
|
||||||
@@ -32,6 +37,8 @@ void application()
|
|||||||
{ {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR} },
|
{ {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR} },
|
||||||
{ VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR }
|
{ VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR }
|
||||||
);
|
);
|
||||||
|
glfwSetWindowUserPointer(window, &swapchain);
|
||||||
|
|
||||||
basalt::RenderPass pass = basalt::RenderPassBuilder(dev)
|
basalt::RenderPass pass = basalt::RenderPassBuilder(dev)
|
||||||
.add_attachment({
|
.add_attachment({
|
||||||
.format = swapchain.details.cached_format.format,
|
.format = swapchain.details.cached_format.format,
|
||||||
@@ -105,8 +112,13 @@ void application()
|
|||||||
{
|
{
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
swapchain.wait_and_reset();
|
u32 image_index = swapchain.wait_acquire_reset();
|
||||||
u32 image_index = swapchain.acquire_next_image();
|
if (image_index == -1 || !swapchain.framebuffers_created)
|
||||||
|
{
|
||||||
|
swapchain.create_framebuffers(pass.render_pass);
|
||||||
|
swapchain.current_frame = (swapchain.current_frame + 1) % swapchain.max_frames_in_flight;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cmdbufs[swapchain.current_frame].reset();
|
cmdbufs[swapchain.current_frame].reset();
|
||||||
cmdbufs[swapchain.current_frame].start(pass, swapchain.framebuffers[image_index], render_area);
|
cmdbufs[swapchain.current_frame].start(pass, swapchain.framebuffers[image_index], render_area);
|
||||||
@@ -138,10 +150,17 @@ void application()
|
|||||||
present_info.pSwapchains = &swapchain.swapchain;
|
present_info.pSwapchains = &swapchain.swapchain;
|
||||||
present_info.pImageIndices = &image_index;
|
present_info.pImageIndices = &image_index;
|
||||||
|
|
||||||
VK_ASSERT(vkQueuePresentKHR(dev.queues[1].queue, &present_info), "Failed to queue presentation of rendered frame\n\tAt %s:%d\n\tError %s\n");
|
VkResult err = vkQueuePresentKHR(dev.queues[1].queue, &present_info);
|
||||||
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
|
{
|
||||||
|
swapchain.framebuffers_created = false;
|
||||||
|
swapchain.current_frame = (swapchain.current_frame + 1) % swapchain.max_frames_in_flight;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VK_ASSERT(err, "Failed to queue presentation of rendered frame\n\tAt %s:%d\n\tError %s\n");
|
||||||
swapchain.current_frame = (swapchain.current_frame + 1) % swapchain.max_frames_in_flight;
|
swapchain.current_frame = (swapchain.current_frame + 1) % swapchain.max_frames_in_flight;
|
||||||
}
|
}
|
||||||
cmdbufs.resize(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -166,3 +185,10 @@ int main()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void framebuffer_resized(GLFWwindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
basalt::Swapchain* swapchain = (basalt::Swapchain*)glfwGetWindowUserPointer(window);
|
||||||
|
if (swapchain == nullptr)
|
||||||
|
return;
|
||||||
|
swapchain->framebuffers_created = false;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user