@@ -44,13 +44,24 @@ 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 ++ ) {
5055 free_layer_configuration (inst , & settings -> layer_configurations [i ]);
5156 }
57+ loader_instance_heap_free (inst , settings -> layer_configurations );
58+ }
59+ if (NULL != settings -> additional_drivers ) {
60+ for (uint32_t i = 0 ; i < settings -> additional_driver_count ; i ++ ) {
61+ free_driver_configuration (inst , & settings -> additional_drivers [i ]);
62+ }
63+ loader_instance_heap_free (inst , settings -> additional_drivers );
5264 }
53- loader_instance_heap_free (inst , settings -> layer_configurations );
5465 loader_instance_heap_free (inst , settings -> settings_file_path );
5566 memset (settings , 0 , sizeof (loader_settings ));
5667}
@@ -207,6 +218,74 @@ VkResult parse_layer_configurations(const struct loader_instance* inst, cJSON* s
207218 return res ;
208219}
209220
221+ VkResult parse_additional_driver (const struct loader_instance * inst , cJSON * additional_driver_json ,
222+ loader_settings_driver_configuration * additional_driver ) {
223+ VkResult res = VK_SUCCESS ;
224+ res = loader_parse_json_string (additional_driver_json , "path" , & (additional_driver -> path ));
225+ if (res != VK_SUCCESS ) {
226+ goto out ;
227+ }
228+ out :
229+ if (res != VK_SUCCESS ) {
230+ free_driver_configuration (inst , additional_driver );
231+ }
232+ return res ;
233+ }
234+
235+ VkResult parse_additional_drivers (const struct loader_instance * inst , cJSON * settings_object , loader_settings * loader_settings ) {
236+ VkResult res = VK_SUCCESS ;
237+
238+ cJSON * use_additional_drivers_exclusively_json =
239+ loader_cJSON_GetObjectItem (settings_object , "use_additional_drivers_exclusively" );
240+ if (use_additional_drivers_exclusively_json && use_additional_drivers_exclusively_json -> type == cJSON_True ) {
241+ loader_settings -> use_additional_drivers_exclusively = true;
242+ }
243+
244+ cJSON * additional_drivers_json = loader_cJSON_GetObjectItem (settings_object , "additional_drivers" );
245+ if (NULL == additional_drivers_json ) {
246+ return VK_SUCCESS ;
247+ }
248+
249+ uint32_t additional_driver_count = loader_cJSON_GetArraySize (additional_drivers_json );
250+ if (additional_driver_count == 0 ) {
251+ return VK_SUCCESS ;
252+ }
253+
254+ loader_settings -> additional_driver_count = additional_driver_count ;
255+
256+ loader_settings -> additional_drivers = loader_instance_heap_calloc (
257+ inst , sizeof (loader_settings_layer_configuration ) * additional_driver_count , VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE );
258+ if (NULL == loader_settings -> additional_drivers ) {
259+ res = VK_ERROR_OUT_OF_HOST_MEMORY ;
260+ goto out ;
261+ }
262+
263+ cJSON * driver = NULL ;
264+ size_t i = 0 ;
265+ cJSON_ArrayForEach (driver , additional_drivers_json ) {
266+ if (driver -> type != cJSON_Object ) {
267+ res = VK_ERROR_INITIALIZATION_FAILED ;
268+ goto out ;
269+ }
270+ res = parse_additional_driver (inst , driver , & (loader_settings -> additional_drivers [i ++ ]));
271+ if (VK_SUCCESS != res ) {
272+ goto out ;
273+ }
274+ }
275+ out :
276+ if (res != VK_SUCCESS ) {
277+ if (loader_settings -> additional_drivers ) {
278+ for (size_t index = 0 ; index < loader_settings -> additional_driver_count ; index ++ ) {
279+ free_driver_configuration (inst , & (loader_settings -> additional_drivers [index ]));
280+ }
281+ loader_settings -> additional_driver_count = 0 ;
282+ loader_instance_heap_free (inst , loader_settings -> additional_drivers );
283+ loader_settings -> additional_drivers = NULL ;
284+ }
285+ }
286+ return res ;
287+ }
288+
210289VkResult check_if_settings_path_exists (const struct loader_instance * inst , const char * base , const char * suffix ,
211290 char * * settings_file_path ) {
212291 if (NULL == base || NULL == suffix ) {
@@ -248,6 +327,23 @@ VkResult get_unix_settings_path(const struct loader_instance* inst, char** setti
248327 settings_file_path );
249328}
250329
330+ bool check_if_layer_configurations_are_equal (loader_settings_layer_configuration * a , loader_settings_layer_configuration * b ) {
331+ if (!a -> name || !b -> name || 0 != strcmp (a -> name , b -> name )) {
332+ return false;
333+ }
334+ if (!a -> path || !b -> path || 0 != strcmp (a -> path , b -> path )) {
335+ return false;
336+ }
337+ return a -> control == b -> control ;
338+ }
339+
340+ bool check_if_driver_configurations_are_equal (loader_settings_driver_configuration * a , loader_settings_driver_configuration * b ) {
341+ if (!a -> path || !b -> path || 0 != strcmp (a -> path , b -> path )) {
342+ return false;
343+ }
344+ return true;
345+ }
346+
251347bool check_if_settings_are_equal (loader_settings * a , loader_settings * b ) {
252348 // If either pointer is null, return true
253349 if (NULL == a || NULL == b ) return false;
@@ -256,19 +352,13 @@ bool check_if_settings_are_equal(loader_settings* a, loader_settings* b) {
256352 are_equal &= a -> has_unordered_layer_location == b -> has_unordered_layer_location ;
257353 are_equal &= a -> debug_level == b -> debug_level ;
258354 are_equal &= a -> layer_configuration_count == b -> layer_configuration_count ;
355+ are_equal &= a -> additional_driver_count == b -> additional_driver_count ;
259356 if (!are_equal ) return false;
260357 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 ;
358+ are_equal &= check_if_layer_configurations_are_equal (& a -> layer_configurations [i ], & b -> layer_configurations [i ]);
359+ }
360+ for (uint32_t i = 0 ; i < a -> additional_driver_count && i < b -> additional_driver_count ; i ++ ) {
361+ are_equal &= check_if_driver_configurations_are_equal (& a -> additional_drivers [i ], & b -> additional_drivers [i ]);
272362 }
273363 return are_equal ;
274364}
@@ -302,6 +392,17 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings)
302392 loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Control: %s" ,
303393 loader_settings_layer_control_to_string (settings -> layer_configurations [i ].control ));
304394 }
395+ if (settings -> additional_driver_count > 0 ) {
396+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "----" );
397+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Use Additional Drivers Exclusively = %s" ,
398+ settings -> use_additional_drivers_exclusively ? "true" : "false" );
399+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Additional Driver Configurations count = %d" ,
400+ settings -> additional_driver_count );
401+ for (uint32_t i = 0 ; i < settings -> additional_driver_count ; i ++ ) {
402+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "---- Driver Configuration [%d] ----" , i );
403+ loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "Path: %s" , settings -> additional_drivers [i ].path );
404+ }
405+ }
305406 loader_log (inst , VULKAN_LOADER_DEBUG_BIT , 0 , "---------------------------------" );
306407}
307408
@@ -471,6 +572,11 @@ VkResult get_loader_settings(const struct loader_instance* inst, loader_settings
471572 }
472573 }
473574
575+ res = parse_additional_drivers (inst , settings_to_use , loader_settings );
576+ if (res != VK_SUCCESS ) {
577+ goto out ;
578+ }
579+
474580 loader_settings -> settings_file_path = settings_file_path ;
475581 settings_file_path = NULL ;
476582 loader_settings -> settings_active = true;
@@ -866,3 +972,25 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
866972out :
867973 return res ;
868974}
975+
976+ VkResult loader_settings_get_additional_driver_files (const struct loader_instance * inst , struct loader_string_list * out_files ) {
977+ VkResult res = VK_SUCCESS ;
978+
979+ const loader_settings * settings = get_current_settings_and_lock (inst );
980+
981+ if (NULL == settings || !settings -> settings_active ) {
982+ goto out ;
983+ }
984+
985+ if (settings -> use_additional_drivers_exclusively ) {
986+ free_string_list (inst , out_files );
987+ }
988+
989+ for (uint32_t i = 0 ; i < settings -> additional_driver_count ; i ++ ) {
990+ res = prepend_if_manifest_file (inst , settings -> additional_drivers [i ].path , out_files );
991+ }
992+
993+ out :
994+ release_current_settings_lock (inst );
995+ return res ;
996+ }
0 commit comments