mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 23:24:34 +00:00
Added defer_surface_initialization which allows skipping checking if a device and surface work together
This commit is contained in:
parent
3097f46074
commit
40488fc7cd
@ -487,42 +487,6 @@ InstanceBuilder& InstanceBuilder::set_allocation_callbacks (VkAllocationCallback
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
struct SurfaceSupportDetails {
|
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
|
||||||
std::vector<VkSurfaceFormatKHR> formats;
|
|
||||||
std::vector<VkPresentModeKHR> present_modes;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SurfaceSupportError {
|
|
||||||
surface_handle_null,
|
|
||||||
failed_get_surface_capabilities,
|
|
||||||
failed_enumerate_surface_formats,
|
|
||||||
failed_enumerate_present_modes
|
|
||||||
};
|
|
||||||
|
|
||||||
Expected<SurfaceSupportDetails, detail::Error<SurfaceSupportError>> query_surface_support_details (
|
|
||||||
VkPhysicalDevice phys_device, VkSurfaceKHR surface) {
|
|
||||||
if (surface == VK_NULL_HANDLE)
|
|
||||||
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::surface_handle_null };
|
|
||||||
|
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
|
||||||
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR (phys_device, surface, &capabilities);
|
|
||||||
if (res != VK_SUCCESS) {
|
|
||||||
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::failed_get_surface_capabilities, res };
|
|
||||||
}
|
|
||||||
auto formats = detail::get_vector<VkSurfaceFormatKHR> (
|
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, surface);
|
|
||||||
if (!formats.has_value ())
|
|
||||||
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::failed_enumerate_surface_formats,
|
|
||||||
formats.error () };
|
|
||||||
auto present_modes = detail::get_vector<VkPresentModeKHR> (
|
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, surface);
|
|
||||||
if (!present_modes.has_value ())
|
|
||||||
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::failed_enumerate_present_modes,
|
|
||||||
formats.error () };
|
|
||||||
return SurfaceSupportDetails{ capabilities, formats.value (), present_modes.value () };
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char*> check_device_extension_support (
|
std::vector<const char*> check_device_extension_support (
|
||||||
VkPhysicalDevice device, std::vector<const char*> desired_extensions) {
|
VkPhysicalDevice device, std::vector<const char*> desired_extensions) {
|
||||||
auto available_extensions =
|
auto available_extensions =
|
||||||
@ -720,13 +684,17 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (Phy
|
|||||||
|
|
||||||
|
|
||||||
bool swapChainAdequate = false;
|
bool swapChainAdequate = false;
|
||||||
if (!system_info.headless) {
|
if (criteria.defer_surface_initialization) {
|
||||||
auto swapChainSupport_ret =
|
swapChainAdequate = true;
|
||||||
detail::query_surface_support_details (pd.phys_device, system_info.surface);
|
} else if (!system_info.headless) {
|
||||||
if (swapChainSupport_ret.has_value ()) {
|
|
||||||
auto swapchain_support = swapChainSupport_ret.value ();
|
auto formats = detail::get_vector<VkSurfaceFormatKHR> (
|
||||||
swapChainAdequate =
|
vkGetPhysicalDeviceSurfaceFormatsKHR, pd.phys_device, system_info.surface);
|
||||||
!swapchain_support.formats.empty () && !swapchain_support.present_modes.empty ();
|
auto present_modes = detail::get_vector<VkPresentModeKHR> (
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR, pd.phys_device, system_info.surface);
|
||||||
|
|
||||||
|
if (formats.has_value () && present_modes.has_value ()) {
|
||||||
|
swapChainAdequate = !formats.value ().empty () && !present_modes.value ().empty ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (criteria.require_present && !swapChainAdequate) suitable = Suitable::no;
|
if (criteria.require_present && !swapChainAdequate) suitable = Suitable::no;
|
||||||
@ -892,6 +860,10 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features (VkPhysica
|
|||||||
criteria.required_features = features;
|
criteria.required_features = features;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
PhysicalDeviceSelector& PhysicalDeviceSelector::defer_surface_initialization () {
|
||||||
|
criteria.defer_surface_initialization = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditionally (bool unconditionally) {
|
PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditionally (bool unconditionally) {
|
||||||
criteria.use_first_gpu_unconditionally = unconditionally;
|
criteria.use_first_gpu_unconditionally = unconditionally;
|
||||||
return *this;
|
return *this;
|
||||||
@ -1045,6 +1017,42 @@ DeviceBuilder& DeviceBuilder::set_allocation_callbacks (VkAllocationCallbacks* c
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
struct SurfaceSupportDetails {
|
||||||
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
|
std::vector<VkPresentModeKHR> present_modes;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SurfaceSupportError {
|
||||||
|
surface_handle_null,
|
||||||
|
failed_get_surface_capabilities,
|
||||||
|
failed_enumerate_surface_formats,
|
||||||
|
failed_enumerate_present_modes
|
||||||
|
};
|
||||||
|
|
||||||
|
Expected<SurfaceSupportDetails, detail::Error<SurfaceSupportError>> query_surface_support_details (
|
||||||
|
VkPhysicalDevice phys_device, VkSurfaceKHR surface) {
|
||||||
|
if (surface == VK_NULL_HANDLE)
|
||||||
|
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::surface_handle_null };
|
||||||
|
|
||||||
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
|
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR (phys_device, surface, &capabilities);
|
||||||
|
if (res != VK_SUCCESS) {
|
||||||
|
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::failed_get_surface_capabilities, res };
|
||||||
|
}
|
||||||
|
auto formats = detail::get_vector<VkSurfaceFormatKHR> (
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, surface);
|
||||||
|
if (!formats.has_value ())
|
||||||
|
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::failed_enumerate_surface_formats,
|
||||||
|
formats.error () };
|
||||||
|
auto present_modes = detail::get_vector<VkPresentModeKHR> (
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, surface);
|
||||||
|
if (!present_modes.has_value ())
|
||||||
|
return detail::Error<SurfaceSupportError>{ SurfaceSupportError::failed_enumerate_present_modes,
|
||||||
|
formats.error () };
|
||||||
|
return SurfaceSupportDetails{ capabilities, formats.value (), present_modes.value () };
|
||||||
|
}
|
||||||
|
|
||||||
VkSurfaceFormatKHR find_surface_format (std::vector<VkSurfaceFormatKHR> const& available_formats,
|
VkSurfaceFormatKHR find_surface_format (std::vector<VkSurfaceFormatKHR> const& available_formats,
|
||||||
std::vector<VkSurfaceFormatKHR> const& desired_formats) {
|
std::vector<VkSurfaceFormatKHR> const& desired_formats) {
|
||||||
for (auto const& desired_format : desired_formats) {
|
for (auto const& desired_format : desired_formats) {
|
||||||
|
@ -364,6 +364,10 @@ class PhysicalDeviceSelector {
|
|||||||
// Require a physical device which supports the features in VkPhysicalDeviceFeatures.
|
// Require a physical device which supports the features in VkPhysicalDeviceFeatures.
|
||||||
PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features);
|
PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features);
|
||||||
|
|
||||||
|
// Used when surface creation happens after physical device selection.
|
||||||
|
// Warning: This disables checking if the physical device supports a given surface.
|
||||||
|
PhysicalDeviceSelector& defer_surface_initialization ();
|
||||||
|
|
||||||
// Ignore all criteria and choose the first physical device that is available.
|
// Ignore all criteria and choose the first physical device that is available.
|
||||||
// Only use when: The first gpu in the list may be set by global user preferences and an application may wish to respect it.
|
// Only use when: The first gpu in the list may be set by global user preferences and an application may wish to respect it.
|
||||||
PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true);
|
PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true);
|
||||||
@ -404,6 +408,7 @@ class PhysicalDeviceSelector {
|
|||||||
|
|
||||||
VkPhysicalDeviceFeatures required_features{};
|
VkPhysicalDeviceFeatures required_features{};
|
||||||
|
|
||||||
|
bool defer_surface_initialization = false;
|
||||||
bool use_first_gpu_unconditionally = false;
|
bool use_first_gpu_unconditionally = false;
|
||||||
} criteria;
|
} criteria;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user