mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-10 02:41:47 +00:00
Finished basic rewrite of queue handling logic
Premise is to let the easy creation of a compute or transfer queue. If the user supplies a custom list they want to use, defer to that. Else, enable the basic requirements and be on your merry way.
This commit is contained in:
parent
3e7e283e3f
commit
2b711f30d5
@ -75,8 +75,18 @@ int device_initialization (Init& init) {
|
||||
}
|
||||
|
||||
int get_queues (Init& init, RenderData& data) {
|
||||
data.graphics_queue = vkb::get_graphics_queue (init.device).value ();
|
||||
data.present_queue = vkb::get_present_queue (init.device).value ();
|
||||
auto gq = vkb::get_graphics_queue (init.device);
|
||||
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);
|
||||
if (!pq.has_value ()) {
|
||||
std::cout << "failed to get present queue\n";
|
||||
return -1;
|
||||
}
|
||||
data.present_queue = pq.value ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,27 @@ bool check_layers_supported (std::vector<const char*> layer_names) {
|
||||
return all_found;
|
||||
}
|
||||
|
||||
bool check_extensions_supported (std::vector<const char*> extension_names) {
|
||||
auto available_extensions =
|
||||
detail::get_vector<VkExtensionProperties> (vkEnumerateInstanceExtensionProperties, nullptr);
|
||||
if (!available_extensions.has_value ()) {
|
||||
return false; // maybe report error?
|
||||
}
|
||||
bool all_found = true;
|
||||
for (const auto& extension_name : extension_names) {
|
||||
bool found = false;
|
||||
for (const auto& layer_properties : available_extensions.value ()) {
|
||||
if (strcmp (extension_name, layer_properties.extensionName) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) all_found = false;
|
||||
}
|
||||
|
||||
return all_found;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void setup_pNext_chain (T& structure, std::vector<VkBaseOutStructure*>& structs) {
|
||||
structure.pNext = nullptr;
|
||||
@ -180,6 +201,11 @@ detail::Expected<Instance, detail::Error<InstanceError>> InstanceBuilder::build
|
||||
extensions.push_back ("VK_KHR_metal_surface");
|
||||
#endif
|
||||
}
|
||||
bool all_extensions_supported = detail::check_extensions_supported (extensions);
|
||||
if (!all_extensions_supported) {
|
||||
return detail::Error<InstanceError>{ InstanceError::requested_extensions_not_present };
|
||||
}
|
||||
|
||||
std::vector<const char*> layers;
|
||||
for (auto& layer : info.layers)
|
||||
layers.push_back (layer.c_str ());
|
||||
@ -499,33 +525,46 @@ int get_present_queue_index (VkPhysicalDevice const phys_device,
|
||||
return -1;
|
||||
}
|
||||
|
||||
PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkPhysicalDevice phys_device) {
|
||||
Suitable suitable = Suitable::yes;
|
||||
|
||||
PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details (
|
||||
VkPhysicalDevice phys_device) {
|
||||
PhysicalDeviceSelector::PhysicalDeviceDesc desc{};
|
||||
desc.phys_device = phys_device;
|
||||
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
||||
vkGetPhysicalDeviceQueueFamilyProperties, phys_device);
|
||||
bool dedicated_compute = get_distinct_compute_queue_index (queue_families);
|
||||
bool dedicated_transfer = get_distinct_transfer_queue_index (queue_families);
|
||||
bool present_queue = get_present_queue_index (phys_device, info.surface, queue_families);
|
||||
desc.queue_families = queue_families;
|
||||
|
||||
vkGetPhysicalDeviceProperties (phys_device, &desc.device_properties);
|
||||
vkGetPhysicalDeviceFeatures (phys_device, &desc.device_features);
|
||||
vkGetPhysicalDeviceMemoryProperties (phys_device, &desc.mem_properties);
|
||||
return desc;
|
||||
}
|
||||
|
||||
PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (PhysicalDeviceDesc pd) {
|
||||
Suitable suitable = Suitable::yes;
|
||||
|
||||
bool dedicated_compute = get_distinct_compute_queue_index (pd.queue_families);
|
||||
bool dedicated_transfer = get_distinct_transfer_queue_index (pd.queue_families);
|
||||
bool present_queue = get_present_queue_index (pd.phys_device, system_info.surface, pd.queue_families);
|
||||
|
||||
if (criteria.require_dedicated_compute_queue && !dedicated_compute) suitable = Suitable::no;
|
||||
if (criteria.require_dedicated_transfer_queue && !dedicated_transfer) suitable = Suitable::no;
|
||||
if (criteria.require_present && !present_queue) suitable = Suitable::no;
|
||||
|
||||
auto required_extensions_supported =
|
||||
detail::check_device_extension_support (phys_device, criteria.required_extensions);
|
||||
detail::check_device_extension_support (pd.phys_device, criteria.required_extensions);
|
||||
if (required_extensions_supported.size () != criteria.required_extensions.size ())
|
||||
suitable = Suitable::no;
|
||||
|
||||
auto desired_extensions_supported =
|
||||
detail::check_device_extension_support (phys_device, criteria.desired_extensions);
|
||||
detail::check_device_extension_support (pd.phys_device, criteria.desired_extensions);
|
||||
if (desired_extensions_supported.size () != criteria.desired_extensions.size ())
|
||||
suitable = Suitable::partial;
|
||||
|
||||
|
||||
bool swapChainAdequate = false;
|
||||
if (!info.headless) {
|
||||
auto swapChainSupport_ret = detail::query_surface_support_details (phys_device, info.surface);
|
||||
if (!system_info.headless) {
|
||||
auto swapChainSupport_ret =
|
||||
detail::query_surface_support_details (pd.phys_device, system_info.surface);
|
||||
if (swapChainSupport_ret.has_value ()) {
|
||||
auto swapchain_support = swapChainSupport_ret.value ();
|
||||
swapChainAdequate =
|
||||
@ -534,17 +573,33 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkP
|
||||
}
|
||||
if (criteria.require_present && !swapChainAdequate) suitable = Suitable::no;
|
||||
|
||||
VkPhysicalDeviceMemoryProperties mem_properties;
|
||||
vkGetPhysicalDeviceMemoryProperties (phys_device, &mem_properties);
|
||||
if ((criteria.preferred_type == PreferredDeviceType::discrete &&
|
||||
pd.device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) ||
|
||||
(criteria.preferred_type == PreferredDeviceType::integrated &&
|
||||
pd.device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) ||
|
||||
(criteria.preferred_type == PreferredDeviceType::virtual_gpu &&
|
||||
pd.device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)) {
|
||||
if (criteria.allow_fallback)
|
||||
suitable = Suitable::partial;
|
||||
else
|
||||
suitable = Suitable::no;
|
||||
}
|
||||
|
||||
if (criteria.required_version < pd.device_properties.apiVersion) suitable = Suitable::no;
|
||||
if (criteria.desired_version < pd.device_properties.apiVersion) suitable = Suitable::partial;
|
||||
|
||||
bool required_features_supported =
|
||||
detail::supports_features (pd.device_features, criteria.required_features);
|
||||
if (!required_features_supported) suitable = Suitable::no;
|
||||
|
||||
bool has_required_memory = false;
|
||||
bool has_preferred_memory = false;
|
||||
for (int i = 0; i < mem_properties.memoryHeapCount; i++) {
|
||||
if (mem_properties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
|
||||
if (mem_properties.memoryHeaps[i].size > criteria.required_mem_size) {
|
||||
for (int i = 0; i < pd.mem_properties.memoryHeapCount; i++) {
|
||||
if (pd.mem_properties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
|
||||
if (pd.mem_properties.memoryHeaps[i].size > criteria.required_mem_size) {
|
||||
has_required_memory = true;
|
||||
}
|
||||
if (mem_properties.memoryHeaps[i].size > criteria.desired_mem_size) {
|
||||
if (pd.mem_properties.memoryHeaps[i].size > criteria.desired_mem_size) {
|
||||
has_preferred_memory = true;
|
||||
}
|
||||
}
|
||||
@ -552,40 +607,18 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkP
|
||||
if (!has_required_memory) suitable = Suitable::no;
|
||||
if (!has_preferred_memory) suitable = Suitable::partial;
|
||||
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
vkGetPhysicalDeviceProperties (phys_device, &device_properties);
|
||||
if ((criteria.preferred_type == PreferredDeviceType::discrete &&
|
||||
device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) ||
|
||||
(criteria.preferred_type == PreferredDeviceType::integrated &&
|
||||
device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) ||
|
||||
(criteria.preferred_type == PreferredDeviceType::virtual_gpu &&
|
||||
device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)) {
|
||||
if (criteria.allow_fallback)
|
||||
suitable = Suitable::partial;
|
||||
else
|
||||
suitable = Suitable::no;
|
||||
}
|
||||
|
||||
if (criteria.required_version < device_properties.apiVersion) suitable = Suitable::no;
|
||||
if (criteria.desired_version < device_properties.apiVersion) suitable = Suitable::partial;
|
||||
|
||||
VkPhysicalDeviceFeatures supported_features{};
|
||||
vkGetPhysicalDeviceFeatures (phys_device, &supported_features);
|
||||
bool required_features_supported =
|
||||
detail::supports_features (supported_features, criteria.required_features);
|
||||
if (!required_features_supported) suitable = Suitable::no;
|
||||
|
||||
return suitable;
|
||||
}
|
||||
|
||||
PhysicalDeviceSelector::PhysicalDeviceSelector (Instance const& instance) {
|
||||
info.instance = instance.instance;
|
||||
info.headless = instance.headless;
|
||||
system_info.instance = instance.instance;
|
||||
system_info.headless = instance.headless;
|
||||
criteria.require_present = !instance.headless;
|
||||
}
|
||||
|
||||
detail::Expected<PhysicalDevice, detail::Error<PhysicalDeviceError>> PhysicalDeviceSelector::select () {
|
||||
auto physical_devices = detail::get_vector<VkPhysicalDevice> (vkEnumeratePhysicalDevices, info.instance);
|
||||
auto physical_devices =
|
||||
detail::get_vector<VkPhysicalDevice> (vkEnumeratePhysicalDevices, system_info.instance);
|
||||
if (!physical_devices.has_value ()) {
|
||||
return detail::Error<PhysicalDeviceError>{ PhysicalDeviceError::failed_enumerate_physical_devices,
|
||||
physical_devices.error () };
|
||||
@ -594,42 +627,50 @@ detail::Expected<PhysicalDevice, detail::Error<PhysicalDeviceError>> PhysicalDev
|
||||
return detail::Error<PhysicalDeviceError>{ PhysicalDeviceError::no_physical_devices_found };
|
||||
}
|
||||
|
||||
PhysicalDevice physical_device;
|
||||
std::vector<PhysicalDeviceDesc> phys_device_descriptions;
|
||||
for (auto& phys_device : physical_devices.value ()) {
|
||||
phys_device_descriptions.push_back (populate_device_details (phys_device));
|
||||
}
|
||||
|
||||
PhysicalDeviceDesc selected_device{};
|
||||
|
||||
if (criteria.use_first_gpu_unconditionally) {
|
||||
physical_device.phys_device = physical_devices.value ().at (0);
|
||||
selected_device = phys_device_descriptions.at (0);
|
||||
} else {
|
||||
for (const auto& device : physical_devices.value ()) {
|
||||
for (const auto& device : phys_device_descriptions) {
|
||||
auto suitable = is_device_suitable (device);
|
||||
if (suitable == Suitable::yes) {
|
||||
physical_device.phys_device = device;
|
||||
selected_device = device;
|
||||
break;
|
||||
} else if (suitable == Suitable::partial) {
|
||||
physical_device.phys_device = device;
|
||||
selected_device = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (physical_device.phys_device == VK_NULL_HANDLE) {
|
||||
if (selected_device.phys_device == VK_NULL_HANDLE) {
|
||||
return detail::Error<PhysicalDeviceError>{ PhysicalDeviceError::no_suitable_device };
|
||||
}
|
||||
PhysicalDevice out_device{};
|
||||
out_device.phys_device = selected_device.phys_device;
|
||||
out_device.surface = system_info.surface;
|
||||
out_device.features = criteria.required_features;
|
||||
out_device.queue_families = selected_device.queue_families;
|
||||
|
||||
physical_device.surface = info.surface;
|
||||
physical_device.features = criteria.required_features;
|
||||
|
||||
physical_device.extensions_to_enable.insert (physical_device.extensions_to_enable.end (),
|
||||
out_device.extensions_to_enable.insert (out_device.extensions_to_enable.end (),
|
||||
criteria.required_extensions.begin (),
|
||||
criteria.required_extensions.end ());
|
||||
auto desired_extensions_supported =
|
||||
detail::check_device_extension_support (physical_device.phys_device, criteria.desired_extensions);
|
||||
physical_device.extensions_to_enable.insert (physical_device.extensions_to_enable.end (),
|
||||
detail::check_device_extension_support (out_device.phys_device, criteria.desired_extensions);
|
||||
out_device.extensions_to_enable.insert (out_device.extensions_to_enable.end (),
|
||||
desired_extensions_supported.begin (),
|
||||
desired_extensions_supported.end ());
|
||||
return physical_device;
|
||||
return out_device;
|
||||
}
|
||||
|
||||
PhysicalDeviceSelector& PhysicalDeviceSelector::set_surface (VkSurfaceKHR surface) {
|
||||
info.surface = surface;
|
||||
info.headless = false;
|
||||
system_info.surface = surface;
|
||||
system_info.headless = false;
|
||||
return *this;
|
||||
}
|
||||
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_gpu_device_type (PreferredDeviceType type) {
|
||||
@ -706,21 +747,41 @@ void destroy_device (Device device) { vkDestroyDevice (device.device, nullptr);
|
||||
DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
|
||||
info.physical_device = phys_device;
|
||||
info.extensions = phys_device.extensions_to_enable;
|
||||
info.queue_families = phys_device.queue_families;
|
||||
}
|
||||
|
||||
detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () {
|
||||
|
||||
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
||||
vkGetPhysicalDeviceQueueFamilyProperties, info.physical_device.phys_device);
|
||||
std::vector<CustomQueueDescription> queue_descriptions;
|
||||
queue_descriptions.insert (
|
||||
queue_descriptions.end (), info.queue_descriptions.begin (), info.queue_descriptions.end ());
|
||||
|
||||
if (queue_descriptions.size () == 0) {
|
||||
int graphics = get_graphics_queue_index (info.queue_families);
|
||||
if (graphics >= 0) {
|
||||
queue_descriptions.push_back ({ static_cast<uint32_t> (graphics), 1, { 1.0f } });
|
||||
}
|
||||
if (info.request_compute_queue) {
|
||||
int compute = get_distinct_compute_queue_index (info.queue_families);
|
||||
if (compute >= 0) {
|
||||
queue_descriptions.push_back ({ static_cast<uint32_t> (compute), 1, { 1.0f } });
|
||||
}
|
||||
}
|
||||
if (info.request_transfer_queue) {
|
||||
int transfer = get_distinct_transfer_queue_index (info.queue_families);
|
||||
if (transfer >= 0) {
|
||||
queue_descriptions.push_back ({ static_cast<uint32_t> (transfer), 1, { 1.0f } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||
float priority = 1.0f;
|
||||
for (int i = 0; i < queue_families.size (); i++) {
|
||||
for (auto& desc : queue_descriptions) {
|
||||
VkDeviceQueueCreateInfo queue_create_info = {};
|
||||
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queue_create_info.queueFamilyIndex = static_cast<uint32_t> (i);
|
||||
queue_create_info.queueCount = 1;
|
||||
queue_create_info.pQueuePriorities = &priority;
|
||||
queue_create_info.queueFamilyIndex = desc.index;
|
||||
queue_create_info.queueCount = desc.count;
|
||||
queue_create_info.pQueuePriorities = desc.priorities.data ();
|
||||
queueCreateInfos.push_back (queue_create_info);
|
||||
}
|
||||
|
||||
@ -748,6 +809,7 @@ detail::Expected<Device, detail::Error<DeviceError>> DeviceBuilder::build () {
|
||||
}
|
||||
device.physical_device = info.physical_device;
|
||||
device.surface = info.physical_device.surface;
|
||||
device.queue_families = info.queue_families;
|
||||
return device;
|
||||
}
|
||||
|
||||
@ -756,6 +818,20 @@ template <typename T> DeviceBuilder& DeviceBuilder::add_pNext (T* structure) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeviceBuilder& DeviceBuilder::request_dedicated_compute_queue (bool compute) {
|
||||
info.request_compute_queue = compute;
|
||||
return *this;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::request_dedicated_transfer_queue (bool transfer) {
|
||||
info.request_transfer_queue = transfer;
|
||||
return *this;
|
||||
}
|
||||
DeviceBuilder& DeviceBuilder::custom_queue_setup (std::vector<CustomQueueDescription> queue_descriptions) {
|
||||
info.queue_descriptions = queue_descriptions;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// ---- Getting Queues ---- //
|
||||
|
||||
detail::Expected<uint32_t, detail::Error<QueueError>> get_present_queue_index (Device const& device) {
|
||||
|
@ -124,6 +124,8 @@ struct Instance {
|
||||
|
||||
void destroy_instance (Instance instance); // release instance resources
|
||||
|
||||
// TODO utility function for users to check if layer/extension is supported
|
||||
|
||||
class InstanceBuilder {
|
||||
public:
|
||||
detail::Expected<Instance, detail::Error<InstanceError>> build (); // use builder pattern
|
||||
@ -138,9 +140,14 @@ class InstanceBuilder {
|
||||
InstanceBuilder& add_layer (std::string app_name);
|
||||
InstanceBuilder& add_extension (std::string app_name);
|
||||
|
||||
bool check_and_add_layer (std::string app_name);
|
||||
bool check_and_add_extension (std::string app_name);
|
||||
|
||||
InstanceBuilder& setup_validation_layers (bool enable_validation = true);
|
||||
InstanceBuilder& set_headless (bool headless = false);
|
||||
|
||||
bool check_and_setup_validation_layers (bool enable_validation = true);
|
||||
|
||||
InstanceBuilder& set_default_debug_messenger ();
|
||||
InstanceBuilder& set_debug_callback (PFN_vkDebugUtilsMessengerCallbackEXT callback);
|
||||
InstanceBuilder& set_debug_messenger_severity (VkDebugUtilsMessageSeverityFlagsEXT severity);
|
||||
@ -222,6 +229,7 @@ struct PhysicalDevice {
|
||||
private:
|
||||
VkPhysicalDeviceFeatures features{};
|
||||
std::vector<std::string> extensions_to_enable;
|
||||
std::vector<VkQueueFamilyProperties> queue_families;
|
||||
friend class PhysicalDeviceSelector;
|
||||
friend class DeviceBuilder;
|
||||
};
|
||||
@ -259,11 +267,21 @@ struct PhysicalDeviceSelector {
|
||||
PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true);
|
||||
|
||||
private:
|
||||
struct PhysicalDeviceInfo {
|
||||
struct SystemInfo {
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
bool headless = false;
|
||||
} info;
|
||||
} system_info;
|
||||
|
||||
struct PhysicalDeviceDesc {
|
||||
VkPhysicalDevice phys_device = VK_NULL_HANDLE;
|
||||
std::vector<VkQueueFamilyProperties> queue_families;
|
||||
|
||||
VkPhysicalDeviceFeatures device_features;
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
VkPhysicalDeviceMemoryProperties mem_properties;
|
||||
};
|
||||
PhysicalDeviceDesc populate_device_details (VkPhysicalDevice phys_device);
|
||||
|
||||
struct SelectionCriteria {
|
||||
PreferredDeviceType preferred_type = PreferredDeviceType::discrete;
|
||||
@ -287,13 +305,9 @@ struct PhysicalDeviceSelector {
|
||||
|
||||
enum class Suitable { yes, partial, no };
|
||||
|
||||
Suitable is_device_suitable (VkPhysicalDevice phys_device);
|
||||
Suitable is_device_suitable (PhysicalDeviceDesc phys_device);
|
||||
};
|
||||
|
||||
// ---- Queue Selection ---- //
|
||||
|
||||
enum class QueueType : uint8_t { primary, compute, transfer };
|
||||
|
||||
// ---- Device ---- //
|
||||
enum class DeviceError {
|
||||
failed_create_device,
|
||||
@ -308,6 +322,12 @@ struct Device {
|
||||
|
||||
void destroy_device (Device device);
|
||||
|
||||
struct CustomQueueDescription {
|
||||
uint32_t index;
|
||||
uint32_t count;
|
||||
std::vector<float> priorities;
|
||||
};
|
||||
|
||||
class DeviceBuilder {
|
||||
public:
|
||||
DeviceBuilder (PhysicalDevice device);
|
||||
@ -315,12 +335,22 @@ class DeviceBuilder {
|
||||
|
||||
template <typename T> DeviceBuilder& add_pNext (T* structure);
|
||||
|
||||
DeviceBuilder& request_dedicated_compute_queue (bool compute = true);
|
||||
DeviceBuilder& request_dedicated_transfer_queue (bool transfer = true);
|
||||
|
||||
/* For advanced users */
|
||||
DeviceBuilder& custom_queue_setup (std::vector<CustomQueueDescription> queue_descriptions);
|
||||
|
||||
private:
|
||||
struct DeviceInfo {
|
||||
VkDeviceCreateFlags flags = 0;
|
||||
std::vector<VkBaseOutStructure*> pNext_chain;
|
||||
PhysicalDevice physical_device;
|
||||
std::vector<std::string> extensions;
|
||||
std::vector<VkQueueFamilyProperties> queue_families;
|
||||
std::vector<CustomQueueDescription> queue_descriptions;
|
||||
bool request_compute_queue = true;
|
||||
bool request_transfer_queue = true;
|
||||
} info;
|
||||
};
|
||||
|
||||
@ -381,9 +411,6 @@ class SwapchainBuilder {
|
||||
detail::Expected<Swapchain, detail::Error<SwapchainError>> build ();
|
||||
detail::Expected<Swapchain, detail::Error<SwapchainError>> recreate (Swapchain const& swapchain);
|
||||
|
||||
// SwapchainBuilder& set_desired_image_count (uint32_t count);
|
||||
// SwapchainBuilder& set_maximum_image_count (uint32_t count);
|
||||
|
||||
SwapchainBuilder& set_desired_format (VkSurfaceFormatKHR format);
|
||||
SwapchainBuilder& add_fallback_format (VkSurfaceFormatKHR format);
|
||||
SwapchainBuilder& use_default_format_selection ();
|
||||
|
Loading…
Reference in New Issue
Block a user