vulkan: deprecate device layers

Allow instance layers to intercept all commands and enumerate device
extensions.  Ignore application device layers.  Enumerate all enabled
instance layers in vkEnumerateDeviceLayerProperties.

Bug: 27911856
Change-Id: I6e89439ab10835dd1a43732c2333a92201e52550
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 21a6c89..28b172d 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -116,7 +116,7 @@
     };
 
     void AddImplicitLayers() {
-        if (!driver::Debuggable())
+        if (!is_instance_ || !driver::Debuggable())
             return;
 
         ParseDebugVulkanLayers();
@@ -367,6 +367,14 @@
 // chaining.
 class LayerChain {
    public:
+    struct ActiveLayer {
+        LayerRef ref;
+        union {
+            VkLayerInstanceLink instance_link;
+            VkLayerDeviceLink device_link;
+        };
+    };
+
     static VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
                                    const VkAllocationCallbacks* allocator,
                                    VkInstance* instance_out);
@@ -382,15 +390,10 @@
     static void DestroyDevice(VkDevice dev,
                               const VkAllocationCallbacks* allocator);
 
-   private:
-    struct ActiveLayer {
-        LayerRef ref;
-        union {
-            VkLayerInstanceLink instance_link;
-            VkLayerDeviceLink device_link;
-        };
-    };
+    static const ActiveLayer* GetActiveLayers(VkPhysicalDevice physical_dev,
+                                              uint32_t& count);
 
+   private:
     LayerChain(bool is_instance, const VkAllocationCallbacks& allocator);
     ~LayerChain();
 
@@ -398,6 +401,11 @@
                             uint32_t layer_count,
                             const char* const* extension_names,
                             uint32_t extension_count);
+    VkResult ActivateLayers(VkPhysicalDevice physical_dev,
+                            const char* const* layer_names,
+                            uint32_t layer_count,
+                            const char* const* extension_names,
+                            uint32_t extension_count);
     ActiveLayer* AllocateLayerArray(uint32_t count) const;
     VkResult LoadLayer(ActiveLayer& layer, const char* name);
     void SetupLayerLinks();
@@ -507,8 +515,6 @@
     if (!layer_count) {
         // point head of chain to the driver
         get_instance_proc_addr_ = driver::GetInstanceProcAddr;
-        if (!is_instance_)
-            get_device_proc_addr_ = driver::GetDeviceProcAddr;
 
         return VK_SUCCESS;
     }
@@ -532,10 +538,76 @@
     return VK_SUCCESS;
 }
 
+VkResult LayerChain::ActivateLayers(VkPhysicalDevice physical_dev,
+                                    const char* const* layer_names,
+                                    uint32_t layer_count,
+                                    const char* const* extension_names,
+                                    uint32_t extension_count) {
+    uint32_t instance_layer_count;
+    const ActiveLayer* instance_layers =
+        GetActiveLayers(physical_dev, instance_layer_count);
+
+    // log a message if the application device layer array is not empty nor an
+    // exact match of the instance layer array.
+    if (layer_count) {
+        bool exact_match = (instance_layer_count == layer_count);
+        if (exact_match) {
+            for (uint32_t i = 0; i < instance_layer_count; i++) {
+                const Layer& l = *instance_layers[i].ref;
+                if (strcmp(GetLayerProperties(l).layerName, layer_names[i])) {
+                    exact_match = false;
+                    break;
+                }
+            }
+        }
+
+        if (!exact_match) {
+            ALOGW("Device layers");
+            for (uint32_t i = 0; i < layer_count; i++)
+                ALOGW("  %s", layer_names[i]);
+            ALOGW(
+                "disagree with instance layers and are overridden by "
+                "instance layers");
+        }
+    }
+
+    VkResult result =
+        override_extensions_.Parse(extension_names, extension_count);
+    if (result != VK_SUCCESS)
+        return result;
+
+    if (!instance_layer_count) {
+        // point head of chain to the driver
+        get_instance_proc_addr_ = driver::GetInstanceProcAddr;
+        get_device_proc_addr_ = driver::GetDeviceProcAddr;
+
+        return VK_SUCCESS;
+    }
+
+    layers_ = AllocateLayerArray(instance_layer_count);
+    if (!layers_)
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+    for (uint32_t i = 0; i < instance_layer_count; i++) {
+        const Layer& l = *instance_layers[i].ref;
+
+        // no need to and cannot chain non-global layers
+        if (!IsLayerGlobal(l))
+            continue;
+
+        // this never fails
+        new (&layers_[layer_count_++]) ActiveLayer{GetLayerRef(l), {}};
+    }
+
+    SetupLayerLinks();
+
+    return VK_SUCCESS;
+}
+
 LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const {
     VkSystemAllocationScope scope = (is_instance_)
                                         ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
-                                        : VK_SYSTEM_ALLOCATION_SCOPE_DEVICE;
+                                        : VK_SYSTEM_ALLOCATION_SCOPE_COMMAND;
 
     return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation(
         allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer),
@@ -544,7 +616,7 @@
 
 VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) {
     const Layer* l = FindLayer(name);
-    if (!l || (!is_instance_ && !IsLayerGlobal(*l))) {
+    if (!l) {
         ALOGW("Failed to find layer %s", name);
         return VK_ERROR_LAYER_NOT_PRESENT;
     }
@@ -556,7 +628,7 @@
         return VK_ERROR_LAYER_NOT_PRESENT;
     }
 
-    ALOGI("Loaded %s layer %s", (is_instance_) ? "instance" : "device", name);
+    ALOGI("Loaded layer %s", name);
 
     return VK_SUCCESS;
 }
