Reland "Reland "Let client pass in full extension to GrVkBackendContext.""

This reverts commit dc13c21b1e49ca1e16251d01bd1062157c5c1c2b.

Reason for revert: fuchsia should be fixed

Original change's description:
> Revert "Reland "Let client pass in full extension to GrVkBackendContext.""
> 
> This reverts commit a782dcb3c407a7e30d7c1263bf9965792088e786.
> 
> Reason for revert: fuchsia changes reverted
> 
> Original change's description:
> > Reland "Let client pass in full extension to GrVkBackendContext."
> > 
> > This reverts commit cb92b26e5ca6063bcf1a922109b8224e0b6eb4da.
> > 
> > Reason for revert: <INSERT REASONING HERE>
> > 
> > Original change's description:
> > > Revert "Let client pass in full extension to GrVkBackendContext."
> > > 
> > > This reverts commit 45c9dab4c3ec43cedb28d1b8c08e166fe0c2e767.
> > > 
> > > Reason for revert: fucshia uses GrVkBackendContext. Need to revert earlier changes
> > > 
> > > Original change's description:
> > > > Let client pass in full extension to GrVkBackendContext.
> > > > 
> > > > Bug: skia:
> > > > Change-Id: I772ab4ccbca0f4f7e7d429d6c421b07d97f0606f
> > > > Reviewed-on: https://skia-review.googlesource.com/131880
> > > > Reviewed-by: Jim Van Verth <jvanverth@google.com>
> > > > Commit-Queue: Greg Daniel <egdaniel@google.com>
> > > 
> > > TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
> > > 
> > > Change-Id: I1a765ff406c83cb234c3614b804fbed677d5a382
> > > No-Presubmit: true
> > > No-Tree-Checks: true
> > > No-Try: true
> > > Bug: skia:
> > > Reviewed-on: https://skia-review.googlesource.com/137901
> > > Reviewed-by: Greg Daniel <egdaniel@google.com>
> > > Commit-Queue: Greg Daniel <egdaniel@google.com>
> > 
> > TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
> > 
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> > 
> > Bug: skia:
> > Change-Id: I0af797c51dde705473e9afaccb1d4b4423e8c41e
> > Reviewed-on: https://skia-review.googlesource.com/138302
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
> > Reviewed-by: Greg Daniel <egdaniel@google.com>
> 
> TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
> 
> Change-Id: Idf760d5ac6b82df33a4408079a0223be833058ad
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:
> Reviewed-on: https://skia-review.googlesource.com/138420
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: skia:
Change-Id: Ied1323b7197b600e895d85ac7e85d6f65985dabc
Reviewed-on: https://skia-review.googlesource.com/139002
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index b48b9ae..9f63e36 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -15,9 +15,8 @@
 #include "vk/GrVkBackendContext.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 @@
 
     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 @@
 }
 
 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 a3c7144..7d9dbff 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -27,7 +27,7 @@
      * 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 @@
         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 @@
     };
 
     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);
@@ -191,7 +186,6 @@
 
     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 e4768d9..6cc20e6 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,31 @@
     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);
-
+void GrVkExtensions::init(uint32_t instanceExtensionCount,
+                          const char* const* instanceExtensions,
+                          uint32_t deviceExtensionCount,
+                          const char* const* deviceExtensions) {
     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;
+    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);
         }
-        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;
 }
 
-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;
-
-    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;
-        }
-    }
-    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::hasExtension(const char ext[]) const {
+    return find_string(fExtensionStrings, ext) >= 0;
 }
 
-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 : "");
-    }
-}
diff --git a/src/gpu/vk/GrVkExtensions.h b/src/gpu/vk/GrVkExtensions.h
deleted file mode 100644
index 6a0e356..0000000
--- 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 "GrVkInterface.h"
-#include "SkString.h"
-#include "vk/GrVkTypes.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(GrVkGetProc 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:
-    GrVkGetProc 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 9a17b73..5a19713 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/GrVkTypes.h"
 
 #include <utility>
@@ -64,13 +65,27 @@
         return nullptr;
     }
 
