[Bf-blender-cvs] [5629ff5f695] tmp-vulkan: GHOST: Vulkan: Support window resizing
Clément Foucault
noreply at git.blender.org
Fri Jul 24 22:09:21 CEST 2020
Commit: 5629ff5f6953385b74d03aa93121c85a484d2348
Author: Clément Foucault
Date: Fri Jul 24 19:50:42 2020 +0200
Branches: tmp-vulkan
https://developer.blender.org/rB5629ff5f6953385b74d03aa93121c85a484d2348
GHOST: Vulkan: Support window resizing
===================================================================
M intern/ghost/intern/GHOST_ContextVK.cpp
M intern/ghost/intern/GHOST_ContextVK.h
===================================================================
diff --git a/intern/ghost/intern/GHOST_ContextVK.cpp b/intern/ghost/intern/GHOST_ContextVK.cpp
index a4ac9f1262b..48940a6d6d7 100644
--- a/intern/ghost/intern/GHOST_ContextVK.cpp
+++ b/intern/ghost/intern/GHOST_ContextVK.cpp
@@ -154,6 +154,30 @@ GHOST_ContextVK::~GHOST_ContextVK()
vkDeviceWaitIdle(m_device);
}
+ destroySwapchain();
+
+ if (m_command_pool != VK_NULL_HANDLE) {
+ vkDestroyCommandPool(m_device, m_command_pool, NULL);
+ }
+ if (m_device != VK_NULL_HANDLE) {
+ vkDestroyDevice(m_device, NULL);
+ }
+ if (m_surface != VK_NULL_HANDLE) {
+ vkDestroySurfaceKHR(m_instance, m_surface, NULL);
+ }
+ if (m_instance != VK_NULL_HANDLE) {
+ vkDestroyInstance(m_instance, NULL);
+ }
+}
+
+GHOST_TSuccess GHOST_ContextVK::destroySwapchain(void)
+{
+ if (m_device != VK_NULL_HANDLE) {
+ vkDeviceWaitIdle(m_device);
+ }
+
+ m_in_flight_images.resize(0);
+
for (auto semaphore : m_image_available_semaphores) {
vkDestroySemaphore(m_device, semaphore, NULL);
}
@@ -169,24 +193,16 @@ GHOST_ContextVK::~GHOST_ContextVK()
if (m_render_pass != VK_NULL_HANDLE) {
vkDestroyRenderPass(m_device, m_render_pass, NULL);
}
+ for (auto command_buffer : m_command_buffers) {
+ vkFreeCommandBuffers(m_device, m_command_pool, 1, &command_buffer);
+ }
for (auto imageView : m_swapchain_image_views) {
vkDestroyImageView(m_device, imageView, NULL);
}
if (m_swapchain != VK_NULL_HANDLE) {
vkDestroySwapchainKHR(m_device, m_swapchain, NULL);
}
- if (m_command_pool != VK_NULL_HANDLE) {
- vkDestroyCommandPool(m_device, m_command_pool, NULL);
- }
- if (m_device != VK_NULL_HANDLE) {
- vkDestroyDevice(m_device, NULL);
- }
- if (m_surface != VK_NULL_HANDLE) {
- vkDestroySurfaceKHR(m_instance, m_surface, NULL);
- }
- if (m_instance != VK_NULL_HANDLE) {
- vkDestroyInstance(m_instance, NULL);
- }
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_ContextVK::swapBuffers()
@@ -198,12 +214,25 @@ GHOST_TSuccess GHOST_ContextVK::swapBuffers()
vkWaitForFences(m_device, 1, &m_in_flight_fences[m_currentFrame], VK_TRUE, UINT64_MAX);
uint32_t image_id;
- VK_CHECK(vkAcquireNextImageKHR(m_device,
- m_swapchain,
- UINT64_MAX,
- m_image_available_semaphores[m_currentFrame],
- VK_NULL_HANDLE,
- &image_id));
+ VkResult result = vkAcquireNextImageKHR(m_device,
+ m_swapchain,
+ UINT64_MAX,
+ m_image_available_semaphores[m_currentFrame],
+ VK_NULL_HANDLE,
+ &image_id);
+
+ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
+ /* Swapchain is out of date. Recreate swapchain and skip this frame. */
+ destroySwapchain();
+ createSwapchain();
+ return GHOST_kSuccess;
+ }
+ else if (result != VK_SUCCESS) {
+ fprintf(stderr,
+ "Error: Failed to acquire swap chain image : %s\n",
+ vulkan_error_as_string(result));
+ return GHOST_kFailure;
+ }
/* Check if a previous frame is using this image (i.e. there is its fence to wait on) */
if (m_in_flight_images[image_id] != VK_NULL_HANDLE) {
@@ -238,7 +267,20 @@ GHOST_TSuccess GHOST_ContextVK::swapBuffers()
.pResults = NULL,
};
- VK_CHECK(vkQueuePresentKHR(m_present_queue, &present_info));
+ result = vkQueuePresentKHR(m_present_queue, &present_info);
+
+ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
+ /* Swapchain is out of date. Recreate swapchain and skip this frame. */
+ destroySwapchain();
+ createSwapchain();
+ return GHOST_kSuccess;
+ }
+ else if (result != VK_SUCCESS) {
+ fprintf(stderr,
+ "Error: Failed to present swap chain image : %s\n",
+ vulkan_error_as_string(result));
+ return GHOST_kFailure;
+ }
m_currentFrame = (m_currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
@@ -548,7 +590,70 @@ static GHOST_TSuccess selectPresentMode(VkPhysicalDevice device,
return GHOST_kFailure;
}
-GHOST_TSuccess GHOST_ContextVK::createSwapChain(void)
+/* This is only for testing. */
+GHOST_TSuccess GHOST_ContextVK::recordCommandBuffers(void)
+{
+ for (int i = 0; i < m_command_buffers.size(); i++) {
+ VkCommandBufferBeginInfo begin_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .flags = 0,
+ .pInheritanceInfo = NULL,
+ };
+
+ VK_CHECK(vkBeginCommandBuffer(m_command_buffers[i], &begin_info));
+ {
+ VkRect2D area = {
+ .offset = {0, 0},
+ .extent = m_render_extent,
+ };
+ VkClearValue clearColor = {0.0f, 0.5f, 0.3f, 1.0f};
+ VkRenderPassBeginInfo render_pass_info = {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ .renderPass = m_render_pass,
+ .framebuffer = m_swapchain_framebuffers[i],
+ .renderArea = area,
+ .clearValueCount = 1,
+ .pClearValues = &clearColor,
+ };
+
+ vkCmdBeginRenderPass(m_command_buffers[i], &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
+
+ /* TODO draw something. */
+
+ vkCmdEndRenderPass(m_command_buffers[i]);
+ }
+ VK_CHECK(vkEndCommandBuffer(m_command_buffers[i]));
+ }
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_ContextVK::createCommandBuffers(void)
+{
+ m_command_buffers.resize(m_swapchain_image_views.size());
+
+ VkCommandPoolCreateInfo poolInfo = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .flags = 0,
+ .queueFamilyIndex = m_queue_family_graphic,
+ };
+
+ VK_CHECK(vkCreateCommandPool(m_device, &poolInfo, NULL, &m_command_pool));
+
+ VkCommandBufferAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .commandPool = m_command_pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = static_cast<uint32_t>(m_command_buffers.size()),
+ };
+
+ VK_CHECK(vkAllocateCommandBuffers(m_device, &alloc_info, m_command_buffers.data()));
+
+ recordCommandBuffers();
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_ContextVK::createSwapchain(void)
{
VkPhysicalDevice device = m_physical_device;
@@ -690,6 +795,8 @@ GHOST_TSuccess GHOST_ContextVK::createSwapChain(void)
VK_CHECK(vkCreateFence(m_device, &fence_info, NULL, &m_in_flight_fences[i]));
}
+ createCommandBuffers();
+
return GHOST_kSuccess;
}
@@ -829,65 +936,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
if (use_window_surface) {
vkGetDeviceQueue(m_device, m_queue_family_present, 0, &m_present_queue);
- createSwapChain();
-
- {
- /* This is only a test. */
- m_command_buffers.resize(m_swapchain_image_views.size());
-
- VkCommandPoolCreateInfo poolInfo = {
- .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
- .flags = 0,
- .queueFamilyIndex = m_queue_family_graphic,
- };
-
- VK_CHECK(vkCreateCommandPool(m_device, &poolInfo, NULL, &m_command_pool));
-
- VkCommandBufferAllocateInfo alloc_info = {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
- .commandPool = m_command_pool,
- .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
- .commandBufferCount = static_cast<uint32_t>(m_command_buffers.size()),
- };
-
- VK_CHECK(vkAllocateCommandBuffers(m_device, &alloc_info, m_command_buffers.data()));
-
- for (int i = 0; i < m_command_buffers.size(); i++) {
- VkCommandBufferBeginInfo begin_info = {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
- .flags = 0,
- .pInheritanceInfo = NULL,
- };
-
- VK_CHECK(vkBeginCommandBuffer(m_command_buffers[i], &begin_info));
-
- {
- VkRect2D area = {
- .offset = {0, 0},
- .extent = m_render_extent,
- };
-
- VkClearValue clearColor = {0.0f, 0.5f, 0.3f, 1.0f};
- VkRenderPassBeginInfo render_pass_info = {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = m_render_pass,
- .framebuffer = m_swapchain_framebuffers[i],
- .renderArea = area,
- .clearValueCount = 1,
- .pClearValues = &clearColor,
- };
-
- vkCmdBeginRenderPass(
- m_command_buffers[i], &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
-
- /* TODO draw something. */
-
- vkCmdEndRenderPass(m_command_buffers[i]);
- }
-
- VK_CHECK(vkEndCommandBuffer(m_command_buffers[i]));
- }
- }
+ createSwapchain();
}
return GHOST_kFailure;
}
diff --git a/intern/ghost/intern/GHOST_ContextVK.h b/intern/ghost/intern/GHOST_ContextVK.h
index 0913bbf3f6b..3cae1e560fd 100644
--- a/intern/ghost/intern/GHOST_ContextVK.h
+++ b/intern/ghost/intern/GHOST_ContextVK.h
@@ -158,7 +158,10 @@ class GHOST_ContextVK : public GHOST_Context {
int m_currentFrame = 0;
GHOST_TSuccess pickPhysicalDevice(std::vector<const char *> required_exts);
- GHOST_TSuccess createSwapChain(void);
+ GHOST_TSuccess createSwapchain(void);
+ GHOST_TSuccess destroySwapchain(void);
+ GHOST_TSuccess createCommandBuffers(void);
+ GHOST_TSuccess recordCommandBuffers(void);
};
#endif // __GHOST_CONTEXTVK_H__
More information about the Bf-blender-cvs
mailing list