aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/gpu.gni2
-rw-r--r--include/gpu/vk/GrVkBackendContext.h1
-rw-r--r--include/gpu/vk/GrVkExtensions.h35
-rw-r--r--include/gpu/vk/GrVkInterface.h21
-rw-r--r--src/gpu/vk/GrVkCaps.cpp7
-rw-r--r--src/gpu/vk/GrVkCaps.h10
-rw-r--r--src/gpu/vk/GrVkExtensions.cpp268
-rw-r--r--src/gpu/vk/GrVkExtensions.h50
-rw-r--r--src/gpu/vk/GrVkGpu.cpp5
-rw-r--r--src/gpu/vk/GrVkGpu.h2
-rw-r--r--src/gpu/vk/GrVkInterface.cpp27
-rw-r--r--tools/gpu/vk/VkTestUtils.cpp318
-rw-r--r--tools/sk_app/VulkanWindowContext.cpp5
13 files changed, 388 insertions, 363 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni
index aac56400d4..d150dd5b9f 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -537,6 +537,7 @@ skia_null_gpu_sources = []
skia_vk_sources = [
"$_include/gpu/vk/GrVkBackendContext.h",
"$_include/gpu/vk/GrVkDefines.h",
+ "$_include/gpu/vk/GrVkExtensions.h",
"$_include/gpu/vk/GrVkInterface.h",
"$_include/gpu/vk/GrVkMemoryAllocator.h",
"$_include/gpu/vk/GrVkTypes.h",
@@ -562,7 +563,6 @@ skia_vk_sources = [
"$_src/gpu/vk/GrVkDescriptorSetManager.cpp",
"$_src/gpu/vk/GrVkDescriptorSetManager.h",
"$_src/gpu/vk/GrVkExtensions.cpp",
- "$_src/gpu/vk/GrVkExtensions.h",
"$_src/gpu/vk/GrVkFramebuffer.cpp",
"$_src/gpu/vk/GrVkFramebuffer.h",
"$_src/gpu/vk/GrVkGpu.cpp",
diff --git a/include/gpu/vk/GrVkBackendContext.h b/include/gpu/vk/GrVkBackendContext.h
index fe018e494f..3775c345ce 100644
--- a/include/gpu/vk/GrVkBackendContext.h
+++ b/include/gpu/vk/GrVkBackendContext.h
@@ -49,7 +49,6 @@ struct SK_API GrVkBackendContext {
uint32_t fFeatures;
sk_sp<const GrVkInterface> fInterface;
sk_sp<GrVkMemoryAllocator> fMemoryAllocator;
-
// This is deprecated and should be set to false. The client is responsible for managing the
// lifetime of the VkInstance and VkDevice objects.
bool fOwnsInstanceAndDevice = false;
diff --git a/include/gpu/vk/GrVkExtensions.h b/include/gpu/vk/GrVkExtensions.h
new file mode 100644
index 0000000000..a6badcd33f
--- /dev/null
+++ b/include/gpu/vk/GrVkExtensions.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrVkExtensions_DEFINED
+#define GrVkExtensions_DEFINED
+
+#include "../private/SkTArray.h"
+#include "SkString.h"
+
+/**
+ * Helper class that eats in an array of extensions strings for instance and device and allows for
+ * quicker querying if an extension is present.
+ */
+class GrVkExtensions {
+public:
+ GrVkExtensions(uint32_t instanceExtensionCount, const char* const* instanceExtensions,
+ uint32_t deviceExtensionCount, const char* const* deviceExtensions);
+ // TODO: Remove once we remove the old fExtensions from GrVkBackendContext
+ GrVkExtensions(uint32_t extensionFlags);
+
+ // TODO: Remove once we remove the old fExtensions from GrVkBackendContext
+ static void GetExtensionArrayFromFlags(uint32_t extensionFlags,
+ SkTArray<const char*>* extensions);
+
+ bool hasExtension(const char[]) const;
+
+private:
+ SkTArray<SkString> fExtensionStrings;
+};
+
+#endif
diff --git a/include/gpu/vk/GrVkInterface.h b/include/gpu/vk/GrVkInterface.h
index 05ce561829..b4691e8994 100644
--- a/include/gpu/vk/GrVkInterface.h
+++ b/include/gpu/vk/GrVkInterface.h
@@ -11,6 +11,7 @@
#include "SkRefCnt.h"
#include "vk/GrVkDefines.h"
+#include "vk/GrVkExtensions.h"
////////////////////////////////////////////////////////////////////////////////
@@ -50,17 +51,25 @@ public:
GrVkInterface(GetProc getProc,
VkInstance instance,
VkDevice device,
- uint32_t extensionFlags);
+ uint32_t instanceExtensionCount,
+ const char* const* instanceExtensions,
+ uint32_t deviceExtensionCount,
+ const char* const* deviceExtensions);
- GrVkInterface(const GetInstanceProc&,
- const GetDeviceProc&,
+ // TODO: This is deprecated. Remove onces clients have switch to new interface
+ GrVkInterface(GetProc getProc,
VkInstance instance,
VkDevice device,
uint32_t extensionFlags);
// Validates that the GrVkInterface supports its advertised standard. This means the necessary
// function pointers have been initialized for Vulkan version.
- bool validate(uint32_t extensionFlags) const;
+ bool validate() const;
+
+ // This is deprecated since the extensions information is stored already on the GrVkInterface.
+ bool validate(uint32_t /*extensionFlags*/) const {
+ return this->validate();
+ }
/**
* The function pointers are in a struct so that we can have a compiler generated assignment
@@ -208,6 +217,10 @@ public:
VkPtr<PFN_vkDestroyDebugReportCallbackEXT> fDestroyDebugReportCallbackEXT;
} fFunctions;
+ GrVkExtensions fExtensions;
+
+private:
+ void init(GetProc getProc, VkInstance instance, VkDevice device);
};
#endif
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 1a14648642..d1dfcf08e1 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -15,9 +15,8 @@
#include "vk/GrVkInterface.h"
GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
- VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags)
+ VkPhysicalDevice physDev, uint32_t featureFlags)
: INHERITED(contextOptions) {
- fCanUseGLSLForShaderModule = false;
fMustDoCopiesFromOrigin = false;
fMustSubmitCommandsBeforeCopyOp = false;
fMustSleepOnTearDown = false;
@@ -48,7 +47,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
fShaderCaps.reset(new GrShaderCaps(contextOptions));
- this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags);
+ this->init(contextOptions, vkInterface, physDev, featureFlags);
}
bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
@@ -196,7 +195,7 @@ bool GrVkCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* s
}
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
- VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) {
+ VkPhysicalDevice physDev, uint32_t featureFlags) {
VkPhysicalDeviceProperties properties;
GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 2ed225423b..6e23af018a 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -27,7 +27,7 @@ public:
* be called to fill out the caps.
*/
GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
- VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
+ VkPhysicalDevice device, uint32_t featureFlags);
bool isConfigTexturable(GrPixelConfig config) const override {
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
@@ -64,11 +64,6 @@ public:
return SkToBool(ConfigInfo::kBlitSrc_Flag & flags);
}
- // Tells of if we can pass in straight GLSL string into vkCreateShaderModule
- bool canUseGLSLForShaderModule() const {
- return fCanUseGLSLForShaderModule;
- }
-
// On Adreno vulkan, they do not respect the imageOffset parameter at least in
// copyImageToBuffer. This flag says that we must do the copy starting from the origin always.
bool mustDoCopiesFromOrigin() const {
@@ -151,7 +146,7 @@ private:
};
void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
- VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
+ VkPhysicalDevice device, uint32_t featureFlags);
void initGrCaps(const VkPhysicalDeviceProperties&,
const VkPhysicalDeviceMemoryProperties&,
uint32_t featureFlags);
@@ -187,7 +182,6 @@ private:
StencilFormat fPreferedStencilFormat;
- bool fCanUseGLSLForShaderModule;
bool fMustDoCopiesFromOrigin;
bool fMustSubmitCommandsBeforeCopyOp;
bool fMustSleepOnTearDown;
diff --git a/src/gpu/vk/GrVkExtensions.cpp b/src/gpu/vk/GrVkExtensions.cpp
index e4768d95c9..46bb94d1b2 100644
--- a/src/gpu/vk/GrVkExtensions.cpp
+++ b/src/gpu/vk/GrVkExtensions.cpp
@@ -6,7 +6,9 @@
*/
#include "vk/GrVkExtensions.h"
-#include "vk/GrVkUtil.h"
+
+// Can remove this once we get rid of the extension flags.
+#include "vk/GrVkBackendContext.h"
#include "SkTSearch.h"
#include "SkTSort.h"
@@ -30,232 +32,82 @@ static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
return idx;
}
-#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);
-
+GrVkExtensions::GrVkExtensions(uint32_t instanceExtensionCount,
+ const char* const* instanceExtensions,
+ uint32_t deviceExtensionCount,
+ const char* const* deviceExtensions)
+ : fExtensionStrings() {
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> 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 < 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);
}
}
- 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 < 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);
}
- 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;
}
-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);
-
+GrVkExtensions::GrVkExtensions(uint32_t extensionFlags)
+ : fExtensionStrings() {
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
- if (!EnumerateDeviceExtensionProperties ||
- !EnumerateDeviceLayerProperties) {
- return false;
- }
-
- // device layers
- uint32_t layerCount = 0;
- VkResult res = EnumerateDeviceLayerProperties(physDev, &layerCount, nullptr);
- if (VK_SUCCESS != res) {
- return false;
- }
- VkLayerProperties* layers = new VkLayerProperties[layerCount];
- res = EnumerateDeviceLayerProperties(physDev, &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)) {
- fDeviceLayerStrings->push_back() = layers[i].layerName;
+ 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);
}
}
- delete[] layers;
- if (!fDeviceLayerStrings->empty()) {
- SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
- SkTQSort(&fDeviceLayerStrings->front(), &fDeviceLayerStrings->back(), cmp);
- }
-
- // 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;
- }
- VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
- res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions);
- if (VK_SUCCESS != res) {
- delete[] extensions;
- return false;
- }
- for (uint32_t i = 0; i < extensionCount; ++i) {
- fDeviceExtensionStrings->push_back() = extensions[i].extensionName;
- }
- 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::hasExtension(const char ext[]) const {
+ return find_string(fExtensionStrings, 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 = " ";
+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);
+ }
+#endif
+ if (extensionFlags & kKHR_surface_GrVkExtensionFlag) {
+ extensions->push_back(VK_KHR_SURFACE_EXTENSION_NAME);
}
- 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 : "");
+ if (extensionFlags & kKHR_swapchain_GrVkExtensionFlag) {
+ extensions->push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
}
- cnt = fDeviceExtensionStrings->count();
- SkDebugf("\nDevice Extensions: ");
- for (int i = 0; i < cnt; ++i) {
- SkDebugf("%s%s", (*fDeviceExtensionStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
+#ifdef SK_BUILD_FOR_WIN
+ if (extensionFlags & kKHR_win32_surface_GrVkExtensionFlag) {
+ extensions->push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
}
- cnt = fInstanceLayerStrings->count();
- SkDebugf("\nInstance Layers: ");
- for (int i = 0; i < cnt; ++i) {
- SkDebugf("%s%s", (*fInstanceLayerStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
+#elif defined(SK_BUILD_FOR_ANDROID)
+ if (extensionFlags & kKHR_android_surface_GrVkExtensionFlag) {
+ extensions->push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
}
- cnt = fDeviceLayerStrings->count();
- SkDebugf("\nDevice Layers: ");
- for (int i = 0; i < cnt; ++i) {
- SkDebugf("%s%s", (*fDeviceLayerStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
+#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__)
+ if (extensionFlags & kKHR_xcb_surface_GrVkExtensionFlag) {
+ extensions->push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
+ }
+#endif
+ // Device extensions
+ if (extensionFlags & kKHR_swapchain_GrVkExtensionFlag) {
+ extensions->push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+ }
+ if (extensionFlags & kNV_glsl_shader_GrVkExtensionFlag) {
+ extensions->push_back("VK_NV_glsl_shader");
}
}
+
diff --git a/src/gpu/vk/GrVkExtensions.h b/src/gpu/vk/GrVkExtensions.h
deleted file mode 100644
index 8de28f4d49..0000000000
--- a/src/gpu/vk/GrVkExtensions.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrVkExtensions_DEFINED
-#define GrVkExtensions_DEFINED
-
-#include "../private/SkTArray.h"
-#include "SkString.h"
-#include "vk/GrVkDefines.h"
-#include "vk/GrVkInterface.h"
-
-/**
- * This helper queries the Vulkan driver for available extensions and layers, remembers them,
- * and can be queried. It supports queries for both instance and device extensions and layers.
- */
-class SK_API GrVkExtensions {
-public:
- GrVkExtensions(GrVkInterface::GetProc getProc)
- : fGetProc(getProc)
- , fInstanceExtensionStrings(new SkTArray<SkString>)
- , fDeviceExtensionStrings(new SkTArray<SkString>)
- , fInstanceLayerStrings(new SkTArray<SkString>)
- , fDeviceLayerStrings(new SkTArray<SkString>) {}
-
- bool initInstance(uint32_t specVersion);
- bool initDevice(uint32_t specVersion, VkInstance, VkPhysicalDevice);
-
- /**
- * Queries whether an extension or layer is present. Will fail if not initialized.
- */
- bool hasInstanceExtension(const char[]) const;
- bool hasDeviceExtension(const char[]) const;
- bool hasInstanceLayer(const char[]) const;
- bool hasDeviceLayer(const char[]) const;
-
- void print(const char* sep = "\n") const;
-
-private:
- GrVkInterface::GetProc fGetProc;
- std::unique_ptr<SkTArray<SkString>> fInstanceExtensionStrings;
- std::unique_ptr<SkTArray<SkString>> fDeviceExtensionStrings;
- std::unique_ptr<SkTArray<SkString>> fInstanceLayerStrings;
- std::unique_ptr<SkTArray<SkString>> fDeviceLayerStrings;
-};
-
-#endif
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 65225d919d..81787b22b0 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -36,6 +36,7 @@
#include "SkMipMap.h"
#include "SkSLCompiler.h"
#include "SkTo.h"
+
#include "vk/GrVkInterface.h"
#include "vk/GrVkTypes.h"
@@ -58,7 +59,7 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
return nullptr;
}
if (!backendContext.fInterface ||
- !backendContext.fInterface->validate(backendContext.fExtensions)) {
+ !backendContext.fInterface->validate()) {
return nullptr;
}
@@ -88,7 +89,7 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
fCompiler = new SkSL::Compiler();
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
- backendContext.fFeatures, backendContext.fExtensions));
+ backendContext.fFeatures));
fCaps.reset(SkRef(fVkCaps.get()));
VK_CALL(GetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &fPhysDevProps));
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 266c916cad..a8138923bb 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -144,7 +144,7 @@ public:
bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size);
private:
- GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext& backendContext);
+ GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext&);
void onResetContext(uint32_t resetBits) override {}
diff --git a/src/gpu/vk/GrVkInterface.cpp b/src/gpu/vk/GrVkInterface.cpp
index dedc264136..c8f33711e0 100644
--- a/src/gpu/vk/GrVkInterface.cpp
+++ b/src/gpu/vk/GrVkInterface.cpp
@@ -22,20 +22,27 @@ GrVkInterface::GetProc make_unified_getter(const GrVkInterface::GetInstanceProc&
};
}
-GrVkInterface::GrVkInterface(const GetInstanceProc& getInstanceProc,
- const GetDeviceProc& getDeviceProc,
+GrVkInterface::GrVkInterface(GetProc getProc,
VkInstance instance,
VkDevice device,
uint32_t extensionFlags)
- : GrVkInterface(make_unified_getter(getInstanceProc, getDeviceProc),
- instance,
- device,
- extensionFlags) {}
+ : fExtensions(extensionFlags) {
+ this->init(getProc, instance, device);
+}
GrVkInterface::GrVkInterface(GetProc getProc,
VkInstance instance,
VkDevice device,
- uint32_t extensionFlags) {
+ uint32_t instanceExtensionCount,
+ const char* const* instanceExtensions,
+ uint32_t deviceExtensionCount,
+ const char* const* deviceExtensions)
+ : fExtensions(instanceExtensionCount, instanceExtensions, deviceExtensionCount,
+ deviceExtensions) {
+ this->init(getProc, instance, device);
+}
+
+void GrVkInterface::init(GetProc getProc, VkInstance instance, VkDevice device) {
if (getProc == nullptr) {
return;
}
@@ -59,7 +66,7 @@ GrVkInterface::GrVkInterface(GetProc getProc,
ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE);
- if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
+ if (fExtensions.hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
// Also instance Procs.
ACQUIRE_PROC(CreateDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(DebugReportMessageEXT, instance, VK_NULL_HANDLE);
@@ -198,7 +205,7 @@ GrVkInterface::GrVkInterface(GetProc getProc,
if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
return false;
-bool GrVkInterface::validate(uint32_t extensionFlags) const {
+bool GrVkInterface::validate() const {
// functions that are always required
if (nullptr == fFunctions.fCreateInstance ||
nullptr == fFunctions.fDestroyInstance ||
@@ -338,7 +345,7 @@ bool GrVkInterface::validate(uint32_t extensionFlags) const {
RETURN_FALSE_INTERFACE
}
- if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
+ if (fExtensions.hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
if (nullptr == fFunctions.fCreateDebugReportCallbackEXT ||
nullptr == fFunctions.fDebugReportMessageEXT ||
nullptr == fFunctions.fDestroyDebugReportCallbackEXT) {
diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp
index e6ddda2fce..9421b002cd 100644
--- a/tools/gpu/vk/VkTestUtils.cpp
+++ b/tools/gpu/vk/VkTestUtils.cpp
@@ -59,36 +59,22 @@ const char* kDebugLayerNames[] = {
"VK_LAYER_GOOGLE_threading",
"VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_object_tracker",
- "VK_LAYER_LUNARG_image",
"VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects",
// not included in standard_validation
//"VK_LAYER_LUNARG_api_dump",
//"VK_LAYER_LUNARG_vktrace",
//"VK_LAYER_LUNARG_screenshot",
};
-#endif
-// the minimum version of Vulkan supported
-#ifdef SK_BUILD_FOR_ANDROID
-const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3);
-#else
-const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8);
-#endif
-
-#define ACQUIRE_VK_PROC(name, instance, device) \
- PFN_vk##name grVk##name = \
- reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
- if (grVk##name == nullptr) { \
- SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
- if (device != VK_NULL_HANDLE) { \
- destroy_instance(getProc, inst, debugCallback, hasDebugExtension); \
- } \
- return false; \
+static bool should_include_debug_layer(const VkLayerProperties& layerProps) {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) {
+ if (!strcmp(layerProps.layerName, kDebugLayerNames[i])) {
+ return true;
+ }
}
-
-#ifdef SK_ENABLE_VK_LAYERS
+ return false;
+}
VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
@@ -112,6 +98,202 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
}
#endif
+#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, device)
+
+#ifdef SK_ENABLE_VK_LAYERS
+static uint32_t remove_patch_version(uint32_t specVersion) {
+ return (specVersion >> 12) << 12;
+}
+#endif
+
+static bool init_instance_extensions_and_layers(GrVkInterface::GetProc getProc,
+ uint32_t specVersion,
+ SkTArray<VkExtensionProperties>* instanceExtensions,
+ SkTArray<VkLayerProperties>* instanceLayers) {
+ if (getProc == nullptr) {
+ return false;
+ }
+
+ GET_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
+ GET_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
+
+ if (!EnumerateInstanceExtensionProperties ||
+ !EnumerateInstanceLayerProperties) {
+ return false;
+ }
+
+ VkResult res;
+ uint32_t layerCount = 0;
+#ifdef SK_ENABLE_VK_LAYERS
+ // instance layers
+ 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;
+ }
+
+ uint32_t nonPatchVersion = remove_patch_version(specVersion);
+ for (uint32_t i = 0; i < layerCount; ++i) {
+ if (nonPatchVersion <= remove_patch_version(layers[i].specVersion) &&
+ should_include_debug_layer(layers[i])) {
+ instanceLayers->push_back() = layers[i];
+ }
+ }
+ delete[] layers;
+#endif
+
+ // 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) {
+ instanceExtensions->push_back() = extensions[i];
+ }
+ delete [] extensions;
+
+ // via explicitly enabled layers
+ layerCount = instanceLayers->count();
+ for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
+ uint32_t extensionCount = 0;
+ res = EnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
+ &extensionCount, nullptr);
+ if (VK_SUCCESS != res) {
+ return false;
+ }
+ VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
+ res = EnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
+ &extensionCount, extensions);
+ if (VK_SUCCESS != res) {
+ delete[] extensions;
+ return false;
+ }
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ instanceExtensions->push_back() = extensions[i];
+ }
+ delete[] extensions;
+ }
+
+ return true;
+}
+
+static bool init_device_extensions_and_layers(GrVkInterface::GetProc getProc, uint32_t specVersion,
+ VkInstance inst, VkPhysicalDevice physDev,
+ SkTArray<VkExtensionProperties>* deviceExtensions,
+ SkTArray<VkLayerProperties>* deviceLayers) {
+ if (getProc == nullptr) {
+ return false;
+ }
+
+ GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst, VK_NULL_HANDLE);
+ GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst, VK_NULL_HANDLE);
+
+ if (!EnumerateDeviceExtensionProperties ||
+ !EnumerateDeviceLayerProperties) {
+ return false;
+ }
+
+ VkResult res;
+ // device layers
+ uint32_t layerCount = 0;
+#ifdef SK_ENABLE_VK_LAYERS
+ res = EnumerateDeviceLayerProperties(physDev, &layerCount, nullptr);
+ if (VK_SUCCESS != res) {
+ return false;
+ }
+ VkLayerProperties* layers = new VkLayerProperties[layerCount];
+ res = EnumerateDeviceLayerProperties(physDev, &layerCount, layers);
+ if (VK_SUCCESS != res) {
+ delete[] layers;
+ return false;
+ }
+
+ uint32_t nonPatchVersion = remove_patch_version(specVersion);
+ for (uint32_t i = 0; i < layerCount; ++i) {
+ if (nonPatchVersion <= remove_patch_version(layers[i].specVersion) &&
+ should_include_debug_layer(layers[i])) {
+ deviceLayers->push_back() = layers[i];
+ }
+ }
+ delete[] layers;
+#endif
+
+ // 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;
+ }
+ VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
+ res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions);
+ if (VK_SUCCESS != res) {
+ delete[] extensions;
+ return false;
+ }
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ deviceExtensions->push_back() = extensions[i];
+ }
+ delete[] extensions;
+
+ // via explicitly enabled layers
+ layerCount = deviceLayers->count();
+ for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
+ uint32_t extensionCount = 0;
+ res = EnumerateDeviceExtensionProperties(physDev,
+ (*deviceLayers)[layerIndex].layerName,
+ &extensionCount, nullptr);
+ if (VK_SUCCESS != res) {
+ return false;
+ }
+ VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
+ res = EnumerateDeviceExtensionProperties(physDev,
+ (*deviceLayers)[layerIndex].layerName,
+ &extensionCount, extensions);
+ if (VK_SUCCESS != res) {
+ delete[] extensions;
+ return false;
+ }
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ deviceExtensions->push_back() = extensions[i];
+ }
+ delete[] extensions;
+ }
+
+ return true;
+}
+
+// the minimum version of Vulkan supported
+#ifdef SK_BUILD_FOR_ANDROID
+const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3);
+#else
+const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8);
+#endif
+
+#define ACQUIRE_VK_PROC(name, instance, device) \
+ PFN_vk##name grVk##name = \
+ reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
+ if (grVk##name == nullptr) { \
+ SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
+ if (device != VK_NULL_HANDLE) { \
+ destroy_instance(getProc, inst, debugCallback, hasDebugExtension); \
+ } \
+ return false; \
+ }
+
#define ACQUIRE_VK_PROC_LOCAL(name, instance, device) \
PFN_vk##name grVk##name = \
reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
@@ -161,50 +343,25 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
kGrVkMinimumVersion, // apiVersion
};
- GrVkExtensions extensions(getProc);
- extensions.initInstance(kGrVkMinimumVersion);
+ SkTArray<VkLayerProperties> instanceLayers;
+ SkTArray<VkExtensionProperties> instanceExtensions;
- SkTArray<const char*> instanceLayerNames;
- SkTArray<const char*> instanceExtensionNames;
- uint32_t extensionFlags = 0;
- bool hasDebugExtension = false;
-#ifdef SK_ENABLE_VK_LAYERS
- for (size_t i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) {
- if (extensions.hasInstanceLayer(kDebugLayerNames[i])) {
- instanceLayerNames.push_back(kDebugLayerNames[i]);
- }
- }
- if (extensions.hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
- instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
- extensionFlags |= kEXT_debug_report_GrVkExtensionFlag;
- hasDebugExtension = true;
+ if (!init_instance_extensions_and_layers(getProc, kGrVkMinimumVersion,
+ &instanceExtensions,
+ &instanceLayers)) {
+ return false;
}
-#endif
- if (extensions.hasInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME)) {
- instanceExtensionNames.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
- extensionFlags |= kKHR_surface_GrVkExtensionFlag;
- }
- if (extensions.hasInstanceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
- instanceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
- extensionFlags |= kKHR_swapchain_GrVkExtensionFlag;
- }
-#ifdef SK_BUILD_FOR_WIN
- if (extensions.hasInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) {
- instanceExtensionNames.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
- extensionFlags |= kKHR_win32_surface_GrVkExtensionFlag;
- }
-#elif defined(SK_BUILD_FOR_ANDROID)
- if (extensions.hasInstanceExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)) {
- instanceExtensionNames.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
- extensionFlags |= kKHR_android_surface_GrVkExtensionFlag;
+ SkTArray<const char*> instanceLayerNames;
+ SkTArray<const char*> instanceExtensionNames;
+ for (int i = 0; i < instanceLayers.count(); ++i) {
+ instanceLayerNames.push_back(instanceLayers[i].layerName);
}
-#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__)
- if (extensions.hasInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) {
- instanceExtensionNames.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
- extensionFlags |= kKHR_xcb_surface_GrVkExtensionFlag;
+ for (int i = 0; i < instanceExtensions.count(); ++i) {
+ if (strncmp(instanceExtensions[i].extensionName, "VK_KHX", 6)) {
+ instanceExtensionNames.push_back(instanceExtensions[i].extensionName);
+ }
}
-#endif
const VkInstanceCreateInfo instance_create = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
@@ -217,6 +374,8 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
instanceExtensionNames.begin(), // ppEnabledExtensionNames
};
+ bool hasDebugExtension = false;
+
ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE);
err = grVkCreateInstance(&instance_create, nullptr, &inst);
if (err < 0) {
@@ -250,7 +409,6 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
}
#endif
- ACQUIRE_VK_PROC(DestroyInstance, inst, VK_NULL_HANDLE);
ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst, VK_NULL_HANDLE);
ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst, VK_NULL_HANDLE);
ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst, VK_NULL_HANDLE);
@@ -332,17 +490,29 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
presentQueueIndex = graphicsQueueIndex;
}
- extensions.initDevice(kGrVkMinimumVersion, inst, physDev);
+ SkTArray<VkLayerProperties> deviceLayers;
+ SkTArray<VkExtensionProperties> deviceExtensions;
+ if (!init_device_extensions_and_layers(getProc, kGrVkMinimumVersion,
+ inst, physDev,
+ &deviceExtensions,
+ &deviceLayers)) {
+ destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+ return false;
+ }
SkTArray<const char*> deviceLayerNames;
SkTArray<const char*> deviceExtensionNames;
- if (extensions.hasDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
- deviceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
- extensionFlags |= kKHR_swapchain_GrVkExtensionFlag;
+ for (int i = 0; i < deviceLayers.count(); ++i) {
+ deviceLayerNames.push_back(deviceLayers[i].layerName);
}
- if (extensions.hasDeviceExtension("VK_NV_glsl_shader")) {
- deviceExtensionNames.push_back("VK_NV_glsl_shader");
- extensionFlags |= kNV_glsl_shader_GrVkExtensionFlag;
+ for (int i = 0; i < deviceExtensions.count(); ++i) {
+ // Don't use experimental extensions since they typically don't work with debug layers and
+ // often are missing dependecy requirements for other extensions. Additionally, these are
+ // often left behind in the driver even after they've been promoted to real extensions.
+ if (strncmp(deviceExtensions[i].extensionName, "VK_KHX", 6) &&
+ strncmp(deviceExtensions[i].extensionName, "VK_NVX", 6)) {
+ deviceExtensionNames.push_back(deviceExtensions[i].extensionName);
+ }
}
// query to get the physical device properties
@@ -406,9 +576,13 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
return false;
}
- auto interface =
- sk_make_sp<GrVkInterface>(getProc, inst, device, extensionFlags);
- if (!interface->validate(extensionFlags)) {
+ auto interface = sk_make_sp<GrVkInterface>(getProc, inst, device,
+ (uint32_t) instanceExtensionNames.count(),
+ instanceExtensionNames.begin(),
+ (uint32_t) deviceExtensionNames.count(),
+ deviceExtensionNames.begin());
+
+ if (!interface->validate()) {
SkDebugf("Vulkan interface validation failed\n");
grVkDeviceWaitIdle(device);
grVkDestroyDevice(device, nullptr);
@@ -425,7 +599,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
ctx->fQueue = queue;
ctx->fGraphicsQueueIndex = graphicsQueueIndex;
ctx->fMinAPIVersion = kGrVkMinimumVersion;
- ctx->fExtensions = extensionFlags;
+ ctx->fExtensions = 0;
ctx->fFeatures = featureFlags;
ctx->fInterface.reset(interface.release());
ctx->fOwnsInstanceAndDevice = false;
diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
index 8e0749ec1b..d038c97e34 100644
--- a/tools/sk_app/VulkanWindowContext.cpp
+++ b/tools/sk_app/VulkanWindowContext.cpp
@@ -12,6 +12,7 @@
#include "SkSurface.h"
#include "VulkanWindowContext.h"
+#include "vk/GrVkExtensions.h"
#include "vk/GrVkImage.h"
#include "vk/GrVkUtil.h"
#include "vk/GrVkTypes.h"
@@ -56,8 +57,8 @@ void VulkanWindowContext::initializeContext() {
return;
}
- if (!(backendContext.fExtensions & kKHR_surface_GrVkExtensionFlag) ||
- !(backendContext.fExtensions & kKHR_swapchain_GrVkExtensionFlag)) {
+ if (!backendContext.fInterface->fExtensions.hasExtension(VK_KHR_SURFACE_EXTENSION_NAME) ||
+ !backendContext.fInterface->fExtensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
return;
}