diff options
author | Chia-I Wu <olv@google.com> | 2016-04-10 22:38:53 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-04-10 22:38:53 +0000 |
commit | a70a4214d85dec0d27e918c977dabd488a5c20e5 (patch) | |
tree | c92bdc44e737fdbc9b1a113d16de1f2df6cd46c9 /vulkan/libvulkan/api.cpp | |
parent | 8391efaf4d43da899a5183f03d4fc3a683125612 (diff) | |
parent | 1f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7 (diff) |
Merge "vulkan: check for unsupported extensions" into nyc-dev
Diffstat (limited to 'vulkan/libvulkan/api.cpp')
-rw-r--r-- | vulkan/libvulkan/api.cpp | 123 |
1 files changed, 120 insertions, 3 deletions
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 9c5aa3bc43..549886feaf 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -416,6 +416,16 @@ class LayerChain { const VkAllocationCallbacks* allocator, VkDevice* dev_out); + VkResult validate_extensions(const char* const* extension_names, + uint32_t extension_count); + VkResult validate_extensions(VkPhysicalDevice physical_dev, + const char* const* extension_names, + uint32_t extension_count); + VkExtensionProperties* allocate_driver_extension_array( + uint32_t count) const; + bool is_layer_extension(const char* name) const; + bool is_driver_extension(const char* name) const; + template <typename DataType> void steal_layers(DataType& data); @@ -449,6 +459,9 @@ class LayerChain { VkLayerInstanceCreateInfo instance_chain_info_; VkLayerDeviceCreateInfo device_chain_info_; }; + + VkExtensionProperties* driver_extensions_; + uint32_t driver_extension_count_; }; LayerChain::LayerChain(bool is_instance, const VkAllocationCallbacks& allocator) @@ -459,9 +472,12 @@ LayerChain::LayerChain(bool is_instance, const VkAllocationCallbacks& allocator) layers_(nullptr), layer_count_(0), get_instance_proc_addr_(nullptr), - get_device_proc_addr_(nullptr) {} + get_device_proc_addr_(nullptr), + driver_extensions_(nullptr), + driver_extension_count_(0) {} LayerChain::~LayerChain() { + allocator_.pfnFree(allocator_.pUserData, driver_extensions_); destroy_layers(layers_, layer_count_, allocator_); } @@ -657,12 +673,17 @@ void LayerChain::modify_create_info(VkDeviceCreateInfo& info) { VkResult LayerChain::create(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* instance_out) { + VkResult result = validate_extensions(create_info->ppEnabledExtensionNames, + create_info->enabledExtensionCount); + if (result != VK_SUCCESS) + return result; + // call down the chain PFN_vkCreateInstance create_instance = reinterpret_cast<PFN_vkCreateInstance>( get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance")); VkInstance instance; - VkResult result = create_instance(create_info, allocator, &instance); + result = create_instance(create_info, allocator, &instance); if (result != VK_SUCCESS) return result; @@ -727,6 +748,12 @@ VkResult LayerChain::create(VkPhysicalDevice physical_dev, const VkDeviceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkDevice* dev_out) { + VkResult result = + validate_extensions(physical_dev, create_info->ppEnabledExtensionNames, + create_info->enabledExtensionCount); + if (result != VK_SUCCESS) + return result; + // call down the chain // // TODO Instance call chain available at @@ -736,7 +763,7 @@ VkResult LayerChain::create(VkPhysicalDevice physical_dev, PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>( get_instance_proc_addr_(instance, "vkCreateDevice")); VkDevice dev; - VkResult result = create_device(physical_dev, create_info, allocator, &dev); + result = create_device(physical_dev, create_info, allocator, &dev); if (result != VK_SUCCESS) return result; @@ -758,6 +785,96 @@ VkResult LayerChain::create(VkPhysicalDevice physical_dev, return VK_SUCCESS; } +VkResult LayerChain::validate_extensions(const char* const* extension_names, + uint32_t extension_count) { + if (!extension_count) + return VK_SUCCESS; + + // query driver instance extensions + uint32_t count; + VkResult result = + EnumerateInstanceExtensionProperties(nullptr, &count, nullptr); + if (result == VK_SUCCESS && count) { + driver_extensions_ = allocate_driver_extension_array(count); + result = (driver_extensions_) ? EnumerateInstanceExtensionProperties( + nullptr, &count, driver_extensions_) + : VK_ERROR_OUT_OF_HOST_MEMORY; + } + if (result != VK_SUCCESS) + return result; + + driver_extension_count_ = count; + + for (uint32_t i = 0; i < extension_count; i++) { + const char* name = extension_names[i]; + if (!is_layer_extension(name) && !is_driver_extension(name)) { + ALOGE("Failed to enable missing instance extension %s", name); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + } + + return VK_SUCCESS; +} + +VkResult LayerChain::validate_extensions(VkPhysicalDevice physical_dev, + const char* const* extension_names, + uint32_t extension_count) { + if (!extension_count) + return VK_SUCCESS; + + // query driver device extensions + uint32_t count; + VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr, + &count, nullptr); + if (result == VK_SUCCESS && count) { + driver_extensions_ = allocate_driver_extension_array(count); + result = (driver_extensions_) + ? EnumerateDeviceExtensionProperties( + physical_dev, nullptr, &count, driver_extensions_) + : VK_ERROR_OUT_OF_HOST_MEMORY; + } + if (result != VK_SUCCESS) + return result; + + driver_extension_count_ = count; + + for (uint32_t i = 0; i < extension_count; i++) { + const char* name = extension_names[i]; + if (!is_layer_extension(name) && !is_driver_extension(name)) { + ALOGE("Failed to enable missing device extension %s", name); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + } + + return VK_SUCCESS; +} + +VkExtensionProperties* LayerChain::allocate_driver_extension_array( + uint32_t count) const { + return reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation( + allocator_.pUserData, sizeof(VkExtensionProperties) * count, + alignof(VkExtensionProperties), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); +} + +bool LayerChain::is_layer_extension(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; + } + + return false; +} + +bool LayerChain::is_driver_extension(const char* name) const { + for (uint32_t i = 0; i < driver_extension_count_; i++) { + if (strcmp(driver_extensions_[i].extensionName, name) == 0) + return true; + } + + return false; +} + template <typename DataType> void LayerChain::steal_layers(DataType& data) { data.layers = layers_; |