Macos ios fixes (#1192)

* Configure MoltenVK to use a dedicated compute queue for compute[*] examples with sync barriers

* Modify descriptorindexing example for iOS and variable descriptor count limitations on MoltenVK

* Remove obsolete macOS #ifdefs no longer needed for modern MoltenVK versions

* Update iOS project to fix missing vkloader.c reference and revise example list

* Set required features and API version for VVL in debugprintf example

* Remove unnecessary Apple-specific code from descriptorindexing example

* Add Layer Settings capability to VulkanExampleBase::createInstance()

* Replace setenv() in examples with Layer Settings configuration for macOS/iOS

* Update comments in examples.h and fix missing initializer in computeraytracing example

* Update imgui overlay and example to support iOS Simulator

* Update more comments in examples.h and remove redundant initializers in deferred* examples

* Separate variable descriptor count declarations for apple and non-apple platforms

* Consolidate variable descriptor count declarations for apple vs. non-apple platforms

* Configure MoltenVK with a dedicated compute queue in VulkanExampleBase() and remove from samples
This commit is contained in:
SRSaunders 2025-03-29 11:21:37 -04:00 committed by GitHub
parent e1c962289f
commit 9a562a5426
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 221 additions and 83 deletions

View file

@ -270,17 +270,6 @@ void VulkanSwapChain::create(uint32_t& width, uint32_t& height, bool vsync, bool
// Determine the number of images
uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
#if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_EXAMPLE_XCODE_GENERATED)
// SRS - Work around known MoltenVK issue re 2x frame rate when vsync (VK_PRESENT_MODE_FIFO_KHR) enabled
struct utsname sysInfo;
uname(&sysInfo);
// SRS - When vsync is on, use minImageCount when not in fullscreen or when running on Apple Silcon
// This forces swapchain image acquire frame rate to match display vsync frame rate
if (vsync && (!fullscreen || strcmp(sysInfo.machine, "arm64") == 0))
{
desiredNumberOfSwapchainImages = surfCaps.minImageCount;
}
#endif
if ((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount))
{
desiredNumberOfSwapchainImages = surfCaps.maxImageCount;

View file

@ -405,7 +405,13 @@ namespace vks
vkCmdDrawIndexed(commandBuffer, pcmd->ElemCount, 1, indexOffset, vertexOffset, 0);
indexOffset += pcmd->ElemCount;
}
#if (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && TARGET_OS_SIMULATOR
// Apple Device Simulator does not support vkCmdDrawIndexed() with vertexOffset > 0, so rebind vertex buffer instead
offsets[0] += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.buffer, offsets);
#else
vertexOffset += cmd_list->VtxBuffer.Size;
#endif
}
}

View file

@ -28,6 +28,10 @@
#include "VulkanAndroid.h"
#endif
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
namespace vks
{
class UIOverlay

View file

@ -111,7 +111,7 @@ VkResult VulkanExampleBase::createInstance()
if (std::find(supportedInstanceExtensions.begin(), supportedInstanceExtensions.end(), VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) != supportedInstanceExtensions.end())
{
instanceExtensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
instanceCreateInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
@ -148,6 +148,18 @@ VkResult VulkanExampleBase::createInstance()
std::cerr << "Validation layer VK_LAYER_KHRONOS_validation not present, validation is disabled";
}
}
// If layer settings are defined, then activate the sample's required layer settings during instance creation.
// Layer settings are typically used to activate specific features of a layer, such as the Validation Layer's
// printf feature, or to configure specific capabilities of drivers such as MoltenVK on macOS and/or iOS.
VkLayerSettingsCreateInfoEXT layerSettingsCreateInfo{VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT};
if (enabledLayerSettings.size() > 0) {
layerSettingsCreateInfo.settingCount = static_cast<uint32_t>(enabledLayerSettings.size());
layerSettingsCreateInfo.pSettings = enabledLayerSettings.data();
layerSettingsCreateInfo.pNext = instanceCreateInfo.pNext;
instanceCreateInfo.pNext = &layerSettingsCreateInfo;
}
VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
// If the debug utils extension is present we set up debug functions, so samples can label objects for debugging
@ -853,6 +865,21 @@ VulkanExampleBase::VulkanExampleBase()
if(commandLineParser.isSet("resourcepath")) {
vks::tools::resourcePath = commandLineParser.getValueAsString("resourcepath", "");
}
#else
// On Apple platforms, use layer settings extension to configure MoltenVK with common project config settings
enabledInstanceExtensions.push_back(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME);
// Configure MoltenVK to use to use a dedicated compute queue (see compute[*] and timelinesemaphore samples)
VkLayerSettingEXT layerSetting;
layerSetting.pLayerName = "MoltenVK";
layerSetting.pSettingName = "MVK_CONFIG_SPECIALIZED_QUEUE_FAMILIES";
layerSetting.type = VK_LAYER_SETTING_TYPE_BOOL32_EXT;
layerSetting.valueCount = 1;
// Make this static so layer setting reference remains valid after leaving constructor scope
static const VkBool32 layerSettingOn = VK_TRUE;
layerSetting.pValues = &layerSettingOn;
enabledLayerSettings.push_back(layerSetting);
#endif
#if !defined(VK_USE_PLATFORM_ANDROID_KHR)

View file

@ -29,6 +29,8 @@
//
#elif defined(VK_USE_PLATFORM_XCB_KHR)
#include <xcb/xcb.h>
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT))
#include <TargetConditionals.h>
#endif
#include <stdio.h>
@ -114,7 +116,10 @@ protected:
VkPhysicalDeviceFeatures enabledFeatures{};
/** @brief Set of device extensions to be enabled for this example (must be set in the derived constructor) */
std::vector<const char*> enabledDeviceExtensions;
/** @brief Set of instance extensions to be enabled for this example (must be set in the derived constructor) */
std::vector<const char*> enabledInstanceExtensions;
/** @brief Set of layer settings to be enabled for this example (must be set in the derived constructor) */
std::vector<VkLayerSettingEXT> enabledLayerSettings;
/** @brief Optional pNext structure for passing extension structures to device creation */
void* deviceCreatepNextChain = nullptr;
/** @brief Logical device, application's view of the physical device (GPU) */