Skip to content

Commit

Permalink
Implement VK_MSFT_layered_driver extension support
Browse files Browse the repository at this point in the history
This extension reorders physical devices enumerated through the windows
EnumerateAdapterPhysicalDevices whenever multiple drivers exist for the same
LUID. This is so that if a driver is considered a 'layered implementation',
eg Dozen's Vulkan on Dx12, the physical device corresponding to the native
vulkan driver is preferred.

The implementation of this extension cause some renaming of structs, variables,
and parameters to make the code easier to understand, such as renaming
the struct loader_phys_devs_per_icd to loader_icd_physical_devices.
During the review process there was quite a bit of confusion about what the
struct's purpose was that should be much clearer now.
  • Loading branch information
charles-lunarg committed Nov 2, 2023
1 parent 9f257b6 commit 5e39148
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 163 deletions.
13 changes: 7 additions & 6 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -6067,7 +6067,7 @@ bool find_phys_dev(VkPhysicalDevice physical_device, uint32_t phys_devs_count, s

// Add physical_device to new_phys_devs
VkResult check_and_add_to_new_phys_devs(struct loader_instance *inst, VkPhysicalDevice physical_device,
struct loader_phys_dev_per_icd *dev_array, uint32_t *cur_new_phys_dev_count,
struct loader_icd_physical_devices *dev_array, uint32_t *cur_new_phys_dev_count,
struct loader_physical_device_term **new_phys_devs) {
uint32_t out_idx = 0;
uint32_t idx = *cur_new_phys_dev_count;
Expand Down Expand Up @@ -6123,9 +6123,9 @@ VkResult setup_loader_term_phys_devs(struct loader_instance *inst) {
struct loader_icd_term *icd_term;
uint32_t icd_idx = 0;
uint32_t windows_sorted_devices_count = 0;
struct loader_phys_dev_per_icd *windows_sorted_devices_array = NULL;
struct loader_icd_physical_devices *windows_sorted_devices_array = NULL;
uint32_t icd_count = 0;
struct loader_phys_dev_per_icd *icd_phys_dev_array = NULL;
struct loader_icd_physical_devices *icd_phys_dev_array = NULL;
uint32_t new_phys_devs_capacity = 0;
uint32_t new_phys_devs_count = 0;
struct loader_physical_device_term **new_phys_devs = NULL;
Expand All @@ -6141,15 +6141,16 @@ VkResult setup_loader_term_phys_devs(struct loader_instance *inst) {
icd_count = inst->total_icd_count;

// Allocate something to store the physical device characteristics that we read from each ICD.
icd_phys_dev_array = (struct loader_phys_dev_per_icd *)loader_stack_alloc(sizeof(struct loader_phys_dev_per_icd) * icd_count);
icd_phys_dev_array =
(struct loader_icd_physical_devices *)loader_stack_alloc(sizeof(struct loader_icd_physical_devices) * icd_count);
if (NULL == icd_phys_dev_array) {
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
"setup_loader_term_phys_devs: Failed to allocate temporary ICD Physical device info array of size %d",
icd_count);
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
memset(icd_phys_dev_array, 0, sizeof(struct loader_phys_dev_per_icd) * icd_count);
memset(icd_phys_dev_array, 0, sizeof(struct loader_icd_physical_devices) * icd_count);

// For each ICD, query the number of physical devices, and then get an
// internal value for those physical devices.
Expand Down Expand Up @@ -6788,7 +6789,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
VkPhysicalDeviceGroupPropertiesKHR **new_phys_dev_groups = NULL;
struct loader_physical_device_group_term *local_phys_dev_groups = NULL;
PFN_vkEnumeratePhysicalDeviceGroups fpEnumeratePhysicalDeviceGroups = NULL;
struct loader_phys_dev_per_icd *sorted_phys_dev_array = NULL;
struct loader_icd_physical_devices *sorted_phys_dev_array = NULL;
uint32_t sorted_count = 0;

// For each ICD, query the number of physical device groups, and then get an
Expand Down
5 changes: 4 additions & 1 deletion loader/loader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,14 @@ enum loader_data_files_type {
LOADER_DATA_FILE_NUM_TYPES // Not a real field, used for possible loop terminator
};

struct loader_phys_dev_per_icd {
struct loader_icd_physical_devices {
uint32_t device_count;
VkPhysicalDevice *physical_devices;
uint32_t icd_index;
struct loader_icd_term *icd_term;
#if defined(WIN32)
LUID windows_adapter_luid;
#endif
};

struct loader_msg_callback_map_entry {
Expand Down
2 changes: 1 addition & 1 deletion loader/loader_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void linux_env_var_default_device(struct loader_instance *inst, uint32_t device_

// This function allocates an array in sorted_devices which must be freed by the caller if not null
VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32_t icd_count,
struct loader_phys_dev_per_icd *icd_devices, uint32_t phys_dev_count,
struct loader_icd_physical_devices *icd_devices, uint32_t phys_dev_count,
struct loader_physical_device_term **sorted_device_term) {
VkResult res = VK_SUCCESS;
bool app_is_vulkan_1_1 = loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version);
Expand Down
2 changes: 1 addition & 1 deletion loader/loader_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

// This function allocates an array in sorted_devices which must be freed by the caller if not null
VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32_t icd_count,
struct loader_phys_dev_per_icd *icd_devices, uint32_t phys_dev_count,
struct loader_icd_physical_devices *icd_devices, uint32_t phys_dev_count,
struct loader_physical_device_term **sorted_device_term);

// This function sorts an array in physical device groups
Expand Down
Loading

0 comments on commit 5e39148

Please sign in to comment.