summaryrefslogtreecommitdiff
path: root/vulkan/libvulkan/api.cpp
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2016-04-29 22:21:04 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-04-29 22:21:04 +0000
commit63fd90068696bda0c59bd36bd543dc6eafc41e51 (patch)
treec7af782a33e4266fd40c515b15cc4bf00e9a561d /vulkan/libvulkan/api.cpp
parent188b9f00358d1f9f880b6d9deadc0b54f07b888e (diff)
parentc3a28913b6a95d2faee0db537c48557e04267511 (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.cpp216
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;