Merge pull request #22732 from hrydgard/moltenvk-portability

Vulkan: MoltenVK portability fixes (loader on Mac, portability subset features)
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-10-22 19:13:22 +02:00
commit ac8976fc71
2 files changed
+29

No files matched your search

+19
View File
@@ -239,6 +239,15 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
#if PPSSPP_VK_STATIC
inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#elif PPSSPP_PLATFORM(MAC)
// Through the Khronos loader (like the SDK's, for the validation layers), MoltenVK is only
// listed if we ask for portability drivers.
if (IsInstanceExtensionAvailable(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) {
instance_extensions_enabled_.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
inst_info.enabledExtensionCount = (uint32_t)instance_extensions_enabled_.size();
inst_info.ppEnabledExtensionNames = instance_extensions_enabled_.data();
inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
#if SIMULATE_VULKAN_FAILURE == 2
@@ -880,6 +889,13 @@ VkResult VulkanContext::CreateDevice(int physical_device, const std::vector<cons
deviceFeatures_.enabled.scalarBlockLayout.scalarBlockLayout = deviceFeatures_.available.scalarBlockLayout.scalarBlockLayout;
}
// What MoltenVK can do of what full Vulkan can (like image view swizzles). Using any of it needs it enabled.
deviceFeatures_.enabled.portabilitySubset = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR };
if (extensionsLookup_.KHR_portability_subset) {
deviceFeatures_.enabled.portabilitySubset = deviceFeatures_.available.portabilitySubset;
deviceFeatures_.enabled.portabilitySubset.pNext = nullptr;
}
// deviceFeatures_.enabled.multiview.multiviewGeometryShader = deviceFeatures_.available.multiview.multiviewGeometryShader;
VkPhysicalDeviceFeatures2 features2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
@@ -911,6 +927,9 @@ VkResult VulkanContext::CreateDevice(int physical_device, const std::vector<cons
if (extensionsLookup_.KHR_present_mode_fifo_latest_ready) {
ChainStruct(features2, &deviceFeatures_.enabled.presentModeFifoProps);
}
if (extensionsLookup_.KHR_portability_subset) {
ChainStruct(features2, &deviceFeatures_.enabled.portabilitySubset);
}
} else {
device_info.pEnabledFeatures = &deviceFeatures_.enabled.standard;
}
+10
View File
@@ -494,6 +494,7 @@ bool VulkanMayBeAvailable() {
std::vector<VkPhysicalDevice> devices;
bool anyGood = false;
const char *instanceExtensions[10]{};
bool portabilityFound = false;
VkInstance instance = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
uint32_t physicalDeviceCount = 0;
@@ -544,6 +545,11 @@ bool VulkanMayBeAvailable() {
platformSurfaceExtensionFound = true;
// Note: Can't stop here - the enumeration order isn't specified anywhere, so VK_KHR_surface
// may well come after the platform one, and we need both.
#if PPSSPP_PLATFORM(MAC)
} else if (!strcmp(iter.extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) {
// See VulkanContext::CreateInstance.
portabilityFound = true;
#endif
} else if (!strcmp(iter.extensionName, VK_KHR_SURFACE_EXTENSION_NAME)) {
instanceExtensions[ci.enabledExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
surfaceExtensionFound = true;
@@ -576,6 +582,10 @@ bool VulkanMayBeAvailable() {
info.pEngineName = "VulkanCheckerEngine";
ci.pApplicationInfo = &info;
ci.flags = 0;
if (portabilityFound) {
instanceExtensions[ci.enabledExtensionCount++] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
ci.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
INFO_LOG(Log::G3D, "VulkanMayBeAvailable: Calling vkCreateInstance");
res = localCreateInstance(&ci, nullptr, &instance);
if (res != VK_SUCCESS) {