summaryrefslogtreecommitdiff
path: root/src/window.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-02-24 15:22:28 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-02-24 15:22:28 -0500
commit4f36a5fb7d0dcb3942d6f8e985361dd8a056cc50 (patch)
tree9b2189d034d3bfdf745be435ce4641845c921250 /src/window.cpp
parentd39e03f461ce34d5bb0d661820298e527ce1f3fa (diff)
pke: prelim work for dynamic Swapchain length
Diffstat (limited to 'src/window.cpp')
-rw-r--r--src/window.cpp194
1 files changed, 132 insertions, 62 deletions
diff --git a/src/window.cpp b/src/window.cpp
index 55fafff..b42a1b3 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -62,6 +62,7 @@ unsigned int transferFamilyIndex;
bool shouldRecreateSwapchain = false;
unsigned int CURRENT_FRAME = 0;
unsigned int selectedSurfaceIndex = -1u;
+unsigned int prevSwapchainLength = 0u;
unsigned int swapchainLength = 0u;
VkSwapchainKHR vkSwapchainKHR = VK_NULL_HANDLE;
VkSurfaceFormatKHR vkSurfaceFormatKHR;
@@ -882,6 +883,27 @@ void CreateSwapchain() {
vkResult = vkCreateSwapchainKHR(vkDevice, &vkSwapchainCreateInfo, vkAllocator, &vkSwapchainKHR);
assert(vkResult == VK_SUCCESS);
+ assert(pkvk_present.images == nullptr || pkvk_present.images == CAFE_BABE(VkImage));
+ assert(pkvk_present.image_views == nullptr || pkvk_present.image_views == CAFE_BABE(VkImageView));
+ assert(pkvk_3d.render_images == nullptr || pkvk_3d.render_images == CAFE_BABE(VkImage));
+ assert(pkvk_3d.image_views == nullptr || pkvk_3d.image_views == CAFE_BABE(VkImageView));
+ assert(pkvk_3d.images_color_resolve == nullptr || pkvk_3d.images_color_resolve == CAFE_BABE(VkImage));
+ assert(pkvk_3d.image_views_color_resolve == nullptr || pkvk_3d.image_views_color_resolve == CAFE_BABE(VkImageView));
+ assert(depthImages == nullptr || depthImages == CAFE_BABE(VkImage));
+ assert(depthImageViews == nullptr || depthImageViews == CAFE_BABE(VkImageView));
+ assert(pkvk_2d.images == nullptr || pkvk_2d.images == CAFE_BABE(VkImage));
+ assert(pkvk_2d.image_views == nullptr || pkvk_2d.image_views == CAFE_BABE(VkImageView));
+ assert(pkvk_2d.images_color_resolve == nullptr || pkvk_2d.images_color_resolve == CAFE_BABE(VkImage));
+ assert(pkvk_2d.image_views_color_resolve == nullptr || pkvk_2d.image_views_color_resolve == CAFE_BABE(VkImageView));
+
+ prevSwapchainLength = swapchainLength;
+ vkResult = vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, nullptr);
+ assert(vkResult == VK_SUCCESS);
+ pkvk_present.images = pk_new<VkImage>(swapchainLength);
+ vkResult = vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, pkvk_present.images);
+ assert(vkResult == VK_SUCCESS);
+ pkvk_present.image_views = pk_new<VkImageView>(swapchainLength);
+
VkImageSubresourceRange vkImageSubresourceRange;
vkImageSubresourceRange.aspectMask = VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT;
vkImageSubresourceRange.baseMipLevel = 0u;
@@ -902,26 +924,6 @@ void CreateSwapchain() {
VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY,
};
vkImageViewCreateInfo.subresourceRange = vkImageSubresourceRange;
-
- assert(pkvk_present.images == nullptr || pkvk_present.images == CAFE_BABE(VkImage));
- assert(pkvk_present.image_views == nullptr || pkvk_present.image_views == CAFE_BABE(VkImageView));
- assert(pkvk_3d.render_images == nullptr || pkvk_3d.render_images == CAFE_BABE(VkImage));
- assert(pkvk_3d.image_views == nullptr || pkvk_3d.image_views == CAFE_BABE(VkImageView));
- assert(pkvk_3d.images_color_resolve == nullptr || pkvk_3d.images_color_resolve == CAFE_BABE(VkImage));
- assert(pkvk_3d.image_views_color_resolve == nullptr || pkvk_3d.image_views_color_resolve == CAFE_BABE(VkImageView));
- assert(depthImages == nullptr || depthImages == CAFE_BABE(VkImage));
- assert(depthImageViews == nullptr || depthImageViews == CAFE_BABE(VkImageView));
- assert(pkvk_2d.images == nullptr || pkvk_2d.images == CAFE_BABE(VkImage));
- assert(pkvk_2d.image_views == nullptr || pkvk_2d.image_views == CAFE_BABE(VkImageView));
- assert(pkvk_2d.images_color_resolve == nullptr || pkvk_2d.images_color_resolve == CAFE_BABE(VkImage));
- assert(pkvk_2d.image_views_color_resolve == nullptr || pkvk_2d.image_views_color_resolve == CAFE_BABE(VkImageView));
-
- vkResult = vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, nullptr);
- assert(vkResult == VK_SUCCESS);
- pkvk_present.images = pk_new<VkImage>(swapchainLength);
- vkResult = vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, pkvk_present.images);
- assert(vkResult == VK_SUCCESS);
- pkvk_present.image_views = pk_new<VkImageView>(swapchainLength);
for (long i = 0; i < swapchainLength; ++i) {
vkImageViewCreateInfo.image = pkvk_present.images[i];
vkResult = vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &pkvk_present.image_views[i]);
@@ -1202,7 +1204,30 @@ void CreateRenderPass() {
}
}
+void CreatePresentDescriptorSetLayout() {
+ VkDescriptorSetLayoutBinding imageSamplerLayoutBinding;
+ imageSamplerLayoutBinding.binding = 0;
+ imageSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ imageSamplerLayoutBinding.descriptorCount = 1;
+ imageSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+ imageSamplerLayoutBinding.pImmutableSamplers = nullptr;
+
+ VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo;
+ descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ descriptorSetLayoutCreateInfo.pNext = nullptr;
+ descriptorSetLayoutCreateInfo.flags = 0;
+ descriptorSetLayoutCreateInfo.bindingCount = 1;
+ descriptorSetLayoutCreateInfo.pBindings = &imageSamplerLayoutBinding;
+
+ auto vkResult = vkCreateDescriptorSetLayout(vkDevice, &descriptorSetLayoutCreateInfo, vkAllocator, &pkvk_present.descriptor_set_layout);
+ if (vkResult != VK_SUCCESS) {
+ throw "failed to create descriptor set layout";
+ }
+}
+
void CreatePresentPipeline() {
+ VkResult vkResult;
+
// enqueue asset loading
AssetHandle vertShaderAsset{AM_GetHandle(AssetKey{"pke_prsnt_vrt\0\0"})};
AssetHandle fragShaderAsset{AM_GetHandle(AssetKey{"pke_prsnt_frg\0\0"})};
@@ -1248,14 +1273,16 @@ void CreatePresentPipeline() {
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
inputAssembly.primitiveRestartEnable = VK_FALSE;
+ // dynamic
VkViewport viewport;
viewport.x = 0.0f;
viewport.y = 0.0f;
- viewport.width = (float) Extent.width;
- viewport.height = (float) Extent.height;
+ viewport.width = 0.0f;
+ viewport.height = 0.0f;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
+ // dynamic
VkRect2D scissor;
scissor.offset = {0, 0};
scissor.extent = Extent;
@@ -1337,25 +1364,6 @@ void CreatePresentPipeline() {
* PipelineLayout + DescriptorSets
*/
- VkDescriptorSetLayoutBinding imageSamplerLayoutBinding;
- imageSamplerLayoutBinding.binding = 0;
- imageSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- imageSamplerLayoutBinding.descriptorCount = 1;
- imageSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
- imageSamplerLayoutBinding.pImmutableSamplers = nullptr;
-
- VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo;
- descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
- descriptorSetLayoutCreateInfo.pNext = nullptr;
- descriptorSetLayoutCreateInfo.flags = 0;
- descriptorSetLayoutCreateInfo.bindingCount = 1;
- descriptorSetLayoutCreateInfo.pBindings = &imageSamplerLayoutBinding;
-
- auto vkResult = vkCreateDescriptorSetLayout(vkDevice, &descriptorSetLayoutCreateInfo, vkAllocator, &pkvk_present.descriptor_set_layout);
- if (vkResult != VK_SUCCESS) {
- throw "failed to create descriptor set layout";
- }
-
VkDescriptorPoolSize vkDescriptorPoolSize;
vkDescriptorPoolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
vkDescriptorPoolSize.descriptorCount = swapchainLength * 2;
@@ -2813,6 +2821,55 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
}
}
+void DestroySyncObjects() {
+ for (long i = 0; i < prevSwapchainLength; ++i) {
+ if (pkvk_present.semaphores_image_available[i] != VK_NULL_HANDLE) {
+ vkDestroySemaphore(vkDevice, pkvk_present.semaphores_image_available[i], vkAllocator);
+ pkvk_present.semaphores_image_available[i] = VK_NULL_HANDLE;
+ }
+ if (pkvk_present.semaphores_render_finished[i] != VK_NULL_HANDLE) {
+ vkDestroySemaphore(vkDevice, pkvk_present.semaphores_render_finished[i], vkAllocator);
+ pkvk_present.semaphores_render_finished[i] = VK_NULL_HANDLE;
+ }
+ if (pkvk_present.fences_in_flight[i] != VK_NULL_HANDLE) {
+ vkDestroyFence(vkDevice, pkvk_present.fences_in_flight[i], vkAllocator);
+ pkvk_present.fences_in_flight[i] = VK_NULL_HANDLE;
+ }
+ }
+
+ pk_delete<VkSemaphore>(pkvk_present.semaphores_image_available, prevSwapchainLength, MemBkt_Vulkan);
+ pkvk_present.semaphores_image_available = CAFE_BABE(VkSemaphore);
+
+ pk_delete<VkSemaphore>(pkvk_present.semaphores_render_finished, prevSwapchainLength, MemBkt_Vulkan);
+ pkvk_present.semaphores_render_finished = CAFE_BABE(VkSemaphore);
+
+ pk_delete<VkFence>(pkvk_present.fences_in_flight, prevSwapchainLength, MemBkt_Vulkan);
+ pkvk_present.fences_in_flight = CAFE_BABE(VkFence);
+}
+
+void DestroyPresentPipeline() {
+ if (pkvk_present.pipeline != VK_NULL_HANDLE) {
+ vkDestroyPipeline(vkDevice, pkvk_present.pipeline, vkAllocator);
+ pkvk_present.pipeline = VK_NULL_HANDLE;
+ }
+
+ if (pkvk_present.pipeline_layout != VK_NULL_HANDLE) {
+ vkDestroyPipelineLayout(vkDevice, pkvk_present.pipeline_layout, vkAllocator);
+ pkvk_present.pipeline_layout = VK_NULL_HANDLE;
+ }
+
+ if (pkvk_present.descriptor_sets != nullptr && pkvk_present.descriptor_sets != CAFE_BABE(VkDescriptorSet)) {
+ vkFreeDescriptorSets(vkDevice, pkvk_present.descriptor_pool, prevSwapchainLength * 2, pkvk_present.descriptor_sets);
+ pk_delete<VkDescriptorSet>(pkvk_present.descriptor_sets, prevSwapchainLength * 2, MemBkt_Vulkan);
+ pkvk_present.descriptor_sets = CAFE_BABE(VkDescriptorSet);
+ }
+
+ if (pkvk_present.descriptor_pool != VK_NULL_HANDLE) {
+ vkDestroyDescriptorPool(vkDevice, pkvk_present.descriptor_pool, vkAllocator);
+ pkvk_present.descriptor_pool = VK_NULL_HANDLE;
+ }
+}
+
void DestroySwapchain() {
if (pkvk_2d.framebuffers != nullptr && pkvk_2d.framebuffers != CAFE_BABE(VkFramebuffer)) {
for (long i = 0; i < swapchainLength; ++i) {
@@ -2903,6 +2960,21 @@ void DestroySwapchain() {
vkDestroySwapchainKHR(vkDevice, vkSwapchainKHR, vkAllocator);
}
+void DestroyUniformBuffers() {
+ for (long i = 0; i < prevSwapchainLength; ++i) {
+ if (UniformBuffers[i] != VK_NULL_HANDLE) {
+ vkDestroyBuffer(vkDevice, UniformBuffers[i], vkAllocator);
+ UniformBuffers[i] = VK_NULL_HANDLE;
+ }
+ }
+
+ pk_delete<VkBuffer>(UniformBuffers, prevSwapchainLength, MemBkt_Vulkan);
+ UniformBuffers = CAFE_BABE(VkBuffer);
+
+ vkFreeMemory(vkDevice, uniformBufferMemory, vkAllocator);
+ uniformBufferMemory = VK_NULL_HANDLE;
+}
+
void DetermineMonitor() {
int monitorCount;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
@@ -2932,12 +3004,24 @@ void RecreateSwapchain() {
ActiveCamera->stale = ActiveCamera->stale | PKE_CAMERA_STALE_PERSPECTIVE;
DetermineMonitor();
vkDeviceWaitIdle(vkDevice);
+ // reminder: prevSwapchainLength set in CreateSwapchain()
DestroySwapchain();
CreateSwapchain();
+ if (prevSwapchainLength != swapchainLength) {
+ DestroySyncObjects();
+ DestroyPresentPipeline();
+ CreatePresentPipeline();
+ CreateSyncObjects();
+ }
UpdatePresentDescriptorSets();
UpdateCamera();
CreateFramebuffers();
+ if (prevSwapchainLength != swapchainLength) {
+ DestroyUniformBuffers();
+ CreateUniformBuffers();
+ }
shouldRecreateSwapchain = false;
+ prevSwapchainLength = swapchainLength;
}
void FramebufferResizeCallback(GLFWwindow *window, int width, int height) {
@@ -2963,6 +3047,7 @@ void CreateWindow(PKEWindowProperties wp) {
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
CreateSwapchain();
CreateRenderPass();
+ CreatePresentDescriptorSetLayout();
CreatePresentPipeline();
UpdatePresentDescriptorSets();
UpdateCamera();
@@ -3017,30 +3102,15 @@ void DestroyWindow() {
if (pkePipelines.descr_layouts.named.glyph != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vkDevice, pkePipelines.descr_layouts.named.glyph, vkAllocator);
- for (long i = 0; i < swapchainLength; ++i) {
- vkDestroyBuffer(vkDevice, UniformBuffers[i], vkAllocator);
- vkDestroySemaphore(vkDevice, pkvk_present.semaphores_image_available[i], vkAllocator);
- vkDestroySemaphore(vkDevice, pkvk_present.semaphores_render_finished[i], vkAllocator);
- vkDestroyFence(vkDevice, pkvk_present.fences_in_flight[i], vkAllocator);
- }
- pk_delete<VkBuffer>(UniformBuffers, swapchainLength, MemBkt_Vulkan);
- UniformBuffers = CAFE_BABE(VkBuffer);
- pk_delete<VkSemaphore>(pkvk_present.semaphores_image_available, swapchainLength, MemBkt_Vulkan);
- pkvk_present.semaphores_image_available = CAFE_BABE(VkSemaphore);
- pk_delete<VkSemaphore>(pkvk_present.semaphores_render_finished, swapchainLength, MemBkt_Vulkan);
- pkvk_present.semaphores_render_finished = CAFE_BABE(VkSemaphore);
- pk_delete<VkFence>(pkvk_present.fences_in_flight, swapchainLength, MemBkt_Vulkan);
- pkvk_present.fences_in_flight = CAFE_BABE(VkFence);
+ DestroySyncObjects();
+
+ DestroyUniformBuffers();
- vkFreeMemory(vkDevice, uniformBufferMemory, vkAllocator);
vkDestroyCommandPool(vkDevice, pkvk_shared.command_pool.graphics, vkAllocator);
vkDestroyCommandPool(vkDevice, pkvk_shared.command_pool.transfer, vkAllocator);
- vkDestroyPipeline(vkDevice, pkvk_present.pipeline, vkAllocator);
- vkDestroyPipelineLayout(vkDevice, pkvk_present.pipeline_layout, vkAllocator);
- vkFreeDescriptorSets(vkDevice, pkvk_present.descriptor_pool, swapchainLength * 2, pkvk_present.descriptor_sets);
- pk_delete<VkDescriptorSet>(pkvk_present.descriptor_sets, swapchainLength * 2, MemBkt_Vulkan);
- pkvk_present.descriptor_sets = CAFE_BABE(VkDescriptorSet);
- vkDestroyDescriptorPool(vkDevice, pkvk_present.descriptor_pool, vkAllocator);
+
+ DestroyPresentPipeline();
+
vkDestroyDescriptorPool(vkDevice, imGuiDescriptorPool, vkAllocator);
vkDestroyDescriptorSetLayout(vkDevice, pkvk_present.descriptor_set_layout, vkAllocator);
vkDestroyRenderPass(vkDevice, pkvk_2d.render_pass, vkAllocator);