Skip to content

Commit 58dd650

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 01526ab commit 58dd650

File tree

6 files changed

+288
-15
lines changed

6 files changed

+288
-15
lines changed

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: 140 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
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++) {
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+
210289
VkResult 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+
251347
bool 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,
866972
out:
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+
}

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)