Fix some issues in RAII
This commit is contained in:
parent
8599c47fe0
commit
4cf41673ba
3 changed files with 54 additions and 61 deletions
|
@ -110,16 +110,16 @@ RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& emu_window,
|
||||||
instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
|
instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
|
||||||
Settings::values.renderer_debug.GetValue())),
|
Settings::values.renderer_debug.GetValue())),
|
||||||
// Now create RAII wrappers for the resources in the correct order
|
// Now create RAII wrappers for the resources in the correct order
|
||||||
raii_instance(MakeInstance(instance, dld)),
|
managed_instance(MakeManagedInstance(instance, dld)),
|
||||||
// Create debug messenger if debug is enabled
|
// Create debug messenger if debug is enabled
|
||||||
debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance)
|
debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance)
|
||||||
: vk::DebugUtilsMessenger{}),
|
: vk::DebugUtilsMessenger{}),
|
||||||
raii_debug_messenger(Settings::values.renderer_debug
|
managed_debug_messenger(Settings::values.renderer_debug
|
||||||
? MakeDebugUtilsMessenger(debug_messenger, instance, dld)
|
? MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld)
|
||||||
: RaiiDebugUtilsMessenger{}),
|
: ManagedDebugUtilsMessenger{}),
|
||||||
// Create surface
|
// Create surface
|
||||||
surface(CreateSurface(instance, render_window.GetWindowInfo())),
|
surface(CreateSurface(instance, render_window.GetWindowInfo())),
|
||||||
raii_surface(MakeSurface(surface, instance, dld)),
|
managed_surface(MakeManagedSurface(surface, instance, dld)),
|
||||||
device(CreateDevice(instance, dld, *surface)), memory_allocator(device), state_tracker(),
|
device(CreateDevice(instance, dld, *surface)), memory_allocator(device), state_tracker(),
|
||||||
scheduler(device, state_tracker),
|
scheduler(device, state_tracker),
|
||||||
swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
|
swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
|
||||||
|
|
|
@ -80,15 +80,15 @@ private:
|
||||||
// Keep original handles for compatibility with existing code
|
// Keep original handles for compatibility with existing code
|
||||||
vk::Instance instance;
|
vk::Instance instance;
|
||||||
// RAII wrapper for instance
|
// RAII wrapper for instance
|
||||||
RaiiInstance raii_instance;
|
ManagedInstance managed_instance;
|
||||||
|
|
||||||
vk::DebugUtilsMessenger debug_messenger;
|
vk::DebugUtilsMessenger debug_messenger;
|
||||||
// RAII wrapper for debug messenger
|
// RAII wrapper for debug messenger
|
||||||
RaiiDebugUtilsMessenger raii_debug_messenger;
|
ManagedDebugUtilsMessenger managed_debug_messenger;
|
||||||
|
|
||||||
vk::SurfaceKHR surface;
|
vk::SurfaceKHR surface;
|
||||||
// RAII wrapper for surface
|
// RAII wrapper for surface
|
||||||
RaiiSurface raii_surface;
|
ManagedSurface managed_surface;
|
||||||
|
|
||||||
Device device;
|
Device device;
|
||||||
MemoryAllocator memory_allocator;
|
MemoryAllocator memory_allocator;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
// Constructor with handle and deleter
|
// Constructor with handle and deleter
|
||||||
VulkanRaii(T handle_, DeleterFunc deleter_, const Dispatch& dispatch_, const char* resource_name = "Vulkan resource")
|
VulkanRaii(T handle_, DeleterFunc deleter_, const Dispatch& dispatch_, const char* resource_name = "Vulkan resource")
|
||||||
: handle{handle_}, deleter{std::move(deleter_)}, dispatch{dispatch_} {
|
: handle{handle_}, deleter{std::move(deleter_)}, dispatch{dispatch_} {
|
||||||
LOG_WARNING(Render_Vulkan, "RAII wrapper created for {}", resource_name);
|
LOG_DEBUG(Render_Vulkan, "RAII wrapper created for {}", resource_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move constructor
|
// Move constructor
|
||||||
|
@ -52,9 +52,6 @@ public:
|
||||||
|
|
||||||
// Destructor - automatically cleans up the resource
|
// Destructor - automatically cleans up the resource
|
||||||
~VulkanRaii() {
|
~VulkanRaii() {
|
||||||
if (handle != VK_NULL_HANDLE) {
|
|
||||||
LOG_WARNING(Render_Vulkan, "RAII wrapper destroying resource");
|
|
||||||
}
|
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +71,7 @@ public:
|
||||||
|
|
||||||
// Release ownership of the handle without destroying it
|
// Release ownership of the handle without destroying it
|
||||||
T release() noexcept {
|
T release() noexcept {
|
||||||
T result = handle;
|
return std::exchange(handle, VK_NULL_HANDLE);
|
||||||
handle = VK_NULL_HANDLE;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the handle (destroying the current one if it exists)
|
// Reset the handle (destroying the current one if it exists)
|
||||||
|
@ -97,12 +92,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Optimized cleanup function that avoids unnecessary checks in release builds
|
// Optimized cleanup function
|
||||||
void cleanup() noexcept {
|
void cleanup() noexcept {
|
||||||
if (handle != VK_NULL_HANDLE) {
|
if (handle != VK_NULL_HANDLE && deleter) {
|
||||||
if (deleter) {
|
|
||||||
deleter(handle, dispatch);
|
deleter(handle, dispatch);
|
||||||
}
|
|
||||||
handle = VK_NULL_HANDLE;
|
handle = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,127 +105,127 @@ private:
|
||||||
Dispatch dispatch;
|
Dispatch dispatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common type aliases for Vulkan RAII wrappers
|
// Common type aliases for Vulkan RAII wrappers with clearer names
|
||||||
using RaiiInstance = VulkanRaii<VkInstance, void*, vk::InstanceDispatch>;
|
using ManagedInstance = VulkanRaii<VkInstance, void*, vk::InstanceDispatch>;
|
||||||
using RaiiDevice = VulkanRaii<VkDevice, void*, vk::DeviceDispatch>;
|
using ManagedDevice = VulkanRaii<VkDevice, void*, vk::DeviceDispatch>;
|
||||||
using RaiiSurface = VulkanRaii<VkSurfaceKHR, VkInstance, vk::InstanceDispatch>;
|
using ManagedSurface = VulkanRaii<VkSurfaceKHR, VkInstance, vk::InstanceDispatch>;
|
||||||
using RaiiSwapchain = VulkanRaii<VkSwapchainKHR, VkDevice, vk::DeviceDispatch>;
|
using ManagedSwapchain = VulkanRaii<VkSwapchainKHR, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiCommandPool = VulkanRaii<VkCommandPool, VkDevice, vk::DeviceDispatch>;
|
using ManagedCommandPool = VulkanRaii<VkCommandPool, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiBuffer = VulkanRaii<VkBuffer, VkDevice, vk::DeviceDispatch>;
|
using ManagedBuffer = VulkanRaii<VkBuffer, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiImage = VulkanRaii<VkImage, VkDevice, vk::DeviceDispatch>;
|
using ManagedImage = VulkanRaii<VkImage, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiImageView = VulkanRaii<VkImageView, VkDevice, vk::DeviceDispatch>;
|
using ManagedImageView = VulkanRaii<VkImageView, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiSampler = VulkanRaii<VkSampler, VkDevice, vk::DeviceDispatch>;
|
using ManagedSampler = VulkanRaii<VkSampler, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiShaderModule = VulkanRaii<VkShaderModule, VkDevice, vk::DeviceDispatch>;
|
using ManagedShaderModule = VulkanRaii<VkShaderModule, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiPipeline = VulkanRaii<VkPipeline, VkDevice, vk::DeviceDispatch>;
|
using ManagedPipeline = VulkanRaii<VkPipeline, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiPipelineLayout = VulkanRaii<VkPipelineLayout, VkDevice, vk::DeviceDispatch>;
|
using ManagedPipelineLayout = VulkanRaii<VkPipelineLayout, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiDescriptorSetLayout = VulkanRaii<VkDescriptorSetLayout, VkDevice, vk::DeviceDispatch>;
|
using ManagedDescriptorSetLayout = VulkanRaii<VkDescriptorSetLayout, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiDescriptorPool = VulkanRaii<VkDescriptorPool, VkDevice, vk::DeviceDispatch>;
|
using ManagedDescriptorPool = VulkanRaii<VkDescriptorPool, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiSemaphore = VulkanRaii<VkSemaphore, VkDevice, vk::DeviceDispatch>;
|
using ManagedSemaphore = VulkanRaii<VkSemaphore, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiFence = VulkanRaii<VkFence, VkDevice, vk::DeviceDispatch>;
|
using ManagedFence = VulkanRaii<VkFence, VkDevice, vk::DeviceDispatch>;
|
||||||
using RaiiDebugUtilsMessenger = VulkanRaii<VkDebugUtilsMessengerEXT, VkInstance, vk::InstanceDispatch>;
|
using ManagedDebugUtilsMessenger = VulkanRaii<VkDebugUtilsMessengerEXT, VkInstance, vk::InstanceDispatch>;
|
||||||
|
|
||||||
// Helper functions to create RAII wrappers
|
// Helper functions to create RAII wrappers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan instance
|
* Creates an RAII wrapper for a Vulkan instance
|
||||||
*/
|
*/
|
||||||
inline RaiiInstance MakeInstance(const vk::Instance& instance, const vk::InstanceDispatch& dispatch) {
|
inline ManagedInstance MakeManagedInstance(const vk::Instance& instance, const vk::InstanceDispatch& dispatch) {
|
||||||
auto deleter = [](VkInstance handle, const vk::InstanceDispatch& dld) {
|
auto deleter = [](VkInstance handle, const vk::InstanceDispatch& dld) {
|
||||||
dld.vkDestroyInstance(handle, nullptr);
|
dld.vkDestroyInstance(handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiInstance(*instance, deleter, dispatch, "VkInstance");
|
return ManagedInstance(*instance, deleter, dispatch, "VkInstance");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan device
|
* Creates an RAII wrapper for a Vulkan device
|
||||||
*/
|
*/
|
||||||
inline RaiiDevice MakeDevice(const vk::Device& device, const vk::DeviceDispatch& dispatch) {
|
inline ManagedDevice MakeManagedDevice(const vk::Device& device, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [](VkDevice handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [](VkDevice handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroyDevice(handle, nullptr);
|
dld.vkDestroyDevice(handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiDevice(*device, deleter, dispatch, "VkDevice");
|
return ManagedDevice(*device, deleter, dispatch, "VkDevice");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan surface
|
* Creates an RAII wrapper for a Vulkan surface
|
||||||
*/
|
*/
|
||||||
inline RaiiSurface MakeSurface(const vk::SurfaceKHR& surface, const vk::Instance& instance, const vk::InstanceDispatch& dispatch) {
|
inline ManagedSurface MakeManagedSurface(const vk::SurfaceKHR& surface, const vk::Instance& instance, const vk::InstanceDispatch& dispatch) {
|
||||||
auto deleter = [instance_ptr = *instance](VkSurfaceKHR handle, const vk::InstanceDispatch& dld) {
|
auto deleter = [instance_ptr = *instance](VkSurfaceKHR handle, const vk::InstanceDispatch& dld) {
|
||||||
dld.vkDestroySurfaceKHR(instance_ptr, handle, nullptr);
|
dld.vkDestroySurfaceKHR(instance_ptr, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiSurface(*surface, deleter, dispatch, "VkSurfaceKHR");
|
return ManagedSurface(*surface, deleter, dispatch, "VkSurfaceKHR");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan debug messenger
|
* Creates an RAII wrapper for a Vulkan debug messenger
|
||||||
*/
|
*/
|
||||||
inline RaiiDebugUtilsMessenger MakeDebugUtilsMessenger(const vk::DebugUtilsMessenger& messenger,
|
inline ManagedDebugUtilsMessenger MakeManagedDebugUtilsMessenger(const vk::DebugUtilsMessenger& messenger,
|
||||||
const vk::Instance& instance,
|
const vk::Instance& instance,
|
||||||
const vk::InstanceDispatch& dispatch) {
|
const vk::InstanceDispatch& dispatch) {
|
||||||
auto deleter = [instance_ptr = *instance](VkDebugUtilsMessengerEXT handle, const vk::InstanceDispatch& dld) {
|
auto deleter = [instance_ptr = *instance](VkDebugUtilsMessengerEXT handle, const vk::InstanceDispatch& dld) {
|
||||||
dld.vkDestroyDebugUtilsMessengerEXT(instance_ptr, handle, nullptr);
|
dld.vkDestroyDebugUtilsMessengerEXT(instance_ptr, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiDebugUtilsMessenger(*messenger, deleter, dispatch, "VkDebugUtilsMessengerEXT");
|
return ManagedDebugUtilsMessenger(*messenger, deleter, dispatch, "VkDebugUtilsMessengerEXT");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan swapchain
|
* Creates an RAII wrapper for a Vulkan swapchain
|
||||||
*/
|
*/
|
||||||
inline RaiiSwapchain MakeSwapchain(VkSwapchainKHR swapchain_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
inline ManagedSwapchain MakeManagedSwapchain(VkSwapchainKHR swapchain_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [device_handle](VkSwapchainKHR handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [device_handle](VkSwapchainKHR handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroySwapchainKHR(device_handle, handle, nullptr);
|
dld.vkDestroySwapchainKHR(device_handle, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiSwapchain(swapchain_handle, deleter, dispatch);
|
return ManagedSwapchain(swapchain_handle, deleter, dispatch, "VkSwapchainKHR");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan buffer
|
* Creates an RAII wrapper for a Vulkan buffer
|
||||||
*/
|
*/
|
||||||
inline RaiiBuffer MakeBuffer(VkBuffer buffer_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
inline ManagedBuffer MakeManagedBuffer(VkBuffer buffer_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [device_handle](VkBuffer handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [device_handle](VkBuffer handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroyBuffer(device_handle, handle, nullptr);
|
dld.vkDestroyBuffer(device_handle, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiBuffer(buffer_handle, deleter, dispatch);
|
return ManagedBuffer(buffer_handle, deleter, dispatch, "VkBuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan image
|
* Creates an RAII wrapper for a Vulkan image
|
||||||
*/
|
*/
|
||||||
inline RaiiImage MakeImage(VkImage image_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
inline ManagedImage MakeManagedImage(VkImage image_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [device_handle](VkImage handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [device_handle](VkImage handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroyImage(device_handle, handle, nullptr);
|
dld.vkDestroyImage(device_handle, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiImage(image_handle, deleter, dispatch);
|
return ManagedImage(image_handle, deleter, dispatch, "VkImage");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan image view
|
* Creates an RAII wrapper for a Vulkan image view
|
||||||
*/
|
*/
|
||||||
inline RaiiImageView MakeImageView(VkImageView view_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
inline ManagedImageView MakeManagedImageView(VkImageView view_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [device_handle](VkImageView handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [device_handle](VkImageView handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroyImageView(device_handle, handle, nullptr);
|
dld.vkDestroyImageView(device_handle, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiImageView(view_handle, deleter, dispatch);
|
return ManagedImageView(view_handle, deleter, dispatch, "VkImageView");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan semaphore
|
* Creates an RAII wrapper for a Vulkan semaphore
|
||||||
*/
|
*/
|
||||||
inline RaiiSemaphore MakeSemaphore(VkSemaphore semaphore_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
inline ManagedSemaphore MakeManagedSemaphore(VkSemaphore semaphore_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [device_handle](VkSemaphore handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [device_handle](VkSemaphore handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroySemaphore(device_handle, handle, nullptr);
|
dld.vkDestroySemaphore(device_handle, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiSemaphore(semaphore_handle, deleter, dispatch);
|
return ManagedSemaphore(semaphore_handle, deleter, dispatch, "VkSemaphore");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an RAII wrapper for a Vulkan fence
|
* Creates an RAII wrapper for a Vulkan fence
|
||||||
*/
|
*/
|
||||||
inline RaiiFence MakeFence(VkFence fence_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
inline ManagedFence MakeManagedFence(VkFence fence_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
|
||||||
auto deleter = [device_handle](VkFence handle, const vk::DeviceDispatch& dld) {
|
auto deleter = [device_handle](VkFence handle, const vk::DeviceDispatch& dld) {
|
||||||
dld.vkDestroyFence(device_handle, handle, nullptr);
|
dld.vkDestroyFence(device_handle, handle, nullptr);
|
||||||
};
|
};
|
||||||
return RaiiFence(fence_handle, deleter, dispatch);
|
return ManagedFence(fence_handle, deleter, dispatch, "VkFence");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
Loading…
Add table
Add a link
Reference in a new issue