loader: Add validation checks to CreateDevice
diff --git a/loader/loader.c b/loader/loader.c
index b845457..5e4ae6d 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -2227,14 +2227,16 @@
return dev->activated_layer_list.count;
}
-VkResult loader_validate_instance_layers(
- const VkInstanceCreateInfo* pCreateInfo)
+VkResult loader_validate_layers(
+ const uint32_t layer_count,
+ const char * const *ppEnabledLayerNames,
+ struct loader_layer_list *list)
{
struct loader_layer_properties *prop;
- for (uint32_t i = 0; i < pCreateInfo->layerCount; i++) {
- prop = get_layer_property(pCreateInfo->ppEnabledLayerNames[i],
- &loader.global_layer_list);
+ for (uint32_t i = 0; i < layer_count; i++) {
+ prop = get_layer_property(ppEnabledLayerNames[i],
+ list);
if (!prop) {
return VK_ERROR_INVALID_LAYER;
}
@@ -2244,8 +2246,91 @@
}
VkResult loader_validate_instance_extensions(
- const VkInstanceCreateInfo* pCreateInfo)
+ const VkInstanceCreateInfo *pCreateInfo)
{
+ struct loader_extension_property *extension_prop;
+ struct loader_layer_properties *layer_prop;
+
+ for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
+ extension_prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i],
+ &loader.global_extensions);
+
+ if (extension_prop) {
+ continue;
+ }
+
+ extension_prop = NULL;
+
+ /* Not in global list, search layer extension lists */
+ for (uint32_t j = 0; j < pCreateInfo->layerCount; j++) {
+ layer_prop = get_layer_property(pCreateInfo->ppEnabledLayerNames[i],
+ &loader.global_layer_list);
+
+ if (!layer_prop) {
+ /* Should NOT get here, loader_validate_instance_layers
+ * should have already filtered this case out.
+ */
+ continue;
+ }
+
+ extension_prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i],
+ &layer_prop->instance_extension_list);
+ if (extension_prop) {
+ /* Found the extension in one of the layers enabled by the app. */
+ break;
+ }
+ }
+
+ if (!extension_prop) {
+ /* Didn't find extension name in any of the global layers, error out */
+ return VK_ERROR_INVALID_EXTENSION;
+ }
+ }
+ return VK_SUCCESS;
+}
+
+VkResult loader_validate_device_extensions(
+ struct loader_icd *icd,
+ const VkDeviceCreateInfo *pCreateInfo)
+{
+ struct loader_extension_property *extension_prop;
+ struct loader_layer_properties *layer_prop;
+
+ for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
+ const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
+ extension_prop = get_extension_property(extension_name,
+ &loader.global_extensions);
+
+ if (extension_prop) {
+ continue;
+ }
+
+ /* Not in global list, search layer extension lists */
+ for (uint32_t j = 0; j < pCreateInfo->layerCount; j++) {
+ const char *layer_name = pCreateInfo->ppEnabledLayerNames[j];
+ layer_prop = get_layer_property(layer_name,
+ &icd->layer_properties_cache);
+
+ if (!layer_prop) {
+ /* Should NOT get here, loader_validate_instance_layers
+ * should have already filtered this case out.
+ */
+ continue;
+ }
+
+ extension_prop = get_extension_property(extension_name,
+ &layer_prop->device_extension_list);
+ if (extension_prop) {
+ /* Found the extension in one of the layers enabled by the app. */
+ break;
+ }
+ }
+
+ if (!extension_prop) {
+ /* Didn't find extension name in any of the device layers, error out */
+ return VK_ERROR_INVALID_EXTENSION;
+ }
+ }
return VK_SUCCESS;
}
@@ -2270,7 +2355,7 @@
/*
* NOTE: Need to filter the extensions to only those
- * supported by the ICD are in the pCreateInfo structure.
+ * supported by the ICD.
* No ICD will advertise support for layers. An ICD
* library could support a layer, but it would be
* independent of the actual ICD, just in the same library.
@@ -2627,6 +2712,17 @@
* TODO: Probably should verify that every extension is
* covered by either the ICD or some layer.
*/
+ res = loader_validate_layers(pCreateInfo->layerCount,
+ pCreateInfo->ppEnabledLayerNames,
+ &icd->layer_properties_cache);
+ if (res != VK_SUCCESS) {
+ return res;
+ }
+
+ res = loader_validate_device_extensions(icd, pCreateInfo);
+ if (res != VK_SUCCESS) {
+ return res;
+ }
res = icd->CreateDevice(gpu, pCreateInfo, pDevice);
if (res != VK_SUCCESS) {
diff --git a/loader/loader.h b/loader/loader.h
index 8982bf1..371a306 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -335,8 +335,7 @@
const VkExtensionProperties* op1,
const VkExtensionProperties* op2);
-VkResult loader_validate_instance_layers(
- const VkInstanceCreateInfo* pCreateInfo);
+VkResult loader_validate_layers(const uint32_t layer_count, const char * const *ppEnabledLayerNames, struct loader_layer_list *list);
VkResult loader_validate_instance_extensions(
const VkInstanceCreateInfo* pCreateInfo);
diff --git a/loader/trampoline.c b/loader/trampoline.c
index b3df9bd..f196194 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -53,7 +53,9 @@
/* merge any duplicate extensions */
loader_platform_thread_once(&once_exts, loader_coalesce_extensions);
- res = loader_validate_instance_layers(pCreateInfo);
+ res = loader_validate_layers(pCreateInfo->layerCount,
+ pCreateInfo->ppEnabledLayerNames,
+ &loader.global_layer_list);
if (res != VK_SUCCESS) {
return res;
}