Skip to content

Commit 37abe1a

Browse files
Add drivers field to settings file
Allows the settings file to contain 'additional drivers' which are just paths to ICD manifest files.
1 parent d396902 commit 37abe1a

6 files changed

Lines changed: 280 additions & 14 deletions

File tree

loader/loader.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,12 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
38183818
goto out;
38193819
}
38203820

3821+
// Add any drivers provided by the loader settings file
3822+
res = loader_settings_get_additional_driver_files(inst, &manifest_files);
3823+
if (VK_SUCCESS != res) {
3824+
goto out;
3825+
}
3826+
38213827
icd_details = loader_stack_alloc(sizeof(struct ICDManifestInfo) * manifest_files.count);
38223828
if (NULL == icd_details) {
38233829
res = VK_ERROR_OUT_OF_HOST_MEMORY;

loader/settings.c

Lines changed: 132 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
4752
void 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+
210283
VkResult 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+
251341
bool 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,
866966
out:
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+
}

loader/settings.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
struct loader_instance;
3636
struct loader_layer_list;
37+
struct loader_string_list;
3738
struct loader_pointer_layer_list;
3839
struct loader_envvar_all_filters;
3940
typedef struct log_configuration log_configuration;
@@ -61,6 +62,10 @@ typedef struct loader_settings_layer_configuration {
6162

6263
} loader_settings_layer_configuration;
6364

65+
typedef struct loader_settings_driver_configuration {
66+
char* path;
67+
} loader_settings_driver_configuration;
68+
6469
typedef struct loader_settings {
6570
bool settings_active;
6671
bool has_unordered_layer_location;
@@ -69,6 +74,10 @@ typedef struct loader_settings {
6974
uint32_t layer_configuration_count;
7075
loader_settings_layer_configuration* layer_configurations;
7176

77+
bool use_additional_drivers_exclusively;
78+
uint32_t additional_driver_count;
79+
loader_settings_driver_configuration* additional_drivers;
80+
7281
char* settings_file_path;
7382
} loader_settings;
7483

@@ -112,3 +121,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst,
112121
const struct loader_layer_list* instance_layers,
113122
struct loader_pointer_layer_list* target_layer_list,
114123
struct loader_pointer_layer_list* activated_layer_list);
124+
125+
// Add any drivers that the loader settings file contains to the out_files list. If the use_additional_drivers_exclusively field is
126+
// true, clear the out_files list before adding any additional drivers
127+
VkResult loader_settings_get_additional_driver_files(const struct loader_instance* inst, struct loader_string_list* out_files);

tests/framework/test_environment.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,12 +687,12 @@ TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
687687
case (ManifestDiscoveryType::unsecured_generic):
688688
platform_shim->add_unsecured_manifest(ManifestCategory::icd, icds.back().manifest_path);
689689
break;
690-
case (ManifestDiscoveryType::null_dir):
691-
case (ManifestDiscoveryType::none):
692-
break;
693690
case (ManifestDiscoveryType::windows_app_package):
694691
platform_shim->set_app_package_path(folder.location());
695692
break;
693+
case (ManifestDiscoveryType::null_dir):
694+
case (ManifestDiscoveryType::none):
695+
break;
696696
}
697697
}
698698
return icds.back().get_test_icd();
@@ -907,6 +907,16 @@ std::string get_loader_settings_file_contents(const LoaderSettings& loader_setti
907907
}
908908
writer.EndArray();
909909
}
910+
if (!setting.driver_configurations.empty()) {
911+
writer.AddKeyedBool("use_additional_drivers_exclusively", setting.use_additional_drivers_exclusively);
912+
writer.StartKeyedArray("additional_drivers");
913+
for (const auto& driver : setting.driver_configurations) {
914+
writer.StartObject();
915+
writer.AddKeyedString("path", driver.path);
916+
writer.EndObject();
917+
}
918+
writer.EndArray();
919+
}
910920
writer.EndObject();
911921
}
912922
if (!one_setting_file) {

tests/framework/test_environment.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ struct LoaderSettingsLayerConfiguration {
513513
BUILDER_VALUE(std::string, control)
514514
BUILDER_VALUE(bool, treat_as_implicit_manifest)
515515
};
516+
// Needed for next_permutation
516517
inline bool operator==(LoaderSettingsLayerConfiguration const& a, LoaderSettingsLayerConfiguration const& b) {
517518
return a.name == b.name && a.path == b.path && a.control == b.control &&
518519
a.treat_as_implicit_manifest == b.treat_as_implicit_manifest;
@@ -525,6 +526,10 @@ inline bool operator>(LoaderSettingsLayerConfiguration const& a, LoaderSettingsL
525526
inline bool operator<=(LoaderSettingsLayerConfiguration const& a, LoaderSettingsLayerConfiguration const& b) { return !(b < a); }
526527
inline bool operator>=(LoaderSettingsLayerConfiguration const& a, LoaderSettingsLayerConfiguration const& b) { return !(a < b); }
527528

529+
struct LoaderSettingsDriverConfiguration {
530+
BUILDER_VALUE(std::string, path)
531+
};
532+
528533
// Log files and their associated filter
529534
struct LoaderLogConfiguration {
530535
BUILDER_VECTOR(std::string, destinations, destination)
@@ -533,6 +538,8 @@ struct LoaderLogConfiguration {
533538
struct AppSpecificSettings {
534539
BUILDER_VECTOR(std::string, app_keys, app_key)
535540
BUILDER_VECTOR(LoaderSettingsLayerConfiguration, layer_configurations, layer_configuration)
541+
BUILDER_VECTOR(LoaderSettingsDriverConfiguration, driver_configurations, driver_configuration)
542+
BUILDER_VALUE(bool, use_additional_drivers_exclusively)
536543
BUILDER_VECTOR(std::string, stderr_log, stderr_log_filter)
537544
BUILDER_VECTOR(LoaderLogConfiguration, log_configurations, log_configuration)
538545
};

0 commit comments

Comments
 (0)