Add support for vulkan extensions needed for AHardwareBuffers.

Bug: skia:
Change-Id: I68198c9f2ea1b859658d2bc75abf33f535960781
Reviewed-on: https://skia-review.googlesource.com/149284
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 9c501d9..773dd36 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -19,17 +19,6 @@
                    VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features,
                    uint32_t instanceVersion, const GrVkExtensions& extensions)
     : INHERITED(contextOptions) {
-    fMustDoCopiesFromOrigin = false;
-    fMustSubmitCommandsBeforeCopyOp = false;
-    fMustSleepOnTearDown  = false;
-    fNewCBOnPipelineChange = false;
-    fShouldAlwaysUseDedicatedImageMemory = false;
-
-    fSupportsPhysicalDeviceProperties2 = false;
-    fSupportsMemoryRequirements2 = false;
-    fSupportsMaintenance1 = false;
-    fSupportsMaintenance2 = false;
-    fSupportsMaintenance3 = false;
 
     /**************************************************************************
      * GrCaps fields
@@ -241,6 +230,29 @@
         fSupportsMaintenance3 = true;
     }
 
+    if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
+        (extensions.hasExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, 3) &&
+         this->supportsMemoryRequirements2())) {
+        fSupportsDedicatedAllocation = true;
+    }
+
+    if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
+        (extensions.hasExtension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 1) &&
+         this->supportsPhysicalDeviceProperties2() &&
+         extensions.hasExtension(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, 1) &&
+         this->supportsDedicatedAllocation())) {
+        fSupportsExternalMemory = true;
+    }
+
+#ifdef SK_BUILD_FOR_ANDROID
+    if (extensions.hasExtension(
+            VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, 3) &&
+        extensions.hasExtension(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, 1) &&
+        this->supportsExternalMemory()) {
+        fSupportsAndroidHWBExternalMemory = true;
+    }
+#endif
+
     this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions);
     this->initShaderCaps(properties, features);
 
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index b3037bc..f46263c 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -115,6 +115,16 @@
     bool supportsMaintenance2() const { return fSupportsMaintenance2; }
     bool supportsMaintenance3() const { return fSupportsMaintenance3; }
 
+    // Returns true if the device supports passing in a flag to say we are using dedicated GPU when
+    // allocating memory. For some devices this allows them to return more optimized memory knowning
+    // they will never need to suballocate amonst multiple objects.
+    bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; }
+
+    // Returns true if the device supports importing of external memory into Vulkan memory.
+    bool supportsExternalMemory() const { return fSupportsExternalMemory; }
+    // Returns true if the device supports importing Android hardware buffers into Vulkan memory.
+    bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; }
+
     /**
      * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
      * the surface is not a render target, otherwise it is the number of samples in the render
@@ -201,17 +211,21 @@
 
     StencilFormat fPreferedStencilFormat;
 
-    bool fMustDoCopiesFromOrigin;
-    bool fMustSubmitCommandsBeforeCopyOp;
-    bool fMustSleepOnTearDown;
-    bool fNewCBOnPipelineChange;
-    bool fShouldAlwaysUseDedicatedImageMemory;
+    bool fMustDoCopiesFromOrigin = false;
+    bool fMustSubmitCommandsBeforeCopyOp = false;
+    bool fMustSleepOnTearDown = false;
+    bool fNewCBOnPipelineChange = false;
+    bool fShouldAlwaysUseDedicatedImageMemory = false;
 
-    bool fSupportsPhysicalDeviceProperties2;
-    bool fSupportsMemoryRequirements2;
-    bool fSupportsMaintenance1;
-    bool fSupportsMaintenance2;
-    bool fSupportsMaintenance3;
+    bool fSupportsPhysicalDeviceProperties2 = false;
+    bool fSupportsMemoryRequirements2 = false;
+    bool fSupportsMaintenance1 = false;
+    bool fSupportsMaintenance2 = false;
+    bool fSupportsMaintenance3 = false;
+
+    bool fSupportsDedicatedAllocation = false;
+    bool fSupportsExternalMemory = false;
+    bool fSupportsAndroidHWBExternalMemory = false;
 
     typedef GrCaps INHERITED;
 };
diff --git a/src/gpu/vk/GrVkInterface.cpp b/src/gpu/vk/GrVkInterface.cpp
index 218d19d..dfce529 100644
--- a/src/gpu/vk/GrVkInterface.cpp
+++ b/src/gpu/vk/GrVkInterface.cpp
@@ -211,6 +211,24 @@
     } else if (extensions->hasExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, 1)) {
         ACQUIRE_PROC_SUFFIX(GetDescriptorSetLayoutSupport, KHR, VK_NULL_HANDLE, device);
     }
+
+    // Functions for VK_KHR_external_memory_capabilities
+    if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+        ACQUIRE_PROC(GetPhysicalDeviceExternalBufferProperties, instance, VK_NULL_HANDLE);
+    } else if (extensions->hasExtension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 1)) {
+        ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceExternalBufferProperties, KHR, instance,
+                            VK_NULL_HANDLE);
+    }
+
+#ifdef SK_BUILD_FOR_ANDROID
+    // Functions for VK_ANDROID_external_memory_android_hardware_buffer
+    if (extensions->hasExtension(
+            VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, 3)) {
+        ACQUIRE_PROC_SUFFIX(GetAndroidHardwareBufferProperties, ANDROID, VK_NULL_HANDLE, device);
+        ACQUIRE_PROC_SUFFIX(GetMemoryAndroidHardwareBuffer, ANDROID, VK_NULL_HANDLE, device);
+    }
+#endif
+
 }
 
 #ifdef SK_DEBUG
@@ -404,6 +422,25 @@
         }
     }
 
+    // Functions for VK_KHR_external_memory_capabilities
+    if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
+        extensions->hasExtension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 1)) {
+        if (nullptr == fFunctions.fGetPhysicalDeviceExternalBufferProperties) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+
+#ifdef SK_BUILD_FOR_ANDROID
+    // Functions for VK_ANDROID_external_memory_android_hardware_buffer
+    if (extensions->hasExtension(
+            VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, 3)) {
+        if (nullptr == fFunctions.fGetAndroidHardwareBufferProperties ||
+            nullptr == fFunctions.fGetMemoryAndroidHardwareBuffer) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+#endif
+
     return true;
 }
 
diff --git a/src/gpu/vk/GrVkInterface.h b/src/gpu/vk/GrVkInterface.h
index be9cbe2..d7ec5bb 100644
--- a/src/gpu/vk/GrVkInterface.h
+++ b/src/gpu/vk/GrVkInterface.h
@@ -211,6 +211,17 @@
 
         // Functions for VK_KHR_maintenance3 or vulkan 1.1
         VkPtr<PFN_vkGetDescriptorSetLayoutSupport> fGetDescriptorSetLayoutSupport;
+
+        // Functions for VK_KHR_external_memory_capabilities
+        VkPtr<PFN_vkGetPhysicalDeviceExternalBufferProperties> fGetPhysicalDeviceExternalBufferProperties;
+
+#ifdef SK_BUILD_FOR_ANDROID
+        // Functions for VK_ANDROID_external_memory_android_hardware_buffer
+        VkPtr<PFN_vkGetAndroidHardwareBufferPropertiesANDROID> fGetAndroidHardwareBufferProperties;
+        VkPtr<PFN_vkGetMemoryAndroidHardwareBufferANDROID> fGetMemoryAndroidHardwareBuffer;
+#endif
+
+
     } fFunctions;
 };
 
diff --git a/third_party/vulkan/SkiaVulkan.h b/third_party/vulkan/SkiaVulkan.h
index 9374259..c15ec28 100644
--- a/third_party/vulkan/SkiaVulkan.h
+++ b/third_party/vulkan/SkiaVulkan.h
@@ -6,3 +6,8 @@
  */
 
 #include "vulkan/vulkan_core.h"
+
+#ifdef SK_BUILD_FOR_ANDROID
+// This is needed to get android extensions for external memory
+#include "vulkan/vulkan_android.h"
+#endif