aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk/GrVkExtensions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/vk/GrVkExtensions.cpp')
-rw-r--r--src/gpu/vk/GrVkExtensions.cpp268
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 : "");
+ }
+}