Fix a gfxstream crash when RenderDoc is used on Vulkan-on-Vulkan apps.

Also, replace a bunch of raw extension names with constants.

Change-Id: I941deb54f2bc89f36ff4c76eb07a2a60ef44b226
diff --git a/stream-servers/vulkan/VkCommonOperations.cpp b/stream-servers/vulkan/VkCommonOperations.cpp
index e2d61d8..af413f4 100644
--- a/stream-servers/vulkan/VkCommonOperations.cpp
+++ b/stream-servers/vulkan/VkCommonOperations.cpp
@@ -501,18 +501,18 @@
     auto gvk = vk;
 
     std::vector<const char*> externalMemoryInstanceExtNames = {
-        "VK_KHR_external_memory_capabilities",
-        "VK_KHR_get_physical_device_properties2",
+        VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
     };
 
     std::vector<const char*> externalMemoryDeviceExtNames = {
-        "VK_KHR_dedicated_allocation",
-        "VK_KHR_get_memory_requirements2",
-        "VK_KHR_external_memory",
+        VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
+        VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
+        VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
 #ifdef _WIN32
-        "VK_KHR_external_memory_win32",
+        VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
 #else
-        "VK_KHR_external_memory_fd",
+        VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
 #endif
     };
 
diff --git a/stream-servers/vulkan/VkDecoderGlobalState.cpp b/stream-servers/vulkan/VkDecoderGlobalState.cpp
index 8eeda8e..6d1b2ef 100644
--- a/stream-servers/vulkan/VkDecoderGlobalState.cpp
+++ b/stream-servers/vulkan/VkDecoderGlobalState.cpp
@@ -91,16 +91,15 @@
     "VK_FUCHSIA_buffer_collection",
     "VK_FUCHSIA_external_memory",
     "VK_FUCHSIA_external_semaphore",
-    "VK_EXT_queue_family_foreign",
-    "VK_KHR_external_memory",
-    "VK_KHR_external_memory_capabilities",
-    "VK_KHR_external_semaphore",
-    "VK_KHR_external_semaphore_capabilities",
-    "VK_KHR_external_semaphore_fd",
-    "VK_KHR_external_semaphore_win32",
-    "VK_KHR_external_fence_capabilities",
-    "VK_KHR_external_fence",
-    "VK_KHR_external_fence_fd",
+    VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
+    VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME,
 };
 
 static constexpr uint32_t kMaxSafeVersion = VK_MAKE_VERSION(1, 1, 0);
@@ -706,7 +705,8 @@
         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
             vk->vkGetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
