Make sure we check the version number of Vulkan Extensions.
Bug: skia:
Change-Id: Iff02911491cc61e39f94370c644b6666e5f9118f
Reviewed-on: https://skia-review.googlesource.com/137881
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/vk/GrVkExtensions.cpp b/src/gpu/vk/GrVkExtensions.cpp
index 6cc20e6..4d7fc11 100644
--- a/src/gpu/vk/GrVkExtensions.cpp
+++ b/src/gpu/vk/GrVkExtensions.cpp
@@ -13,50 +13,119 @@
#include "SkTSearch.h"
#include "SkTSort.h"
-namespace { // This cannot be static because it is used as a template parameter.
-inline bool extension_compare(const SkString& a, const SkString& b) {
- return strcmp(a.c_str(), b.c_str()) < 0;
-}
-}
-
-// finds the index of ext in strings or a negative result if ext is not found.
-static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
- if (strings.empty()) {
+// finds the index of ext in infos or a negative result if ext is not found.
+static int find_info(const SkTArray<GrVkExtensions::Info>& infos, const char ext[]) {
+ if (infos.empty()) {
return -1;
}
SkString extensionStr(ext);
- int idx = SkTSearch<SkString, extension_compare>(&strings.front(),
- strings.count(),
- extensionStr,
- sizeof(SkString));
+ GrVkExtensions::Info::Less less;
+ int idx = SkTSearch<GrVkExtensions::Info, SkString, GrVkExtensions::Info::Less>(
+ &infos.front(), infos.count(), extensionStr, sizeof(GrVkExtensions::Info),
+ less);
return idx;
}
-void GrVkExtensions::init(uint32_t instanceExtensionCount,
+namespace { // This cannot be static because it is used as a template parameter.
+inline bool extension_compare(const GrVkExtensions::Info& a, const GrVkExtensions::Info& b) {
+ return strcmp(a.fName.c_str(), b.fName.c_str()) < 0;
+}
+}
+
+void GrVkExtensions::init(GrVkGetProc getProc,
+ VkInstance instance,
+ VkPhysicalDevice physDev,
+ uint32_t instanceExtensionCount,
const char* const* instanceExtensions,
uint32_t deviceExtensionCount,
const char* const* deviceExtensions) {
- SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
+ SkTLessFunctionToFunctorAdaptor<GrVkExtensions::Info, 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 (find_info(fExtensions, extension) < 0) {
+ fExtensions.push_back() = Info(extension);
+ SkTQSort(&fExtensions.front(), &fExtensions.back(), cmp);
}
}
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);
+ if (find_info(fExtensions, extension) < 0) {
+ fExtensions.push_back() = Info(extension);
+ SkTQSort(&fExtensions.front(), &fExtensions.back(), cmp);
}
}
+ this->getSpecVersions(getProc, instance, physDev);
}
-bool GrVkExtensions::hasExtension(const char ext[]) const {
- return find_string(fExtensionStrings, ext) >= 0;
+#define GET_PROC(F, inst) \
+ PFN_vk##F grVk##F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE)
+
+void GrVkExtensions::getSpecVersions(GrVkGetProc getProc, VkInstance instance,
+ VkPhysicalDevice physDevice) {
+ // We grab all the extensions for the VkInstance and VkDevice so we can look up what spec
+ // version each of the supported extensions are. We do not grab the extensions for layers
+ // because we don't know what layers the client has enabled and in general we don't do anything
+ // special for those extensions.
+
+ if (instance == VK_NULL_HANDLE) {
+ return;
+ }
+ GET_PROC(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE);
+ SkASSERT(grVkEnumerateInstanceExtensionProperties);
+
+ VkResult res;
+ // instance extensions
+ uint32_t extensionCount = 0;
+ res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
+ if (VK_SUCCESS != res) {
+ return;
+ }
+ VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
+ res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
+ if (VK_SUCCESS != res) {
+ delete[] extensions;
+ return;
+ }
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ int idx = find_info(fExtensions, extensions[i].extensionName);
+ if (idx >= 0) {
+ fExtensions[idx].fSpecVersion = extensions[i].specVersion;
+ }
+ }
+ delete[] extensions;
+
+ if (physDevice == VK_NULL_HANDLE) {
+ return;
+ }
+ GET_PROC(EnumerateDeviceExtensionProperties, instance);
+ SkASSERT(grVkEnumerateDeviceExtensionProperties);
+
+ // device extensions
+ extensionCount = 0;
+ res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, nullptr);
+ if (VK_SUCCESS != res) {
+ return;
+ }
+ extensions = new VkExtensionProperties[extensionCount];
+ res = grVkEnumerateDeviceExtensionProperties(physDevice, nullptr, &extensionCount, extensions);
+ if (VK_SUCCESS != res) {
+ delete[] extensions;
+ return;
+ }
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ int idx = find_info(fExtensions, extensions[i].extensionName);
+ if (idx >= 0) {
+ fExtensions[idx].fSpecVersion = extensions[i].specVersion;
+ }
+ }
+ delete[] extensions;
+}
+
+bool GrVkExtensions::hasExtension(const char ext[], uint32_t minVersion) const {
+ int idx = find_info(fExtensions, ext);
+ return idx >= 0 && fExtensions[idx].fSpecVersion >= minVersion;
}
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 5a19713..6a37c27 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -37,6 +37,7 @@
#include "SkSLCompiler.h"
#include "SkTo.h"
+#include "vk/GrVkExtensions.h"
#include "vk/GrVkTypes.h"
#include <utility>
diff --git a/src/gpu/vk/GrVkInterface.cpp b/src/gpu/vk/GrVkInterface.cpp
index 7ffa8c0..bbdb873 100644
--- a/src/gpu/vk/GrVkInterface.cpp
+++ b/src/gpu/vk/GrVkInterface.cpp
@@ -7,6 +7,7 @@
#include "GrVkInterface.h"
#include "vk/GrVkBackendContext.h"
+#include "vk/GrVkExtensions.h"
#include "vk/GrVkUtil.h"
#define ACQUIRE_PROC(name, instance, device) fFunctions.f##name = \
@@ -39,13 +40,6 @@
ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE);
- if (extensions->hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
- // Also instance Procs.
- ACQUIRE_PROC(CreateDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
- ACQUIRE_PROC(DebugReportMessageEXT, instance, VK_NULL_HANDLE);
- ACQUIRE_PROC(DestroyDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
- }
-
// Device Procs.
ACQUIRE_PROC(GetDeviceQueue, VK_NULL_HANDLE, device);
ACQUIRE_PROC(QueueSubmit, VK_NULL_HANDLE, device);
@@ -318,13 +312,6 @@
RETURN_FALSE_INTERFACE
}
- if (extensions->hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
- if (nullptr == fFunctions.fCreateDebugReportCallbackEXT ||
- nullptr == fFunctions.fDebugReportMessageEXT ||
- nullptr == fFunctions.fDestroyDebugReportCallbackEXT) {
- RETURN_FALSE_INTERFACE
- }
- }
return true;
}
diff --git a/src/gpu/vk/GrVkInterface.h b/src/gpu/vk/GrVkInterface.h
index 22991ac..3345831 100644
--- a/src/gpu/vk/GrVkInterface.h
+++ b/src/gpu/vk/GrVkInterface.h
@@ -12,7 +12,9 @@
#include "vk/GrVkBackendContext.h"
#include "vk/GrVkTypes.h"
-#include "vk/GrVkExtensions.h"
+#include "vk/GrVkDefines.h"
+
+class GrVkExtensions;
////////////////////////////////////////////////////////////////////////////////
@@ -22,7 +24,7 @@
* available based on the Vulkan's version must be non-NULL or GrContext creation
* will fail. This can be tested with the validate() method.
*/
-struct SK_API GrVkInterface : public SkRefCnt {
+struct GrVkInterface : public SkRefCnt {
private:
// simple wrapper class that exists only to initialize a pointer to NULL
template <typename FNPTR_TYPE> class VkPtr {
@@ -186,10 +188,6 @@
VkPtr<PFN_vkCmdNextSubpass> fCmdNextSubpass;
VkPtr<PFN_vkCmdEndRenderPass> fCmdEndRenderPass;
VkPtr<PFN_vkCmdExecuteCommands> fCmdExecuteCommands;
-
- VkPtr<PFN_vkCreateDebugReportCallbackEXT> fCreateDebugReportCallbackEXT;
- VkPtr<PFN_vkDebugReportMessageEXT> fDebugReportMessageEXT;
- VkPtr<PFN_vkDestroyDebugReportCallbackEXT> fDestroyDebugReportCallbackEXT;
} fFunctions;
};