221 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
 | 
						|
#include <memory/pointer_types/null_on_move.hpp>
 | 
						|
#include <renderer/backend/vk/vulkan.hpp>
 | 
						|
#include <renderer/frontend/context/device.hpp>
 | 
						|
#include <renderer/frontend/context/gpu.hpp>
 | 
						|
#include <renderer/frontend/context/surface.hpp>
 | 
						|
 | 
						|
namespace lt::renderer::vk {
 | 
						|
 | 
						|
class Device: public IDevice
 | 
						|
{
 | 
						|
public:
 | 
						|
	Device(IGpu *gpu, ISurface *surface);
 | 
						|
 | 
						|
	~Device() override;
 | 
						|
 | 
						|
	Device(Device &&) = default;
 | 
						|
 | 
						|
	Device(const Device &) = delete;
 | 
						|
 | 
						|
	auto operator=(Device &&) -> Device & = default;
 | 
						|
 | 
						|
	auto operator=(const Device &) const -> Device & = delete;
 | 
						|
 | 
						|
	[[nodiscard]] auto vk() const -> VkDevice
 | 
						|
	{
 | 
						|
		return m_device;
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] auto get_family_indices() const -> std::array<uint32_t, 2>
 | 
						|
	{
 | 
						|
		return { m_graphics_queue_family_index, m_present_queue_family_index };
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] auto get_graphics_queue() const -> VkQueue
 | 
						|
	{
 | 
						|
		return m_graphics_queue;
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] auto get_present_queue() const -> VkQueue
 | 
						|
	{
 | 
						|
		return m_present_queue;
 | 
						|
	}
 | 
						|
 | 
						|
	/** utilities */
 | 
						|
	template<typename T, typename... Args>
 | 
						|
	void name(const T &object, std::format_string<Args...> fmt, Args &&...args)
 | 
						|
	{
 | 
						|
		const auto name = std::format(fmt, std::forward<Args>(args)...);
 | 
						|
		auto info = VkDebugUtilsObjectNameInfoEXT {
 | 
						|
			.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
 | 
						|
			.objectType = get_object_type(object),
 | 
						|
			.objectHandle = (uint64_t)(object),
 | 
						|
			.pObjectName = name.c_str(),
 | 
						|
		};
 | 
						|
 | 
						|
		vk_set_debug_object_name(m_device, &info);
 | 
						|
	}
 | 
						|
 | 
						|
	template<typename T>
 | 
						|
	void name(const T &object, const char *name)
 | 
						|
	{
 | 
						|
		auto info = VkDebugUtilsObjectNameInfoEXT {
 | 
						|
			.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
 | 
						|
			.objectType = get_object_type(object),
 | 
						|
			.objectHandle = (uint64_t)(object),
 | 
						|
			.pObjectName = name,
 | 
						|
		};
 | 
						|
 | 
						|
		vk_set_debug_object_name(m_device, &info);
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/** work functions */
 | 
						|
	void submit(VkSubmitInfo info, VkFence fence) const;
 | 
						|
 | 
						|
	void present(VkPresentInfoKHR info) const;
 | 
						|
 | 
						|
	void wait_idle() const;
 | 
						|
 | 
						|
	void wait_for_fence(VkFence fence) const;
 | 
						|
 | 
						|
	void wait_for_fences(std::span<VkFence> fences) const;
 | 
						|
 | 
						|
	void reset_fence(VkFence fence) const;
 | 
						|
 | 
						|
	void reset_fences(std::span<VkFence> fences) const;
 | 
						|
 | 
						|
	/** getter functions */
 | 
						|
	[[nodiscard]] auto acquire_image(
 | 
						|
	    VkSwapchainKHR swapchain,
 | 
						|
	    VkSemaphore semaphore,
 | 
						|
	    uint64_t timeout = 100'000'000
 | 
						|
	) -> std::optional<uint32_t>;
 | 
						|
 | 
						|
	[[nodiscard]] auto get_swapchain_images(VkSwapchainKHR swapchain) const -> std::vector<VkImage>;
 | 
						|
 | 
						|
	/** create functions */
 | 
						|
	[[nodiscard]] auto create_swapchain(VkSwapchainCreateInfoKHR info) const -> VkSwapchainKHR;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_framebuffer(VkFramebufferCreateInfo info) const -> VkFramebuffer;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_image_view(VkImageViewCreateInfo info) const -> VkImageView;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_graphics_pipeline(VkGraphicsPipelineCreateInfo info) const
 | 
						|
	    -> VkPipeline;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_pass(VkRenderPassCreateInfo info) const -> VkRenderPass;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_pipeline_layout(VkPipelineLayoutCreateInfo info) const
 | 
						|
	    -> VkPipelineLayout;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_shader_module(VkShaderModuleCreateInfo info) const -> VkShaderModule;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_command_pool(VkCommandPoolCreateInfo info) const -> VkCommandPool;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_semaphores(uint32_t count) const -> std::vector<VkSemaphore>;
 | 
						|
 | 
						|
	[[nodiscard]] auto create_fences(VkFenceCreateInfo info, uint32_t count) const
 | 
						|
	    -> std::vector<VkFence>;
 | 
						|
 | 
						|
	/** allocation functions */
 | 
						|
	[[nodiscard]] auto allocate_command_buffers(VkCommandBufferAllocateInfo info) const
 | 
						|
	    -> std::vector<VkCommandBuffer>;
 | 
						|
 | 
						|
	/** destroy functions */
 | 
						|
	void destroy_swapchain(VkSwapchainKHR swapchain) const;
 | 
						|
 | 
						|
	void destroy_framebuffer(VkFramebuffer framebuffer) const;
 | 
						|
 | 
						|
	void destroy_framebuffers(std::span<VkFramebuffer> framebuffers) const;
 | 
						|
 | 
						|
	void destroy_image_view(VkImageView image_view) const;
 | 
						|
 | 
						|
	void destroy_image_views(std::span<VkImageView> image_views) const;
 | 
						|
 | 
						|
	void destroy_pipeline(VkPipeline pipeline) const;
 | 
						|
 | 
						|
	void destroy_pass(VkRenderPass pass) const;
 | 
						|
 | 
						|
	void destroy_pipeline_layout(VkPipelineLayout pipeline_layout) const;
 | 
						|
 | 
						|
	void destroy_shader_module(VkShaderModule shader_module) const;
 | 
						|
 | 
						|
	void destroy_command_pool(VkCommandPool command_pool) const;
 | 
						|
 | 
						|
	void destroy_semaphore(VkSemaphore semaphore) const;
 | 
						|
 | 
						|
	void destroy_semaphores(std::span<VkSemaphore> semaphores) const;
 | 
						|
 | 
						|
	void destroy_fence(VkFence fence) const;
 | 
						|
 | 
						|
	void destroy_fences(std::span<VkFence> fences) const;
 | 
						|
 | 
						|
private:
 | 
						|
	template<typename T>
 | 
						|
	static auto get_object_type(const T &object) -> VkObjectType
 | 
						|
	{
 | 
						|
		std::ignore = object;
 | 
						|
 | 
						|
		if constexpr (std::is_same_v<T, VkQueue>)
 | 
						|
		{
 | 
						|
			return VK_OBJECT_TYPE_QUEUE;
 | 
						|
		}
 | 
						|
 | 
						|
		if constexpr (std::is_same_v<T, VkFence>)
 | 
						|
		{
 | 
						|
			return VK_OBJECT_TYPE_FENCE;
 | 
						|
		}
 | 
						|
 | 
						|
		if constexpr (std::is_same_v<T, VkSemaphore>)
 | 
						|
		{
 | 
						|
			return VK_OBJECT_TYPE_SEMAPHORE;
 | 
						|
		}
 | 
						|
 | 
						|
		if constexpr (std::is_same_v<T, VkSwapchainKHR>)
 | 
						|
		{
 | 
						|
			return VK_OBJECT_TYPE_SWAPCHAIN_KHR;
 | 
						|
		}
 | 
						|
 | 
						|
		if constexpr (std::is_same_v<T, VkImage>)
 | 
						|
		{
 | 
						|
			return VK_OBJECT_TYPE_IMAGE;
 | 
						|
		}
 | 
						|
 | 
						|
		if constexpr (std::is_same_v<T, VkImageView>)
 | 
						|
		{
 | 
						|
			return VK_OBJECT_TYPE_IMAGE_VIEW;
 | 
						|
		}
 | 
						|
 | 
						|
		static_assert("invalid type");
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	void initialize_physical_device();
 | 
						|
 | 
						|
	void initialize_logical_device();
 | 
						|
 | 
						|
	void initialize_queue_indices();
 | 
						|
 | 
						|
	[[nodiscard]] auto find_suitable_queue_family() const -> uint32_t;
 | 
						|
 | 
						|
	memory::NullOnMove<class Gpu *> m_gpu {};
 | 
						|
 | 
						|
	class Surface *m_surface {};
 | 
						|
 | 
						|
	VkAllocationCallbacks *m_allocator = nullptr;
 | 
						|
 | 
						|
	VkDevice m_device = VK_NULL_HANDLE;
 | 
						|
 | 
						|
	VkQueue m_graphics_queue = VK_NULL_HANDLE;
 | 
						|
 | 
						|
	VkQueue m_present_queue = VK_NULL_HANDLE;
 | 
						|
 | 
						|
	uint32_t m_graphics_queue_family_index = VK_QUEUE_FAMILY_IGNORED;
 | 
						|
 | 
						|
	uint32_t m_present_queue_family_index = VK_QUEUE_FAMILY_IGNORED;
 | 
						|
};
 | 
						|
 | 
						|
} // namespace lt::renderer::vk
 |