};
void AddImplicitLayers() {
- if (!driver::Debuggable())
+ if (!is_instance_ || !driver::Debuggable())
return;
ParseDebugVulkanLayers();
// 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);
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();
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();
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;
}
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),
}
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;
}
// initialize InstanceData
InstanceData& data = GetData(instance);
- data.instance = instance;
-
if (!InitDispatchTable(instance, get_instance_proc_addr_,
enabled_extensions_)) {
if (data.dispatch.DestroyInstance)
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)
return VK_ERROR_INITIALIZATION_FAILED;
}
- StealLayers(data);
-
+ // no StealLayers so that active layers are destroyed with this
+ // LayerChain
*dev_out = dev;
return VK_SUCCESS;
}
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;
? *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;
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);
}
// ----------------------------------------------------------------------------
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(
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;
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(
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;
VkLayerProperties properties;
size_t library_idx;
+ // true if the layer intercepts vkCreateDevice and device commands
bool is_global;
std::vector<VkExtensionProperties> instance_extensions;
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;
- });
- 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;
+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 (it != extensions.cend()) ? &*it : nullptr;
}
void* GetLayerGetProcAddr(const Layer& layer,
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;
+const Layer& GetLayer(uint32_t index) {
+ return g_instance_layers[index];
+}
- if (n < count)
- properties[n] = layer.properties;
- 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;
+}
- return n;
+const VkLayerProperties& GetLayerProperties(const Layer& layer) {
+ return layer.properties;
}
-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;
- }
+bool IsLayerGlobal(const Layer& layer) {
+ return layer.is_global;
}
-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;
- }
+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_) {
}
}
-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;
}
: 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