Fix interface validation in Vulkan.

TBR=bsalomon@google.com

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3176

Change-Id: Ifad3249e6839e9b4aa34792646b2d54ff9304da7
Reviewed-on: https://skia-review.googlesource.com/3176
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/include/gpu/vk/GrVkInterface.h b/include/gpu/vk/GrVkInterface.h
index 1f17865..9dc0333 100644
--- a/include/gpu/vk/GrVkInterface.h
+++ b/include/gpu/vk/GrVkInterface.h
@@ -53,7 +53,7 @@
 
     // Validates that the GrVkInterface supports its advertised standard. This means the necessary
     // function pointers have been initialized for Vulkan version.
-    bool validate() const;
+    bool validate(uint32_t extensionFlags) const;
 
     /**
      * The function pointers are in a struct so that we can have a compiler generated assignment
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 60a8763..0eb8241 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -80,6 +80,10 @@
         vkBackendContext->ref();
     }
 
+    if (!vkBackendContext->fInterface->validate(vkBackendContext->fExtensions)) {
+        return nullptr;
+    }
+
     return new GrVkGpu(context, options, vkBackendContext);
 }
 
diff --git a/src/gpu/vk/GrVkInterface.cpp b/src/gpu/vk/GrVkInterface.cpp
index 17b254e..34f12b4 100644
--- a/src/gpu/vk/GrVkInterface.cpp
+++ b/src/gpu/vk/GrVkInterface.cpp
@@ -12,6 +12,7 @@
 GrVkInterface::GrVkInterface() {
 }
 
+#define GET_PROC_GLOBAL(F) functions->f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(NULL, "vk" #F)
 #define GET_PROC(F) functions->f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk" #F)
 #define GET_PROC_LOCAL(inst, F) PFN_vk ## F F = (PFN_vk ## F) vkGetInstanceProcAddr(inst, "vk" #F)
 #define GET_DEV_PROC(F) functions->f ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk" #F)
@@ -22,7 +23,9 @@
     GrVkInterface* interface = new GrVkInterface();
     GrVkInterface::Functions* functions = &interface->fFunctions;
 
-    GET_PROC(CreateInstance);
+    GET_PROC_GLOBAL(CreateInstance);
+    GET_PROC_GLOBAL(EnumerateInstanceExtensionProperties);
+    GET_PROC_GLOBAL(EnumerateInstanceLayerProperties);
     GET_PROC(DestroyInstance);
     GET_PROC(EnumeratePhysicalDevices);
     GET_PROC(GetPhysicalDeviceFeatures);
@@ -33,9 +36,7 @@
     GET_PROC(GetPhysicalDeviceMemoryProperties);
     GET_PROC(CreateDevice);
     GET_PROC(DestroyDevice);
-    GET_PROC(EnumerateInstanceExtensionProperties);
     GET_PROC(EnumerateDeviceExtensionProperties);
-    GET_PROC(EnumerateInstanceLayerProperties);
     GET_PROC(EnumerateDeviceLayerProperties);
     GET_DEV_PROC(GetDeviceQueue);
     GET_DEV_PROC(QueueSubmit);
@@ -167,11 +168,17 @@
     return interface;
 }
 
+#ifdef SK_DEBUG
+    static int kIsDebug = 1;
+#else
+    static int kIsDebug = 0;
+#endif
+
 #define RETURN_FALSE_INTERFACE                                                                   \
     if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
     return false;
 
-bool GrVkInterface::validate() const {
+bool GrVkInterface::validate(uint32_t extensionFlags) const {
     // functions that are always required
     if (NULL == fFunctions.fCreateInstance ||
         NULL == fFunctions.fDestroyInstance ||
@@ -307,12 +314,17 @@
         NULL == fFunctions.fCmdBeginRenderPass ||
         NULL == fFunctions.fCmdNextSubpass ||
         NULL == fFunctions.fCmdEndRenderPass ||
-        NULL == fFunctions.fCmdExecuteCommands ||
-        NULL == fFunctions.fCreateDebugReportCallbackEXT ||
-        NULL == fFunctions.fDebugReportMessageEXT ||
-        NULL == fFunctions.fDestroyDebugReportCallbackEXT) {
+        NULL == fFunctions.fCmdExecuteCommands) {
+        RETURN_FALSE_INTERFACE
+    }
 
-        return false;
+    if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
+        if (NULL == fFunctions.fCreateDebugReportCallbackEXT ||
+            NULL == fFunctions.fDebugReportMessageEXT ||
+            NULL == fFunctions.fDestroyDebugReportCallbackEXT) {
+            RETURN_FALSE_INTERFACE
+        }
     }
     return true;
 }
+