diff options
| author | 2016-04-29 22:21:04 +0000 | |
|---|---|---|
| committer | 2016-04-29 22:21:04 +0000 | |
| commit | 63fd90068696bda0c59bd36bd543dc6eafc41e51 (patch) | |
| tree | c7af782a33e4266fd40c515b15cc4bf00e9a561d /vulkan/libvulkan/api.cpp | |
| parent | 188b9f00358d1f9f880b6d9deadc0b54f07b888e (diff) | |
| parent | c3a28913b6a95d2faee0db537c48557e04267511 (diff) | |
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
Diffstat (limited to 'vulkan/libvulkan/api.cpp')
| -rw-r--r-- | vulkan/libvulkan/api.cpp | 216 |
1 files changed, 155 insertions, 61 deletions
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index e7f10b351b..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<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,10 +939,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; @@ -990,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; @@ -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; |