mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 07:24:34 +00:00
Moved some functions to .cpp, modified preferred physical device.
Also adjusted the .clang-format for better legibility of code
This commit is contained in:
parent
c30782a106
commit
8b33c46bf9
File diff suppressed because it is too large
Load Diff
@ -8,39 +8,32 @@
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace vkb {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace detail {
|
||||
|
||||
enum class BootstrapErrorType : uint32_t
|
||||
{
|
||||
enum class BootstrapErrorType : uint32_t {
|
||||
|
||||
};
|
||||
|
||||
struct Error
|
||||
{
|
||||
struct Error {
|
||||
VkResult error_code;
|
||||
const char* msg;
|
||||
};
|
||||
template <typename E, typename U> class Expected
|
||||
{
|
||||
template <typename E, typename U> class Expected {
|
||||
public:
|
||||
Expected (const E& expect) : m_expect{ expect }, m_init{ true } {}
|
||||
Expected (E&& expect) : m_expect{ std::move (expect) }, m_init{ true } {}
|
||||
Expected (const Error& error) : m_error{ error }, m_init{ false } {}
|
||||
Expected (Error&& error) : m_error{ std::move (error) }, m_init{ false } {}
|
||||
~Expected () { destroy (); }
|
||||
Expected (Expected const& expected) : m_init (expected.m_init)
|
||||
{
|
||||
Expected (Expected const& expected) : m_init (expected.m_init) {
|
||||
if (m_init)
|
||||
new (&m_expect) E{ expected.m_expect };
|
||||
else
|
||||
new (&m_error) Error{ expected.m_error };
|
||||
}
|
||||
Expected (Expected&& expected) : m_init (expected.m_init)
|
||||
{
|
||||
Expected (Expected&& expected) : m_init (expected.m_init) {
|
||||
if (m_init)
|
||||
new (&m_expect) E{ std::move (expected.m_expect) };
|
||||
else
|
||||
@ -48,29 +41,25 @@ template <typename E, typename U> class Expected
|
||||
expected.destroy ();
|
||||
}
|
||||
|
||||
Expected& operator= (const E& expect)
|
||||
{
|
||||
Expected& operator= (const E& expect) {
|
||||
destroy ();
|
||||
m_init = true;
|
||||
new (&m_expect) E{ expect };
|
||||
return *this;
|
||||
}
|
||||
Expected& operator= (E&& expect)
|
||||
{
|
||||
Expected& operator= (E&& expect) {
|
||||
destroy ();
|
||||
m_init = true;
|
||||
new (&m_expect) E{ std::move (expect) };
|
||||
return *this;
|
||||
}
|
||||
Expected& operator= (const Error& error)
|
||||
{
|
||||
Expected& operator= (const Error& error) {
|
||||
destroy ();
|
||||
m_init = false;
|
||||
new (&m_error) Error{ error };
|
||||
return *this;
|
||||
}
|
||||
Expected& operator= (Error&& error)
|
||||
{
|
||||
Expected& operator= (Error&& error) {
|
||||
destroy ();
|
||||
m_init = false;
|
||||
new (&m_error) Error{ std::move (error) };
|
||||
@ -95,8 +84,7 @@ template <typename E, typename U> class Expected
|
||||
explicit operator bool () const { return m_init; }
|
||||
|
||||
private:
|
||||
void destroy ()
|
||||
{
|
||||
void destroy () {
|
||||
if (m_init)
|
||||
m_expect.~E ();
|
||||
else
|
||||
@ -111,86 +99,27 @@ template <typename E, typename U> class Expected
|
||||
|
||||
/* TODO implement operator == and operator != as friend or global */
|
||||
|
||||
|
||||
// Helper for robustly executing the two-call pattern
|
||||
template <typename T, typename F, typename... Ts>
|
||||
auto get_vector_init (F&& f, T init, Ts&&... ts) -> Expected<std::vector<T>, VkResult>
|
||||
{
|
||||
uint32_t count = 0;
|
||||
std::vector<T> results;
|
||||
VkResult err;
|
||||
do
|
||||
{
|
||||
err = f (ts..., &count, nullptr);
|
||||
if (err)
|
||||
{
|
||||
return Error{ err, "" };
|
||||
};
|
||||
results.resize (count, init);
|
||||
err = f (ts..., &count, results.data ());
|
||||
} while (err == VK_INCOMPLETE);
|
||||
if (err)
|
||||
{
|
||||
return Error{ err, "" };
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename... Ts>
|
||||
auto get_vector (F&& f, Ts&&... ts) -> Expected<std::vector<T>, VkResult>
|
||||
{
|
||||
return get_vector_init (f, T (), ts...);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename... Ts>
|
||||
auto get_vector_noerror (F&& f, T init, Ts&&... ts) -> std::vector<T>
|
||||
{
|
||||
uint32_t count = 0;
|
||||
std::vector<T> results;
|
||||
f (ts..., &count, nullptr);
|
||||
results.resize (count, init);
|
||||
f (ts..., &count, results.data ());
|
||||
return results;
|
||||
}
|
||||
template <typename T, typename F, typename... Ts>
|
||||
auto get_vector_noerror (F&& f, Ts&&... ts) -> std::vector<T>
|
||||
{
|
||||
return get_vector_noerror (f, T (), ts...);
|
||||
}
|
||||
|
||||
VkResult create_debug_utils_messenger (VkInstance instance,
|
||||
PFN_vkDebugUtilsMessengerCallbackEXT debug_callback,
|
||||
VkDebugUtilsMessageSeverityFlagsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
||||
VkDebugUtilsMessengerEXT* pDebugMessenger);
|
||||
|
||||
void destroy_debug_utils_messenger (VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger);
|
||||
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData);
|
||||
|
||||
bool check_layers_supported (std::vector<const char*> layer_names);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
const char* to_string_message_severity (VkDebugUtilsMessageSeverityFlagBitsEXT s);
|
||||
const char* to_string_message_type (VkDebugUtilsMessageTypeFlagsEXT s);
|
||||
class InstanceBuilder;
|
||||
class PhysicalDeviceSelector;
|
||||
|
||||
struct Instance
|
||||
{
|
||||
struct Instance {
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkDebugUtilsMessengerEXT debug_messenger = VK_NULL_HANDLE;
|
||||
|
||||
private:
|
||||
bool headless = false;
|
||||
bool validation_enabled = false;
|
||||
bool debug_callback_enabled = false;
|
||||
|
||||
friend class InstanceBuilder;
|
||||
friend class PhysicalDeviceSelector;
|
||||
};
|
||||
|
||||
void destroy_instance (Instance instance); // release instance resources
|
||||
|
||||
class InstanceBuilder
|
||||
{
|
||||
class InstanceBuilder {
|
||||
public:
|
||||
detail::Expected<Instance, VkResult> build (); // use builder pattern
|
||||
|
||||
@ -219,8 +148,7 @@ class InstanceBuilder
|
||||
InstanceBuilder& add_validation_feature_disable (VkValidationFeatureDisableEXT disable);
|
||||
|
||||
private:
|
||||
struct InstanceInfo
|
||||
{
|
||||
struct InstanceInfo {
|
||||
// VkApplicationInfo
|
||||
std::string app_name;
|
||||
std::string engine_name;
|
||||
@ -255,21 +183,23 @@ class InstanceBuilder
|
||||
} info;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
const char* to_string_message_severity (VkDebugUtilsMessageSeverityFlagBitsEXT s);
|
||||
const char* to_string_message_type (VkDebugUtilsMessageTypeFlagsEXT s);
|
||||
|
||||
struct SurfaceSupportDetails
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
std::vector<VkSurfaceFormatKHR> formats;
|
||||
std::vector<VkPresentModeKHR> present_modes;
|
||||
};
|
||||
VkResult create_debug_utils_messenger (VkInstance instance,
|
||||
PFN_vkDebugUtilsMessengerCallbackEXT debug_callback,
|
||||
VkDebugUtilsMessageSeverityFlagsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
||||
VkDebugUtilsMessengerEXT* pDebugMessenger);
|
||||
|
||||
Expected<SurfaceSupportDetails, VkResult> query_surface_support_details (
|
||||
VkPhysicalDevice phys_device, VkSurfaceKHR surface);
|
||||
void destroy_debug_utils_messenger (VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger);
|
||||
|
||||
struct QueueFamilies
|
||||
{
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData);
|
||||
|
||||
struct QueueFamilies {
|
||||
int graphics = -1;
|
||||
int present = -1;
|
||||
int transfer = -1;
|
||||
@ -281,51 +211,35 @@ struct QueueFamilies
|
||||
uint32_t count_sparse = 0;
|
||||
};
|
||||
|
||||
VkFormat find_supported_format (VkPhysicalDevice physical_device,
|
||||
const std::vector<VkFormat>& candidates,
|
||||
VkImageTiling tiling,
|
||||
VkFormatFeatureFlags features);
|
||||
|
||||
std::vector<std::string> device_extension_support (VkPhysicalDevice device, std::vector<std::string> extensions);
|
||||
|
||||
detail::QueueFamilies find_queue_families (VkPhysicalDevice physDevice, VkSurfaceKHR windowSurface);
|
||||
|
||||
bool supports_features (VkPhysicalDeviceFeatures supported, VkPhysicalDeviceFeatures requested);
|
||||
|
||||
} // namespace detail
|
||||
QueueFamilies find_queue_families (VkPhysicalDevice phys_device, VkSurfaceKHR surface);
|
||||
|
||||
// ---- Physical Device ---- //
|
||||
|
||||
struct PhysicalDevice
|
||||
{
|
||||
struct PhysicalDevice {
|
||||
VkPhysicalDevice phys_device = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
|
||||
VkPhysicalDeviceFeatures physical_device_features{};
|
||||
VkPhysicalDeviceProperties physical_device_properties{};
|
||||
VkPhysicalDeviceFeatures features{};
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
VkPhysicalDeviceMemoryProperties memory_properties{};
|
||||
|
||||
detail::QueueFamilies queue_family_properties;
|
||||
QueueFamilies queue_family_properties;
|
||||
|
||||
std::vector<std::string> extensions_to_enable;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
void populate_physical_device_details (PhysicalDevice physical_device);
|
||||
} // namespace detail
|
||||
|
||||
struct PhysicalDeviceSelector
|
||||
{
|
||||
struct PhysicalDeviceSelector {
|
||||
public:
|
||||
PhysicalDeviceSelector (Instance instance);
|
||||
PhysicalDeviceSelector (Instance const& instance);
|
||||
|
||||
detail::Expected<PhysicalDevice, VkResult> select ();
|
||||
|
||||
PhysicalDeviceSelector& set_surface (VkSurfaceKHR instance);
|
||||
|
||||
PhysicalDeviceSelector& prefer_discrete (bool prefer_discrete = true);
|
||||
PhysicalDeviceSelector& prefer_integrated (bool prefer_integrated = true);
|
||||
PhysicalDeviceSelector& prefer_discrete ();
|
||||
PhysicalDeviceSelector& prefer_integrated ();
|
||||
PhysicalDeviceSelector& prefer_virtual_gpu ();
|
||||
|
||||
PhysicalDeviceSelector& allow_fallback (bool fallback = true);
|
||||
|
||||
PhysicalDeviceSelector& require_present (bool require = true);
|
||||
@ -344,17 +258,16 @@ struct PhysicalDeviceSelector
|
||||
PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features);
|
||||
|
||||
private:
|
||||
struct PhysicalDeviceInfo
|
||||
{
|
||||
struct PhysicalDeviceInfo {
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
bool headless = false;
|
||||
} info;
|
||||
|
||||
struct SelectionCriteria
|
||||
{
|
||||
bool prefer_discrete = true;
|
||||
bool prefer_integrated = false;
|
||||
enum PreferredDevice { discrete, integrated, virtual_gpu, cpu, dont_care };
|
||||
|
||||
struct SelectionCriteria {
|
||||
PreferredDevice preferred_type = PreferredDevice::discrete;
|
||||
bool allow_fallback = true;
|
||||
bool require_present = true;
|
||||
bool require_dedicated_transfer_queue = false;
|
||||
@ -369,23 +282,18 @@ struct PhysicalDeviceSelector
|
||||
uint32_t desired_version = VK_MAKE_VERSION (1, 0, 0);
|
||||
|
||||
VkPhysicalDeviceFeatures required_features{};
|
||||
VkPhysicalDeviceFeatures desired_features{};
|
||||
|
||||
} criteria;
|
||||
|
||||
enum class Suitable
|
||||
{
|
||||
yes,
|
||||
partial,
|
||||
no
|
||||
};
|
||||
enum class Suitable { yes, partial, no };
|
||||
|
||||
Suitable is_device_suitable (VkPhysicalDevice phys_device);
|
||||
};
|
||||
|
||||
// ---- Device ---- //
|
||||
|
||||
struct Device
|
||||
{
|
||||
struct Device {
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
PhysicalDevice physical_device;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
@ -393,8 +301,7 @@ struct Device
|
||||
|
||||
void destroy_device (Device device);
|
||||
|
||||
class DeviceBuilder
|
||||
{
|
||||
class DeviceBuilder {
|
||||
public:
|
||||
DeviceBuilder (PhysicalDevice device);
|
||||
detail::Expected<Device, VkResult> build ();
|
||||
@ -402,8 +309,7 @@ class DeviceBuilder
|
||||
template <typename T> DeviceBuilder& add_pNext (T* structure);
|
||||
|
||||
private:
|
||||
struct DeviceInfo
|
||||
{
|
||||
struct DeviceInfo {
|
||||
VkDeviceCreateFlags flags;
|
||||
std::vector<VkBaseOutStructure*> pNext_chain;
|
||||
PhysicalDevice physical_device;
|
||||
@ -413,11 +319,6 @@ class DeviceBuilder
|
||||
|
||||
// ---- Queue ---- //
|
||||
|
||||
namespace detail
|
||||
{
|
||||
VkQueue get_queue (Device const& device, uint32_t family, uint32_t index = 0);
|
||||
}
|
||||
|
||||
uint32_t get_queue_index_present (Device const& device);
|
||||
uint32_t get_queue_index_graphics (Device const& device);
|
||||
uint32_t get_queue_index_compute (Device const& device);
|
||||
@ -430,18 +331,7 @@ detail::Expected<VkQueue, VkResult> get_queue_compute (Device const& device, uin
|
||||
detail::Expected<VkQueue, VkResult> get_queue_transfer (Device const& device, uint32_t index = 0);
|
||||
detail::Expected<VkQueue, VkResult> get_queue_sparse (Device const& device, uint32_t index = 0);
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
VkSurfaceFormatKHR find_surface_format (std::vector<VkFormat> const& available_formats);
|
||||
VkPresentModeKHR find_present_mode (std::vector<VkPresentModeKHR> const& available_present_modes,
|
||||
std::vector<VkPresentModeKHR> const& desired_present_modes);
|
||||
VkExtent2D find_extent (
|
||||
VkSurfaceCapabilitiesKHR const& capabilities, uint32_t desired_width, uint32_t desired_height);
|
||||
} // namespace detail
|
||||
|
||||
struct Swapchain
|
||||
{
|
||||
struct Swapchain {
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
||||
uint32_t image_count = 0;
|
||||
@ -454,8 +344,7 @@ detail::Expected<std::vector<VkImage>, VkResult> get_swapchain_images (Swapchain
|
||||
detail::Expected<std::vector<VkImageView>, VkResult> get_swapchain_image_views (
|
||||
Swapchain const& swapchain, std::vector<VkImage> const& images);
|
||||
|
||||
class SwapchainBuilder
|
||||
{
|
||||
class SwapchainBuilder {
|
||||
public:
|
||||
SwapchainBuilder (Device const& device);
|
||||
SwapchainBuilder (VkPhysicalDevice const physical_device, VkDevice const device, VkSurfaceKHR const surface);
|
||||
@ -474,9 +363,10 @@ class SwapchainBuilder
|
||||
SwapchainBuilder& add_fallback_present_mode (VkPresentModeKHR present_mode);
|
||||
SwapchainBuilder& use_default_present_mode_selection ();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
struct SwapchainInfo
|
||||
{
|
||||
struct SwapchainInfo {
|
||||
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
@ -485,6 +375,7 @@ class SwapchainBuilder
|
||||
std::vector<VkPresentModeKHR> desired_present_modes;
|
||||
uint32_t desired_width = 256;
|
||||
uint32_t desired_height = 256;
|
||||
std::vector<VkBaseOutStructure*> pNext_elements;
|
||||
} info;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user