diff --git a/examples/example_runner.hpp b/examples/example_runner.hpp index 892a9175..d60ae57d 100644 --- a/examples/example_runner.hpp +++ b/examples/example_runner.hpp @@ -100,7 +100,7 @@ namespace vuk { if (width == 0 && height == 0) { runner.suspend = true; } else { - runner.swapchain = util::make_swapchain(*runner.superframe_allocator, runner.vkbdevice, runner.swapchain->surface, runner.swapchain); + runner.swapchain = util::make_swapchain(*runner.superframe_allocator, runner.vkbdevice, runner.swapchain->surface, std::move(runner.swapchain)); for (auto& iv : runner.swapchain->images) { runner.context->set_name(iv.image_view.payload, "Swapchain ImageView"); } @@ -137,6 +137,7 @@ namespace vuk { render_complete.reset(); imgui_data.font_image.reset(); imgui_data.font_image_view.reset(); + swapchain.reset(); superframe_resource.reset(); context.reset(); auto vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)vkbinstance.fp_vkGetInstanceProcAddr(vkbinstance.instance, "vkDestroySurfaceKHR"); diff --git a/examples/utils.hpp b/examples/utils.hpp index c394c959..f01fdc2d 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp @@ -102,7 +102,7 @@ namespace util { old_swapchain->swapchain = vkswapchain->swapchain; old_swapchain->surface = surface; - return *old_swapchain; + return std::move(*old_swapchain); } struct ImGuiData { diff --git a/include/vuk/IR.hpp b/include/vuk/IR.hpp index 6b095835..3711fd16 100644 --- a/include/vuk/IR.hpp +++ b/include/vuk/IR.hpp @@ -666,10 +666,9 @@ namespace vuk { } Ref make_declare_swapchain(Swapchain& bundle) { - auto swp_ptr = new Swapchain(bundle); auto args_ptr = new Ref[2]; auto mem_ty = new Type*(emplace_type(Type{ .kind = Type::MEMORY_TY })); - args_ptr[0] = first(emplace_op(Node{ .kind = Node::CONSTANT, .type = std::span{ mem_ty, 1 }, .constant = { .value = swp_ptr } })); + args_ptr[0] = first(emplace_op(Node{ .kind = Node::CONSTANT, .type = std::span{ mem_ty, 1 }, .constant = { .value = &bundle } })); std::vector imgs; for (auto i = 0; i < bundle.images.size(); i++) { imgs.push_back(make_declare_image(bundle.images[i])); diff --git a/include/vuk/RenderGraph.hpp b/include/vuk/RenderGraph.hpp index 4e291287..5e375a38 100644 --- a/include/vuk/RenderGraph.hpp +++ b/include/vuk/RenderGraph.hpp @@ -663,7 +663,7 @@ private: return { make_ext_ref(rg, ref), ref }; } - [[nodiscard]] inline Value declare_swapchain(Swapchain bundle, std::source_location loc = std::source_location::current()) { + [[nodiscard]] inline Value declare_swapchain(Swapchain& bundle, std::source_location loc = std::source_location::current()) { std::shared_ptr rg = std::make_shared(); Ref ref = rg->make_declare_swapchain(bundle); rg->set_source_location(ref.node, loc); diff --git a/include/vuk/Swapchain.hpp b/include/vuk/Swapchain.hpp index b2d6dcc8..08efc6ea 100644 --- a/include/vuk/Swapchain.hpp +++ b/include/vuk/Swapchain.hpp @@ -63,10 +63,17 @@ namespace vuk { struct Swapchain { Swapchain(Allocator allocator, size_t image_count); + Swapchain(const Swapchain&) = delete; + Swapchain(Swapchain&&) noexcept; + + Swapchain& operator=(const Swapchain&) = delete; + Swapchain& operator=(Swapchain&&) noexcept; + + ~Swapchain(); Allocator allocator; - VkSwapchainKHR swapchain; - VkSurfaceKHR surface; + VkSwapchainKHR swapchain = VK_NULL_HANDLE; + VkSurfaceKHR surface = VK_NULL_HANDLE; std::vector images; uint32_t linear_index = 0; diff --git a/src/Util.cpp b/src/Util.cpp index aad96fcd..c81e740c 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -20,6 +20,40 @@ namespace vuk { allocator.allocate_semaphores(std::span(semaphores)); } + Swapchain::~Swapchain() { + if (swapchain != VK_NULL_HANDLE) { + allocator.deallocate(std::span{ &swapchain, 1 }); + } + for (auto& i : images) { + allocator.deallocate(std::span{ &i.image_view, 1 }); + } + allocator.deallocate(std::span(semaphores)); + } + + Swapchain::Swapchain(Swapchain&& o) noexcept : + swapchain(std::exchange(o.swapchain, VK_NULL_HANDLE)), + semaphores(std::move(o.semaphores)), + allocator(o.allocator) { + images = std::move(o.images); + surface = o.surface; + linear_index = o.linear_index; + image_index = o.image_index; + acquire_result = o.acquire_result; + } + + Swapchain& Swapchain::operator=(Swapchain&& o) noexcept { + swapchain = std::exchange(o.swapchain, VK_NULL_HANDLE); + semaphores = std::move(o.semaphores); + allocator = o.allocator; + images = std::move(o.images); + surface = o.surface; + linear_index = o.linear_index; + image_index = o.image_index; + acquire_result = o.acquire_result; + + return *this; + } + Result Context::wait_for_domains(std::span queue_waits) { std::array domain_to_sema_index = { ~0u, ~0u, ~0u }; std::array queue_timeline_semaphores; @@ -114,7 +148,7 @@ namespace vuk { } else if (acqrel->status == Signal::Status::eHostAvailable || acqrel->status == Signal::Status::eSynchronizable) { return { expected_value }; // nothing to do } else { - //acqrel->status = Signal::Status::eSynchronizable; + // acqrel->status = Signal::Status::eSynchronizable; auto erg = compiler.link(std::span{ &node, 1 }, options); if (!erg) { return erg;