From 25700b452535ce7ae838bfe832392b46ed555ed2 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 28 Apr 2016 06:36:09 +0800 Subject: vulkan: refactor layer enumeration Replace Enumerate*Layers by a set of new functions that do not distinguish instance and device layers. The new functions are also careful not to pollute the rest of the loader with std containers. There should be no user-visible change. Bug: 27911856 Change-Id: I4790fadc1aa2ea934a4628bce55dd45892f15e0b --- vulkan/libvulkan/api.cpp | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index e7f10b351b..e3f69fea82 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -1098,13 +1098,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; + } + + uint32_t copied = std::min(*pPropertyCount, count); + for (uint32_t i = 0; i < copied; i++) + pProperties[i] = GetLayerProperties(GetLayer(i)); + *pPropertyCount = copied; - return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS; + return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE; } VkResult EnumerateInstanceExtensionProperties( @@ -1137,13 +1143,34 @@ VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, VkLayerProperties* pProperties) { (void)physicalDevice; - uint32_t count = - EnumerateDeviceLayers(pProperties ? *pPropertyCount : 0, pProperties); + uint32_t total_count = GetLayerCount(); + + if (!pProperties) { + uint32_t count = 0; + for (uint32_t i = 0; i < total_count; i++) { + if (IsLayerGlobal(GetLayer(i))) + count++; + } - if (!pProperties || *pPropertyCount > 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); + } + + *pPropertyCount = copied; - return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS; + return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE; } VkResult EnumerateDeviceExtensionProperties( -- cgit v1.2.3-59-g8ed1b From 04c6551eb812a7efe38fa74e6ac67c17aab3df2d Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 27 Apr 2016 09:54:02 +0800 Subject: vulkan: refactor layer extension enumeration Replace Get*LayerExtensions by a set of new functions that do not distinguish instance and device layers. There should be no user-visible change. Bug: 27911856 Change-Id: Icd98abf51a936769f8f2f218794043b5e2611c5c --- vulkan/libvulkan/api.cpp | 18 +++++++++++-- vulkan/libvulkan/layers_extensions.cpp | 46 +++++++++++++--------------------- vulkan/libvulkan/layers_extensions.h | 11 ++++---- 3 files changed, 39 insertions(+), 36 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index e3f69fea82..6d558eec80 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -1123,7 +1123,14 @@ VkResult EnumerateInstanceExtensionProperties( if (pLayerName) { const VkExtensionProperties* props; uint32_t count; - GetInstanceLayerExtensions(pLayerName, &props, &count); + + const Layer* layer = FindLayer(pLayerName); + if (layer) { + props = GetLayerInstanceExtensions(*layer, count); + } else { + props = nullptr; + count = 0; + } if (!pProperties || *pPropertyCount > count) *pPropertyCount = count; @@ -1181,7 +1188,14 @@ VkResult EnumerateDeviceExtensionProperties( if (pLayerName) { const VkExtensionProperties* props; uint32_t count; - GetDeviceLayerExtensions(pLayerName, &props, &count); + + const Layer* layer = FindLayer(pLayerName); + if (layer && IsLayerGlobal(*layer)) { + props = GetLayerDeviceExtensions(*layer, count); + } else { + props = nullptr; + count = 0; + } if (!pProperties || *pPropertyCount > count) *pPropertyCount = count; diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp index 4363dd8fa8..b7558a28ea 100644 --- a/vulkan/libvulkan/layers_extensions.cpp +++ b/vulkan/libvulkan/layers_extensions.cpp @@ -331,12 +331,7 @@ void DiscoverLayersInDirectory(const std::string& dir_path) { } 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; - }); - return (layer != g_instance_layers.cend()) ? &*layer : nullptr; + return FindLayer(name); } const Layer* FindDeviceLayer(const char* name) { @@ -368,6 +363,15 @@ const Layer& GetLayer(uint32_t index) { return g_instance_layers[index]; } +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; +} + const VkLayerProperties& GetLayerProperties(const Layer& layer) { return layer.properties; } @@ -376,30 +380,16 @@ bool IsLayerGlobal(const Layer& layer) { return layer.is_global; } -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(layer->instance_extensions.size()); - } else { - *properties = nullptr; - *count = 0; - } +const VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer, + uint32_t& count) { + count = static_cast(layer.instance_extensions.size()); + return layer.instance_extensions.data(); } -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(layer->device_extensions.size()); - } else { - *properties = nullptr; - *count = 0; - } +const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer, + uint32_t& count) { + count = static_cast(layer.device_extensions.size()); + return layer.device_extensions.data(); } LayerRef GetInstanceLayerRef(const char* name) { diff --git a/vulkan/libvulkan/layers_extensions.h b/vulkan/libvulkan/layers_extensions.h index ee85f00227..899d60039b 100644 --- a/vulkan/libvulkan/layers_extensions.h +++ b/vulkan/libvulkan/layers_extensions.h @@ -52,16 +52,15 @@ void DiscoverLayers(); 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); -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); -- cgit v1.2.3-59-g8ed1b From d6e6f51426c566cd67ed765e5c4b206a063aaa30 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 28 Apr 2016 07:39:32 +0800 Subject: vulkan: make Get*LayerRef take a Layer The only user-visible change should be improved error messages. Bug: 27911856 Change-Id: Ie50a9d37f07b590026176642f2c67270225f9280 --- vulkan/libvulkan/api.cpp | 12 +++++++++--- vulkan/libvulkan/layers_extensions.cpp | 34 +++++++--------------------------- vulkan/libvulkan/layers_extensions.h | 4 ++-- 3 files changed, 18 insertions(+), 32 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 6d558eec80..1014c144dc 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -543,13 +543,19 @@ LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const { } VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) { + const Layer* l = FindLayer(name); + if (!l || (!is_instance_ && !IsLayerGlobal(*l))) { + ALOGW("Failed to find layer %s", name); + return VK_ERROR_LAYER_NOT_PRESENT; + } + if (is_instance_) - new (&layer) ActiveLayer{GetInstanceLayerRef(name), {}}; + new (&layer) ActiveLayer{GetInstanceLayerRef(*l), {}}; else - new (&layer) ActiveLayer{GetDeviceLayerRef(name), {}}; + new (&layer) ActiveLayer{GetDeviceLayerRef(*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; } diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp index b7558a28ea..9998aeeab7 100644 --- a/vulkan/libvulkan/layers_extensions.cpp +++ b/vulkan/libvulkan/layers_extensions.cpp @@ -330,15 +330,6 @@ void DiscoverLayersInDirectory(const std::string& dir_path) { closedir(directory); } -const Layer* FindInstanceLayer(const char* name) { - return FindLayer(name); -} - -const Layer* FindDeviceLayer(const char* name) { - const Layer* layer = FindInstanceLayer(name); - return (layer && layer->is_global) ? layer : nullptr; -} - void* GetLayerGetProcAddr(const Layer& layer, const char* gpa_name, size_t gpa_name_len) { @@ -392,26 +383,15 @@ const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer, return layer.device_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; - } - - return LayerRef(layer, true); +LayerRef GetInstanceLayerRef(const Layer& layer) { + LayerLibrary& library = g_layer_libraries[layer.library_idx]; + return LayerRef((library.Open()) ? &layer : nullptr, true); } -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; - } - - return LayerRef(layer, false); +LayerRef GetDeviceLayerRef(const Layer& layer) { + LayerLibrary& library = g_layer_libraries[layer.library_idx]; + return LayerRef((layer.is_global && library.Open()) ? &layer : nullptr, + false); } LayerRef::LayerRef(const Layer* layer, bool is_instance) diff --git a/vulkan/libvulkan/layers_extensions.h b/vulkan/libvulkan/layers_extensions.h index 899d60039b..32e1a67c15 100644 --- a/vulkan/libvulkan/layers_extensions.h +++ b/vulkan/libvulkan/layers_extensions.h @@ -61,8 +61,8 @@ const VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer, const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer, uint32_t& count); -LayerRef GetInstanceLayerRef(const char* name); -LayerRef GetDeviceLayerRef(const char* name); +LayerRef GetInstanceLayerRef(const Layer& layer); +LayerRef GetDeviceLayerRef(const Layer& layer); } // namespace api } // namespace vulkan -- cgit v1.2.3-59-g8ed1b From dab25658fb17ec76569b8e91dfed801855027f08 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 28 Apr 2016 07:15:51 +0800 Subject: vulkan: do not distinguish instance or device LayerRef Merge Get*LayerRef into GetLayerRef and remove LayerRef::is_instance_. With the removal, LayerRef::SupportsExtension becomes ambiguous. Replace it with FindLayer*Extension. Remove unused LayerRef::GetName and LayerRef::GetSpecName while at it. There should be no user-visible change. Bug: 27911856 Change-Id: I38340654b52338e9ed46d1c4462a6b254b0cab64 --- vulkan/libvulkan/api.cpp | 22 ++++++++------- vulkan/libvulkan/layers_extensions.cpp | 49 +++++++++++++++------------------- vulkan/libvulkan/layers_extensions.h | 16 +++++------ 3 files changed, 42 insertions(+), 45 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 1014c144dc..3db625fbe7 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -549,11 +549,7 @@ VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) { return VK_ERROR_LAYER_NOT_PRESENT; } - if (is_instance_) - new (&layer) ActiveLayer{GetInstanceLayerRef(*l), {}}; - else - new (&layer) ActiveLayer{GetDeviceLayerRef(*l), {}}; - + new (&layer) ActiveLayer{GetLayerRef(*l), {}}; if (!layer.ref) { ALOGW("Failed to open layer %s", name); layer.ref.~LayerRef(); @@ -878,10 +874,18 @@ VkExtensionProperties* LayerChain::AllocateDriverExtensionArray( } bool LayerChain::IsLayerExtension(const char* name) const { - for (uint32_t i = 0; i < layer_count_; i++) { - const ActiveLayer& layer = layers_[i]; - if (layer.ref.SupportsExtension(name)) - return true; + 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 (FindLayerDeviceExtension(*layer.ref, name)) + return true; + } } return false; diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp index 9998aeeab7..f9b1002efe 100644 --- a/vulkan/libvulkan/layers_extensions.cpp +++ b/vulkan/libvulkan/layers_extensions.cpp @@ -330,6 +330,16 @@ void DiscoverLayersInDirectory(const std::string& dir_path) { closedir(directory); } +const VkExtensionProperties* FindExtension( + const std::vector& extensions, + const char* name) { + auto it = std::find_if(extensions.cbegin(), extensions.cend(), + [=](const VkExtensionProperties& ext) { + return (strcmp(ext.extensionName, name) == 0); + }); + return (it != extensions.cend()) ? &*it : nullptr; +} + void* GetLayerGetProcAddr(const Layer& layer, const char* gpa_name, size_t gpa_name_len) { @@ -383,19 +393,22 @@ const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer, return layer.device_extensions.data(); } -LayerRef GetInstanceLayerRef(const Layer& layer) { - LayerLibrary& library = g_layer_libraries[layer.library_idx]; - return LayerRef((library.Open()) ? &layer : nullptr, true); +const VkExtensionProperties* FindLayerInstanceExtension(const Layer& layer, + const char* name) { + return FindExtension(layer.instance_extensions, name); } -LayerRef GetDeviceLayerRef(const Layer& layer) { +const VkExtensionProperties* FindLayerDeviceExtension(const Layer& layer, + const char* name) { + return FindExtension(layer.device_extensions, name); +} + +LayerRef GetLayerRef(const Layer& layer) { LayerLibrary& library = g_layer_libraries[layer.library_idx]; - return LayerRef((layer.is_global && library.Open()) ? &layer : nullptr, - false); + 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_) { @@ -404,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; } @@ -429,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 diff --git a/vulkan/libvulkan/layers_extensions.h b/vulkan/libvulkan/layers_extensions.h index 32e1a67c15..79fe59d7cf 100644 --- a/vulkan/libvulkan/layers_extensions.h +++ b/vulkan/libvulkan/layers_extensions.h @@ -26,26 +26,20 @@ 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(); @@ -61,8 +55,12 @@ const VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer, const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer, uint32_t& count); -LayerRef GetInstanceLayerRef(const Layer& layer); -LayerRef GetDeviceLayerRef(const Layer& layer); +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 -- cgit v1.2.3-59-g8ed1b From 6184b20d8e2301ecc21f815e1f9c2676c43878d1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 27 Apr 2016 11:57:53 +0800 Subject: vulkan: detect errors in VkEnumerate*ExtensionProperties Return VK_ERROR_LAYER_NOT_PRESENT when the layer is not available. Change-Id: I9d9aafe6e40c2ca49e58bc7c70114d0f11de2f81 --- vulkan/libvulkan/api.cpp | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 3db625fbe7..21a6c895bd 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -1131,16 +1131,13 @@ VkResult EnumerateInstanceExtensionProperties( return VK_ERROR_INITIALIZATION_FAILED; if (pLayerName) { - const VkExtensionProperties* props; - uint32_t count; - const Layer* layer = FindLayer(pLayerName); - if (layer) { - props = GetLayerInstanceExtensions(*layer, count); - } else { - props = nullptr; - count = 0; - } + if (!layer) + return VK_ERROR_LAYER_NOT_PRESENT; + + uint32_t count; + const VkExtensionProperties* props = + GetLayerInstanceExtensions(*layer, count); if (!pProperties || *pPropertyCount > count) *pPropertyCount = count; @@ -1196,16 +1193,13 @@ VkResult EnumerateDeviceExtensionProperties( uint32_t* pPropertyCount, VkExtensionProperties* pProperties) { if (pLayerName) { - const VkExtensionProperties* props; - uint32_t count; - const Layer* layer = FindLayer(pLayerName); - if (layer && IsLayerGlobal(*layer)) { - props = GetLayerDeviceExtensions(*layer, count); - } else { - props = nullptr; - count = 0; - } + if (!layer || !IsLayerGlobal(*layer)) + return VK_ERROR_LAYER_NOT_PRESENT; + + uint32_t count; + const VkExtensionProperties* props = + GetLayerDeviceExtensions(*layer, count); if (!pProperties || *pPropertyCount > count) *pPropertyCount = count; -- cgit v1.2.3-59-g8ed1b From c3a28913b6a95d2faee0db537c48557e04267511 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 14 Apr 2016 11:55:51 +0800 Subject: 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 --- vulkan/libvulkan/api.cpp | 171 +++++++++++++++++++++++++++++----------------- vulkan/libvulkan/driver.h | 7 -- 2 files changed, 110 insertions(+), 68 deletions(-) (limited to 'vulkan/libvulkan/api.cpp') diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 21a6c895bd..28b172d4fe 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -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(allocator_.pfnAllocation( allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer), @@ -544,7 +616,7 @@ LayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const { 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 @@ VkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) { 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 @@ 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) @@ -765,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( - 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 @@ 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; @@ -1000,10 +1065,10 @@ 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, - 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::DestroyInstance(VkInstance instance, void LayerChain::DestroyDevice(VkDevice device, const VkAllocationCallbacks* allocator) { DeviceData& data = GetData(device); - - ActiveLayer* layers = reinterpret_cast(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(GetData(physical_dev).layers); } // ---------------------------------------------------------------------------- @@ -1155,33 +1216,18 @@ VkResult EnumerateInstanceExtensionProperties( 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 @@ VkResult EnumerateDeviceExtensionProperties( 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; diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 85b36b6bfb..2b1f545ace 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -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 -- cgit v1.2.3-59-g8ed1b