diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-02-24 15:22:28 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-02-24 15:22:28 -0500 |
| commit | 4f36a5fb7d0dcb3942d6f8e985361dd8a056cc50 (patch) | |
| tree | 9b2189d034d3bfdf745be435ce4641845c921250 /src/window.cpp | |
| parent | d39e03f461ce34d5bb0d661820298e527ce1f3fa (diff) | |
pke: prelim work for dynamic Swapchain length
Diffstat (limited to 'src/window.cpp')
| -rw-r--r-- | src/window.cpp | 194 |
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); |
