Add external memory and semaphore extensions

Also adds GetGlobalInfo, similar to GetDeviceInfo, but for code that wants to query instance extensions or API version.

Bug: chromium:976495
Change-Id: Ia7131aa1780737ec2691cde0007acb86a120d307
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9620
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn_native/vulkan/BackendVk.cpp b/src/dawn_native/vulkan/BackendVk.cpp
index f1c00ec..e7516c2 100644
--- a/src/dawn_native/vulkan/BackendVk.cpp
+++ b/src/dawn_native/vulkan/BackendVk.cpp
@@ -55,6 +55,10 @@
         return mInstance;
     }
 
+    const VulkanGlobalInfo& Backend::GetGlobalInfo() const {
+        return mGlobalInfo;
+    }
+
     MaybeError Backend::Initialize() {
         if (!mVulkanLib.Open(kVulkanLibName)) {
             return DAWN_CONTEXT_LOST_ERROR(std::string("Couldn't open ") + kVulkanLibName);
@@ -138,6 +142,18 @@
             extensionsToRequest.push_back(kExtensionNameMvkMacosSurface);
             usedKnobs.macosSurface = true;
         }
+        if (mGlobalInfo.externalMemoryCapabilities) {
+            extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryCapabilities);
+            usedKnobs.externalMemoryCapabilities = true;
+        }
+        if (mGlobalInfo.externalSemaphoreCapabilities) {
+            extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreCapabilities);
+            usedKnobs.externalSemaphoreCapabilities = true;
+        }
+        if (mGlobalInfo.getPhysicalDeviceProperties2) {
+            extensionsToRequest.push_back(kExtensionNameKhrGetPhysicalDeviceProperties2);
+            usedKnobs.getPhysicalDeviceProperties2 = true;
+        }
         if (mGlobalInfo.surface) {
             extensionsToRequest.push_back(kExtensionNameKhrSurface);
             usedKnobs.surface = true;
diff --git a/src/dawn_native/vulkan/BackendVk.h b/src/dawn_native/vulkan/BackendVk.h
index b3ab47e..a0606b7 100644
--- a/src/dawn_native/vulkan/BackendVk.h
+++ b/src/dawn_native/vulkan/BackendVk.h
@@ -30,6 +30,7 @@
 
         const VulkanFunctions& GetFunctions() const;
         VkInstance GetVkInstance() const;
+        const VulkanGlobalInfo& GetGlobalInfo() const;
 
         MaybeError Initialize();
 
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index 94845c7..fc3b152 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -343,7 +343,22 @@
             extensionsToRequest.push_back(kExtensionNameExtDebugMarker);
             usedKnobs.debugMarker = true;
         }
-
+        if (mDeviceInfo.externalMemory) {
+            extensionsToRequest.push_back(kExtensionNameKhrExternalMemory);
+            usedKnobs.externalMemory = true;
+        }
+        if (mDeviceInfo.externalMemoryFD) {
+            extensionsToRequest.push_back(kExtensionNameKhrExternalMemoryFD);
+            usedKnobs.externalMemoryFD = true;
+        }
+        if (mDeviceInfo.externalSemaphore) {
+            extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphore);
+            usedKnobs.externalSemaphore = true;
+        }
+        if (mDeviceInfo.externalSemaphoreFD) {
+            extensionsToRequest.push_back(kExtensionNameKhrExternalSemaphoreFD);
+            usedKnobs.externalSemaphoreFD = true;
+        }
         if (mDeviceInfo.swapchain) {
             extensionsToRequest.push_back(kExtensionNameKhrSwapchain);
             usedKnobs.swapchain = true;
diff --git a/src/dawn_native/vulkan/VulkanFunctions.cpp b/src/dawn_native/vulkan/VulkanFunctions.cpp
index 6921244..b3e32e0 100644
--- a/src/dawn_native/vulkan/VulkanFunctions.cpp
+++ b/src/dawn_native/vulkan/VulkanFunctions.cpp
@@ -48,7 +48,7 @@
     }
 
     MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance,
-                                                  const VulkanGlobalKnobs& usedKnobs) {
+                                                  const VulkanGlobalInfo& globalInfo) {
         // Load this proc first so that we can destroy the instance even if some other
         // GET_INSTANCE_PROC fails
         GET_INSTANCE_PROC(DestroyInstance);
@@ -67,13 +67,35 @@
         GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties);
         GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties);
 
