From f5d306104349a4ed157b2615e31f0319f3301a61 Mon Sep 17 00:00:00 2001 From: Cody Goodson Date: Mon, 7 Jun 2021 00:05:59 -0500 Subject: [PATCH] Added optional dispatch table usage to swapchain. --- src/VkBootstrap.cpp | 37 ++++++++++++++++++++++++++++++------- src/VkBootstrap.h | 13 +++++++++++++ tests/bootstrap_tests.cpp | 9 +++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/VkBootstrap.cpp b/src/VkBootstrap.cpp index 3ba1fe5..72a2d0e 100644 --- a/src/VkBootstrap.cpp +++ b/src/VkBootstrap.cpp @@ -1619,8 +1619,9 @@ VkExtent2D find_extent(VkSurfaceCapabilitiesKHR const& capabilities, uint32_t de void destroy_swapchain(Swapchain const& swapchain) { if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE) { - detail::vulkan_functions().fp_vkDestroySwapchainKHR( - swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks); + /*detail::vulkan_functions().fp_vkDestroySwapchainKHR( + swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);*/ + swapchain.internal_table.fp_vkDestroySwapchainKHR(swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks); } } @@ -1737,14 +1738,31 @@ detail::Result SwapchainBuilder::build() const { swapchain_create_info.clipped = info.clipped; swapchain_create_info.oldSwapchain = info.old_swapchain; Swapchain swapchain{}; - VkResult res = detail::vulkan_functions().fp_vkCreateSwapchainKHR( - info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain); + VkResult res; + if(info.dispatch_table != nullptr) { + assert(info.dispatch_table->device == info.device); + res = info.dispatch_table->createSwapchainKHR(&swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain); + } else { + res = detail::vulkan_functions().fp_vkCreateSwapchainKHR( + info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain); + } if (res != VK_SUCCESS) { return detail::Error{ SwapchainError::failed_create_swapchain, res }; } swapchain.device = info.device; swapchain.image_format = surface_format.format; swapchain.extent = extent; + if(info.dispatch_table != nullptr) { + swapchain.internal_table.fp_vkGetSwapchainImagesKHR = info.dispatch_table->fp_vkGetSwapchainImagesKHR; + swapchain.internal_table.fp_vkCreateImageView = info.dispatch_table->fp_vkCreateImageView; + swapchain.internal_table.fp_vkDestroyImageView = info.dispatch_table->fp_vkDestroyImageView; + swapchain.internal_table.fp_vkDestroySwapchainKHR = info.dispatch_table->fp_vkDestroySwapchainKHR; + } else { + swapchain.internal_table.fp_vkGetSwapchainImagesKHR = detail::vulkan_functions().fp_vkGetSwapchainImagesKHR; + swapchain.internal_table.fp_vkCreateImageView = detail::vulkan_functions().fp_vkCreateImageView; + swapchain.internal_table.fp_vkDestroyImageView = detail::vulkan_functions().fp_vkDestroyImageView; + swapchain.internal_table.fp_vkDestroySwapchainKHR = detail::vulkan_functions().fp_vkDestroySwapchainKHR; + } auto images = swapchain.get_images(); if (!images) { return detail::Error{ SwapchainError::failed_get_swapchain_images }; @@ -1787,8 +1805,9 @@ detail::Result> Swapchain::get_image_views() { createInfo.subresourceRange.baseArrayLayer = 0; createInfo.subresourceRange.layerCount = 1; - VkResult res = detail::vulkan_functions().fp_vkCreateImageView( - device, &createInfo, allocation_callbacks, &views[i]); + /*VkResult res = detail::vulkan_functions().fp_vkCreateImageView( + device, &createInfo, allocation_callbacks, &views[i]);*/ + VkResult res = internal_table.fp_vkCreateImageView(device, &createInfo, allocation_callbacks, &views[i]); if (res != VK_SUCCESS) return detail::Error{ SwapchainError::failed_create_swapchain_image_views, res }; } @@ -1796,7 +1815,7 @@ detail::Result> Swapchain::get_image_views() { } void Swapchain::destroy_image_views(std::vector const& image_views) { for (auto& image_view : image_views) { - detail::vulkan_functions().fp_vkDestroyImageView(device, image_view, allocation_callbacks); + internal_table.fp_vkDestroyImageView(device, image_view, allocation_callbacks); } } SwapchainBuilder& SwapchainBuilder::set_old_swapchain(VkSwapchainKHR old_swapchain) { @@ -1843,6 +1862,10 @@ SwapchainBuilder& SwapchainBuilder::set_allocation_callbacks(VkAllocationCallbac info.allocation_callbacks = callbacks; return *this; } +SwapchainBuilder& SwapchainBuilder::use_dispatch_table(DispatchTable& dispatch_table) { + info.dispatch_table = &dispatch_table; + return *this; +} SwapchainBuilder& SwapchainBuilder::set_image_usage_flags(VkImageUsageFlags usage_flags) { info.image_usage_flags = usage_flags; return *this; diff --git a/src/VkBootstrap.h b/src/VkBootstrap.h index d8d4dd1..7b1c0c4 100644 --- a/src/VkBootstrap.h +++ b/src/VkBootstrap.h @@ -615,6 +615,15 @@ struct Swapchain { // VkImageViews must be destroyed. detail::Result> get_image_views(); void destroy_image_views(std::vector const& image_views); + private: + struct { + PFN_vkGetSwapchainImagesKHR fp_vkGetSwapchainImagesKHR = nullptr; + PFN_vkCreateImageView fp_vkCreateImageView = nullptr; + PFN_vkDestroyImageView fp_vkDestroyImageView = nullptr; + PFN_vkDestroySwapchainKHR fp_vkDestroySwapchainKHR = nullptr; + } internal_table; + friend class SwapchainBuilder; + friend void destroy_swapchain(Swapchain const& swapchain); }; void destroy_swapchain(Swapchain const& swapchain); @@ -705,6 +714,9 @@ class SwapchainBuilder { // Provide custom allocation callbacks. SwapchainBuilder& set_allocation_callbacks(VkAllocationCallbacks* callbacks); + // Provide an optional dispatch table for the builder to use for device pfn's + SwapchainBuilder& use_dispatch_table(DispatchTable& dispatch_table); + private: void add_desired_formats(std::vector& formats) const; void add_desired_present_modes(std::vector& modes) const; @@ -729,6 +741,7 @@ class SwapchainBuilder { bool clipped = true; VkSwapchainKHR old_swapchain = VK_NULL_HANDLE; VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE; + DispatchTable* dispatch_table = nullptr; } info; }; diff --git a/tests/bootstrap_tests.cpp b/tests/bootstrap_tests.cpp index 31f099f..8df4df1 100644 --- a/tests/bootstrap_tests.cpp +++ b/tests/bootstrap_tests.cpp @@ -322,6 +322,15 @@ TEST_CASE("Swapchain", "[VkBootstrap.bootstrap]") { vkb::destroy_swapchain(recreated_swapchain_ret.value()); } + AND_THEN("Swapchain can be created with a dispatch table") { + vkb::DispatchTable dispatch_table = device.make_table(); + vkb::SwapchainBuilder swapchain_builder( + device.physical_device.physical_device, device.device, surface); + auto swapchain_ret = swapchain_builder.use_dispatch_table(dispatch_table).build(); + REQUIRE(swapchain_ret.has_value()); + + vkb::destroy_swapchain(swapchain_ret.value()); + } vkb::destroy_device(device_ret.value()); vkb::destroy_surface(instance_ret.value(), surface);