Moved some functions to .cpp, modified preferred physical device.

Also adjusted the .clang-format for better legibility of code
This commit is contained in:
Charles Giessen 2020-02-06 15:46:14 -07:00
parent c30782a106
commit 8b33c46bf9
2 changed files with 328 additions and 544 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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;
};