Program Listing for File device.hpp¶
↰ Return to documentation for file (inexor/vulkan-renderer/wrapper/device.hpp
)
#pragma once
#include "inexor/vulkan-renderer/wrapper/command_pool.hpp"
#include <array>
#include <functional>
#include <optional>
#include <span>
#include <string>
namespace inexor::vulkan_renderer::wrapper {
// Forward declaration
class Instance;
struct DeviceInfo {
std::string name;
VkPhysicalDevice physical_device{nullptr};
VkPhysicalDeviceType type{VK_PHYSICAL_DEVICE_TYPE_OTHER};
VkDeviceSize total_device_local{0};
VkPhysicalDeviceFeatures features{};
std::vector<VkExtensionProperties> extensions;
bool presentation_supported{false};
bool swapchain_supported{false};
};
class Device {
VkDevice m_device{VK_NULL_HANDLE};
VkPhysicalDevice m_physical_device{VK_NULL_HANDLE};
VmaAllocator m_allocator{VK_NULL_HANDLE};
std::string m_gpu_name;
VkPhysicalDeviceFeatures m_enabled_features{};
VkQueue m_graphics_queue{VK_NULL_HANDLE};
VkQueue m_present_queue{VK_NULL_HANDLE};
VkQueue m_transfer_queue{VK_NULL_HANDLE};
std::uint32_t m_present_queue_family_index{0};
std::uint32_t m_graphics_queue_family_index{0};
std::uint32_t m_transfer_queue_family_index{0};
mutable std::vector<std::unique_ptr<CommandPool>> m_cmd_pools;
mutable std::mutex m_mutex;
// The debug marker extension is not part of the core, so function pointers need to be loaded manually
PFN_vkDebugMarkerSetObjectTagEXT m_vk_debug_marker_set_object_tag{nullptr};
PFN_vkDebugMarkerSetObjectNameEXT m_vk_debug_marker_set_object_name{nullptr};
PFN_vkCmdDebugMarkerBeginEXT m_vk_cmd_debug_marker_begin{nullptr};
PFN_vkCmdDebugMarkerEndEXT m_vk_cmd_debug_marker_end{nullptr};
PFN_vkCmdDebugMarkerInsertEXT m_vk_cmd_debug_marker_insert{nullptr};
PFN_vkSetDebugUtilsObjectNameEXT m_vk_set_debug_utils_object_name{nullptr};
CommandPool &thread_graphics_pool() const;
public:
static VkPhysicalDevice pick_best_physical_device(std::vector<DeviceInfo> &&physical_device_infos,
const VkPhysicalDeviceFeatures &required_features,
std::span<const char *> required_extensions);
static VkPhysicalDevice pick_best_physical_device(const Instance &inst, VkSurfaceKHR surface,
const VkPhysicalDeviceFeatures &required_features,
std::span<const char *> required_extensions);
Device(const Instance &inst, VkSurfaceKHR surface, bool prefer_distinct_transfer_queue,
VkPhysicalDevice physical_device, std::span<const char *> required_extensions,
const VkPhysicalDeviceFeatures &required_features, const VkPhysicalDeviceFeatures &optional_features = {});
Device(const Device &) = delete;
Device(Device &&) noexcept;
~Device();
Device &operator=(const Device &) = delete;
Device &operator=(Device &&) = delete;
[[nodiscard]] VkDevice device() const {
return m_device;
}
[[nodiscard]] VkSurfaceCapabilitiesKHR get_surface_capabilities(VkSurfaceKHR surface) const;
[[nodiscard]] bool format_supports_feature(VkFormat format, VkFormatFeatureFlagBits feature) const;
[[nodiscard]] bool is_presentation_supported(VkSurfaceKHR surface, std::uint32_t queue_family_index) const;
void execute(const std::string &name, const std::function<void(const CommandBuffer &cmd_buf)> &cmd_lambda) const;
std::optional<std::uint32_t> find_queue_family_index_if(
const std::function<bool(std::uint32_t index, const VkQueueFamilyProperties &)> &criteria_lambda);
[[nodiscard]] VkPhysicalDevice physical_device() const {
return m_physical_device;
}
[[nodiscard]] VmaAllocator allocator() const {
return m_allocator;
}
[[nodiscard]] const VkPhysicalDeviceFeatures &enabled_device_features() const {
return m_enabled_features;
}
[[nodiscard]] const std::string &gpu_name() const {
return m_gpu_name;
}
[[nodiscard]] VkQueue graphics_queue() const {
return m_graphics_queue;
}
[[nodiscard]] VkQueue present_queue() const {
return m_present_queue;
}
[[nodiscard]] VkQueue transfer_queue() const {
return m_transfer_queue;
}
[[nodiscard]] std::uint32_t graphics_queue_family_index() const {
return m_graphics_queue_family_index;
}
[[nodiscard]] std::uint32_t present_queue_family_index() const {
return m_present_queue_family_index;
}
[[nodiscard]] std::uint32_t transfer_queue_family_index() const {
return m_transfer_queue_family_index;
}
void set_debug_marker_name(void *object, VkDebugReportObjectTypeEXT object_type, const std::string &name) const;
void set_memory_block_attachment(void *object, VkDebugReportObjectTypeEXT object_type, std::uint64_t name,
std::size_t memory_size, const void *memory_block) const;
void bind_debug_region(VkCommandBuffer command_buffer, const std::string &name, std::array<float, 4> color) const;
void insert_debug_marker(VkCommandBuffer command_buffer, const std::string &name, std::array<float, 4> color) const;
void end_debug_region(VkCommandBuffer command_buffer) const;
void create_command_pool(const VkCommandPoolCreateInfo &command_pool_ci, VkCommandPool *command_pool,
const std::string &name) const;
void create_descriptor_pool(const VkDescriptorPoolCreateInfo &descriptor_pool_ci, VkDescriptorPool *descriptor_pool,
const std::string &name) const;
void create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo &descriptor_set_layout_ci,
VkDescriptorSetLayout *descriptor_set_layout, const std::string &name) const;
void create_fence(const VkFenceCreateInfo &fence_ci, VkFence *fence, const std::string &name) const;
void create_framebuffer(const VkFramebufferCreateInfo &framebuffer_ci, VkFramebuffer *framebuffer,
const std::string &name) const;
// TODO: Offer parameter for Vulkan pipeline caches!
// TODO: Use std::span to offer a more general method (creating multiple pipelines with one call)
// TODO: We might want to use std::span<std::pair<VkGraphicsPipelineCreateInfo, VkPipeline *>>
void create_graphics_pipeline(const VkGraphicsPipelineCreateInfo &pipeline_ci, VkPipeline *pipeline,
const std::string &name) const;
void create_image_view(const VkImageViewCreateInfo &image_view_ci, VkImageView *image_view,
const std::string &name) const;
void create_pipeline_layout(const VkPipelineLayoutCreateInfo &pipeline_layout_ci, VkPipelineLayout *pipeline_layout,
const std::string &name) const;
void create_render_pass(const VkRenderPassCreateInfo &render_pass_ci, VkRenderPass *render_pass,
const std::string &name) const;
void create_sampler(const VkSamplerCreateInfo &sampler_ci, VkSampler *sampler, const std::string &name) const;
void create_semaphore(const VkSemaphoreCreateInfo &semaphore_ci, VkSemaphore *semaphore,
const std::string &name) const;
void create_shader_module(const VkShaderModuleCreateInfo &shader_module_ci, VkShaderModule *shader_module,
const std::string &name) const;
void create_swapchain(const VkSwapchainCreateInfoKHR &swapchain_ci, VkSwapchainKHR *swapchain,
const std::string &name) const;
[[nodiscard]] const CommandBuffer &request_command_buffer(const std::string &name);
[[nodiscard]] bool surface_supports_usage(VkSurfaceKHR surface, VkImageUsageFlagBits usage) const;
void wait_idle() const;
};
} // namespace inexor::vulkan_renderer::wrapper