mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 15:24:34 +00:00
Ammended readme and moved around code for better readability
This commit is contained in:
parent
1014c836cb
commit
f74ee5e9fc
13
README.md
13
README.md
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -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,54 +894,43 @@ 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) {
|
||||||
index = detail::get_present_queue_index (physical_device.phys_device, surface, queue_families);
|
case QueueType::present:
|
||||||
if (index < 0) return detail::Error<QueueError>{ QueueError::present_unavailable };
|
index = detail::get_present_queue_index (physical_device.phys_device, surface, queue_families);
|
||||||
} else if (type == QueueType::graphics) {
|
if (index < 0) return detail::Error<QueueError>{ QueueError::present_unavailable };
|
||||||
index = detail::get_graphics_queue_index (queue_families);
|
break;
|
||||||
if (index < 0) return detail::Error<QueueError>{ QueueError::graphics_unavailable };
|
case QueueType::graphics:
|
||||||
} else if (type == QueueType::compute) {
|
index = detail::get_graphics_queue_index (queue_families);
|
||||||
index = detail::get_separate_compute_queue_index (queue_families);
|
if (index < 0) return detail::Error<QueueError>{ QueueError::graphics_unavailable };
|
||||||
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
break;
|
||||||
} else if (type == QueueType::transfer) {
|
case QueueType::compute:
|
||||||
index = detail::get_separate_transfer_queue_index (queue_families);
|
index = detail::get_separate_compute_queue_index (queue_families);
|
||||||
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||||
} else if (index == -1) {
|
break;
|
||||||
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
|
case QueueType::transfer:
|
||||||
|
index = detail::get_separate_transfer_queue_index (queue_families);
|
||||||
|
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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) {
|
||||||
index = detail::get_dedicated_compute_queue_index (queue_families);
|
case QueueType::compute:
|
||||||
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
index = detail::get_dedicated_compute_queue_index (queue_families);
|
||||||
} else if (type == QueueType::transfer) {
|
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||||
index = detail::get_dedicated_transfer_queue_index (queue_families);
|
break;
|
||||||
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
case QueueType::transfer:
|
||||||
} else if (index == -1) {
|
index = detail::get_dedicated_transfer_queue_index (queue_families);
|
||||||
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
|
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user