-        } else if (hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2")) {
+        } else if (hasInstanceExtension(instance,
+                                        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
             vk->vkGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
         } else {
             // No instance extension, fake it!!!!
@@ -811,7 +811,7 @@
                 physicalDevice, pImageFormatInfo, pImageFormatProperties);
         } else if (hasInstanceExtension(
                     instance,
-                    "VK_KHR_get_physical_device_properties2")) {
+                    VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
             res = vk->vkGetPhysicalDeviceImageFormatProperties2KHR(
                 physicalDevice, pImageFormatInfo, pImageFormatProperties);
         } else {
@@ -895,7 +895,7 @@
                     vk, physicalDevice, format, pFormatProperties);
         } else if (hasInstanceExtension(
                     instance,
-                    "VK_KHR_get_physical_device_properties2")) {
+                    VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
             getPhysicalDeviceFormatPropertiesCore<VkFormatProperties2>(
                     [vk](VkPhysicalDevice physicalDevice, VkFormat format,
                         VkFormatProperties2* pFormatProperties) {
@@ -961,7 +961,8 @@
         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
             vk->vkGetPhysicalDeviceProperties2(physicalDevice, pProperties);
-        } else if (hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2")) {
+        } else if (hasInstanceExtension(instance,
+                                        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
             vk->vkGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
         } else {
             // No instance extension, fake it!!!!
@@ -1034,7 +1035,8 @@
         if (instanceInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0) &&
             physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
             vk->vkGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties);
-        } else if (hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2")) {
+        } else if (hasInstanceExtension(instance,
+                                        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
             vk->vkGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties);
         } else {
             // No instance extension, fake it!!!!
@@ -1090,24 +1092,13 @@
         // If MoltenVK is supported on host, we need to ensure that we include
         // VK_MVK_moltenvk extenstion in returned properties.
         std::vector<VkExtensionProperties> properties;
-        uint32_t propertyCount = 0u;
-        VkResult result = vk->vkEnumerateDeviceExtensionProperties(
-            physicalDevice, pLayerName, &propertyCount, nullptr);
+        VkResult result =
+            enumerateDeviceExtensionProperties(vk, physicalDevice, pLayerName, properties);
         if (result != VK_SUCCESS) {
             return result;
         }
 
-        properties.resize(propertyCount);
-        result = vk->vkEnumerateDeviceExtensionProperties(
-            physicalDevice, pLayerName, &propertyCount, properties.data());
-        if (result != VK_SUCCESS) {
-            return result;
-        }
-
-        if (std::find_if(properties.begin(), properties.end(),
-            [](const VkExtensionProperties& props) {
-                return strcmp(props.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME) == 0;
-            }) == properties.end()) {
+        if (!hasDeviceExtension(properties, VK_MVK_MOLTENVK_EXTENSION_NAME)) {
             VkExtensionProperties mvk_props;
             strncpy(mvk_props.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME,
                     sizeof(mvk_props.extensionName));
@@ -1143,6 +1134,14 @@
                     pCreateInfo->enabledExtensionCount,
                     pCreateInfo->ppEnabledExtensionNames);
 
+#ifdef _WIN32
+        // Always request VK_KHR_external_semaphore_win32 if it's supported. This fixes a crash
+        // when RenderDoc is used on Vulkan-on-Vulkan apps.
+        if (isExternalSemaphoreWin32Supported(vk, physicalDevice)) {
+            finalExts.push_back(VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME);
+        }
+#endif
+
         // Run the underlying API call, filtering extensions.
         VkDeviceCreateInfo createInfoFiltered = *pCreateInfo;
         bool emulateTextureEtc2 = false;
@@ -2685,12 +2684,9 @@
 
         if ((physdevInfo->props.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) &&
             vk->vkGetImageMemoryRequirements2) {
-            vk->vkGetImageMemoryRequirements2(device, pInfo,
-                    pMemoryRequirements);
-        } else if (hasDeviceExtension(device,
-                    "VK_KHR_get_memory_requirements2")) {
-            vk->vkGetImageMemoryRequirements2KHR(device, pInfo,
-                    pMemoryRequirements);
+            vk->vkGetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
+        } else if (hasDeviceExtension(device, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
+            vk->vkGetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
         } else {
             if (pInfo->pNext) {
                 fprintf(stderr,
@@ -3506,6 +3502,41 @@
         return false;
     }
 
+    // Returns whether a vector of VkExtensionProperties contains a particular extension
+    bool hasDeviceExtension(const std::vector<VkExtensionProperties>& properties,
+                            const char* name) {
+        for (const auto& prop : properties) {
+            if (strcmp(prop.extensionName, name) == 0) return true;
+        }
+        return false;
+    }
+
+    // Convenience function to call vkEnumerateDeviceExtensionProperties and get the results as an
+    // std::vector
+    VkResult enumerateDeviceExtensionProperties(VulkanDispatch* vk, VkPhysicalDevice physicalDevice,
+                                                const char* pLayerName,
+                                                std::vector<VkExtensionProperties>& properties) {
+        uint32_t propertyCount = 0;
+        VkResult result = vk->vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName,
+                                                                   &propertyCount, nullptr);
+        if (result != VK_SUCCESS) return result;
+
+        properties.resize(propertyCount);
+        return vk->vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, &propertyCount,
+                                                        properties.data());
+    }
+
+#ifdef _WIN32
+    bool isExternalSemaphoreWin32Supported(VulkanDispatch* vk, VkPhysicalDevice physicalDevice) {
+        std::vector<VkExtensionProperties> properties;
+        VkResult result =
+            enumerateDeviceExtensionProperties(vk, physicalDevice, nullptr, properties);
+        if (result != VK_SUCCESS) return false;
+
+        return hasDeviceExtension(properties, VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME);
+    }
+#endif
+
     // VK_ANDROID_native_buffer
     VkResult on_vkGetSwapchainGrallocUsageANDROID(
             android::base::BumpPool* pool,
@@ -5142,33 +5173,31 @@
                 if (m_emu->instanceSupportsMoltenVK) {
                     continue;
                 }
-                if (!strcmp("VK_KHR_external_memory_capabilities", extName)) {
-                    res.push_back("VK_KHR_external_memory_capabilities");
+                if (!strcmp(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, extName)) {
+                    res.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
                 }
-                if (!strcmp("VK_KHR_external_memory", extName)) {
-                    res.push_back("VK_KHR_external_memory");
+                if (!strcmp(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, extName)) {
+                    res.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
                 }
-                if (!strcmp("VK_KHR_external_semaphore_capabilities", extName)) {
-                    res.push_back("VK_KHR_external_semaphore_capabilities");
+                if (!strcmp(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, extName)) {
+                    res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
                 }
-                if (!strcmp("VK_KHR_external_semaphore", extName)) {
-                    res.push_back("VK_KHR_external_semaphore");
+                if (!strcmp(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, extName)) {
+                    res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
                 }
                 if (!strcmp("VK_ANDROID_external_memory_android_hardware_buffer", extName) ||
                     !strcmp("VK_FUCHSIA_external_memory", extName)) {
 #ifdef _WIN32
-                    res.push_back("VK_KHR_external_memory_win32");
+                    res.push_back(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
 #else
-                    res.push_back("VK_KHR_external_memory_fd");
+                    res.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
 #endif
                 }
-                // External semaphore maps to the win32 version on windows,
-                // continues with external semaphore fd on non-windows
-                if (!strcmp("VK_KHR_external_semaphore_fd", extName)) {
-#ifdef _WIN32
-                    res.push_back("VK_KHR_external_semaphore_win32");
-#else
-                    res.push_back("VK_KHR_external_semaphore_fd");
+                // External semaphore - non-Windows case is handled here
+                // Windows case is handled in on_vkCreateDevice
+                if (!strcmp(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, extName)) {
+#ifndef _WIN32
+                    res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
 #endif
                 }
             }