-        if (usedKnobs.debugReport) {
+        if (globalInfo.debugReport) {
             GET_INSTANCE_PROC(CreateDebugReportCallbackEXT);
             GET_INSTANCE_PROC(DebugReportMessageEXT);
             GET_INSTANCE_PROC(DestroyDebugReportCallbackEXT);
         }
 
-        if (usedKnobs.surface) {
+        // Vulkan 1.1 is not required to report promoted extensions from 1.0
+        if (globalInfo.externalMemoryCapabilities ||
+            globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+            GET_INSTANCE_PROC(GetPhysicalDeviceExternalBufferPropertiesKHR);
+        }
+
+        if (globalInfo.externalSemaphoreCapabilities ||
+            globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+            GET_INSTANCE_PROC(GetPhysicalDeviceExternalSemaphorePropertiesKHR);
+        }
+
+        if (globalInfo.getPhysicalDeviceProperties2 ||
+            globalInfo.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+            GET_INSTANCE_PROC(GetPhysicalDeviceFeatures2KHR);
+            GET_INSTANCE_PROC(GetPhysicalDeviceProperties2KHR);
+            GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties2KHR);
+            GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties2KHR);
+            GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties2KHR);
+            GET_INSTANCE_PROC(GetPhysicalDeviceMemoryProperties2KHR);
+            GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties2KHR);
+        }
+
+        if (globalInfo.surface) {
             GET_INSTANCE_PROC(DestroySurfaceKHR);
             GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceSupportKHR);
             GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
@@ -218,6 +240,16 @@
             GET_DEVICE_PROC(CmdDebugMarkerInsertEXT);
         }
 
+        if (usedKnobs.externalMemoryFD) {
+            GET_DEVICE_PROC(GetMemoryFdKHR);
+            GET_DEVICE_PROC(GetMemoryFdPropertiesKHR);
+        }
+
+        if (usedKnobs.externalSemaphoreFD) {
+            GET_DEVICE_PROC(ImportSemaphoreFdKHR);
+            GET_DEVICE_PROC(GetSemaphoreFdKHR);
+        }
+
         if (usedKnobs.swapchain) {
             GET_DEVICE_PROC(CreateSwapchainKHR);
             GET_DEVICE_PROC(DestroySwapchainKHR);
diff --git a/src/dawn_native/vulkan/VulkanFunctions.h b/src/dawn_native/vulkan/VulkanFunctions.h
index e3b0b23..b1f24f1 100644
--- a/src/dawn_native/vulkan/VulkanFunctions.h
+++ b/src/dawn_native/vulkan/VulkanFunctions.h
@@ -23,14 +23,14 @@
 
 namespace dawn_native { namespace vulkan {
 
-    struct VulkanGlobalKnobs;
+    struct VulkanGlobalInfo;
     struct VulkanDeviceKnobs;
 
     // Stores the Vulkan entry points. Also loads them from the dynamic library
     // and the vkGet*ProcAddress entry points.
     struct VulkanFunctions {
         MaybeError LoadGlobalProcs(const DynamicLib& vulkanLib);
-        MaybeError LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedGlobals);
+        MaybeError LoadInstanceProcs(VkInstance instance, const VulkanGlobalInfo& globalInfo);
         MaybeError LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs);
 
         // ---------- Global procs
@@ -84,6 +84,28 @@
         PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR =
             nullptr;
 
+        // Core Vulkan 1.1 promoted extensions
+
+        // VK_KHR_external_memory_capabilities
+        PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR
+            GetPhysicalDeviceExternalBufferPropertiesKHR = nullptr;
+
+        // VK_KHR_external_semaphore_capabilities
+        PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR
+            GetPhysicalDeviceExternalSemaphorePropertiesKHR = nullptr;
+
+        // VK_KHR_get_physical_device_properties2
+        PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR = nullptr;
+        PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR = nullptr;
+        PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR = nullptr;
+        PFN_vkGetPhysicalDeviceImageFormatProperties2KHR
+            GetPhysicalDeviceImageFormatProperties2KHR = nullptr;
+        PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR
+            GetPhysicalDeviceQueueFamilyProperties2KHR = nullptr;
+        PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR = nullptr;
+        PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR
+            GetPhysicalDeviceSparseImageFormatProperties2KHR = nullptr;
+
         // ---------- Device procs
 
         // Core Vulkan 1.0
@@ -218,6 +240,14 @@
         PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR = nullptr;
         PFN_vkAcquireNextImageKHR AcquireNextImageKHR = nullptr;
         PFN_vkQueuePresentKHR QueuePresentKHR = nullptr;
+
+        // VK_KHR_external_memory_fd
+        PFN_vkGetMemoryFdKHR GetMemoryFdKHR = nullptr;
+        PFN_vkGetMemoryFdPropertiesKHR GetMemoryFdPropertiesKHR = nullptr;
+
+        // VK_KHR_external_semaphore_fd
+        PFN_vkImportSemaphoreFdKHR ImportSemaphoreFdKHR = nullptr;
+        PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR = nullptr;
     };
 
 }}  // namespace dawn_native::vulkan