@@ -700,8 +772,6 @@
     // initialize InstanceData
     InstanceData& data = GetData(instance);
 
-    data.instance = instance;
-
     if (!InitDispatchTable(instance, get_instance_proc_addr_,
                            enabled_extensions_)) {
         if (data.dispatch.DestroyInstance)
@@ -765,13 +835,8 @@
         return result;
 
     // call down the chain
-    //
-    // TODO Instance call chain available at
-    // GetData(physical_dev).dispatch.CreateDevice is ignored.  Is that
-    // right?
-    VkInstance instance = GetData(physical_dev).instance;
-    PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
-        get_instance_proc_addr_(instance, "vkCreateDevice"));
+    PFN_vkCreateDevice create_device =
+        GetData(physical_dev).dispatch.CreateDevice;
     VkDevice dev;
     result = create_device(physical_dev, create_info, allocator, &dev);
     if (result != VK_SUCCESS)
@@ -787,8 +852,8 @@
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
-    StealLayers(data);
-
+    // no StealLayers so that active layers are destroyed with this
+    // LayerChain
     *dev_out = dev;
 
     return VK_SUCCESS;
@@ -1000,10 +1065,10 @@
                                 ? *allocator
                                 : driver::GetData(physical_dev).allocator);
 
-    VkResult result = chain.ActivateLayers(create_info->ppEnabledLayerNames,
-                                           create_info->enabledLayerCount,
-                                           create_info->ppEnabledExtensionNames,
-                                           create_info->enabledExtensionCount);
+    VkResult result = chain.ActivateLayers(
+        physical_dev, create_info->ppEnabledLayerNames,
+        create_info->enabledLayerCount, create_info->ppEnabledExtensionNames,
+        create_info->enabledExtensionCount);
     if (result != VK_SUCCESS)
         return result;
 
@@ -1042,19 +1107,15 @@
 void LayerChain::DestroyDevice(VkDevice device,
                                const VkAllocationCallbacks* allocator) {
     DeviceData& data = GetData(device);
-
-    ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
-    uint32_t layer_count = data.layer_count;
-
-    VkAllocationCallbacks local_allocator;
-    if (!allocator)
-        local_allocator = driver::GetData(device).allocator;
-
     // this also destroys DeviceData
     data.dispatch.DestroyDevice(device, allocator);
+}
 
-    DestroyLayers(layers, layer_count,
-                  (allocator) ? *allocator : local_allocator);
+const LayerChain::ActiveLayer* LayerChain::GetActiveLayers(
+    VkPhysicalDevice physical_dev,
+    uint32_t& count) {
+    count = GetData(physical_dev).layer_count;
+    return reinterpret_cast<const ActiveLayer*>(GetData(physical_dev).layers);
 }
 
 // ----------------------------------------------------------------------------
@@ -1155,33 +1216,18 @@
 VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
                                         uint32_t* pPropertyCount,
                                         VkLayerProperties* pProperties) {
-    (void)physicalDevice;
-
-    uint32_t total_count = GetLayerCount();
+    uint32_t count;
+    const LayerChain::ActiveLayer* layers =
+        LayerChain::GetActiveLayers(physicalDevice, count);
 
     if (!pProperties) {
-        uint32_t count = 0;
-        for (uint32_t i = 0; i < total_count; i++) {
-            if (IsLayerGlobal(GetLayer(i)))
-                count++;
-        }
-
         *pPropertyCount = count;
         return VK_SUCCESS;
     }
 
-    uint32_t count = 0;
-    uint32_t copied = 0;
-    for (uint32_t i = 0; i < total_count; i++) {
-        const Layer& layer = GetLayer(i);
-        if (!IsLayerGlobal(layer))
-            continue;
-
-        count++;
-        if (copied < *pPropertyCount)
-            pProperties[copied++] = GetLayerProperties(layer);
-    }
-
+    uint32_t copied = std::min(*pPropertyCount, count);
+    for (uint32_t i = 0; i < copied; i++)
+        pProperties[i] = GetLayerProperties(*layers[i].ref);
     *pPropertyCount = copied;
 
     return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
@@ -1193,8 +1239,11 @@
     uint32_t* pPropertyCount,
     VkExtensionProperties* pProperties) {
     if (pLayerName) {
+        // EnumerateDeviceLayerProperties enumerates active layers for
+        // backward compatibility.  The extension query here should work for
+        // all layers.
         const Layer* layer = FindLayer(pLayerName);
-        if (!layer || !IsLayerGlobal(*layer))
+        if (!layer)
             return VK_ERROR_LAYER_NOT_PRESENT;
 
         uint32_t count;