diff options
Diffstat (limited to 'src/gpu/vk/GrVkExtensions.cpp')
-rw-r--r-- | src/gpu/vk/GrVkExtensions.cpp | 268 |
1 files changed, 208 insertions, 60 deletions
diff --git a/src/gpu/vk/GrVkExtensions.cpp b/src/gpu/vk/GrVkExtensions.cpp index 46bb94d1b2..e4768d95c9 100644 --- a/src/gpu/vk/GrVkExtensions.cpp +++ b/src/gpu/vk/GrVkExtensions.cpp @@ -6,9 +6,7 @@ */ #include "vk/GrVkExtensions.h" - -// Can remove this once we get rid of the extension flags. -#include "vk/GrVkBackendContext.h" +#include "vk/GrVkUtil.h" #include "SkTSearch.h" #include "SkTSort.h" @@ -32,82 +30,232 @@ static int find_string(const SkTArray<SkString>& strings, const char ext[]) { return idx; } -GrVkExtensions::GrVkExtensions(uint32_t instanceExtensionCount, - const char* const* instanceExtensions, - uint32_t deviceExtensionCount, - const char* const* deviceExtensions) - : fExtensionStrings() { +#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) fGetProc("vk" #F, inst, device) + +static uint32_t remove_patch_version(uint32_t specVersion) { + return (specVersion >> 12) << 12; +} + +bool GrVkExtensions::initInstance(uint32_t specVersion) { + if (fGetProc == nullptr) { + return false; + } + + uint32_t nonPatchVersion = remove_patch_version(specVersion); + + GET_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE); + GET_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE); + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp; - for (uint32_t i = 0; i < instanceExtensionCount; ++i) { - const char* extension = instanceExtensions[i]; - // if not already in the list, add it - if (find_string(fExtensionStrings, extension) < 0) { - fExtensionStrings.push_back() = extension; - SkTQSort(&fExtensionStrings.front(), &fExtensionStrings.back(), cmp); + if (!EnumerateInstanceExtensionProperties || + !EnumerateInstanceLayerProperties) { + return false; + } + + // instance layers + uint32_t layerCount = 0; + VkResult res = EnumerateInstanceLayerProperties(&layerCount, nullptr); + if (VK_SUCCESS != res) { + return false; + } + VkLayerProperties* layers = new VkLayerProperties[layerCount]; + res = EnumerateInstanceLayerProperties(&layerCount, layers); + if (VK_SUCCESS != res) { + delete[] layers; + return false; + } + for (uint32_t i = 0; i < layerCount; ++i) { + if (nonPatchVersion <= remove_patch_version(layers[i].specVersion)) { + fInstanceLayerStrings->push_back() = layers[i].layerName; } } - for (uint32_t i = 0; i < deviceExtensionCount; ++i) { - const char* extension = deviceExtensions[i]; - // if not already in the list, add it - if (find_string(fExtensionStrings, extension) < 0) { - fExtensionStrings.push_back() = extension; - SkTQSort(&fExtensionStrings.front(), &fExtensionStrings.back(), cmp); + delete[] layers; + if (!fInstanceLayerStrings->empty()) { + SkTQSort(&fInstanceLayerStrings->front(), &fInstanceLayerStrings->back(), cmp); + } + + // instance extensions + // via Vulkan implementation and implicitly enabled layers + uint32_t extensionCount = 0; + res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); + if (VK_SUCCESS != res) { + return false; + } + VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount]; + res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions); + if (VK_SUCCESS != res) { + delete[] extensions; + return false; + } + for (uint32_t i = 0; i < extensionCount; ++i) { + fInstanceExtensionStrings->push_back() = extensions[i].extensionName; + } + delete [] extensions; + // sort so we can search + if (!fInstanceExtensionStrings->empty()) { + SkTQSort(&fInstanceExtensionStrings->front(), &fInstanceExtensionStrings->back(), cmp); + } + // via explicitly enabled layers + layerCount = fInstanceLayerStrings->count(); + for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) { + uint32_t extensionCount = 0; + res = EnumerateInstanceExtensionProperties((*fInstanceLayerStrings)[layerIndex].c_str(), + &extensionCount, nullptr); + if (VK_SUCCESS != res) { + return false; + } + VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount]; + res = EnumerateInstanceExtensionProperties((*fInstanceLayerStrings)[layerIndex].c_str(), + &extensionCount, extensions); + if (VK_SUCCESS != res) { + delete[] extensions; + return false; } + for (uint32_t i = 0; i < extensionCount; ++i) { + // if not already in the list, add it + if (find_string(*fInstanceExtensionStrings, extensions[i].extensionName) < 0) { + fInstanceExtensionStrings->push_back() = extensions[i].extensionName; + SkTQSort(&fInstanceExtensionStrings->front(), &fInstanceExtensionStrings->back(), + cmp); + } + } + delete[] extensions; } + + return true; } -GrVkExtensions::GrVkExtensions(uint32_t extensionFlags) - : fExtensionStrings() { +bool GrVkExtensions::initDevice(uint32_t specVersion, VkInstance inst, VkPhysicalDevice physDev) { + if (fGetProc == nullptr) { + return false; + } + + uint32_t nonPatchVersion = remove_patch_version(specVersion); + + GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst, VK_NULL_HANDLE); + GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst, VK_NULL_HANDLE); + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp; - SkTArray<const char*> extensionNames; - GetExtensionArrayFromFlags(extensionFlags, &extensionNames); - for (int i = 0; i < extensionNames.count(); ++i) { - // if not already in the list, add it - if (find_string(fExtensionStrings, extensionNames[i]) < 0) { - fExtensionStrings.push_back() = extensionNames[i]; - SkTQSort(&fExtensionStrings.front(), &fExtensionStrings.back(), cmp); - } + if (!EnumerateDeviceExtensionProperties || + !EnumerateDeviceLayerProperties) { + return false; } -} - -bool GrVkExtensions::hasExtension(const char ext[]) const { - return find_string(fExtensionStrings, ext) >= 0; -} -void GrVkExtensions::GetExtensionArrayFromFlags(uint32_t extensionFlags, - SkTArray<const char*>* extensions) { -#ifdef SK_ENABLE_VK_LAYERS - if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) { - extensions->push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + // device layers + uint32_t layerCount = 0; + VkResult res = EnumerateDeviceLayerProperties(physDev, &layerCount, nullptr); + if (VK_SUCCESS != res) { + return false; } -#endif - if (extensionFlags & kKHR_surface_GrVkExtensionFlag) { - extensions->push_back(VK_KHR_SURFACE_EXTENSION_NAME); + VkLayerProperties* layers = new VkLayerProperties[layerCount]; + res = EnumerateDeviceLayerProperties(physDev, &layerCount, layers); + if (VK_SUCCESS != res) { + delete[] layers; + return false; } - if (extensionFlags & kKHR_swapchain_GrVkExtensionFlag) { - extensions->push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + for (uint32_t i = 0; i < layerCount; ++i) { + if (nonPatchVersion <= remove_patch_version(layers[i].specVersion)) { + fDeviceLayerStrings->push_back() = layers[i].layerName; + } } -#ifdef SK_BUILD_FOR_WIN - if (extensionFlags & kKHR_win32_surface_GrVkExtensionFlag) { - extensions->push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + delete[] layers; + if (!fDeviceLayerStrings->empty()) { + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp; + SkTQSort(&fDeviceLayerStrings->front(), &fDeviceLayerStrings->back(), cmp); } -#elif defined(SK_BUILD_FOR_ANDROID) - if (extensionFlags & kKHR_android_surface_GrVkExtensionFlag) { - extensions->push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); + + // device extensions + // via Vulkan implementation and implicitly enabled layers + uint32_t extensionCount = 0; + res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, nullptr); + if (VK_SUCCESS != res) { + return false; } -#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__) - if (extensionFlags & kKHR_xcb_surface_GrVkExtensionFlag) { - extensions->push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); + VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount]; + res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions); + if (VK_SUCCESS != res) { + delete[] extensions; + return false; } -#endif - // Device extensions - if (extensionFlags & kKHR_swapchain_GrVkExtensionFlag) { - extensions->push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + for (uint32_t i = 0; i < extensionCount; ++i) { + fDeviceExtensionStrings->push_back() = extensions[i].extensionName; } - if (extensionFlags & kNV_glsl_shader_GrVkExtensionFlag) { - extensions->push_back("VK_NV_glsl_shader"); + delete[] extensions; + if (!fDeviceExtensionStrings->empty()) { + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp; + SkTQSort(&fDeviceExtensionStrings->front(), &fDeviceExtensionStrings->back(), cmp); } + // via explicitly enabled layers + layerCount = fDeviceLayerStrings->count(); + for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) { + uint32_t extensionCount = 0; + res = EnumerateDeviceExtensionProperties(physDev, + (*fDeviceLayerStrings)[layerIndex].c_str(), + &extensionCount, nullptr); + if (VK_SUCCESS != res) { + return false; + } + VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount]; + res = EnumerateDeviceExtensionProperties(physDev, + (*fDeviceLayerStrings)[layerIndex].c_str(), + &extensionCount, extensions); + if (VK_SUCCESS != res) { + delete[] extensions; + return false; + } + for (uint32_t i = 0; i < extensionCount; ++i) { + // if not already in the list, add it + if (find_string(*fDeviceExtensionStrings, extensions[i].extensionName) < 0) { + fDeviceExtensionStrings->push_back() = extensions[i].extensionName; + SkTQSort(&fDeviceExtensionStrings->front(), &fDeviceExtensionStrings->back(), cmp); + } + } + delete[] extensions; + } + + return true; +} + +bool GrVkExtensions::hasInstanceExtension(const char ext[]) const { + return find_string(*fInstanceExtensionStrings, ext) >= 0; } +bool GrVkExtensions::hasDeviceExtension(const char ext[]) const { + return find_string(*fDeviceExtensionStrings, ext) >= 0; +} + +bool GrVkExtensions::hasInstanceLayer(const char ext[]) const { + return find_string(*fInstanceLayerStrings, ext) >= 0; +} + +bool GrVkExtensions::hasDeviceLayer(const char ext[]) const { + return find_string(*fDeviceLayerStrings, ext) >= 0; +} + +void GrVkExtensions::print(const char* sep) const { + if (nullptr == sep) { + sep = " "; + } + int cnt = fInstanceExtensionStrings->count(); + SkDebugf("Instance Extensions: "); + for (int i = 0; i < cnt; ++i) { + SkDebugf("%s%s", (*fInstanceExtensionStrings)[i].c_str(), (i < cnt - 1) ? sep : ""); + } + cnt = fDeviceExtensionStrings->count(); + SkDebugf("\nDevice Extensions: "); + for (int i = 0; i < cnt; ++i) { + SkDebugf("%s%s", (*fDeviceExtensionStrings)[i].c_str(), (i < cnt - 1) ? sep : ""); + } + cnt = fInstanceLayerStrings->count(); + SkDebugf("\nInstance Layers: "); + for (int i = 0; i < cnt; ++i) { + SkDebugf("%s%s", (*fInstanceLayerStrings)[i].c_str(), (i < cnt - 1) ? sep : ""); + } + cnt = fDeviceLayerStrings->count(); + SkDebugf("\nDevice Layers: "); + for (int i = 0; i < cnt; ++i) { + SkDebugf("%s%s", (*fDeviceLayerStrings)[i].c_str(), (i < cnt - 1) ? sep : ""); + } +} |