Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63fd9006 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I6e89439a,I9d9aafe6,I38340654,Ie50a9d37,Icd98abf5, ... into nyc-dev

* changes:
  vulkan: deprecate device layers
  vulkan: detect errors in VkEnumerate*ExtensionProperties
  vulkan: do not distinguish instance or device LayerRef
  vulkan: make Get*LayerRef take a Layer
  vulkan: refactor layer extension enumeration
  vulkan: refactor layer enumeration
parents 188b9f00 c3a28913
Loading
Loading
Loading
Loading
+155 −61
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ class OverrideLayerNames {
    };

    void AddImplicitLayers() {
        if (!driver::Debuggable())
        if (!is_instance_ || !driver::Debuggable())
            return;

        ParseDebugVulkanLayers();
@@ -367,6 +367,14 @@ class OverrideExtensionNames {
// 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 @@ class LayerChain {
    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 @@ class LayerChain {
                            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 @@ VkResult LayerChain::ActivateLayers(const char* const* layer_names,
    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 @@ VkResult LayerChain::ActivateLayers(const char* const* layer_names,
    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),
@@ -543,18 +615,20 @@ LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const {
}

VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) {
    if (is_instance_)
        new (&layer) ActiveLayer{GetInstanceLayerRef(name), {}};
    else
        new (&layer) ActiveLayer{GetDeviceLayerRef(name), {}};
    const Layer* l = FindLayer(name);
    if (!l) {
        ALOGW("Failed to find layer %s", name);
        return VK_ERROR_LAYER_NOT_PRESENT;
    }

    new (&layer) ActiveLayer{GetLayerRef(*l), {}};
    if (!layer.ref) {
        ALOGE("Failed to load layer %s", name);
        ALOGW("Failed to open layer %s", name);
        layer.ref.~LayerRef();
        return VK_ERROR_LAYER_NOT_PRESENT;
    }

    ALOGI("Loaded %s layer %s", (is_instance_) ? "instance" : "device", name);
    ALOGI("Loaded layer %s", name);

    return VK_SUCCESS;
}
@@ -698,8 +772,6 @@ VkResult LayerChain::Create(const VkInstanceCreateInfo* create_info,
    // initialize InstanceData
    InstanceData& data = GetData(instance);

    data.instance = instance;

    if (!InitDispatchTable(instance, get_instance_proc_addr_,
                           enabled_extensions_)) {
        if (data.dispatch.DestroyInstance)
@@ -763,13 +835,8 @@ VkResult LayerChain::Create(VkPhysicalDevice physical_dev,
        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)
@@ -785,8 +852,8 @@ VkResult LayerChain::Create(VkPhysicalDevice physical_dev,
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    StealLayers(data);

    // no StealLayers so that active layers are destroyed with this
    // LayerChain
    *dev_out = dev;

    return VK_SUCCESS;
@@ -872,11 +939,19 @@ VkExtensionProperties* LayerChain::AllocateDriverExtensionArray(
}

bool LayerChain::IsLayerExtension(const char* name) const {
    if (is_instance_) {
        for (uint32_t i = 0; i < layer_count_; i++) {
            const ActiveLayer& layer = layers_[i];
            if (FindLayerInstanceExtension(*layer.ref, name))
                return true;
        }
    } else {
        for (uint32_t i = 0; i < layer_count_; i++) {
            const ActiveLayer& layer = layers_[i];
        if (layer.ref.SupportsExtension(name))
            if (FindLayerDeviceExtension(*layer.ref, name))
                return true;
        }
    }

    return false;
}
@@ -990,9 +1065,9 @@ VkResult LayerChain::CreateDevice(VkPhysicalDevice physical_dev,
                                ? *allocator
                                : driver::GetData(physical_dev).allocator);

    VkResult result = chain.ActivateLayers(create_info->ppEnabledLayerNames,
                                           create_info->enabledLayerCount,
                                           create_info->ppEnabledExtensionNames,
    VkResult result = chain.ActivateLayers(
        physical_dev, create_info->ppEnabledLayerNames,
        create_info->enabledLayerCount, create_info->ppEnabledExtensionNames,
        create_info->enabledExtensionCount);
    if (result != VK_SUCCESS)
        return result;
@@ -1032,19 +1107,15 @@ void LayerChain::DestroyInstance(VkInstance instance,
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);
}

// ----------------------------------------------------------------------------
@@ -1098,13 +1169,19 @@ VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
    if (!EnsureInitialized())
        return VK_ERROR_INITIALIZATION_FAILED;

    uint32_t count =
        EnumerateInstanceLayers(pProperties ? *pPropertyCount : 0, pProperties);
    uint32_t count = GetLayerCount();

    if (!pProperties || *pPropertyCount > count)
    if (!pProperties) {
        *pPropertyCount = count;
        return VK_SUCCESS;
    }

    return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
    uint32_t copied = std::min(*pPropertyCount, count);
    for (uint32_t i = 0; i < copied; i++)
        pProperties[i] = GetLayerProperties(GetLayer(i));
    *pPropertyCount = copied;

    return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE;
}

VkResult EnumerateInstanceExtensionProperties(
@@ -1115,9 +1192,13 @@ VkResult EnumerateInstanceExtensionProperties(
        return VK_ERROR_INITIALIZATION_FAILED;

    if (pLayerName) {
        const VkExtensionProperties* props;
        const Layer* layer = FindLayer(pLayerName);
        if (!layer)
            return VK_ERROR_LAYER_NOT_PRESENT;

        uint32_t count;
        GetInstanceLayerExtensions(pLayerName, &props, &count);
        const VkExtensionProperties* props =
            GetLayerInstanceExtensions(*layer, count);

        if (!pProperties || *pPropertyCount > count)
            *pPropertyCount = count;
@@ -1135,15 +1216,21 @@ VkResult EnumerateInstanceExtensionProperties(
VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
                                        uint32_t* pPropertyCount,
                                        VkLayerProperties* pProperties) {
    (void)physicalDevice;

    uint32_t count =
        EnumerateDeviceLayers(pProperties ? *pPropertyCount : 0, pProperties);
    uint32_t count;
    const LayerChain::ActiveLayer* layers =
        LayerChain::GetActiveLayers(physicalDevice, count);

    if (!pProperties || *pPropertyCount > count)
    if (!pProperties) {
        *pPropertyCount = count;
        return VK_SUCCESS;
    }

    return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
    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;
}

VkResult EnumerateDeviceExtensionProperties(
@@ -1152,9 +1239,16 @@ VkResult EnumerateDeviceExtensionProperties(
    uint32_t* pPropertyCount,
    VkExtensionProperties* pProperties) {
    if (pLayerName) {
        const VkExtensionProperties* props;
        // EnumerateDeviceLayerProperties enumerates active layers for
        // backward compatibility.  The extension query here should work for
        // all layers.
        const Layer* layer = FindLayer(pLayerName);
        if (!layer)
            return VK_ERROR_LAYER_NOT_PRESENT;

        uint32_t count;
        GetDeviceLayerExtensions(pLayerName, &props, &count);
        const VkExtensionProperties* props =
            GetLayerDeviceExtensions(*layer, count);

        if (!pProperties || *pPropertyCount > count)
            *pPropertyCount = count;
+0 −7
Original line number Diff line number Diff line
@@ -40,9 +40,6 @@ namespace api {
struct InstanceData {
    InstanceDispatchTable dispatch;

    // for VkPhysicalDevice->VkInstance mapping
    VkInstance instance;

    // LayerChain::ActiveLayer array
    void* layers;
    uint32_t layer_count;
@@ -54,10 +51,6 @@ struct InstanceData {

struct DeviceData {
    DeviceDispatchTable dispatch;

    // LayerChain::ActiveLayer array
    void* layers;
    uint32_t layer_count;
};

}  // namespace api
+46 −89
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ struct Layer {
    VkLayerProperties properties;
    size_t library_idx;

    // true if the layer intercepts vkCreateDevice and device commands
    bool is_global;

    std::vector<VkExtensionProperties> instance_extensions;
@@ -329,18 +330,14 @@ void DiscoverLayersInDirectory(const std::string& dir_path) {
    closedir(directory);
}

const Layer* FindInstanceLayer(const char* name) {
    auto layer =
        std::find_if(g_instance_layers.cbegin(), g_instance_layers.cend(),
                     [=](const Layer& entry) {
                         return strcmp(entry.properties.layerName, name) == 0;
const VkExtensionProperties* FindExtension(
    const std::vector<VkExtensionProperties>& extensions,
    const char* name) {
    auto it = std::find_if(extensions.cbegin(), extensions.cend(),
                           [=](const VkExtensionProperties& ext) {
                               return (strcmp(ext.extensionName, name) == 0);
                           });
    return (layer != g_instance_layers.cend()) ? &*layer : nullptr;
}

const Layer* FindDeviceLayer(const char* name) {
    const Layer* layer = FindInstanceLayer(name);
    return (layer && layer->is_global) ? layer : nullptr;
    return (it != extensions.cend()) ? &*it : nullptr;
}

void* GetLayerGetProcAddr(const Layer& layer,
@@ -359,81 +356,59 @@ void DiscoverLayers() {
        DiscoverLayersInDirectory(LoaderData::GetInstance().layer_path.c_str());
}

uint32_t EnumerateInstanceLayers(uint32_t count,
                                 VkLayerProperties* properties) {
    uint32_t n =
        std::min(count, static_cast<uint32_t>(g_instance_layers.size()));
    for (uint32_t i = 0; i < n; i++)
        properties[i] = g_instance_layers[i].properties;

uint32_t GetLayerCount() {
    return static_cast<uint32_t>(g_instance_layers.size());
}

uint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties) {
    uint32_t n = 0;
    for (const auto& layer : g_instance_layers) {
        // ignore non-global layers
        if (!layer.is_global)
            continue;

        if (n < count)
            properties[n] = layer.properties;
        n++;
const Layer& GetLayer(uint32_t index) {
    return g_instance_layers[index];
}

    return n;
const Layer* FindLayer(const char* name) {
    auto layer =
        std::find_if(g_instance_layers.cbegin(), g_instance_layers.cend(),
                     [=](const Layer& entry) {
                         return strcmp(entry.properties.layerName, name) == 0;
                     });
    return (layer != g_instance_layers.cend()) ? &*layer : nullptr;
}

void GetInstanceLayerExtensions(const char* name,
                                const VkExtensionProperties** properties,
                                uint32_t* count) {
    const Layer* layer = FindInstanceLayer(name);
    if (layer) {
        *properties = layer->instance_extensions.data();
        *count = static_cast<uint32_t>(layer->instance_extensions.size());
    } else {
        *properties = nullptr;
        *count = 0;
    }
const VkLayerProperties& GetLayerProperties(const Layer& layer) {
    return layer.properties;
}

void GetDeviceLayerExtensions(const char* name,
                              const VkExtensionProperties** properties,
                              uint32_t* count) {
    const Layer* layer = FindDeviceLayer(name);
    if (layer) {
        *properties = layer->device_extensions.data();
        *count = static_cast<uint32_t>(layer->device_extensions.size());
    } else {
        *properties = nullptr;
        *count = 0;
bool IsLayerGlobal(const Layer& layer) {
    return layer.is_global;
}

const VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer,
                                                        uint32_t& count) {
    count = static_cast<uint32_t>(layer.instance_extensions.size());
    return layer.instance_extensions.data();
}

LayerRef GetInstanceLayerRef(const char* name) {
    const Layer* layer = FindInstanceLayer(name);
    if (layer) {
        LayerLibrary& library = g_layer_libraries[layer->library_idx];
        if (!library.Open())
            layer = nullptr;
const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer,
                                                      uint32_t& count) {
    count = static_cast<uint32_t>(layer.device_extensions.size());
    return layer.device_extensions.data();
}

    return LayerRef(layer, true);
const VkExtensionProperties* FindLayerInstanceExtension(const Layer& layer,
                                                        const char* name) {
    return FindExtension(layer.instance_extensions, name);
}

LayerRef GetDeviceLayerRef(const char* name) {
    const Layer* layer = FindDeviceLayer(name);
    if (layer) {
        LayerLibrary& library = g_layer_libraries[layer->library_idx];
        if (!library.Open())
            layer = nullptr;
const VkExtensionProperties* FindLayerDeviceExtension(const Layer& layer,
                                                      const char* name) {
    return FindExtension(layer.device_extensions, name);
}

    return LayerRef(layer, false);
LayerRef GetLayerRef(const Layer& layer) {
    LayerLibrary& library = g_layer_libraries[layer.library_idx];
    return LayerRef((library.Open()) ? &layer : nullptr);
}

LayerRef::LayerRef(const Layer* layer, bool is_instance)
    : layer_(layer), is_instance_(is_instance) {}
LayerRef::LayerRef(const Layer* layer) : layer_(layer) {}

LayerRef::~LayerRef() {
    if (layer_) {
@@ -442,16 +417,7 @@ LayerRef::~LayerRef() {
    }
}

const char* LayerRef::GetName() const {
    return layer_->properties.layerName;
}

uint32_t LayerRef::GetSpecVersion() const {
    return layer_->properties.specVersion;
}

LayerRef::LayerRef(LayerRef&& other)
    : layer_(other.layer_), is_instance_(other.is_instance_) {
LayerRef::LayerRef(LayerRef&& other) : layer_(other.layer_) {
    other.layer_ = nullptr;
}

@@ -467,14 +433,5 @@ PFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const {
                  : nullptr;
}

bool LayerRef::SupportsExtension(const char* name) const {
    const auto& extensions = (is_instance_) ? layer_->instance_extensions
                                            : layer_->device_extensions;
    return std::find_if(extensions.cbegin(), extensions.cend(),
                        [=](const VkExtensionProperties& ext) {
                            return strcmp(ext.extensionName, name) == 0;
                        }) != extensions.cend();
}

}  // namespace api
}  // namespace vulkan
+20 −17
Original line number Diff line number Diff line
@@ -23,41 +23,44 @@ namespace vulkan {
namespace api {

struct Layer;

class LayerRef {
   public:
    LayerRef(const Layer* layer, bool is_instance);
    LayerRef(const Layer* layer);
    LayerRef(LayerRef&& other);
    ~LayerRef();
    LayerRef(const LayerRef&) = delete;
    LayerRef& operator=(const LayerRef&) = delete;

    const char* GetName() const;
    uint32_t GetSpecVersion() const;

    // provides bool-like behavior
    operator const Layer*() const { return layer_; }

    PFN_vkGetInstanceProcAddr GetGetInstanceProcAddr() const;
    PFN_vkGetDeviceProcAddr GetGetDeviceProcAddr() const;

    bool SupportsExtension(const char* name) const;

   private:
    const Layer* layer_;
    bool is_instance_;
};

void DiscoverLayers();
uint32_t EnumerateInstanceLayers(uint32_t count, VkLayerProperties* properties);
uint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties);
void GetInstanceLayerExtensions(const char* name,
                                const VkExtensionProperties** properties,
                                uint32_t* count);
void GetDeviceLayerExtensions(const char* name,
                              const VkExtensionProperties** properties,
                              uint32_t* count);
LayerRef GetInstanceLayerRef(const char* name);
LayerRef GetDeviceLayerRef(const char* name);

uint32_t GetLayerCount();
const Layer& GetLayer(uint32_t index);
const Layer* FindLayer(const char* name);

const VkLayerProperties& GetLayerProperties(const Layer& layer);
bool IsLayerGlobal(const Layer& layer);
const VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer,
                                                        uint32_t& count);
const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer,
                                                      uint32_t& count);

const VkExtensionProperties* FindLayerInstanceExtension(const Layer& layer,
                                                        const char* name);
const VkExtensionProperties* FindLayerDeviceExtension(const Layer& layer,
                                                      const char* name);

LayerRef GetLayerRef(const Layer& layer);

}  // namespace api
}  // namespace vulkan