-    sk_sp<const GrVkInterface> interface(new GrVkInterface(backendContext.fGetProc,
-                                         backendContext.fInstance,
-                                         backendContext.fDevice,
-                                         backendContext.fExtensions));
+    sk_sp<const GrVkInterface> interface;
 
-    if (!interface->validate(backendContext.fExtensions)) {
-        return nullptr;
+    if (backendContext.fVkExtensions) {
+        interface.reset(new GrVkInterface(backendContext.fGetProc,
+                                          backendContext.fInstance,
+                                          backendContext.fDevice,
+                                          backendContext.fVkExtensions));
+        if (!interface->validate(backendContext.fVkExtensions)) {
+            return nullptr;
+        }
+    } else {
+        // None of our current GrVkExtension flags actually affect the vulkan backend so we just
+        // make an empty GrVkExtensions and pass that to the GrVkInterface.
+        GrVkExtensions extensions;
+        interface.reset(new GrVkInterface(backendContext.fGetProc,
+                                          backendContext.fInstance,
+                                          backendContext.fDevice,
+                                          &extensions));
+        if (!interface->validate(&extensions)) {
+            return nullptr;
+        }
     }
 
     return sk_sp<GrGpu>(new GrVkGpu(context, options, backendContext, interface));
@@ -99,7 +114,7 @@
     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 52b6ee7..c0d068e 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -144,7 +144,7 @@
     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&,
             sk_sp<const GrVkInterface>);
 
     void onResetContext(uint32_t resetBits) override {}
diff --git a/src/gpu/vk/GrVkInterface.cpp b/src/gpu/vk/GrVkInterface.cpp
index f658505..7ffa8c0 100644
--- a/src/gpu/vk/GrVkInterface.cpp
+++ b/src/gpu/vk/GrVkInterface.cpp
@@ -15,7 +15,7 @@
 GrVkInterface::GrVkInterface(GrVkGetProc getProc,
                              VkInstance instance,
                              VkDevice device,
-                             uint32_t extensionFlags) {
+                             const GrVkExtensions* extensions) {
     if (getProc == nullptr) {
         return;
     }
@@ -39,7 +39,7 @@
     ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE);
     ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE);
 
-    if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
+    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);
@@ -178,7 +178,7 @@
     if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
     return false;
 
-bool GrVkInterface::validate(uint32_t extensionFlags) const {
+bool GrVkInterface::validate(const GrVkExtensions* extensions) const {
     // functions that are always required
     if (nullptr == fFunctions.fCreateInstance ||
         nullptr == fFunctions.fDestroyInstance ||
@@ -318,7 +318,7 @@
         RETURN_FALSE_INTERFACE
     }
 
-    if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
+    if (extensions->hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
         if (nullptr == fFunctions.fCreateDebugReportCallbackEXT ||
             nullptr == fFunctions.fDebugReportMessageEXT ||
             nullptr == fFunctions.fDestroyDebugReportCallbackEXT) {
diff --git a/src/gpu/vk/GrVkInterface.h b/src/gpu/vk/GrVkInterface.h
index 69f99e2..22991ac 100644
--- a/src/gpu/vk/GrVkInterface.h
+++ b/src/gpu/vk/GrVkInterface.h
@@ -12,6 +12,7 @@
 
 #include "vk/GrVkBackendContext.h"
 #include "vk/GrVkTypes.h"
+#include "vk/GrVkExtensions.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -39,11 +40,11 @@
     GrVkInterface(GrVkGetProc getProc,
                   VkInstance instance,
                   VkDevice device,
-                  uint32_t extensionFlags);
+                  const GrVkExtensions*);
 
     // 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 GrVkExtensions*) const;
 
     /**
      * The function pointers are in a struct so that we can have a compiler generated assignment
@@ -190,7 +191,6 @@
         VkPtr<PFN_vkDebugReportMessageEXT> fDebugReportMessageEXT;
         VkPtr<PFN_vkDestroyDebugReportCallbackEXT> fDestroyDebugReportCallbackEXT;
     } fFunctions;
-
 };
 
 #endif