loader: Re-add old 1.1 loader work
authorLenny Komow <lenny@lunarg.com>
Wed, 25 Oct 2017 21:26:15 +0000 (15:26 -0600)
committerMike Schuchardt <mikes@lunarg.com>
Fri, 9 Mar 2018 20:54:31 +0000 (13:54 -0700)
vkEnumerateInstanceVersion got removed, as did the checks for layer
versions when we rebased off of github. This adds them back in.

loader/loader.c
loader/loader.h
loader/trampoline.c

index 6acbd21..fb94d2a 100644 (file)
@@ -1355,6 +1355,8 @@ void loader_destroy_layer_list(const struct loader_instance *inst, struct loader
 VkResult loader_add_to_layer_list(const struct loader_instance *inst, struct loader_layer_list *list, uint32_t prop_list_count,
                                   const struct loader_layer_properties *props) {
     uint32_t i;
+    uint16_t layer_api_major_version;
+    uint16_t layer_api_minor_version;
     struct loader_layer_properties *layer;
 
     if (list->list == NULL || list->capacity == 0) {
@@ -1385,6 +1387,18 @@ VkResult loader_add_to_layer_list(const struct loader_instance *inst, struct loa
             list->capacity = new_capacity;
         }
 
+        // Verify that the layer api version is at least that of the application's request, if not, throw a warning since
+        // undefined behavior could occur.
+        layer_api_major_version = VK_VERSION_MAJOR(props[i].info.specVersion);
+        layer_api_minor_version = VK_VERSION_MINOR(props[i].info.specVersion);
+        if (inst->app_api_major_version > layer_api_major_version ||
+            (inst->app_api_major_version == layer_api_major_version && inst->app_api_minor_version > layer_api_minor_version)) {
+            loader_log(
+                inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                "loader_add_to_layer_list: Explicit layer %s is using an old API version %d.%d versus application requested %d.%d",
+                props[i].info.layerName, layer_api_major_version, layer_api_minor_version, inst->app_api_major_version,-                inst->app_api_minor_version);
+        }
+
         memcpy(&list->list[list->count], layer, sizeof(struct loader_layer_properties));
         list->count++;
     }
@@ -1398,6 +1412,23 @@ static void loader_add_implicit_layer(const struct loader_instance *inst, const
                                       struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
                                       const struct loader_layer_list *source_list) {
     bool enable = loader_is_implicit_layer_enabled(inst, prop);
+
+    // If the implicit layer is supposed to be enable, make sure the layer supports at least the same API version
+    // that the application is asking (i.e. layer's API >= app's API).  If it's not, disable this layer.
+    if (enable) {
+        uint16_t layer_api_major_version = VK_VERSION_MAJOR(prop->info.specVersion);
+        uint16_t layer_api_minor_version = VK_VERSION_MINOR(prop->info.specVersion);
+        if (inst->app_api_major_version > layer_api_major_version ||
+            (inst->app_api_major_version == layer_api_major_version && inst->app_api_minor_version > layer_api_minor_version)) {
+            loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+                       "loader_add_implicit_layer: Disabling implicit layer %s for using an old API version %d.%d versus "
+                       "application requested %d.%d",
+                       prop->info.layerName, layer_api_major_version, layer_api_minor_version, inst->app_api_major_version,
+                       inst->app_api_minor_version);
+            enable = false;
+        }
+    }
+
     if (enable) {
         if (0 == (prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
             if (NULL != target_list && !has_vk_layer_property(&prop->info, target_list)) {
index c59b944..ae928f9 100644 (file)
@@ -228,6 +228,10 @@ struct loader_instance_dispatch_table {
 struct loader_instance {
     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
 
+    // Vulkan API version the app is intending to use.
+    uint16_t app_api_major_version;
+    uint16_t app_api_minor_version;
+
     // We need to manually track physical devices over time.  If the user
     // re-queries the information, we don't want to delete old data or
     // create new data unless necessary.
index 58fcf77..7915006 100644 (file)
@@ -272,6 +272,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
     return res;
 }
 
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
+    // NOTE: The Vulkan WG doesn't want us checking pApiVersion for NULL, but instead
+    // prefers us crashing.
+    *pApiVersion = VK_MAKE_VERSION(loader_major_version, loader_minor_version, 0);
+    return VK_SUCCESS;
+}
+
 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
                                                               const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
     struct loader_instance *ptr_instance = NULL;
@@ -307,6 +314,16 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
         ptr_instance->alloc_callbacks = *pAllocator;
     }
 
+    // Save the application version
+    if (NULL == pCreateInfo || NULL == pCreateInfo->pApplicationInfo || 0 == pCreateInfo->pApplicationInfo->apiVersion)
+{
+        ptr_instance->app_api_major_version = 1;
+        ptr_instance->app_api_minor_version = 0;
+    } else {
+        ptr_instance->app_api_major_version = VK_VERSION_MAJOR(pCreateInfo->pApplicationInfo->apiVersion);
+        ptr_instance->app_api_minor_version = VK_VERSION_MINOR(pCreateInfo->pApplicationInfo->apiVersion);
+    }
+
     // Look for one or more debug report create info structures
     // and setup a callback(s) for each one found.
     ptr_instance->num_tmp_callbacks = 0;