Ammended readme and moved around code for better readability

This commit is contained in:
Charles Giessen 2020-03-07 17:19:58 -07:00
parent 1014c836cb
commit f74ee5e9fc
3 changed files with 146 additions and 142 deletions

View File

@ -25,9 +25,9 @@ It also adds several conveniences for:
void init_vulkan() void init_vulkan()
{ {
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
builder.check_and_setup_validation_layers() builder.request_validation_layers()
.set_app_name ("Example Vulkan Application") .set_app_name ("Example Vulkan Application")
.set_default_debug_messenger (); .use_default_debug_messenger ();
auto inst_ret = builder.build(); auto inst_ret = builder.build();
if (!inst_ret.has_value()) { if (!inst_ret.has_value()) {
// error // error
@ -37,7 +37,7 @@ void init_vulkan()
vkb::PhysicalDeviceSelector selector{ inst }; vkb::PhysicalDeviceSelector selector{ inst };
selector.set_surface (/* from user created window*/) selector.set_surface (/* from user created window*/)
.set_minimum_version (1, 1) //require a vulkan 1.1 capable device .set_minimum_version (1, 1) //require a vulkan 1.1 capable device
.require_dedicated_transfer_queue(); //require a transfer queue .require_dedicated_transfer_queue();
auto phys_ret = selector.select (); auto phys_ret = selector.select ();
if (!phys_ret.has_value()) { if (!phys_ret.has_value()) {
// error // error
@ -48,18 +48,19 @@ void init_vulkan()
if (!dev_ret.has_value()){ if (!dev_ret.has_value()){
// error // error
} }
vkb::Device dev = dev_ret.value();
// Get the VkDevice handle used in the rest of a vulkan application // Get the VkDevice handle used in the rest of a vulkan application
VkDevice device = dev_ret.value().device; VkDevice device = dev.device;
// Get the graphics queue with a helper function // Get the graphics queue with a helper function
auto graphics_queue_ret = vkb::get_graphics_queue(dev_ret.value()); auto graphics_queue_ret = dev.get_queue(vkb::QueueType::graphics);
if (!graphics_queue_ret.has_value()){ if (!graphics_queue_ret.has_value()){
// error // error
} }
VkQueue graphics_queue = graphics_queue_ret.value(); VkQueue graphics_queue = graphics_queue_ret.value();
// Reduced 400-500 lines of boilerplate to a less than fifty. // Turned 400-500 lines of boilerplate into less than fifty.
} }
``` ```

View File

@ -159,6 +159,73 @@ const char* validation_layer_name = "VK_LAYER_KHRONOS_validation";
} // namespace detail } // namespace detail
const char* to_string (InstanceError err) {
switch (err) {
case InstanceError::failed_create_debug_messenger:
return "failed_create_debug_messenger";
case InstanceError::failed_create_instance:
return "failed_create_instance";
case InstanceError::requested_layers_not_present:
return "requested_layers_not_present";
case InstanceError::requested_extensions_not_present:
return "requested_extensions_not_present";
default:
return "";
}
}
const char* to_string (PhysicalDeviceError err) {
switch (err) {
case PhysicalDeviceError::failed_enumerate_physical_devices:
return "failed_enumerate_physical_devices";
case PhysicalDeviceError::no_physical_devices_found:
return "no_physical_devices_found";
case PhysicalDeviceError::no_suitable_device:
return "no_suitable_device";
default:
return "";
}
}
const char* to_string (QueueError err) {
switch (err) {
case QueueError::present_unavailable:
return "present_unavailable";
case QueueError::graphics_unavailable:
return "graphics_unavailable";
case QueueError::compute_unavailable:
return "compute_unavailable";
case QueueError::transfer_unavailable:
return "transfer_unavailable";
case QueueError::queue_index_out_of_range:
return "queue_index_out_of_range";
case QueueError::invalid_queue_family_index:
return "invalid_queue_family_index";
default:
return "";
}
}
const char* to_string (DeviceError err) {
switch (err) {
case DeviceError::failed_create_device:
return "failed_create_device";
default:
return "";
}
}
const char* to_string (SwapchainError err) {
switch (err) {
case SwapchainError::failed_query_surface_support_details:
return "failed_query_surface_support_details";
case SwapchainError::failed_create_swapchain:
return "failed_create_swapchain";
case SwapchainError::failed_get_swapchain_images:
return "failed_get_swapchain_images";
case SwapchainError::failed_create_swapchain_image_views:
return "failed_create_swapchain_image_views";
default:
return "";
}
}
SystemInfo::SystemInfo () { SystemInfo::SystemInfo () {
auto available_extensions = auto available_extensions =
detail::get_vector<VkExtensionProperties> (vkEnumerateInstanceExtensionProperties, nullptr); detail::get_vector<VkExtensionProperties> (vkEnumerateInstanceExtensionProperties, nullptr);
@ -186,21 +253,6 @@ bool SystemInfo::is_layer_available (const char* layer_name) {
return detail::check_layer_supported (available_layers, layer_name); return detail::check_layer_supported (available_layers, layer_name);
} }
const char* to_string (InstanceError err) {
switch (err) {
case InstanceError::failed_create_debug_messenger:
return "failed_create_debug_messenger";
case InstanceError::failed_create_instance:
return "failed_create_instance";
case InstanceError::requested_layers_not_present:
return "requested_layers_not_present";
case InstanceError::requested_extensions_not_present:
return "requested_extensions_not_present";
default:
return "";
}
}
void destroy_instance (Instance instance) { void destroy_instance (Instance instance) {
if (instance.instance != VK_NULL_HANDLE) { if (instance.instance != VK_NULL_HANDLE) {
if (instance.debug_messenger != nullptr) if (instance.debug_messenger != nullptr)
@ -607,19 +659,6 @@ int get_present_queue_index (VkPhysicalDevice const phys_device,
} // namespace detail } // namespace detail
const char* to_string (PhysicalDeviceError err) {
switch (err) {
case PhysicalDeviceError::failed_enumerate_physical_devices:
return "failed_enumerate_physical_devices";
case PhysicalDeviceError::no_physical_devices_found:
return "no_physical_devices_found";
case PhysicalDeviceError::no_suitable_device:
return "no_suitable_device";
default:
return "";
}
}
PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details ( PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details (
VkPhysicalDevice phys_device) { VkPhysicalDevice phys_device) {
PhysicalDeviceSelector::PhysicalDeviceDesc desc{}; PhysicalDeviceSelector::PhysicalDeviceDesc desc{};
@ -855,53 +894,42 @@ bool PhysicalDevice::has_separate_transfer_queue () {
// ---- Queues ---- // // ---- Queues ---- //
const char* to_string (QueueError err) {
switch (err) {
case QueueError::present_unavailable:
return "present_unavailable";
case QueueError::graphics_unavailable:
return "graphics_unavailable";
case QueueError::compute_unavailable:
return "compute_unavailable";
case QueueError::transfer_unavailable:
return "transfer_unavailable";
case QueueError::queue_index_out_of_range:
return "queue_index_out_of_range";
case QueueError::invalid_queue_family_index:
return "invalid_queue_family_index";
default:
return "";
}
}
detail::Expected<int32_t, detail::Error<QueueError>> Device::get_queue_index (QueueType type) const { detail::Expected<int32_t, detail::Error<QueueError>> Device::get_queue_index (QueueType type) const {
int index = -1; int index = -1;
if (type == QueueType::present) { switch (type) {
case QueueType::present:
index = detail::get_present_queue_index (physical_device.phys_device, surface, queue_families); index = detail::get_present_queue_index (physical_device.phys_device, surface, queue_families);
if (index < 0) return detail::Error<QueueError>{ QueueError::present_unavailable }; if (index < 0) return detail::Error<QueueError>{ QueueError::present_unavailable };
} else if (type == QueueType::graphics) { break;
case QueueType::graphics:
index = detail::get_graphics_queue_index (queue_families); index = detail::get_graphics_queue_index (queue_families);
if (index < 0) return detail::Error<QueueError>{ QueueError::graphics_unavailable }; if (index < 0) return detail::Error<QueueError>{ QueueError::graphics_unavailable };
} else if (type == QueueType::compute) { break;
case QueueType::compute:
index = detail::get_separate_compute_queue_index (queue_families); index = detail::get_separate_compute_queue_index (queue_families);
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable }; if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
} else if (type == QueueType::transfer) { break;
case QueueType::transfer:
index = detail::get_separate_transfer_queue_index (queue_families); index = detail::get_separate_transfer_queue_index (queue_families);
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable }; if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
} else if (index == -1) { break;
default:
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index }; return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
} }
return index; return index;
} } // namespace vkb
detail::Expected<int32_t, detail::Error<QueueError>> Device::get_dedicated_queue_index (QueueType type) const { detail::Expected<int32_t, detail::Error<QueueError>> Device::get_dedicated_queue_index (QueueType type) const {
int index = -1; int index = -1;
if (type == QueueType::compute) { switch (type) {
case QueueType::compute:
index = detail::get_dedicated_compute_queue_index (queue_families); index = detail::get_dedicated_compute_queue_index (queue_families);
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable }; if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
} else if (type == QueueType::transfer) { break;
case QueueType::transfer:
index = detail::get_dedicated_transfer_queue_index (queue_families); index = detail::get_dedicated_transfer_queue_index (queue_families);
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable }; if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
} else if (index == -1) { break;
default:
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index }; return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
} }
return index; return index;
@ -926,15 +954,6 @@ detail::Expected<VkQueue, detail::Error<QueueError>> Device::get_dedicated_queue
// ---- Device ---- // // ---- Device ---- //
const char* to_string (DeviceError err) {
switch (err) {
case DeviceError::failed_create_device:
return "failed_create_device";
default:
return "";
}
}
void destroy_device (Device device) { void destroy_device (Device device) {
vkDestroyDevice (device.device, device.allocation_callbacks); vkDestroyDevice (device.device, device.allocation_callbacks);
} }
@ -1059,21 +1078,6 @@ VkExtent2D find_extent (
} }
} // namespace detail } // namespace detail
const char* to_string (SwapchainError err) {
switch (err) {
case SwapchainError::failed_query_surface_support_details:
return "failed_query_surface_support_details";
case SwapchainError::failed_create_swapchain:
return "failed_create_swapchain";
case SwapchainError::failed_get_swapchain_images:
return "failed_get_swapchain_images";
case SwapchainError::failed_create_swapchain_image_views:
return "failed_create_swapchain_image_views";
default:
return "";
}
}
SwapchainBuilder::SwapchainBuilder (Device const& device) { SwapchainBuilder::SwapchainBuilder (Device const& device) {
info.device = device.device; info.device = device.device;
info.physical_device = device.physical_device.phys_device; info.physical_device = device.physical_device.phys_device;

View File

@ -97,6 +97,44 @@ template <typename E, typename U> class Expected {
/* TODO implement operator == and operator != as friend or global */ /* TODO implement operator == and operator != as friend or global */
} // namespace detail } // namespace detail
enum class InstanceError {
failed_create_instance,
failed_create_debug_messenger,
requested_layers_not_present,
requested_extensions_not_present
};
enum class PhysicalDeviceError {
failed_enumerate_physical_devices,
no_physical_devices_found,
no_suitable_device,
};
enum class QueueError {
present_unavailable,
graphics_unavailable,
compute_unavailable,
transfer_unavailable,
queue_index_out_of_range,
invalid_queue_family_index
};
enum class DeviceError {
failed_create_device,
};
enum class SwapchainError {
failed_query_surface_support_details,
failed_create_swapchain,
failed_get_swapchain_images,
failed_create_swapchain_image_views,
};
const char* to_string_message_severity (VkDebugUtilsMessageSeverityFlagBitsEXT s);
const char* to_string_message_type (VkDebugUtilsMessageTypeFlagsEXT s);
const char* to_string (InstanceError err);
const char* to_string (PhysicalDeviceError err);
const char* to_string (QueueError err);
const char* to_string (DeviceError err);
const char* to_string (SwapchainError err);
struct SystemInfo { struct SystemInfo {
SystemInfo (); SystemInfo ();
// Returns true if a layer is available // Returns true if a layer is available
@ -110,13 +148,6 @@ struct SystemInfo {
bool debug_messenger_available = false; bool debug_messenger_available = false;
}; };
enum class InstanceError {
failed_create_instance,
failed_create_debug_messenger,
requested_layers_not_present,
requested_extensions_not_present
};
const char* to_string (InstanceError err);
class InstanceBuilder; class InstanceBuilder;
class PhysicalDeviceSelector; class PhysicalDeviceSelector;
@ -233,9 +264,6 @@ class InstanceBuilder {
SystemInfo system; SystemInfo system;
}; };
const char* to_string_message_severity (VkDebugUtilsMessageSeverityFlagBitsEXT s);
const char* to_string_message_type (VkDebugUtilsMessageTypeFlagsEXT s);
VkResult create_debug_utils_messenger (VkInstance instance, VkResult create_debug_utils_messenger (VkInstance instance,
PFN_vkDebugUtilsMessengerCallbackEXT debug_callback, PFN_vkDebugUtilsMessengerCallbackEXT debug_callback,
VkDebugUtilsMessageSeverityFlagsEXT severity, VkDebugUtilsMessageSeverityFlagsEXT severity,
@ -253,14 +281,6 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessag
void* pUserData); void* pUserData);
// ---- Physical Device ---- // // ---- Physical Device ---- //
enum class PhysicalDeviceError {
failed_enumerate_physical_devices,
no_physical_devices_found,
no_suitable_device,
};
const char* to_string (PhysicalDeviceError err);
class PhysicalDeviceSelector; class PhysicalDeviceSelector;
class DeviceBuilder; class DeviceBuilder;
@ -392,25 +412,10 @@ class PhysicalDeviceSelector {
Suitable is_device_suitable (PhysicalDeviceDesc phys_device); Suitable is_device_suitable (PhysicalDeviceDesc phys_device);
}; };
// ---- Queues ---- // // ---- Queue ---- //
enum class QueueType { present, graphics, compute, transfer }; enum class QueueType { present, graphics, compute, transfer };
enum class QueueError {
present_unavailable,
graphics_unavailable,
compute_unavailable,
transfer_unavailable,
queue_index_out_of_range,
invalid_queue_family_index
};
const char* to_string (QueueError err);
// ---- Device ---- // // ---- Device ---- //
enum class DeviceError {
failed_create_device,
};
const char* to_string (DeviceError err);
struct Device { struct Device {
VkDevice device = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE;
@ -420,9 +425,11 @@ struct Device {
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE; VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
detail::Expected<int32_t, detail::Error<QueueError>> get_queue_index (QueueType type) const; detail::Expected<int32_t, detail::Error<QueueError>> get_queue_index (QueueType type) const;
// Only a compute or transfer queue type is valid. All other queue types do not support a 'dedicated' queue index
detail::Expected<int32_t, detail::Error<QueueError>> get_dedicated_queue_index (QueueType type) const; detail::Expected<int32_t, detail::Error<QueueError>> get_dedicated_queue_index (QueueType type) const;
detail::Expected<VkQueue, detail::Error<QueueError>> get_queue (QueueType type) const; detail::Expected<VkQueue, detail::Error<QueueError>> get_queue (QueueType type) const;
// Only a compute or transfer queue type is valid. All other queue types do not support a 'dedicated' queue
detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_queue (QueueType type) const; detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_queue (QueueType type) const;
}; };
@ -466,14 +473,6 @@ class DeviceBuilder {
}; };
// ---- Swapchain ---- // // ---- Swapchain ---- //
enum class SwapchainError {
failed_query_surface_support_details,
failed_create_swapchain,
failed_get_swapchain_images,
failed_create_swapchain_image_views,
};
const char* to_string (SwapchainError err);
struct Swapchain { struct Swapchain {
VkDevice device = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE;
VkSwapchainKHR swapchain = VK_NULL_HANDLE; VkSwapchainKHR swapchain = VK_NULL_HANDLE;