diff --git a/src/dawn_native/vulkan/VulkanInfo.cpp b/src/dawn_native/vulkan/VulkanInfo.cpp
index 2c0128e..2174662 100644
--- a/src/dawn_native/vulkan/VulkanInfo.cpp
+++ b/src/dawn_native/vulkan/VulkanInfo.cpp
@@ -38,6 +38,16 @@
     const char kExtensionNameExtDebugMarker[] = "VK_EXT_debug_marker";
     const char kExtensionNameExtDebugReport[] = "VK_EXT_debug_report";
     const char kExtensionNameMvkMacosSurface[] = "VK_MVK_macos_surface";
+    const char kExtensionNameKhrExternalMemory[] = "VK_KHR_external_memory";
+    const char kExtensionNameKhrExternalMemoryCapabilities[] =
+        "VK_KHR_external_memory_capabilities";
+    const char kExtensionNameKhrExternalMemoryFD[] = "VK_KHR_external_memory_fd";
+    const char kExtensionNameKhrExternalSemaphore[] = "VK_KHR_external_semaphore";
+    const char kExtensionNameKhrExternalSemaphoreCapabilities[] =
+        "VK_KHR_external_semaphore_capabilities";
+    const char kExtensionNameKhrExternalSemaphoreFD[] = "VK_KHR_external_semaphore_fd";
+    const char kExtensionNameKhrGetPhysicalDeviceProperties2[] =
+        "VK_KHR_get_physical_device_properties2";
     const char kExtensionNameKhrSurface[] = "VK_KHR_surface";
     const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain";
     const char kExtensionNameKhrWaylandSurface[] = "VK_KHR_wayland_surface";
@@ -102,6 +112,15 @@
                 if (IsExtensionName(extension, kExtensionNameMvkMacosSurface)) {
                     info.macosSurface = true;
                 }
+                if (IsExtensionName(extension, kExtensionNameKhrExternalMemoryCapabilities)) {
+                    info.externalMemoryCapabilities = true;
+                }
+                if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphoreCapabilities)) {
+                    info.externalSemaphoreCapabilities = true;
+                }
+                if (IsExtensionName(extension, kExtensionNameKhrGetPhysicalDeviceProperties2)) {
+                    info.getPhysicalDeviceProperties2 = true;
+                }
                 if (IsExtensionName(extension, kExtensionNameKhrSurface)) {
                     info.surface = true;
                 }
@@ -224,7 +243,18 @@
                 if (IsExtensionName(extension, kExtensionNameExtDebugMarker)) {
                     info.debugMarker = true;
                 }
-
+                if (IsExtensionName(extension, kExtensionNameKhrExternalMemory)) {
+                    info.externalMemory = true;
+                }
+                if (IsExtensionName(extension, kExtensionNameKhrExternalMemoryFD)) {
+                    info.externalMemoryFD = true;
+                }
+                if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphore)) {
+                    info.externalSemaphore = true;
+                }
+                if (IsExtensionName(extension, kExtensionNameKhrExternalSemaphoreFD)) {
+                    info.externalSemaphoreFD = true;
+                }
                 if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) {
                     info.swapchain = true;
                 }
diff --git a/src/dawn_native/vulkan/VulkanInfo.h b/src/dawn_native/vulkan/VulkanInfo.h
index 168f677..48bcd9a 100644
--- a/src/dawn_native/vulkan/VulkanInfo.h
+++ b/src/dawn_native/vulkan/VulkanInfo.h
@@ -32,6 +32,13 @@
     extern const char kExtensionNameExtDebugMarker[];
     extern const char kExtensionNameExtDebugReport[];
     extern const char kExtensionNameMvkMacosSurface[];
+    extern const char kExtensionNameKhrExternalMemory[];
+    extern const char kExtensionNameKhrExternalMemoryCapabilities[];
+    extern const char kExtensionNameKhrExternalMemoryFD[];
+    extern const char kExtensionNameKhrExternalSemaphore[];
+    extern const char kExtensionNameKhrExternalSemaphoreCapabilities[];
+    extern const char kExtensionNameKhrExternalSemaphoreFD[];
+    extern const char kExtensionNameKhrGetPhysicalDeviceProperties2[];
     extern const char kExtensionNameKhrSurface[];
     extern const char kExtensionNameKhrSwapchain[];
     extern const char kExtensionNameKhrWaylandSurface[];
@@ -48,6 +55,9 @@
 
         // Extensions
         bool debugReport = false;
+        bool externalMemoryCapabilities = false;
+        bool externalSemaphoreCapabilities = false;
+        bool getPhysicalDeviceProperties2 = false;
         bool macosSurface = false;
         bool surface = false;
         bool waylandSurface = false;
@@ -69,6 +79,10 @@
 
         // Extensions
         bool debugMarker = false;
+        bool externalMemory = false;
+        bool externalMemoryFD = false;
+        bool externalSemaphore = false;
+        bool externalSemaphoreFD = false;
         bool swapchain = false;
     };