vulkan-cereal: refactor instance/device filtering
- Separate out instance and device extension filtering
- Use the global VK instance to determine whether to request
external and semaphore capabilities (even on MoltenVK)
- Always request external memory (both guest AHB and Fuchsia
buffer collection required)
- Always request filtered device extensions when available
BUG=235485545
TEST=compile and run
Change-Id: I840107d8c9b5e077054a673fff59d99b3eeb53bc
diff --git a/stream-servers/vulkan/VkCommonOperations.cpp b/stream-servers/vulkan/VkCommonOperations.cpp
index b192bc2..18a7d52 100644
--- a/stream-servers/vulkan/VkCommonOperations.cpp
+++ b/stream-servers/vulkan/VkCommonOperations.cpp
@@ -517,6 +517,10 @@
#endif
};
+ std::vector<const char*> externalSemaphoreInstanceExtNames = {
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
+ };
+
uint32_t extCount = 0;
gvk->vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
std::vector<VkExtensionProperties>& exts = sVkEmulation->instanceExtensions;
@@ -525,6 +529,8 @@
bool externalMemoryCapabilitiesSupported =
extensionsSupported(exts, externalMemoryInstanceExtNames);
+ bool externalSemaphoreCapabilitiesSupported =
+ extensionsSupported(exts, externalSemaphoreInstanceExtNames);
bool moltenVKSupported =
(vk->vkGetMTLTextureMVK != nullptr) && (vk->vkSetMTLTextureMVK != nullptr);
@@ -633,6 +639,7 @@
sVkEmulation->vulkanInstanceVersion = appInfo.apiVersion;
sVkEmulation->instanceSupportsExternalMemoryCapabilities = externalMemoryCapabilitiesSupported;
+ sVkEmulation->instanceSupportsExternalSemaphoreCapabilities = externalSemaphoreCapabilitiesSupported;
sVkEmulation->instanceSupportsMoltenVK = moltenVKSupported;
if (sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
diff --git a/stream-servers/vulkan/VkCommonOperations.h b/stream-servers/vulkan/VkCommonOperations.h
index 7b91809..c9c73cf 100644
--- a/stream-servers/vulkan/VkCommonOperations.h
+++ b/stream-servers/vulkan/VkCommonOperations.h
@@ -103,6 +103,7 @@
VulkanDispatch* dvk = nullptr;
bool instanceSupportsExternalMemoryCapabilities = false;
+ bool instanceSupportsExternalSemaphoreCapabilities = false;
PFN_vkGetPhysicalDeviceImageFormatProperties2KHR getImageFormatProperties2Func = nullptr;
PFN_vkGetPhysicalDeviceProperties2KHR getPhysicalDeviceProperties2Func = nullptr;
PFN_vkGetPhysicalDeviceFeatures2 getPhysicalDeviceFeatures2Func = nullptr;
diff --git a/stream-servers/vulkan/VkDecoderGlobalState.cpp b/stream-servers/vulkan/VkDecoderGlobalState.cpp
index 46285fd..a813558 100644
--- a/stream-servers/vulkan/VkDecoderGlobalState.cpp
+++ b/stream-servers/vulkan/VkDecoderGlobalState.cpp
@@ -88,9 +88,9 @@
namespace goldfish_vk {
-// A list of extensions that should not be passed to the host driver.
+// A list of device extensions that should not be passed to the host driver.
// These will mainly include Vulkan features that we emulate ourselves.
-static constexpr const char* const kEmulatedExtensions[] = {
+static constexpr const char* const kEmulatedDeviceExtensions[] = {
"VK_ANDROID_external_memory_android_hardware_buffer",
"VK_ANDROID_native_buffer",
"VK_FUCHSIA_buffer_collection",
@@ -98,13 +98,19 @@
"VK_FUCHSIA_external_semaphore",
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,
+ VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
+};
+
+// A list of instance extensions that should not be passed to the host driver.
+// On older pre-1.1 Vulkan platforms, gfxstream emulates these features.
+static constexpr const char* const kEmulatedInstanceExtensions[] = {
+ VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
};
static constexpr uint32_t kMaxSafeVersion = VK_MAKE_VERSION(1, 1, 0);
@@ -387,7 +393,7 @@
VkResult on_vkCreateInstance(android::base::BumpPool* pool,
const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
- std::vector<const char*> finalExts = filteredExtensionNames(
+ std::vector<const char*> finalExts = filteredInstanceExtensionNames(
pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
INFO("Creating Vulkan instance for app: %s engine: %s",
@@ -1139,17 +1145,9 @@
auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
- std::vector<const char*> finalExts = filteredExtensionNames(
+ std::vector<const char*> finalExts = filteredDeviceExtensionNames(vk, physicalDevice,
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;
// According to the spec, it seems that the application can use compressed texture formats
@@ -3500,17 +3498,6 @@
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, VkDevice,
VkFormat format, VkImageUsageFlags imageUsage,
@@ -5220,13 +5207,16 @@
VkDecoderSnapshot* snapshot() { return &mSnapshot; }
private:
- bool isEmulatedExtension(const char* name) const {
- for (auto emulatedExt : kEmulatedExtensions) {
+ bool isEmulatedInstanceExtension(const char *name) const {
+ for (auto emulatedExt : kEmulatedInstanceExtensions) {
if (!strcmp(emulatedExt, name)) return true;
}
- if (!strcmp(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, name)) {
- return !m_emu->deviceInfo.hasSamplerYcbcrConversionExtension &&
- m_emu->enableYcbcrEmulation;
+ return false;
+ }
+
+ bool isEmulatedDeviceExtension(const char* name) const {
+ for (auto emulatedExt : kEmulatedDeviceExtensions) {
+ if (!strcmp(emulatedExt, name)) return true;
}
return false;
}
@@ -5238,46 +5228,82 @@
return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(type == VK_IMAGE_TYPE_1D);
}
- std::vector<const char*> filteredExtensionNames(uint32_t count, const char* const* extNames) {
+ std::vector<const char*> filteredDeviceExtensionNames(VulkanDispatch* vk, VkPhysicalDevice physicalDevice,
+ uint32_t count, const char* const* extNames) {
std::vector<const char*> res;
+ std::vector<VkExtensionProperties> properties;
+ VkResult result;
+
for (uint32_t i = 0; i < count; ++i) {
auto extName = extNames[i];
- if (!isEmulatedExtension(extName)) {
+ if (!isEmulatedDeviceExtension(extName)) {
res.push_back(extName);
continue;
}
- if (m_emu->instanceSupportsMoltenVK) {
- continue;
- }
- 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_EXTENSION_NAME, extName)) {
- res.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
- }
- 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_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)) {
+ }
+
+ result = enumerateDeviceExtensionProperties(vk, physicalDevice, nullptr, properties);
+ if (result != VK_SUCCESS) {
+ VKDGS_LOG("failed to enumerate device extensions");
+ return res;
+ }
+
+ if (hasDeviceExtension(properties, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
+ }
+
+ if (hasDeviceExtension(properties, VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
+ }
+
+ if (hasDeviceExtension(properties, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
+
+ }
+
#ifdef _WIN32
- res.push_back(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
-#else
- res.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
+ if (hasDeviceExtension(properties, VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
+ }
+
+ if (hasDeviceExtension(properties, VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME);
+ }
+#elif __unix__
+ if (hasDeviceExtension(properties, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
+ }
+
+ if (hasDeviceExtension(properties, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME)) {
+ res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
+ }
#endif
- }
- // 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);
+
+#ifdef __linux__
+ if (hasDeviceExtension(properties, VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME)) {
+ res.push_back(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
+ }
#endif
+ return res;
+ }
+
+ std::vector<const char*> filteredInstanceExtensionNames(uint32_t count, const char* const* extNames) {
+ std::vector<const char*> res;
+ for (uint32_t i = 0; i < count; ++i) {
+ auto extName = extNames[i];
+ if (!isEmulatedInstanceExtension(extName)) {
+ res.push_back(extName);
}
}
+ if (m_emu->instanceSupportsExternalMemoryCapabilities) {
+ res.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
+ }
+
+ if (m_emu->instanceSupportsExternalSemaphoreCapabilities) {
+ res.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
+ }
+
return res;
}