mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 15:24:34 +00:00
Call KHR version of get phys dev properties if necessary
Previously, vk-bootstrap didn't support calling vkGetPhyicalDeviceFeaturesKHR on devices which support the extension. This makes vk-bootstrap more amenable to 1.0 only hardware, like rasberry pi's.
This commit is contained in:
parent
f955777c8a
commit
05683f6b6b
@ -120,7 +120,8 @@ class VulkanFunctions {
|
|||||||
out_ptr = reinterpret_cast<T>(ptr_vkGetInstanceProcAddr(instance, func_name));
|
out_ptr = reinterpret_cast<T>(ptr_vkGetInstanceProcAddr(instance, func_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void get_device_proc_addr(VkDevice device, T& out_ptr, const char* func_name) {
|
template <typename T>
|
||||||
|
void get_device_proc_addr(VkDevice device, T& out_ptr, const char* func_name) {
|
||||||
out_ptr = reinterpret_cast<T>(fp_vkGetDeviceProcAddr(device, func_name));
|
out_ptr = reinterpret_cast<T>(fp_vkGetDeviceProcAddr(device, func_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +137,7 @@ class VulkanFunctions {
|
|||||||
PFN_vkEnumeratePhysicalDevices fp_vkEnumeratePhysicalDevices = nullptr;
|
PFN_vkEnumeratePhysicalDevices fp_vkEnumeratePhysicalDevices = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceFeatures fp_vkGetPhysicalDeviceFeatures = nullptr;
|
PFN_vkGetPhysicalDeviceFeatures fp_vkGetPhysicalDeviceFeatures = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceFeatures2 fp_vkGetPhysicalDeviceFeatures2 = nullptr;
|
PFN_vkGetPhysicalDeviceFeatures2 fp_vkGetPhysicalDeviceFeatures2 = nullptr;
|
||||||
|
PFN_vkGetPhysicalDeviceFeatures2KHR fp_vkGetPhysicalDeviceFeatures2KHR = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceFormatProperties fp_vkGetPhysicalDeviceFormatProperties = nullptr;
|
PFN_vkGetPhysicalDeviceFormatProperties fp_vkGetPhysicalDeviceFormatProperties = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceImageFormatProperties fp_vkGetPhysicalDeviceImageFormatProperties = nullptr;
|
PFN_vkGetPhysicalDeviceImageFormatProperties fp_vkGetPhysicalDeviceImageFormatProperties = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceProperties fp_vkGetPhysicalDeviceProperties = nullptr;
|
PFN_vkGetPhysicalDeviceProperties fp_vkGetPhysicalDeviceProperties = nullptr;
|
||||||
@ -169,6 +171,7 @@ class VulkanFunctions {
|
|||||||
get_inst_proc_addr(fp_vkEnumeratePhysicalDevices, "vkEnumeratePhysicalDevices");
|
get_inst_proc_addr(fp_vkEnumeratePhysicalDevices, "vkEnumeratePhysicalDevices");
|
||||||
get_inst_proc_addr(fp_vkGetPhysicalDeviceFeatures, "vkGetPhysicalDeviceFeatures");
|
get_inst_proc_addr(fp_vkGetPhysicalDeviceFeatures, "vkGetPhysicalDeviceFeatures");
|
||||||
get_inst_proc_addr(fp_vkGetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2");
|
get_inst_proc_addr(fp_vkGetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2");
|
||||||
|
get_inst_proc_addr(fp_vkGetPhysicalDeviceFeatures2KHR, "vkGetPhysicalDeviceFeatures2KHR");
|
||||||
get_inst_proc_addr(fp_vkGetPhysicalDeviceFormatProperties, "vkGetPhysicalDeviceFormatProperties");
|
get_inst_proc_addr(fp_vkGetPhysicalDeviceFormatProperties, "vkGetPhysicalDeviceFormatProperties");
|
||||||
get_inst_proc_addr(fp_vkGetPhysicalDeviceImageFormatProperties, "vkGetPhysicalDeviceImageFormatProperties");
|
get_inst_proc_addr(fp_vkGetPhysicalDeviceImageFormatProperties, "vkGetPhysicalDeviceImageFormatProperties");
|
||||||
get_inst_proc_addr(fp_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties");
|
get_inst_proc_addr(fp_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties");
|
||||||
@ -615,6 +618,10 @@ detail::Result<Instance> InstanceBuilder::build() const {
|
|||||||
if (info.debug_callback != nullptr && system.debug_utils_available) {
|
if (info.debug_callback != nullptr && system.debug_utils_available) {
|
||||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
if (detail::check_extension_supported(
|
||||||
|
system.available_extensions, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
|
||||||
|
extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
if (!info.headless_context) {
|
if (!info.headless_context) {
|
||||||
auto check_add_window_ext = [&](const char* name) -> bool {
|
auto check_add_window_ext = [&](const char* name) -> bool {
|
||||||
@ -978,8 +985,7 @@ uint32_t get_present_queue_index(VkPhysicalDevice const phys_device,
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details(uint32_t instance_version,
|
PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_device_details(VkPhysicalDevice phys_device,
|
||||||
VkPhysicalDevice phys_device,
|
|
||||||
std::vector<detail::GenericFeaturesPNextNode> const& src_extended_features_chain) const {
|
std::vector<detail::GenericFeaturesPNextNode> const& src_extended_features_chain) const {
|
||||||
PhysicalDeviceSelector::PhysicalDeviceDesc desc{};
|
PhysicalDeviceSelector::PhysicalDeviceDesc desc{};
|
||||||
desc.phys_device = phys_device;
|
desc.phys_device = phys_device;
|
||||||
@ -993,10 +999,14 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
|
|||||||
|
|
||||||
#if defined(VK_API_VERSION_1_1)
|
#if defined(VK_API_VERSION_1_1)
|
||||||
desc.device_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
desc.device_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||||
|
#else
|
||||||
|
desc.device_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
|
||||||
|
#endif
|
||||||
|
|
||||||
auto fill_chain = src_extended_features_chain;
|
auto fill_chain = src_extended_features_chain;
|
||||||
|
|
||||||
if (!fill_chain.empty() && instance_version >= VK_API_VERSION_1_1) {
|
if (!fill_chain.empty() &&
|
||||||
|
(instance_info.version >= VK_API_VERSION_1_1 || instance_info.supports_properties2_ext)) {
|
||||||
|
|
||||||
detail::GenericFeaturesPNextNode* prev = nullptr;
|
detail::GenericFeaturesPNextNode* prev = nullptr;
|
||||||
for (auto& extension : fill_chain) {
|
for (auto& extension : fill_chain) {
|
||||||
@ -1006,15 +1016,26 @@ PhysicalDeviceSelector::PhysicalDeviceDesc PhysicalDeviceSelector::populate_devi
|
|||||||
prev = &extension;
|
prev = &extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(VK_API_VERSION_1_1)
|
||||||
VkPhysicalDeviceFeatures2 local_features{};
|
VkPhysicalDeviceFeatures2 local_features{};
|
||||||
local_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
local_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||||
local_features.pNext = &fill_chain.front();
|
local_features.pNext = &fill_chain.front();
|
||||||
|
if (desc.device_properties.apiVersion >= VK_API_VERSION_1_1) {
|
||||||
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &local_features);
|
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2(phys_device, &local_features);
|
||||||
|
} else if (instance_info.supports_properties2_ext) {
|
||||||
|
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2KHR(phys_device, &local_features);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
VkPhysicalDeviceFeatures2KHR local_features{};
|
||||||
|
local_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||||
|
local_features.pNext = &fill_chain.front();
|
||||||
|
if (instance_info.supports_properties2_ext) {
|
||||||
|
detail::vulkan_functions().fp_vkGetPhysicalDeviceFeatures2KHR(phys_device, &local_features);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
desc.extended_features_chain = fill_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc.extended_features_chain = fill_chain;
|
|
||||||
#endif
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,6 +1137,10 @@ PhysicalDeviceSelector::PhysicalDeviceSelector(Instance const& instance) {
|
|||||||
criteria.require_present = !instance.headless;
|
criteria.require_present = !instance.headless;
|
||||||
criteria.required_version = instance.instance_version;
|
criteria.required_version = instance.instance_version;
|
||||||
criteria.desired_version = instance.instance_version;
|
criteria.desired_version = instance.instance_version;
|
||||||
|
detail::get_vector<VkExtensionProperties>(
|
||||||
|
instance_info.extensions, detail::vulkan_functions().fp_vkEnumerateInstanceExtensionProperties, nullptr);
|
||||||
|
instance_info.supports_properties2_ext = detail::check_extension_supported(
|
||||||
|
instance_info.extensions, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
|
detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
|
||||||
@ -1125,6 +1150,8 @@ detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> physical_devices;
|
std::vector<VkPhysicalDevice> physical_devices;
|
||||||
|
|
||||||
auto physical_devices_ret = detail::get_vector<VkPhysicalDevice>(
|
auto physical_devices_ret = detail::get_vector<VkPhysicalDevice>(
|
||||||
@ -1139,8 +1166,7 @@ detail::Result<PhysicalDevice> PhysicalDeviceSelector::select() const {
|
|||||||
|
|
||||||
std::vector<PhysicalDeviceDesc> phys_device_descriptions;
|
std::vector<PhysicalDeviceDesc> phys_device_descriptions;
|
||||||
for (auto& phys_device : physical_devices) {
|
for (auto& phys_device : physical_devices) {
|
||||||
phys_device_descriptions.push_back(populate_device_details(
|
phys_device_descriptions.push_back(populate_device_details(phys_device, criteria.extended_features_chain));
|
||||||
instance_info.version, phys_device, criteria.extended_features_chain));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceDesc selected_device{};
|
PhysicalDeviceDesc selected_device{};
|
||||||
@ -1471,12 +1497,10 @@ detail::Result<Device> DeviceBuilder::build() const {
|
|||||||
device.queue_families = physical_device.queue_families;
|
device.queue_families = physical_device.queue_families;
|
||||||
device.allocation_callbacks = info.allocation_callbacks;
|
device.allocation_callbacks = info.allocation_callbacks;
|
||||||
device.fp_vkGetDeviceProcAddr = detail::vulkan_functions().fp_vkGetDeviceProcAddr;
|
device.fp_vkGetDeviceProcAddr = detail::vulkan_functions().fp_vkGetDeviceProcAddr;
|
||||||
detail::vulkan_functions().get_device_proc_addr(device.device,
|
detail::vulkan_functions().get_device_proc_addr(
|
||||||
device.internal_table.fp_vkGetDeviceQueue,
|
device.device, device.internal_table.fp_vkGetDeviceQueue, "vkGetDeviceQueue");
|
||||||
"vkGetDeviceQueue");
|
detail::vulkan_functions().get_device_proc_addr(
|
||||||
detail::vulkan_functions().get_device_proc_addr(device.device,
|
device.device, device.internal_table.fp_vkDestroyDevice, "vkDestroyDevice");
|
||||||
device.internal_table.fp_vkDestroyDevice,
|
|
||||||
"vkDestroyDevice");
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
DeviceBuilder& DeviceBuilder::custom_queue_setup(std::vector<CustomQueueDescription> queue_descriptions) {
|
DeviceBuilder& DeviceBuilder::custom_queue_setup(std::vector<CustomQueueDescription> queue_descriptions) {
|
||||||
@ -1607,7 +1631,8 @@ VkExtent2D find_extent(VkSurfaceCapabilitiesKHR const& capabilities, uint32_t de
|
|||||||
|
|
||||||
void destroy_swapchain(Swapchain const& swapchain) {
|
void destroy_swapchain(Swapchain const& swapchain) {
|
||||||
if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE) {
|
if (swapchain.device != VK_NULL_HANDLE && swapchain.swapchain != VK_NULL_HANDLE) {
|
||||||
swapchain.internal_table.fp_vkDestroySwapchainKHR(swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);
|
swapchain.internal_table.fp_vkDestroySwapchainKHR(
|
||||||
|
swapchain.device, swapchain.swapchain, swapchain.allocation_callbacks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1726,25 +1751,23 @@ detail::Result<Swapchain> SwapchainBuilder::build() const {
|
|||||||
Swapchain swapchain{};
|
Swapchain swapchain{};
|
||||||
PFN_vkCreateSwapchainKHR swapchain_create_proc;
|
PFN_vkCreateSwapchainKHR swapchain_create_proc;
|
||||||
detail::vulkan_functions().get_device_proc_addr(info.device, swapchain_create_proc, "vkCreateSwapchainKHR");
|
detail::vulkan_functions().get_device_proc_addr(info.device, swapchain_create_proc, "vkCreateSwapchainKHR");
|
||||||
auto res = swapchain_create_proc(info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain);
|
auto res = swapchain_create_proc(
|
||||||
; if (res != VK_SUCCESS) {
|
info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain);
|
||||||
|
;
|
||||||
|
if (res != VK_SUCCESS) {
|
||||||
return detail::Error{ SwapchainError::failed_create_swapchain, res };
|
return detail::Error{ SwapchainError::failed_create_swapchain, res };
|
||||||
}
|
}
|
||||||
swapchain.device = info.device;
|
swapchain.device = info.device;
|
||||||
swapchain.image_format = surface_format.format;
|
swapchain.image_format = surface_format.format;
|
||||||
swapchain.extent = extent;
|
swapchain.extent = extent;
|
||||||
detail::vulkan_functions().get_device_proc_addr(info.device,
|
detail::vulkan_functions().get_device_proc_addr(
|
||||||
swapchain.internal_table.fp_vkGetSwapchainImagesKHR,
|
info.device, swapchain.internal_table.fp_vkGetSwapchainImagesKHR, "vkGetSwapchainImagesKHR");
|
||||||
"vkGetSwapchainImagesKHR");
|
detail::vulkan_functions().get_device_proc_addr(
|
||||||
detail::vulkan_functions().get_device_proc_addr(info.device,
|
info.device, swapchain.internal_table.fp_vkCreateImageView, "vkCreateImageView");
|
||||||
swapchain.internal_table.fp_vkCreateImageView,
|
detail::vulkan_functions().get_device_proc_addr(
|
||||||
"vkCreateImageView");
|
info.device, swapchain.internal_table.fp_vkDestroyImageView, "vkDestroyImageView");
|
||||||
detail::vulkan_functions().get_device_proc_addr(info.device,
|
detail::vulkan_functions().get_device_proc_addr(
|
||||||
swapchain.internal_table.fp_vkDestroyImageView,
|
info.device, swapchain.internal_table.fp_vkDestroySwapchainKHR, "vkDestroySwapchainKHR");
|
||||||
"vkDestroyImageView");
|
|
||||||
detail::vulkan_functions().get_device_proc_addr(info.device,
|
|
||||||
swapchain.internal_table.fp_vkDestroySwapchainKHR,
|
|
||||||
"vkDestroySwapchainKHR");
|
|
||||||
auto images = swapchain.get_images();
|
auto images = swapchain.get_images();
|
||||||
if (!images) {
|
if (!images) {
|
||||||
return detail::Error{ SwapchainError::failed_get_swapchain_images };
|
return detail::Error{ SwapchainError::failed_get_swapchain_images };
|
||||||
@ -1787,7 +1810,8 @@ detail::Result<std::vector<VkImageView>> Swapchain::get_image_views() {
|
|||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
VkResult res = internal_table.fp_vkCreateImageView(device, &createInfo, allocation_callbacks, &views[i]);
|
VkResult res =
|
||||||
|
internal_table.fp_vkCreateImageView(device, &createInfo, allocation_callbacks, &views[i]);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
return detail::Error{ SwapchainError::failed_create_swapchain_image_views, res };
|
return detail::Error{ SwapchainError::failed_create_swapchain_image_views, res };
|
||||||
}
|
}
|
||||||
|
@ -474,7 +474,9 @@ class PhysicalDeviceSelector {
|
|||||||
VkInstance instance = VK_NULL_HANDLE;
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||||
uint32_t version = VK_MAKE_VERSION(1, 0, 0);
|
uint32_t version = VK_MAKE_VERSION(1, 0, 0);
|
||||||
|
std::vector<VkExtensionProperties> extensions;
|
||||||
bool headless = false;
|
bool headless = false;
|
||||||
|
bool supports_properties2_ext = false;
|
||||||
} instance_info;
|
} instance_info;
|
||||||
|
|
||||||
struct PhysicalDeviceDesc {
|
struct PhysicalDeviceDesc {
|
||||||
@ -484,17 +486,20 @@ class PhysicalDeviceSelector {
|
|||||||
VkPhysicalDeviceFeatures device_features{};
|
VkPhysicalDeviceFeatures device_features{};
|
||||||
VkPhysicalDeviceProperties device_properties{};
|
VkPhysicalDeviceProperties device_properties{};
|
||||||
VkPhysicalDeviceMemoryProperties mem_properties{};
|
VkPhysicalDeviceMemoryProperties mem_properties{};
|
||||||
|
|
||||||
|
// Because the KHR version is a typedef in Vulkan 1.1, it is safe to define one or the other.
|
||||||
#if defined(VK_API_VERSION_1_1)
|
#if defined(VK_API_VERSION_1_1)
|
||||||
VkPhysicalDeviceFeatures2 device_features2{};
|
VkPhysicalDeviceFeatures2 device_features2{};
|
||||||
std::vector<detail::GenericFeaturesPNextNode> extended_features_chain;
|
#else
|
||||||
|
VkPhysicalDeviceFeatures2KHR device_features2{};
|
||||||
#endif
|
#endif
|
||||||
|
std::vector<detail::GenericFeaturesPNextNode> extended_features_chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We copy the extension features stored in the selector criteria under the prose of a
|
// We copy the extension features stored in the selector criteria under the prose of a
|
||||||
// "template" to ensure that after fetching everything is compared 1:1 during a match.
|
// "template" to ensure that after fetching everything is compared 1:1 during a match.
|
||||||
|
|
||||||
PhysicalDeviceDesc populate_device_details(uint32_t instance_version,
|
PhysicalDeviceDesc populate_device_details(VkPhysicalDevice phys_device,
|
||||||
VkPhysicalDevice phys_device,
|
|
||||||
std::vector<detail::GenericFeaturesPNextNode> const& src_extended_features_chain) const;
|
std::vector<detail::GenericFeaturesPNextNode> const& src_extended_features_chain) const;
|
||||||
|
|
||||||
struct SelectionCriteria {
|
struct SelectionCriteria {
|
||||||
@ -556,6 +561,7 @@ struct Device {
|
|||||||
|
|
||||||
// Return a loaded dispatch table
|
// Return a loaded dispatch table
|
||||||
DispatchTable make_table() const;
|
DispatchTable make_table() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct {
|
struct {
|
||||||
PFN_vkGetDeviceQueue fp_vkGetDeviceQueue = nullptr;
|
PFN_vkGetDeviceQueue fp_vkGetDeviceQueue = nullptr;
|
||||||
@ -622,6 +628,7 @@ struct Swapchain {
|
|||||||
// VkImageViews must be destroyed.
|
// VkImageViews must be destroyed.
|
||||||
detail::Result<std::vector<VkImageView>> get_image_views();
|
detail::Result<std::vector<VkImageView>> get_image_views();
|
||||||
void destroy_image_views(std::vector<VkImageView> const& image_views);
|
void destroy_image_views(std::vector<VkImageView> const& image_views);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct {
|
struct {
|
||||||
PFN_vkGetSwapchainImagesKHR fp_vkGetSwapchainImagesKHR = nullptr;
|
PFN_vkGetSwapchainImagesKHR fp_vkGetSwapchainImagesKHR = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user