@@ -44,6 +44,11 @@ void free_layer_configuration(const struct loader_instance* inst, loader_setting
4444 memset (layer_configuration , 0 , sizeof (loader_settings_layer_configuration ));
4545}
4646
47+ void free_driver_configuration (const struct loader_instance * inst , loader_settings_driver_configuration * driver_configuration ) {
48+ loader_instance_heap_free (inst , driver_configuration -> path );
49+ memset (driver_configuration , 0 , sizeof (loader_settings_driver_configuration ));
50+ }
51+
4752void free_loader_settings (const struct loader_instance * inst , loader_settings * settings ) {
4853 if (NULL != settings -> layer_configurations ) {
4954 for (uint32_t i = 0 ; i < settings -> layer_configuration_count ; i ++ ) {
@@ -207,6 +212,74 @@ VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* s
207212 return res ;
208213}
209214
215+ VkResult parse_additional_driver (const struct loader_instance * inst , cJSON * additional_driver_json ,
216+ loader_settings_driver_configuration * additional_driver ) {
217+ VkResult res = VK_SUCCESS ;
218+ res = loader_parse_json_string (additional_driver_json , "path" , & (additional_driver -> path ));
219+ if (res != VK_SUCCESS ) {
220+ goto out ;
221+ }
222+ out :
223+ if (res != VK_SUCCESS ) {
224+ free_driver_configuration (inst , additional_driver );
225+ }
226+ return res ;
227+ }
228+
229+ VkResult parse_additional_drivers (const struct loader_instance * inst , cJSON * settings_object , loader_settings * loader_settings ) {
230+ VkResult res = VK_SUCCESS ;
231+
232+ cJSON * use_additional_drivers_exclusively_json =
233+ loader_cJSON_GetObjectItem (settings_object , "use_additional_drivers_exclusively" );
234+ if (use_additional_drivers_exclusively_json && use_additional_drivers_exclusively_json -> type == cJSON_True ) {
235+ loader_settings -> use_additional_drivers_exclusively = true;
236+ }
237+
238+ cJSON * additional_drivers_json = loader_cJSON_GetObjectItem (settings_object , "additional_drivers" );
239+ if (NULL == additional_drivers_json ) {
240+ return VK_SUCCESS ;
241+ }
242+
243+ uint32_t additional_driver_count = loader_cJSON_GetArraySize (additional_drivers_json );
244+ if (additional_driver_count == 0 ) {
245+ return VK_SUCCESS ;
246+ }
247+
248+ loader_settings -> additional_driver_count = additional_driver_count ;
249+
250+ loader_settings -> additional_drivers = loader_instance_heap_calloc (
251+ inst , sizeof (loader_settings_layer_configuration ) * additional_driver_count , VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE );
252+ if (NULL == loader_settings -> additional_drivers ) {
253+ res = VK_ERROR_OUT_OF_HOST_MEMORY ;
254+ goto out ;
255+ }
256+
257+ cJSON * driver = NULL ;
258+ size_t i = 0 ;
259+ cJSON_ArrayForEach (driver , additional_drivers_json ) {
260+ if (driver -> type != cJSON_Object ) {
261+ res = VK_ERROR_INITIALIZATION_FAILED ;
262+ goto out ;
263+ }
264+ res = parse_additional_driver (inst , driver , & (loader_settings -> additional_drivers [i ++ ]));
265+ if (VK_SUCCESS != res ) {
266+ goto out ;
267+ }
268+ }
269+ out :
270+ if (res != VK_SUCCESS ) {
271+ if (loader_settings -> additional_drivers ) {
272+ for (size_t index = 0 ; index < loader_settings -> additional_driver_count ; index ++ ) {
273+ free_driver_configuration (inst , & (loader_settings -> additional_drivers [index ]));
274+ }
275+ loader_settings -> additional_driver_count = 0 ;
276+ loader_instance_heap_free (inst , loader_settings -> additional_drivers );
277+ loader_settings -> additional_drivers = NULL ;
278+ }
279+ }
280+ return res ;
281+ }
282+
210283VkResult check_if_settings_path_exists (const struct loader_instance * inst , const char * base , const char * suffix ,
211284 char * * settings_file_path ) {
212285 if (NULL == base || NULL == suffix ) {
@@ -248,6 +321,23 @@ VkResult get_unix_settings_path(const struct loader_instance* inst, char** setti
248321 settings_file_path );
249322}
250323
324+ bool check_if_layer_configurations_are_equal (loader_settings_layer_configuration * a , loader_settings_layer_configuration * b ) {
325+ if (!a -> name || !b -> name || 0 != strcmp (a -> name , b -> name )) {
326+ return false;
327+ }
328+ if (!a -> path || !b -> path || 0 != strcmp (a -> path , b -> path )) {
329+ return false;
330+ }
331+ return a -> control == b -> control ;
332+ }
333+
334+ bool check_if_driver_configurations_are_equal (loader_settings_driver_configuration * a , loader_settings_driver_configuration * b ) {
335+ if (!a -> path || !b -> path || 0 != strcmp (a -> path , b -> path )) {
336+ return false;
337+ }
338+ return true;
339+ }
340+
251341bool check_if_settings_are_equal (loader_settings * a , loader_settings * b ) {
252342 // If either pointer is null, return true
253343 if (NULL == a || NULL == b ) return false;
@@ -256,19 +346,13 @@ bool check_if_settings_are_equal(loader_settings* a, loader_settings* b) {
256346 are_equal &= a -> has_unordered_layer_location == b -> has_unordered_layer_location ;
257347 are_equal &= a -> debug_level == b -> debug_level ;
258348 are_equal &= a -> layer_configuration_count == b -> layer_configuration_count ;
349+ are_equal &= a -> additional_driver_count == b -> additional_driver_count ;
259350 if (!are_equal ) return false;
260351 for (uint32_t i = 0 ; i < a -> layer_configuration_count && i < b -> layer_configuration_count ; i ++ ) {
261- if (a -> layer_configurations [i ].name && b -> layer_configurations [i ].name ) {
262- are_equal &= 0 == strcmp (a -> layer_configurations [i ].name , b -> layer_configurations [i ].name );
263- } else {
264- are_equal = false;
265- }
266- if (a -> layer_configurations [i ].path && b -> layer_configurations [i ].path ) {
267- are_equal &= 0 == strcmp (a -> layer_configurations [i ].path , b -> layer_configurations [i ].path );
268- } else {
269- are_equal = false;
270- }
271- are_equal &= a -> layer_configurations [i ].control == b -> layer_configurations [i ].control ;
352+ are_equal &= check_if_layer_configurations_are_equal (& a -> layer_configurations [i ], & b -> layer_configurations [i ]);
353+ }
354+ for (uint32_t i = 0 ; i < a -> additional_driver_count && i < b -> additional_driver_count ; i ++ ) {
355+ are_equal &= check_if_driver_configurations_are_equal (& a -> additional_drivers [i ], & b -> additional_drivers [i ]);
272356 }
273357 return are_equal ;
274358}
@@ -302,6 +386,17 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings)
302386 loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Control: %s" ,
303387 loader_settings_layer_control_to_string (settings -> layer_configurations [i ].control ));
304388 }
389+ if (settings -> additional_driver_count > 0 ) {
390+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "----" );
391+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Use Additional Drivers Exclusively = %s" ,
392+ settings -> use_additional_drivers_exclusively ? "true" : "false" );
393+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Additional Driver Configurations count = %d" ,
394+ settings -> additional_driver_count );
395+ for (uint32_t i = 0 ; i < settings -> additional_driver_count ; i ++ ) {
396+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "---- Driver Configuration [%d] ----" , i );
397+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Path: %s" , settings -> additional_drivers [i ].path );
398+ }
399+ }
305400 loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "---------------------------------" );
306401}
307402
@@ -471,6 +566,11 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings
471566 }
472567 }
473568
569+ res = parse_additional_drivers (inst , settings_to_use , loader_settings );
570+ if (res != VK_SUCCESS ) {
571+ goto out ;
572+ }
573+
474574 loader_settings -> settings_file_path = settings_file_path ;
475575 settings_file_path = NULL ;
476576 loader_settings -> settings_active = true;
@@ -866,3 +966,24 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
866966out :
867967 return res ;
868968}
969+
970+ VkResult loader_settings_get_additional_driver_files (const struct loader_instance * inst , struct loader_string_list * out_files ) {
971+ VkResult res = VK_SUCCESS ;
972+
973+ const loader_settings * settings = get_current_settings_and_lock (inst );
974+
975+ if (NULL == settings || !settings -> settings_active ) {
976+ goto out ;
977+ }
978+
979+ if (settings -> use_additional_drivers_exclusively ) {
980+ free_string_list (inst , out_files );
981+ }
982+
983+ for (uint32_t i = 0 ; i < settings -> additional_driver_count ; i ++ ) {
984+ res = prepend_if_manifest_file (inst , settings -> additional_drivers [i ].path , out_files );
985+ }
986+
987+ out :
988+ return res ;
989+ }
0 commit comments