mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 07:24:34 +00:00
Refactor of queue selection and getting
This commit is contained in:
parent
83fd58348b
commit
1014c836cb
@ -75,13 +75,14 @@ int device_initialization (Init& init) {
|
||||
}
|
||||
|
||||
int get_queues (Init& init, RenderData& data) {
|
||||
auto gq = vkb::get_graphics_queue (init.device);
|
||||
auto gq = init.device.get_queue (vkb::QueueType::graphics);
|
||||
if (!gq.has_value ()) {
|
||||
std::cout << "failed to get graphics queue\n";
|
||||
return -1;
|
||||
}
|
||||
data.graphics_queue = gq.value ();
|
||||
auto pq = vkb::get_present_queue (init.device);
|
||||
|
||||
auto pq = init.device.get_queue (vkb::QueueType::present);
|
||||
if (!pq.has_value ()) {
|
||||
std::cout << "failed to get present queue\n";
|
||||
return -1;
|
||||
@ -314,7 +315,7 @@ int create_framebuffers (Init& init, RenderData& data) {
|
||||
int create_command_pool (Init& init, RenderData& data) {
|
||||
VkCommandPoolCreateInfo pool_info = {};
|
||||
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
pool_info.queueFamilyIndex = vkb::get_graphics_queue_index (init.device).value ();
|
||||
pool_info.queueFamilyIndex = init.device.get_queue_index (vkb::QueueType::graphics).value ();
|
||||
|
||||
if (vkCreateCommandPool (init.device.device, &pool_info, nullptr, &data.command_pool) != VK_SUCCESS) {
|
||||
return -1; // failed to create command pool
|
||||
|
@ -840,7 +840,92 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditiona
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool PhysicalDevice::has_dedicated_compute_queue () {
|
||||
return detail::get_dedicated_compute_queue_index (queue_families) >= 0;
|
||||
}
|
||||
bool PhysicalDevice::has_separate_compute_queue () {
|
||||
return detail::get_separate_compute_queue_index (queue_families) >= 0;
|
||||
}
|
||||
bool PhysicalDevice::has_dedicated_transfer_queue () {
|
||||
return detail::get_dedicated_transfer_queue_index (queue_families) >= 0;
|
||||
}
|
||||
bool PhysicalDevice::has_separate_transfer_queue () {
|
||||
return detail::get_separate_transfer_queue_index (queue_families) >= 0;
|
||||
}
|
||||
|
||||
// ---- 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 {
|
||||
int index = -1;
|
||||
if (type == QueueType::present) {
|
||||
index = detail::get_present_queue_index (physical_device.phys_device, surface, queue_families);
|
||||
if (index < 0) return detail::Error<QueueError>{ QueueError::present_unavailable };
|
||||
} else if (type == QueueType::graphics) {
|
||||
index = detail::get_graphics_queue_index (queue_families);
|
||||
if (index < 0) return detail::Error<QueueError>{ QueueError::graphics_unavailable };
|
||||
} else if (type == QueueType::compute) {
|
||||
index = detail::get_separate_compute_queue_index (queue_families);
|
||||
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||
} else if (type == QueueType::transfer) {
|
||||
index = detail::get_separate_transfer_queue_index (queue_families);
|
||||
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||
} else if (index == -1) {
|
||||
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
|
||||
}
|
||||
return index;
|
||||
}
|
||||
detail::Expected<int32_t, detail::Error<QueueError>> Device::get_dedicated_queue_index (QueueType type) const {
|
||||
int index = -1;
|
||||
if (type == QueueType::compute) {
|
||||
index = detail::get_dedicated_compute_queue_index (queue_families);
|
||||
if (index < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||
} else if (type == QueueType::transfer) {
|
||||
index = detail::get_dedicated_transfer_queue_index (queue_families);
|
||||
if (index < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||
} else if (index == -1) {
|
||||
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
|
||||
}
|
||||
return index;
|
||||
}
|
||||
namespace detail {
|
||||
VkQueue get_queue (VkDevice device, int32_t family) {
|
||||
VkQueue out_queue;
|
||||
vkGetDeviceQueue (device, family, 0, &out_queue);
|
||||
return out_queue;
|
||||
}
|
||||
} // namespace detail
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> Device::get_queue (QueueType type) const {
|
||||
auto index = get_queue_index (type);
|
||||
if (!index.has_value ()) return index.error ();
|
||||
return detail::get_queue (device, index.value ());
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> Device::get_dedicated_queue (QueueType type) const {
|
||||
auto index = get_dedicated_queue_index (type);
|
||||
if (!index.has_value ()) return index.error ();
|
||||
return detail::get_queue (device, index.value ());
|
||||
}
|
||||
|
||||
// ---- Device ---- //
|
||||
|
||||
const char* to_string (DeviceError err) {
|
||||
switch (err) {
|
||||
case DeviceError::failed_create_device:
|
||||
@ -858,10 +943,6 @@ DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
|
||||
info.physical_device = phys_device;
|
||||
info.extensions = phys_device.extensions_to_enable;
|
||||
info.queue_families = phys_device.queue_families;
|
||||
info.dedicated_compute = phys_device.dedicated_compute;
|
||||
info.separate_compute = phys_device.separate_compute;
|
||||
info.dedicated_transfer = phys_device.dedicated_transfer;
|
||||
info.separate_transfer = phys_device.separate_transfer;
|
||||
}
|
||||
|
||||
detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () {
|
||||
@ -871,38 +952,8 @@ detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () {
|
||||
queue_descriptions.end (), info.queue_descriptions.begin (), info.queue_descriptions.end ());
|
||||
|
||||
if (queue_descriptions.size () == 0) {
|
||||
int graphics = detail::get_graphics_queue_index (info.queue_families);
|
||||
if (graphics >= 0) {
|
||||
queue_descriptions.push_back ({ static_cast<uint32_t> (graphics), 1, std::vector<float>{ 1.0f } });
|
||||
}
|
||||
if (info.separate_compute || info.dedicated_compute) {
|
||||
int compute = -1;
|
||||
if (info.dedicated_compute)
|
||||
compute = detail::get_separate_compute_queue_index (info.queue_families);
|
||||
else if (info.separate_compute) {
|
||||
compute = detail::get_separate_compute_queue_index (info.queue_families);
|
||||
int transfer = detail::get_separate_transfer_queue_index (info.queue_families);
|
||||
if (compute == transfer && compute >= 0) compute = -1;
|
||||
}
|
||||
|
||||
if (compute >= 0) {
|
||||
queue_descriptions.push_back (
|
||||
{ static_cast<uint32_t> (compute), 1, std::vector<float>{ 1.0f } });
|
||||
}
|
||||
}
|
||||
if (info.separate_transfer || info.dedicated_transfer) {
|
||||
int transfer = -1;
|
||||
if (info.dedicated_transfer)
|
||||
transfer = detail::get_dedicated_transfer_queue_index (info.queue_families);
|
||||
else if (info.separate_transfer) {
|
||||
transfer = detail::get_separate_transfer_queue_index (info.queue_families);
|
||||
int compute = detail::get_separate_transfer_queue_index (info.queue_families);
|
||||
if (transfer == compute && transfer >= 0) transfer = -1;
|
||||
}
|
||||
if (transfer >= 0) {
|
||||
queue_descriptions.push_back (
|
||||
{ static_cast<uint32_t> (transfer), 1, std::vector<float>{ 1.0f } });
|
||||
}
|
||||
for (uint32_t i = 0; i < info.queue_families.size (); i++) {
|
||||
queue_descriptions.push_back ({ i, 1, std::vector<float>{ 1.0f } });
|
||||
}
|
||||
}
|
||||
|
||||
@ -944,22 +995,6 @@ detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () {
|
||||
device.allocation_callbacks = info.allocation_callbacks;
|
||||
return device;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::request_dedicated_compute_queue (bool compute) {
|
||||
info.dedicated_compute = compute;
|
||||
return *this;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::request_dedicated_transfer_queue (bool transfer) {
|
||||
info.dedicated_transfer = transfer;
|
||||
return *this;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::request_separate_compute_queue (bool compute) {
|
||||
info.separate_compute = compute;
|
||||
return *this;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::request_separate_transfer_queue (bool transfer) {
|
||||
info.separate_transfer = transfer;
|
||||
return *this;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::custom_queue_setup (std::vector<CustomQueueDescription> queue_descriptions) {
|
||||
info.queue_descriptions = queue_descriptions;
|
||||
return *this;
|
||||
@ -973,109 +1008,6 @@ DeviceBuilder& DeviceBuilder::set_allocation_callbacks (VkAllocationCallbacks* c
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// ---- Queues ---- //
|
||||
const char* to_string (QueueError err) {
|
||||
switch (err) {
|
||||
case QueueError::present_unavailable:
|
||||
return "present_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 "";
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceBuilder::has_dedicated_compute_queue () {
|
||||
return detail::get_dedicated_compute_queue_index (info.queue_families) >= 0;
|
||||
}
|
||||
bool DeviceBuilder::has_separate_compute_queue () {
|
||||
return detail::get_separate_compute_queue_index (info.queue_families) >= 0;
|
||||
}
|
||||
bool DeviceBuilder::has_dedicated_transfer_queue () {
|
||||
return detail::get_dedicated_transfer_queue_index (info.queue_families) >= 0;
|
||||
}
|
||||
bool DeviceBuilder::has_separate_transfer_queue () {
|
||||
return detail::get_separate_transfer_queue_index (info.queue_families) >= 0;
|
||||
}
|
||||
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_present_queue_index (Device const& device) {
|
||||
int present = detail::get_present_queue_index (
|
||||
device.physical_device.phys_device, device.surface, device.queue_families);
|
||||
if (present < 0) return detail::Error<QueueError>{ QueueError::present_unavailable };
|
||||
return static_cast<uint32_t> (present);
|
||||
}
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_graphics_queue_index (Device const& device) {
|
||||
int graphics = detail::get_graphics_queue_index (device.queue_families);
|
||||
if (graphics < 0) return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
|
||||
return static_cast<uint32_t> (graphics);
|
||||
}
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_compute_queue_index (Device const& device) {
|
||||
int compute = detail::get_separate_compute_queue_index (device.queue_families);
|
||||
if (compute < 0) return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||
return static_cast<uint32_t> (compute);
|
||||
}
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_transfer_queue_index (Device const& device) {
|
||||
int transfer = detail::get_separate_transfer_queue_index (device.queue_families);
|
||||
if (transfer < 0) return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||
return static_cast<uint32_t> (transfer);
|
||||
}
|
||||
|
||||
VkQueue get_queue (VkDevice device, int32_t family) {
|
||||
VkQueue out_queue;
|
||||
vkGetDeviceQueue (device, family, 0, &out_queue);
|
||||
return out_queue;
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_present_queue (Device const& device) {
|
||||
int present = detail::get_present_queue_index (
|
||||
device.physical_device.phys_device, device.surface, device.queue_families);
|
||||
if (present < 0) {
|
||||
return detail::Error<QueueError>{ QueueError::present_unavailable };
|
||||
}
|
||||
return get_queue (device.device, present);
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_graphics_queue (Device const& device) {
|
||||
int graphics = detail::get_graphics_queue_index (device.queue_families);
|
||||
if (graphics < 0) {
|
||||
return detail::Error<QueueError>{ QueueError::invalid_queue_family_index };
|
||||
}
|
||||
return get_queue (device.device, graphics);
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_compute_queue (Device const& device) {
|
||||
int compute = detail::get_dedicated_compute_queue_index (device.queue_families);
|
||||
if (compute < 0) {
|
||||
return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||
}
|
||||
return get_queue (device.device, compute);
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_transfer_queue (Device const& device) {
|
||||
int transfer = detail::get_dedicated_transfer_queue_index (device.queue_families);
|
||||
if (transfer < 0) {
|
||||
return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||
}
|
||||
return get_queue (device.device, transfer);
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_separate_compute_queue (Device const& device) {
|
||||
int compute = detail::get_separate_compute_queue_index (device.queue_families);
|
||||
if (compute < 0) {
|
||||
return detail::Error<QueueError>{ QueueError::compute_unavailable };
|
||||
}
|
||||
return get_queue (device.device, compute);
|
||||
}
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_separate_transfer_queue (Device const& device) {
|
||||
int transfer = detail::get_separate_transfer_queue_index (device.queue_families);
|
||||
if (transfer < 0) {
|
||||
return detail::Error<QueueError>{ QueueError::transfer_unavailable };
|
||||
}
|
||||
return get_queue (device.device, transfer);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
VkSurfaceFormatKHR find_surface_format (std::vector<VkSurfaceFormatKHR> const& available_formats,
|
||||
std::vector<VkSurfaceFormatKHR> const& desired_formats) {
|
||||
@ -1146,12 +1078,11 @@ SwapchainBuilder::SwapchainBuilder (Device const& device) {
|
||||
info.device = device.device;
|
||||
info.physical_device = device.physical_device.phys_device;
|
||||
info.surface = device.surface;
|
||||
int present = detail::get_present_queue_index (
|
||||
device.physical_device.phys_device, device.surface, device.queue_families);
|
||||
int graphics = detail::get_graphics_queue_index (device.queue_families);
|
||||
|
||||
info.graphics_queue_index = graphics;
|
||||
info.present_queue_index = present;
|
||||
auto present = device.get_queue_index (QueueType::present);
|
||||
auto graphics = device.get_queue_index (QueueType::graphics);
|
||||
// TODO: handle error of queue's not available
|
||||
info.graphics_queue_index = present.value ();
|
||||
info.present_queue_index = graphics.value ();
|
||||
}
|
||||
|
||||
SwapchainBuilder::SwapchainBuilder (VkPhysicalDevice const physical_device,
|
||||
|
@ -268,14 +268,20 @@ struct PhysicalDevice {
|
||||
VkPhysicalDevice phys_device = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
|
||||
// Has a queue family that supports compute operations but not graphics nor transfer.
|
||||
bool has_dedicated_compute_queue ();
|
||||
// Has a queue family that supports transfer operations but not graphics nor compute.
|
||||
bool has_dedicated_transfer_queue ();
|
||||
|
||||
// Has a queue family that supports transfer operations but not graphics.
|
||||
bool has_separate_compute_queue ();
|
||||
// Has a queue family that supports transfer operations but not graphics.
|
||||
bool has_separate_transfer_queue ();
|
||||
|
||||
private:
|
||||
VkPhysicalDeviceFeatures features{};
|
||||
std::vector<const char*> extensions_to_enable;
|
||||
std::vector<VkQueueFamilyProperties> queue_families;
|
||||
bool dedicated_compute = false;
|
||||
bool separate_compute = false;
|
||||
bool dedicated_transfer = false;
|
||||
bool separate_transfer = false;
|
||||
friend class PhysicalDeviceSelector;
|
||||
friend class DeviceBuilder;
|
||||
};
|
||||
@ -304,10 +310,12 @@ class PhysicalDeviceSelector {
|
||||
|
||||
// Require that a physical device supports presentation. Defaults to true.
|
||||
PhysicalDeviceSelector& require_present (bool require = true);
|
||||
|
||||
// Require a queue family that supports compute operations but not graphics nor transfer.
|
||||
PhysicalDeviceSelector& require_dedicated_compute_queue ();
|
||||
// Require a queue family that supports transfer operations but not graphics nor compute.
|
||||
PhysicalDeviceSelector& require_dedicated_transfer_queue ();
|
||||
|
||||
// Require a queue family that supports compute operations but not graphics.
|
||||
PhysicalDeviceSelector& require_separate_compute_queue ();
|
||||
// Require a queue family that supports transfer operations but not graphics.
|
||||
@ -384,6 +392,19 @@ class PhysicalDeviceSelector {
|
||||
Suitable is_device_suitable (PhysicalDeviceDesc phys_device);
|
||||
};
|
||||
|
||||
// ---- Queues ---- //
|
||||
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 ---- //
|
||||
enum class DeviceError {
|
||||
failed_create_device,
|
||||
@ -397,6 +418,12 @@ struct Device {
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
std::vector<VkQueueFamilyProperties> queue_families;
|
||||
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_dedicated_queue_index (QueueType type) const;
|
||||
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_queue (QueueType type) const;
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_dedicated_queue (QueueType type) const;
|
||||
};
|
||||
|
||||
void destroy_device (Device device);
|
||||
@ -415,26 +442,11 @@ class DeviceBuilder {
|
||||
|
||||
detail::Expected<Device, detail::Error<DeviceError>> build ();
|
||||
|
||||
bool has_dedicated_compute_queue ();
|
||||
bool has_separate_compute_queue ();
|
||||
bool has_dedicated_transfer_queue ();
|
||||
bool has_separate_transfer_queue ();
|
||||
|
||||
// Require a queue family that supports compute operations but not graphics nor transfer.
|
||||
DeviceBuilder& request_dedicated_compute_queue (bool compute = true);
|
||||
// Require a queue family that supports transfer operations but not graphics nor compute.
|
||||
DeviceBuilder& request_dedicated_transfer_queue (bool transfer = true);
|
||||
|
||||
// Require a queue family that supports compute operations but not graphics.
|
||||
DeviceBuilder& request_separate_compute_queue (bool compute = true);
|
||||
// Require a queue family that supports transfer operations but not graphics.
|
||||
DeviceBuilder& request_separate_transfer_queue (bool transfer = true);
|
||||
|
||||
// For Advanced Users: specify the exact list of VkDeviceQueueCreateInfo's needed for the application.
|
||||
// If a custom queue setup is provided, getting the queues and queue indexes is up to the application.
|
||||
DeviceBuilder& custom_queue_setup (std::vector<CustomQueueDescription> queue_descriptions);
|
||||
|
||||
// For Advanced Users: Add a structure to the pNext chain of VkDeviceCreateInfo.
|
||||
// Add a structure to the pNext chain of VkDeviceCreateInfo.
|
||||
// The structure must be valid when DeviceBuilder::build() is called.
|
||||
template <typename T> DeviceBuilder& add_pNext (T* structure);
|
||||
|
||||
@ -449,36 +461,10 @@ class DeviceBuilder {
|
||||
std::vector<const char*> extensions;
|
||||
std::vector<VkQueueFamilyProperties> queue_families;
|
||||
std::vector<CustomQueueDescription> queue_descriptions;
|
||||
bool dedicated_compute = false;
|
||||
bool separate_compute = false;
|
||||
bool dedicated_transfer = false;
|
||||
bool separate_transfer = false;
|
||||
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
||||
} info;
|
||||
};
|
||||
|
||||
// ---- Queues ---- //
|
||||
|
||||
enum class QueueError {
|
||||
present_unavailable,
|
||||
compute_unavailable,
|
||||
transfer_unavailable,
|
||||
queue_index_out_of_range,
|
||||
invalid_queue_family_index
|
||||
};
|
||||
const char* to_string (QueueError err);
|
||||
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_present_queue_index (Device const& device);
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_graphics_queue_index (Device const& device);
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_compute_queue_index (Device const& device);
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_transfer_queue_index (Device const& device);
|
||||
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_present_queue (Device const& device);
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_graphics_queue (Device const& device);
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_compute_queue (Device const& device);
|
||||
detail::Expected<VkQueue, detail::Error<QueueError>> get_transfer_queue (Device const& device);
|
||||
|
||||
|
||||
// ---- Swapchain ---- //
|
||||
|
||||
enum class SwapchainError {
|
||||
|
Loading…
Reference in New Issue
Block a user