vulkan: Only enable KHR_portability_enumeration when available

This commit is contained in:
Ethan Lee
2026-02-20 10:31:53 -05:00
parent 1223767b2c
commit fa9bad2e4b
2 changed files with 71 additions and 11 deletions
+15 -7
View File
@@ -1171,6 +1171,7 @@ struct VulkanRenderer
bool supportsDebugUtils; bool supportsDebugUtils;
bool supportsColorspace; bool supportsColorspace;
bool supportsPhysicalDeviceProperties2; bool supportsPhysicalDeviceProperties2;
bool supportsPortabilityEnumeration;
bool supportsFillModeNonSolid; bool supportsFillModeNonSolid;
bool supportsMultiDrawIndirect; bool supportsMultiDrawIndirect;
@@ -11153,6 +11154,7 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
bool *supportsDebugUtils, bool *supportsDebugUtils,
bool *supportsColorspace, bool *supportsColorspace,
bool *supportsPhysicalDeviceProperties2, bool *supportsPhysicalDeviceProperties2,
bool *supportsPortabilityEnumeration,
int *firstUnsupportedExtensionIndex) int *firstUnsupportedExtensionIndex)
{ {
Uint32 extensionCount, i; Uint32 extensionCount, i;
@@ -11199,6 +11201,12 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
availableExtensions, availableExtensions,
extensionCount); extensionCount);
// Only needed for MoltenVK!
*supportsPortabilityEnumeration = SupportsInstanceExtension(
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
availableExtensions,
extensionCount);
SDL_free(availableExtensions); SDL_free(availableExtensions);
return allExtensionsSupported; return allExtensionsSupported;
} }
@@ -11824,13 +11832,6 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeat
nextInstanceExtensionNamePtr += extraInstanceExtensionCount; nextInstanceExtensionNamePtr += extraInstanceExtensionCount;
} }
#ifdef SDL_PLATFORM_APPLE
*nextInstanceExtensionNamePtr++ = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
instanceExtensionCount++;
createFlags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif
int firstUnsupportedExtensionIndex = 0; int firstUnsupportedExtensionIndex = 0;
if (!VULKAN_INTERNAL_CheckInstanceExtensions( if (!VULKAN_INTERNAL_CheckInstanceExtensions(
instanceExtensionNames, instanceExtensionNames,
@@ -11838,6 +11839,7 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeat
&renderer->supportsDebugUtils, &renderer->supportsDebugUtils,
&renderer->supportsColorspace, &renderer->supportsColorspace,
&renderer->supportsPhysicalDeviceProperties2, &renderer->supportsPhysicalDeviceProperties2,
&renderer->supportsPortabilityEnumeration,
&firstUnsupportedExtensionIndex)) { &firstUnsupportedExtensionIndex)) {
if (renderer->debugMode) { if (renderer->debugMode) {
SDL_LogError(SDL_LOG_CATEGORY_GPU, SDL_LogError(SDL_LOG_CATEGORY_GPU,
@@ -11873,6 +11875,12 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeat
instanceExtensionCount++; instanceExtensionCount++;
} }
if (renderer->supportsPortabilityEnumeration) {
*nextInstanceExtensionNamePtr++ = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
instanceExtensionCount++;
createFlags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pNext = NULL; createInfo.pNext = NULL;
createInfo.flags = createFlags; createInfo.flags = createFlags;
+56 -4
View File
@@ -218,22 +218,74 @@ static void loadGlobalFunctions(void)
#undef VULKAN_INSTANCE_FUNCTION #undef VULKAN_INSTANCE_FUNCTION
} }
static bool checkVulkanPortability(void)
{
Uint32 extensionCount, i;
VkExtensionProperties *availableExtensions;
bool supported = false;
vkEnumerateInstanceExtensionProperties(
NULL,
&extensionCount,
NULL);
availableExtensions = SDL_malloc(
extensionCount * sizeof(VkExtensionProperties));
vkEnumerateInstanceExtensionProperties(
NULL,
&extensionCount,
availableExtensions);
for (i = 0; i < extensionCount; i += 1) {
if (SDL_strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, availableExtensions[i].extensionName) == 0) {
supported = true;
break;
}
}
SDL_free(availableExtensions);
return supported;
}
static void createInstance(void) static void createInstance(void)
{ {
VkApplicationInfo appInfo = { 0 }; VkApplicationInfo appInfo = { 0 };
VkInstanceCreateInfo instanceCreateInfo = { 0 }; VkInstanceCreateInfo instanceCreateInfo = { 0 };
bool supportsPortabilityEnumeration;
const char **instanceExtensions;
VkResult result; VkResult result;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.apiVersion = VK_API_VERSION_1_0; appInfo.apiVersion = VK_API_VERSION_1_0;
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pApplicationInfo = &appInfo; instanceCreateInfo.pApplicationInfo = &appInfo;
#ifdef __APPLE__
instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif
instanceCreateInfo.ppEnabledExtensionNames = SDL_Vulkan_GetInstanceExtensions(&instanceCreateInfo.enabledExtensionCount); supportsPortabilityEnumeration = checkVulkanPortability();
if (supportsPortabilityEnumeration) {
// Allocate our own extension array so that we can add the KHR_portability extensions for MoltenVK
Uint32 count_instance_extensions;
const char * const *instance_extensions = SDL_Vulkan_GetInstanceExtensions(&count_instance_extensions);
int count_extensions = count_instance_extensions + 1;
instanceExtensions = SDL_malloc(count_extensions * sizeof(const char *));
instanceExtensions[0] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
SDL_memcpy(&instanceExtensions[1], instance_extensions, count_instance_extensions * sizeof(const char*));
instanceCreateInfo.enabledExtensionCount = count_extensions;
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions;
instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
} else {
// No need to allocate anything, just use SDL's array directly
instanceExtensions = NULL;
instanceCreateInfo.ppEnabledExtensionNames =
SDL_Vulkan_GetInstanceExtensions(&instanceCreateInfo.enabledExtensionCount);
}
result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext->instance); result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext->instance);
if (instanceExtensions != NULL) {
SDL_free(instanceExtensions);
}
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
vulkanContext->instance = VK_NULL_HANDLE; vulkanContext->instance = VK_NULL_HANDLE;
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,