From a3f571e89ba967e12c405b10ea3c374fa6808e97 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 2 Oct 2018 12:48:51 -0400 Subject: [PATCH 1/5] Include version number in VK_MVK_moltenvk extension functions that pass structs that might change. --- Docs/Whats_New.md | 1 + MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h | 75 +++++++++++++++------ MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm | 71 ++++++++++++------- 3 files changed, 104 insertions(+), 43 deletions(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 1b80ce41..c87f8fc0 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -17,6 +17,7 @@ MoltenVK 1.0.24 Released TBD +- Include version number in VK_MVK_moltenvk extension functions that pass structs that might change. - Allocate MVKDescriptorSets from a pool within MVKDescriptorPool, diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index 9583b200..3c0f2e87 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -54,7 +54,7 @@ extern "C" { #define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH) -#define VK_MVK_MOLTENVK_SPEC_VERSION 10 +#define VK_MVK_MOLTENVK_SPEC_VERSION 11 #define VK_MVK_MOLTENVK_EXTENSION_NAME "VK_MVK_moltenvk" /** @@ -307,11 +307,11 @@ typedef struct { #pragma mark - #pragma mark Function types -typedef void (VKAPI_PTR *PFN_vkGetMoltenVKConfigurationMVK)(VkDevice device, MVKConfiguration* pConfiguration); -typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKConfigurationMVK)(VkDevice device, MVKConfiguration* pConfiguration); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMetalFeaturesMVK)(VkPhysicalDevice physicalDevice, MVKPhysicalDeviceMetalFeatures* pMetalFeatures); -typedef void (VKAPI_PTR *PFN_vkGetSwapchainPerformanceMVK)(VkDevice device, VkSwapchainKHR swapchain, MVKSwapchainPerformance* pSwapchainPerf); -typedef void (VKAPI_PTR *PFN_vkGetPerformanceStatisticsMVK)(VkDevice device, MVKPerformanceStatistics* pPerf); +typedef VkResult (VKAPI_PTR *PFN_vkGetMoltenVKConfigurationMVK)(uint32_t mvkSpecVersion, VkDevice device, MVKConfiguration* pConfiguration); +typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKConfigurationMVK)(uint32_t mvkSpecVersion, VkDevice device, MVKConfiguration* pConfiguration); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceMetalFeaturesMVK)(uint32_t mvkSpecVersion, VkPhysicalDevice physicalDevice, MVKPhysicalDeviceMetalFeatures* pMetalFeatures); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainPerformanceMVK)(uint32_t mvkSpecVersion, VkDevice device, VkSwapchainKHR swapchain, MVKSwapchainPerformance* pSwapchainPerf); +typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceStatisticsMVK)(uint32_t mvkSpecVersion, VkDevice device, MVKPerformanceStatistics* pPerf); typedef void (VKAPI_PTR *PFN_vkGetVersionStringsMVK)(char* pMoltenVersionStringBuffer, uint32_t moltenVersionStringBufferLength, char* pVulkanVersionStringBuffer, uint32_t vulkanVersionStringBufferLength); #ifdef __OBJC__ @@ -322,7 +322,7 @@ typedef VkResult (VKAPI_PTR *PFN_vkUseIOSurfaceMVK)(VkImage image, IOSurfaceRef typedef void (VKAPI_PTR *PFN_vkGetIOSurfaceMVK)(VkImage image, IOSurfaceRef* pIOSurface); #endif // __OBJC__ -// Deprecated functions +// Deprecated functions. These do nothing now. typedef MVKConfiguration MVKDeviceConfiguration; __attribute__((deprecated("Use PFN_vkGetMoltenVKConfigurationMVK instead."))) typedef void (VKAPI_PTR *PFN_vkGetMoltenVKDeviceConfigurationMVK)(VkDevice device, MVKConfiguration* pConfiguration); @@ -344,10 +344,17 @@ typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKDeviceConfigurationMVK)(VkDevice d * * To be active, some configuration settings must be set before a VkDevice is created. * See the description of the MVKConfiguration members for more information. + * + * To ensure passing compatible memory structures, mvkSpecVersion must be set to the + * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise + * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. + * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the + * version of this header file included in the MoltenVK build to which you will link your app. */ -VKAPI_ATTR void VKAPI_CALL vkGetMoltenVKConfigurationMVK( - VkInstance instance, - MVKConfiguration* pConfiguration); +VKAPI_ATTR VkResult VKAPI_CALL vkGetMoltenVKConfigurationMVK( + uint32_t mvkSpecVersion, + VkInstance instance, + MVKConfiguration* pConfiguration); /** * Sets the MoltenVK configuration settings to those found in the pConfiguration structure. @@ -358,35 +365,63 @@ VKAPI_ATTR void VKAPI_CALL vkGetMoltenVKConfigurationMVK( * * To be active, some configuration settings must be set before a VkDevice is created. * See the description of the MVKConfiguration members for more information. + * + * To ensure passing compatible memory structures, mvkSpecVersion must be set to the + * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise + * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. + * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the + * version of this header file included in the MoltenVK build to which you will link your app. */ VKAPI_ATTR VkResult VKAPI_CALL vkSetMoltenVKConfigurationMVK( - VkInstance instance, - MVKConfiguration* pConfiguration); + uint32_t mvkSpecVersion, + VkInstance instance, + MVKConfiguration* pConfiguration); /** * Populates the pMetalFeatures structure with the Metal-specific features * supported by the specified physical device. + * + * To ensure passing compatible memory structures, mvkSpecVersion must be set to the + * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise + * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. + * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the + * version of this header file included in the MoltenVK build to which you will link your app. */ -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMetalFeaturesMVK( +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceMetalFeaturesMVK( + uint32_t mvkSpecVersion, VkPhysicalDevice physicalDevice, MVKPhysicalDeviceMetalFeatures* pMetalFeatures); /** * Populates the specified MVKSwapchainPerformance structure with * the current performance statistics for the specified swapchain. + * + * To ensure passing compatible memory structures, mvkSpecVersion must be set to the + * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise + * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. + * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the + * version of this header file included in the MoltenVK build to which you will link your app. */ -VKAPI_ATTR void VKAPI_CALL vkGetSwapchainPerformanceMVK( - VkDevice device, - VkSwapchainKHR swapchain, - MVKSwapchainPerformance* pSwapchainPerf); +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainPerformanceMVK( + uint32_t mvkSpecVersion, + VkDevice device, + VkSwapchainKHR swapchain, + MVKSwapchainPerformance* pSwapchainPerf); /** * Populates the specified MVKPerformanceStatistics structure with * the current performance statistics for the specified device. + * + * To ensure passing compatible memory structures, mvkSpecVersion must be set to the + * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise + * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. + * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the + * version of this header file included in the MoltenVK build to which you will link your app. */ -VKAPI_ATTR void VKAPI_CALL vkGetPerformanceStatisticsMVK( - VkDevice device, - MVKPerformanceStatistics* pPerf); +VKAPI_ATTR VkResult VKAPI_CALL vkGetPerformanceStatisticsMVK( + uint32_t mvkSpecVersion, + VkDevice device, + MVKPerformanceStatistics* pPerf); /** * Returns a human readable version of the MoltenVK and Vulkan versions. diff --git a/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm b/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm index cc6bbfb4..a48ff2ab 100644 --- a/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm +++ b/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm @@ -26,46 +26,76 @@ using namespace std; +// Validate the VK_MVK_moltenvk spec version to avoid passing incompatible memory structures +#define MVK_VALIDATE_SPEC_VERSION(mvkSpecVer, cmdName) \ + do { \ + if (mvkSpecVer != VK_MVK_MOLTENVK_SPEC_VERSION) { \ + const char* errMsg = "%s(): This version of MoltenVK supports VK_MVK_moltenvk extension version %d." \ + " You are using version %d." \ + " The memory structures used in this function may be incompatible between the two versions."; \ + return mvkNotifyErrorWithText(VK_ERROR_INCOMPATIBLE_DRIVER, errMsg, cmdName, VK_MVK_MOLTENVK_SPEC_VERSION, mvkSpecVer); \ + } \ + } while(0) -MVK_PUBLIC_SYMBOL void vkGetMoltenVKConfigurationMVK( - VkInstance instance, - MVKConfiguration* pConfiguration) { + +MVK_PUBLIC_SYMBOL VkResult vkGetMoltenVKConfigurationMVK( + uint32_t mvkSpecVersion, + VkInstance instance, + MVKConfiguration* pConfiguration) { + + MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetMoltenVKConfigurationMVK"); MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance); if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkInst->getMoltenVKConfiguration(); } + return VK_SUCCESS; } MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKConfigurationMVK( - VkInstance instance, - MVKConfiguration* pConfiguration) { + uint32_t mvkSpecVersion, + VkInstance instance, + MVKConfiguration* pConfiguration) { + + MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkSetMoltenVKConfigurationMVK"); MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance); if (pConfiguration) { mvkInst->setMoltenVKConfiguration(pConfiguration); } return VK_SUCCESS; } -MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceMetalFeaturesMVK( - VkPhysicalDevice physicalDevice, - MVKPhysicalDeviceMetalFeatures* pMetalFeatures) { - +MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceMetalFeaturesMVK( + uint32_t mvkSpecVersion, + VkPhysicalDevice physicalDevice, + MVKPhysicalDeviceMetalFeatures* pMetalFeatures) { + + MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetPhysicalDeviceMetalFeaturesMVK"); + MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice); mvkPD->getMetalFeatures(pMetalFeatures); + return VK_SUCCESS; } -MVK_PUBLIC_SYMBOL void vkGetSwapchainPerformanceMVK( - VkDevice device, - VkSwapchainKHR swapchain, - MVKSwapchainPerformance* pSwapchainPerf) { +MVK_PUBLIC_SYMBOL VkResult vkGetSwapchainPerformanceMVK( + uint32_t mvkSpecVersion, + VkDevice device, + VkSwapchainKHR swapchain, + MVKSwapchainPerformance* pSwapchainPerf) { + + MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetSwapchainPerformanceMVK"); MVKSwapchain* mvkSwapchain = (MVKSwapchain*)swapchain; mvkSwapchain->getPerformanceStatistics(pSwapchainPerf); + return VK_SUCCESS; } -MVK_PUBLIC_SYMBOL void vkGetPerformanceStatisticsMVK( - VkDevice device, - MVKPerformanceStatistics* pPerf) { +MVK_PUBLIC_SYMBOL VkResult vkGetPerformanceStatisticsMVK( + uint32_t mvkSpecVersion, + VkDevice device, + MVKPerformanceStatistics* pPerf) { + + MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetPerformanceStatisticsMVK"); MVKDevice::getMVKDevice(device)->getPerformanceStatistics(pPerf); + return VK_SUCCESS; } MVK_PUBLIC_SYMBOL void vkGetVersionStringsMVK( @@ -140,18 +170,13 @@ MVK_PUBLIC_SYMBOL void vkGetIOSurfaceMVK( MVK_PUBLIC_SYMBOL void vkGetMoltenVKDeviceConfigurationMVK( VkDevice device, MVKDeviceConfiguration* pConfiguration) { - - MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); - if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkDev->getInstance()->getMoltenVKConfiguration(); } + mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkGetMoltenVKDeviceConfigurationMVK(): This function is no longer supported. Use vkGetMoltenVKConfigurationMVK() instead."); } MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKDeviceConfigurationMVK( VkDevice device, MVKDeviceConfiguration* pConfiguration) { - - MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); - if (pConfiguration) { mvkDev->getInstance()->setMoltenVKConfiguration(pConfiguration); } - return VK_SUCCESS; + return mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkSetMoltenVKDeviceConfigurationMVK(): This function is no longer supported. Use vkSetMoltenVKConfigurationMVK() instead."); } From b296f511532779bde700d2b5843aebdf03058c50 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 2 Oct 2018 15:14:33 -0400 Subject: [PATCH 2/5] Fix descriptive comments in fetchDependencies script. --- fetchDependencies | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fetchDependencies b/fetchDependencies index b4f1f4f0..86dda2e7 100755 --- a/fetchDependencies +++ b/fetchDependencies @@ -107,6 +107,7 @@ echo mkdir -p ${EXT_DIR} cd ${EXT_DIR} + # ----------------- Cereal ------------------- REPO_NAME=cereal @@ -118,8 +119,8 @@ update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV} # ----------------- Vulkan-Headers ------------------- -# When MoltenVK is built by something that already has a copy of the -# Vulkan-Headers repo, use it by creating a symlink. +# When MoltenVK is built by something that already has +# a copy of this repo, use it by creating a symlink. if [ ! "$V_HEADERS_ROOT" = "" ]; then REPO_NAME=Vulkan-Headers rm -rf ${REPO_NAME} @@ -135,8 +136,8 @@ fi # ----------------- SPIRV-Cross ------------------- -# When MoltenVK is built by something that already has a copy of the -# Vulkan-Headers repo, use it by creating a symlink. +# When MoltenVK is built by something that already has +# a copy of this repo, use it by creating a symlink. if [ ! "$SPIRV_CROSS_ROOT" = "" ]; then REPO_NAME=SPIRV-Cross rm -rf ${REPO_NAME} @@ -152,8 +153,8 @@ fi # ----------------- glslang ------------------- -# When MoltenVK is built by something that already has a copy of the -# Vulkan-Headers repo, use it by creating a symlink. +# When MoltenVK is built by something that already has +# a copy of this repo, use it by creating a symlink. if [ ! "$GLSLANG_ROOT" = "" ]; then REPO_NAME=glslang rm -rf ${REPO_NAME} @@ -181,6 +182,7 @@ REPO_REV=$(cat "../${EXT_REV_DIR}/${REPO_NAME}_repo_revision") update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV} + # ----------------- VulkanSamples ------------------- REPO_NAME=VulkanSamples @@ -190,5 +192,7 @@ REPO_REV=$(cat "../${EXT_REV_DIR}/${REPO_NAME}_repo_revision") update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV} +# ----------------- Cleanup ------------------- + cd .. From 4fba647123a5400fc8df7a80fb1f524b0a99fdfb Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Wed, 3 Oct 2018 10:09:47 -0400 Subject: [PATCH 3/5] Optimize scheme configuration and make consistent. --- .../xcschemes/MoltenVK-iOS.xcscheme | 11 ++++++++--- .../xcschemes/MoltenVK-macOS.xcscheme | 13 +++++++++---- ...MoltenVK Package (Debug) (iOS only).xcscheme | 5 +++-- ...ltenVK Package (Debug) (macOS only).xcscheme | 5 +++-- .../xcschemes/MoltenVK Package (Debug).xcscheme | 4 +--- ...ltenVK Package (Release) (iOS only).xcscheme | 11 ++++++++--- ...enVK Package (Release) (macOS only).xcscheme | 11 ++++++++--- .../MoltenVK Package (Release).xcscheme | 6 ++++-- .../MoltenVKGLSLToSPIRVConverter-iOS.xcscheme | 11 ++++++++--- .../MoltenVKGLSLToSPIRVConverter-macOS.xcscheme | 13 +++++++++---- .../MoltenVKSPIRVToMSLConverter-iOS.xcscheme | 11 ++++++++--- .../MoltenVKSPIRVToMSLConverter-macOS.xcscheme | 13 +++++++++---- .../xcschemes/MoltenVKShaderConverter.xcscheme | 17 +++++++++++------ 13 files changed, 89 insertions(+), 42 deletions(-) diff --git a/MoltenVK/MoltenVK.xcodeproj/xcshareddata/xcschemes/MoltenVK-iOS.xcscheme b/MoltenVK/MoltenVK.xcodeproj/xcshareddata/xcschemes/MoltenVK-iOS.xcscheme index afe58709..86fc06d1 100644 --- a/MoltenVK/MoltenVK.xcodeproj/xcshareddata/xcschemes/MoltenVK-iOS.xcscheme +++ b/MoltenVK/MoltenVK.xcodeproj/xcshareddata/xcschemes/MoltenVK-iOS.xcscheme @@ -1,7 +1,7 @@ + version = "2.0"> @@ -33,15 +33,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -33,15 +33,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + enableGPUFrameCaptureMode = "1" + allowLocationSimulation = "NO"> + enableGPUFrameCaptureMode = "1" + allowLocationSimulation = "NO"> + version = "2.0"> @@ -36,12 +36,17 @@ buildConfiguration = "Release" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + disableMainThreadChecker = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" + debugDocumentVersioning = "NO" + debugXPCServices = "NO" debugServiceExtension = "internal" - allowLocationSimulation = "YES"> + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -36,12 +36,17 @@ buildConfiguration = "Release" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + disableMainThreadChecker = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" + debugDocumentVersioning = "NO" + debugXPCServices = "NO" debugServiceExtension = "internal" - allowLocationSimulation = "YES"> + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -41,10 +41,12 @@ useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "NO" + debugXPCServices = "NO" debugServiceExtension = "internal" enableGPUFrameCaptureMode = "3" enableGPUValidationMode = "1" - allowLocationSimulation = "NO"> + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -33,15 +33,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "YES" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -33,15 +33,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -33,15 +33,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "YES" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -33,15 +33,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> + version = "2.0"> @@ -42,15 +42,20 @@ + enableGPUFrameCaptureMode = "3" + enableGPUValidationMode = "1" + allowLocationSimulation = "NO" + queueDebuggingEnabled = "No"> Date: Mon, 8 Oct 2018 20:22:12 -0400 Subject: [PATCH 4/5] Include struct size parameter in VK_MVK_moltenvk extension functions that pass structs that might change size across extension versions --- Docs/MoltenVK_Runtime_UserGuide.md | 5 +- Docs/Whats_New.md | 8 +- MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h | 210 +++++++++++++------ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 6 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 6 +- MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 7 - MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm | 4 - MoltenVK/MoltenVK/Utility/MVKFoundation.h | 15 ++ MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm | 95 ++++----- 10 files changed, 212 insertions(+), 148 deletions(-) diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index dfe7cdf9..d277828d 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -382,9 +382,10 @@ you can address the issue as follows: #include ... MVKConfiguration mvkConfig; - vkGetMoltenVKConfigurationMVK(vkInstance, &mvkConfig); + size_t appConfigSize = sizeof(mvkConfig); + vkGetMoltenVKConfigurationMVK(vkInstance, &mvkConfig, &appConfigSize); mvkConfig.debugMode = true; - vkSetMoltenVKConfigurationMVK(vkInstance, &mvkConfig); + vkSetMoltenVKConfigurationMVK(vkInstance, &mvkConfig, &appConfigSize); Performing these steps will enable debug mode in **MoltenVK**, which includes shader conversion logging, and causes both the incoming *SPIR-V* code and the converted *MSL* source code to be diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index c87f8fc0..0c91f29f 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -17,8 +17,12 @@ MoltenVK 1.0.24 Released TBD -- Include version number in VK_MVK_moltenvk extension functions that pass structs that might change. -- Allocate MVKDescriptorSets from a pool within MVKDescriptorPool, +- Include struct size parameter in VK_MVK_moltenvk extension functions that pass structs that + might change size across extension versions. +- Remove vkGetMoltenVKDeviceConfigurationMVK() & vkSetMoltenVKDeviceConfigurationMVK() functions. +- Allocate MVKDescriptorSets from a pool within MVKDescriptorPool +- Support copying between textures of compatible-sized formats +- Support VK_FORMAT_A2B10G10R10_UNORM_PACKED vertex format MoltenVK 1.0.23 diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index 3c0f2e87..72de1830 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -71,6 +71,12 @@ extern "C" { * is compiled in Debug mode, and not present when compiled in Release mode. The initial values * of the other settings are determined by other build settings when MoltenVK is compiled. * See the description of the individual configuration structure members for more information. + * + * This structure may be extended as new features are added to MoltenVK. If you are linking to + * an implementation of MoltenVK that was compiled from a different VK_MVK_MOLTENVK_SPEC_VERSION + * than your app was, the size of this structure in your app may be larger or smaller than the + * struct in MoltenVK. See the description of the vkGetMoltenVKConfigurationMVK() and + * vkSetMoltenVKConfigurationMVK() functions for information about how to handle this. */ typedef struct { @@ -233,7 +239,16 @@ typedef struct { } MVKConfiguration; -/** Features provided by the current implementation of Metal on the current device. */ +/** + * Features provided by the current implementation of Metal on the current device. You can + * retrieve a copy of this structure using the vkGetPhysicalDeviceMetalFeaturesMVK() function. + * + * This structure may be extended as new features are added to MoltenVK. If you are linking to + * an implementation of MoltenVK that was compiled from a different VK_MVK_MOLTENVK_SPEC_VERSION + * than your app was, the size of this structure in your app may be larger or smaller than the + * struct in MoltenVK. See the description of the vkGetPhysicalDeviceMetalFeaturesMVK() function + * for information about how to handle this. + */ typedef struct { uint32_t mslVersion; /**< The version of the Metal Shading Language available on this device. The format of the integer is MMmmpp, with two decimal digts each for Major, minor, and patch version values (eg. MSL 1.2 would appear as 010200). */ VkBool32 indirectDrawing; /**< If true, draw calls support parameters held in a GPU buffer. */ @@ -256,7 +271,16 @@ typedef struct { VkSampleCountFlags supportedSampleCounts; /**< A bitmask identifying the sample counts supported by the device. */ } MVKPhysicalDeviceMetalFeatures; -/** MoltenVK swapchain performance statistics. */ +/** + * MoltenVK swapchain performance statistics. You can retrieve a copy of this structure using + * the vkGetSwapchainPerformanceMVK() function. + * + * This structure may be extended as new features are added to MoltenVK. If you are linking to + * an implementation of MoltenVK that was compiled from a different VK_MVK_MOLTENVK_SPEC_VERSION + * than your app was, the size of this structure in your app may be larger or smaller than the + * struct in MoltenVK. See the description of the vkGetSwapchainPerformanceMVK() function for + * information about how to handle this. + */ typedef struct { double lastFrameInterval; /**< The time interval between this frame and the immediately previous frame, in milliseconds. */ double averageFrameInterval; /**< The rolling average time interval between frames, in miliseconds. This value has less volatility than the lastFrameInterval value. */ @@ -296,7 +320,15 @@ typedef struct { MVKPerformanceTracker mtlQueueAccess; /** Create an MTLCommmandQueue or access an existing cached instance. */ } MVKQueuePerformance; -/** MoltenVK performance. */ +/** + * MoltenVK performance. You can retrieve a copy of this structure using the vkGetPerformanceStatisticsMVK() function. + * + * This structure may be extended as new features are added to MoltenVK. If you are linking to + * an implementation of MoltenVK that was compiled from a different VK_MVK_MOLTENVK_SPEC_VERSION + * than your app was, the size of this structure in your app may be larger or smaller than the + * struct in MoltenVK. See the description of the vkGetPerformanceStatisticsMVK() function for + * information about how to handle this. + */ typedef struct { MVKShaderCompilationPerformance shaderCompilation; /** Shader compilations activities. */ MVKPipelineCachePerformance pipelineCache; /** Pipeline cache activities. */ @@ -307,11 +339,11 @@ typedef struct { #pragma mark - #pragma mark Function types -typedef VkResult (VKAPI_PTR *PFN_vkGetMoltenVKConfigurationMVK)(uint32_t mvkSpecVersion, VkDevice device, MVKConfiguration* pConfiguration); -typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKConfigurationMVK)(uint32_t mvkSpecVersion, VkDevice device, MVKConfiguration* pConfiguration); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceMetalFeaturesMVK)(uint32_t mvkSpecVersion, VkPhysicalDevice physicalDevice, MVKPhysicalDeviceMetalFeatures* pMetalFeatures); -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainPerformanceMVK)(uint32_t mvkSpecVersion, VkDevice device, VkSwapchainKHR swapchain, MVKSwapchainPerformance* pSwapchainPerf); -typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceStatisticsMVK)(uint32_t mvkSpecVersion, VkDevice device, MVKPerformanceStatistics* pPerf); +typedef VkResult (VKAPI_PTR *PFN_vkGetMoltenVKConfigurationMVK)(VkInstance instance, MVKConfiguration* pConfiguration, size_t* pConfigurationSize); +typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKConfigurationMVK)(VkInstance instance, MVKConfiguration* pConfiguration, size_t* pConfigurationSize); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceMetalFeaturesMVK)(VkPhysicalDevice physicalDevice, MVKPhysicalDeviceMetalFeatures* pMetalFeatures, size_t* pMetalFeaturesSize); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainPerformanceMVK)(VkDevice device, VkSwapchainKHR swapchain, MVKSwapchainPerformance* pSwapchainPerf, size_t* pSwapchainPerfSize); +typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceStatisticsMVK)(VkDevice device, MVKPerformanceStatistics* pPerf, size_t* pPerfSize); typedef void (VKAPI_PTR *PFN_vkGetVersionStringsMVK)(char* pMoltenVersionStringBuffer, uint32_t moltenVersionStringBufferLength, char* pVulkanVersionStringBuffer, uint32_t vulkanVersionStringBufferLength); #ifdef __OBJC__ @@ -322,13 +354,6 @@ typedef VkResult (VKAPI_PTR *PFN_vkUseIOSurfaceMVK)(VkImage image, IOSurfaceRef typedef void (VKAPI_PTR *PFN_vkGetIOSurfaceMVK)(VkImage image, IOSurfaceRef* pIOSurface); #endif // __OBJC__ -// Deprecated functions. These do nothing now. -typedef MVKConfiguration MVKDeviceConfiguration; -__attribute__((deprecated("Use PFN_vkGetMoltenVKConfigurationMVK instead."))) -typedef void (VKAPI_PTR *PFN_vkGetMoltenVKDeviceConfigurationMVK)(VkDevice device, MVKConfiguration* pConfiguration); -__attribute__((deprecated("Use PFN_vkSetMoltenVKConfigurationMVK instead."))) -typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKDeviceConfigurationMVK)(VkDevice device, MVKConfiguration* pConfiguration); - #pragma mark - #pragma mark Function prototypes @@ -338,23 +363,36 @@ typedef VkResult (VKAPI_PTR *PFN_vkSetMoltenVKDeviceConfigurationMVK)(VkDevice d /** * Populates the pConfiguration structure with the current MoltenVK configuration settings. * - * To change a specific configuration value, call vkGetMoltenVKConfigurationMVK() - * to retrieve the current configuration, make changes, and call - * vkSetMoltenVKConfigurationMVK() to update all of the values. + * To change a specific configuration value, call vkGetMoltenVKConfigurationMVK() to retrieve + * the current configuration, make changes, and call vkSetMoltenVKConfigurationMVK() to + * update all of the values. * * To be active, some configuration settings must be set before a VkDevice is created. * See the description of the MVKConfiguration members for more information. * - * To ensure passing compatible memory structures, mvkSpecVersion must be set to the - * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise - * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. - * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the - * version of this header file included in the MoltenVK build to which you will link your app. + * If you are linking to an implementation of MoltenVK that was compiled from a different + * VK_MVK_MOLTENVK_SPEC_VERSION than your app was, the size of the MVKConfiguration structure + * in your app may be larger or smaller than the same struct as expected by MoltenVK. + * + * When calling this function, set the value of *pConfigurationSize to sizeof(MVKConfiguration), + * to tell MoltenVK the limit of the size of your MVKConfiguration structure. Upon return from + * this function, the value of *pConfigurationSize will hold the actual number of bytes copied + * into your passed MVKConfiguration structure, which will be the smaller of what your app + * thinks is the size of MVKConfiguration, and what MoltenVK thinks it is. This represents the + * safe access area within the structure for both MoltenVK and your app. + * + * If the size that MoltenVK expects for MVKConfiguration is different than the value passed in + * *pConfigurationSize, this function will return VK_INCOMPLETE, otherwise it will return VK_SUCCESS. + * + * Although it is not necessary, you can use this function to determine in advance the value + * that MoltenVK expects the size of MVKConfiguration to be by setting the value of pConfiguration + * to NULL. In that case, this function will set *pConfigurationSize to the size that MoltenVK + * expects MVKConfiguration to be. */ VKAPI_ATTR VkResult VKAPI_CALL vkGetMoltenVKConfigurationMVK( - uint32_t mvkSpecVersion, VkInstance instance, - MVKConfiguration* pConfiguration); + MVKConfiguration* pConfiguration, + size_t* pConfigurationSize); /** * Sets the MoltenVK configuration settings to those found in the pConfiguration structure. @@ -366,62 +404,112 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMoltenVKConfigurationMVK( * To be active, some configuration settings must be set before a VkDevice is created. * See the description of the MVKConfiguration members for more information. * - * To ensure passing compatible memory structures, mvkSpecVersion must be set to the - * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise - * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. - * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the - * version of this header file included in the MoltenVK build to which you will link your app. + * If you are linking to an implementation of MoltenVK that was compiled from a different + * VK_MVK_MOLTENVK_SPEC_VERSION than your app was, the size of the MVKConfiguration structure + * in your app may be larger or smaller than the same struct as expected by MoltenVK. + * + * When calling this function, set the value of *pConfigurationSize to sizeof(MVKConfiguration), + * to tell MoltenVK the limit of the size of your MVKConfiguration structure. Upon return from + * this function, the value of *pConfigurationSize will hold the actual number of bytes copied + * out of your passed MVKConfiguration structure, which will be the smaller of what your app + * thinks is the size of MVKConfiguration, and what MoltenVK thinks it is. This represents the + * safe access area within the structure for both MoltenVK and your app. + * + * If the size that MoltenVK expects for MVKConfiguration is different than the value passed in + * *pConfigurationSize, this function will return VK_INCOMPLETE, otherwise it will return VK_SUCCESS. + * + * Although it is not necessary, you can use this function to determine in advance the value + * that MoltenVK expects the size of MVKConfiguration to be by setting the value of pConfiguration + * to NULL. In that case, this function will set *pConfigurationSize to the size that MoltenVK + * expects MVKConfiguration to be. */ VKAPI_ATTR VkResult VKAPI_CALL vkSetMoltenVKConfigurationMVK( - uint32_t mvkSpecVersion, VkInstance instance, - MVKConfiguration* pConfiguration); + const MVKConfiguration* pConfiguration, + size_t* pConfigurationSize); /** * Populates the pMetalFeatures structure with the Metal-specific features * supported by the specified physical device. * - * To ensure passing compatible memory structures, mvkSpecVersion must be set to the - * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise - * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. - * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the - * version of this header file included in the MoltenVK build to which you will link your app. + * If you are linking to an implementation of MoltenVK that was compiled from a different + * VK_MVK_MOLTENVK_SPEC_VERSION than your app was, the size of the MVKPhysicalDeviceMetalFeatures + * structure in your app may be larger or smaller than the same struct as expected by MoltenVK. + * + * When calling this function, set the value of *pMetalFeaturesSize to sizeof(MVKPhysicalDeviceMetalFeatures), + * to tell MoltenVK the limit of the size of your MVKPhysicalDeviceMetalFeatures structure. Upon return from + * this function, the value of *pMetalFeaturesSize will hold the actual number of bytes copied into your + * passed MVKPhysicalDeviceMetalFeatures structure, which will be the smaller of what your app thinks is the + * size of MVKPhysicalDeviceMetalFeatures, and what MoltenVK thinks it is. This represents the safe access + * area within the structure for both MoltenVK and your app. + * + * If the size that MoltenVK expects for MVKPhysicalDeviceMetalFeatures is different than the value passed in + * *pMetalFeaturesSize, this function will return VK_INCOMPLETE, otherwise it will return VK_SUCCESS. + * + * Although it is not necessary, you can use this function to determine in advance the value that MoltenVK + * expects the size of MVKPhysicalDeviceMetalFeatures to be by setting the value of pMetalFeatures to NULL. + * In that case, this function will set *pMetalFeaturesSize to the size that MoltenVK expects + * MVKPhysicalDeviceMetalFeatures to be. */ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceMetalFeaturesMVK( - uint32_t mvkSpecVersion, VkPhysicalDevice physicalDevice, - MVKPhysicalDeviceMetalFeatures* pMetalFeatures); + MVKPhysicalDeviceMetalFeatures* pMetalFeatures, + size_t* pMetalFeaturesSize); /** - * Populates the specified MVKSwapchainPerformance structure with - * the current performance statistics for the specified swapchain. + * Populates the pSwapchainPerf structure with the current performance statistics for the swapchain. * - * To ensure passing compatible memory structures, mvkSpecVersion must be set to the - * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise - * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. - * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the - * version of this header file included in the MoltenVK build to which you will link your app. + * If you are linking to an implementation of MoltenVK that was compiled from a different + * VK_MVK_MOLTENVK_SPEC_VERSION than your app was, the size of the MVKSwapchainPerformance + * structure in your app may be larger or smaller than the same struct as expected by MoltenVK. + * + * When calling this function, set the value of *pSwapchainPerfSize to sizeof(MVKSwapchainPerformance), + * to tell MoltenVK the limit of the size of your MVKSwapchainPerformance structure. Upon return from + * this function, the value of *pSwapchainPerfSize will hold the actual number of bytes copied into + * your passed MVKSwapchainPerformance structure, which will be the smaller of what your app thinks + * is the size of MVKSwapchainPerformance, and what MoltenVK thinks it is. This represents the safe + * access area within the structure for both MoltenVK and your app. + * + * If the size that MoltenVK expects for MVKSwapchainPerformance is different than the value passed in + * *pSwapchainPerfSize, this function will return VK_INCOMPLETE, otherwise it will return VK_SUCCESS. + * + * Although it is not necessary, you can use this function to determine in advance the value + * that MoltenVK expects the size of MVKSwapchainPerformance to be by setting the value of + * pSwapchainPerf to NULL. In that case, this function will set *pSwapchainPerfSize to the + * size that MoltenVK expects MVKSwapchainPerformance to be. */ VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainPerformanceMVK( - uint32_t mvkSpecVersion, VkDevice device, VkSwapchainKHR swapchain, - MVKSwapchainPerformance* pSwapchainPerf); + MVKSwapchainPerformance* pSwapchainPerf, + size_t* pSwapchainPerfSize); /** - * Populates the specified MVKPerformanceStatistics structure with - * the current performance statistics for the specified device. + * Populates the pPerf structure with the current performance statistics for the device. * - * To ensure passing compatible memory structures, mvkSpecVersion must be set to the - * value of VK_MVK_MOLTENVK_SPEC_VERSION under which MoltenVK was compiled, otherwise - * this function will do nothing, and will return the error VK_ERROR_INCOMPATIBLE_DRIVER. - * You can ensure this by setting mvkSpecVersion to VK_MVK_MOLTENVK_SPEC_VERSION from the - * version of this header file included in the MoltenVK build to which you will link your app. + * If you are linking to an implementation of MoltenVK that was compiled from a different + * VK_MVK_MOLTENVK_SPEC_VERSION than your app was, the size of the MVKPerformanceStatistics + * structure in your app may be larger or smaller than the same struct as expected by MoltenVK. + * + * When calling this function, set the value of *pPerfSize to sizeof(MVKPerformanceStatistics), + * to tell MoltenVK the limit of the size of your MVKPerformanceStatistics structure. Upon return + * from this function, the value of *pPerfSize will hold the actual number of bytes copied into + * your passed MVKPerformanceStatistics structure, which will be the smaller of what your app + * thinks is the size of MVKPerformanceStatistics, and what MoltenVK thinks it is. This + * represents the safe access area within the structure for both MoltenVK and your app. + * + * If the size that MoltenVK expects for MVKPerformanceStatistics is different than the value passed + * in *pPerfSize, this function will return VK_INCOMPLETE, otherwise it will return VK_SUCCESS. + * + * Although it is not necessary, you can use this function to determine in advance the value + * that MoltenVK expects the size of MVKPerformanceStatistics to be by setting the value of + * pPerf to NULL. In that case, this function will set *pPerfSize to the size that MoltenVK + * expects MVKPerformanceStatistics to be. */ VKAPI_ATTR VkResult VKAPI_CALL vkGetPerformanceStatisticsMVK( - uint32_t mvkSpecVersion, VkDevice device, - MVKPerformanceStatistics* pPerf); + MVKPerformanceStatistics* pPerf, + size_t* pPerfSize); /** * Returns a human readable version of the MoltenVK and Vulkan versions. @@ -543,13 +631,7 @@ typedef uint32_t MVKMSLSPIRVHeader; #endif // VK_NO_PROTOTYPES - -// Deprecated functions -__attribute__((deprecated("Use vkGetMoltenVKConfigurationMVK() instead."))) -VKAPI_ATTR void VKAPI_CALL vkGetMoltenVKDeviceConfigurationMVK(VkDevice device, MVKDeviceConfiguration* pConfiguration); -__attribute__((deprecated("Use vkSetMoltenVKConfigurationMVK() instead."))) -VKAPI_ATTR VkResult VKAPI_CALL vkSetMoltenVKDeviceConfigurationMVK(VkDevice device, MVKDeviceConfiguration* pConfiguration); - + #ifdef __cplusplus } #endif // __cplusplus diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 7bbc8eb3..9ae03223 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -80,9 +80,6 @@ public: /** Populates the specified structure with the features of this device. */ void getFeatures(VkPhysicalDeviceFeatures2* features); - /** Populates the specified structure with the Metal-specific features of this device. */ - void getMetalFeatures(MVKPhysicalDeviceMetalFeatures* mtlFeatures); - /** Populates the specified structure with the properties of this device. */ void getProperties(VkPhysicalDeviceProperties* properties); @@ -229,6 +226,9 @@ public: #pragma mark Metal + /** Populates the specified structure with the Metal-specific features of this device. */ + const MVKPhysicalDeviceMetalFeatures* getMetalFeatures() { return &_metalFeatures; } + /** Returns the underlying Metal device. */ inline id getMTLDevice() { return _mtlDevice; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index e272b356..23208efc 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -80,10 +80,6 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) { } } -void MVKPhysicalDevice::getMetalFeatures(MVKPhysicalDeviceMetalFeatures* mtlFeatures) { - if (mtlFeatures) { *mtlFeatures = _metalFeatures; } -} - void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties* properties) { if (properties) { *properties = _properties; } } @@ -1592,7 +1588,7 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo _physicalDevice = physicalDevice; _pMVKConfig = _physicalDevice->_mvkInstance->getMoltenVKConfiguration(); _pFeatures = &_physicalDevice->_features; - _pMetalFeatures = &_physicalDevice->_metalFeatures; + _pMetalFeatures = _physicalDevice->getMetalFeatures(); _pProperties = &_physicalDevice->_properties; _pMemoryProperties = &_physicalDevice->_memoryProperties; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 7b6fb663..f899cd70 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -322,13 +322,6 @@ void MVKInstance::initProcAddrs() { ADD_PROC_ADDR(vkCreateMacOSSurfaceMVK); #endif -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - // Deprecated functions - ADD_PROC_ADDR(vkGetMoltenVKDeviceConfigurationMVK); - ADD_PROC_ADDR(vkSetMoltenVKDeviceConfigurationMVK); -#pragma clang diagnostic pop - } void MVKInstance::logVersions() { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h index 77604e94..a7bb266f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h @@ -62,8 +62,8 @@ public: /** Returns whether the surface size has changed since the last time this function was called. */ bool getHasSurfaceSizeChanged(); - /** Populates the specified performance stats structure. */ - void getPerformanceStatistics(MVKSwapchainPerformance* pSwapchainPerf); + /** Returns the specified performance stats structure. */ + const MVKSwapchainPerformance* getPerformanceStatistics() { return &_performanceStatistics; } #pragma mark Metal diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm index d82417ab..d26732ea 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm @@ -157,10 +157,6 @@ void MVKSwapchain::markFrameInterval() { } } -void MVKSwapchain::getPerformanceStatistics(MVKSwapchainPerformance* pSwapchainPerf) { - if (pSwapchainPerf) { *pSwapchainPerf = _performanceStatistics; } -} - #pragma mark Metal diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index 22539cf5..0aa05ae5 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -336,6 +336,21 @@ void mvkRemoveAllOccurances(C& container, T val) { container.erase(remove(container.begin(), container.end(), val), container.end()); } +/** + * If pSrc and pDst are not null, copies at most copySize bytes from the contents of the source + * struct to the destination struct, and returns the number of bytes copied, which is the smaller + * of copySize and the actual size of the struct. If either pSrc or pDst are null, returns zero. + */ +template +size_t mvkCopyStruct(S* pDst, const S* pSrc, size_t copySize = sizeof(S)) { + size_t bytesCopied = 0; + if (pSrc && pDst) { + bytesCopied = std::min(copySize, sizeof(S)); + memcpy(pDst, pSrc, bytesCopied); + } + return bytesCopied; +} + /** * Sets the value referenced by the destination pointer with the value referenced by * the source pointer, and returns whether the value was set. diff --git a/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm b/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm index a48ff2ab..f756b4d2 100644 --- a/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm +++ b/MoltenVK/MoltenVK/Vulkan/vk_mvk_moltenvk.mm @@ -22,80 +22,73 @@ #include "MVKEnvironment.h" #include "MVKSwapchain.h" #include "MVKImage.h" +#include "MVKFoundation.h" #include using namespace std; -// Validate the VK_MVK_moltenvk spec version to avoid passing incompatible memory structures -#define MVK_VALIDATE_SPEC_VERSION(mvkSpecVer, cmdName) \ - do { \ - if (mvkSpecVer != VK_MVK_MOLTENVK_SPEC_VERSION) { \ - const char* errMsg = "%s(): This version of MoltenVK supports VK_MVK_moltenvk extension version %d." \ - " You are using version %d." \ - " The memory structures used in this function may be incompatible between the two versions."; \ - return mvkNotifyErrorWithText(VK_ERROR_INCOMPATIBLE_DRIVER, errMsg, cmdName, VK_MVK_MOLTENVK_SPEC_VERSION, mvkSpecVer); \ - } \ - } while(0) - +// If pSrc and pDst are not null, copies at most *pCopySize bytes from the contents of the source struct +// to the destination struct, and sets *pCopySize to the number of bytes copied, which is the smaller of +// the original value of *pCopySize and the actual size of the struct. Returns VK_SUCCESS if the original +// value of *pCopySize is the same as the actual size of the struct, or VK_INCOMPLETE otherwise. +// If either pSrc or pDst are null, sets the value of *pCopySize to the size of the struct and returns VK_SUCCESS. +template +VkResult mvkCopyStruct(S* pDst, const S* pSrc, size_t* pCopySize) { + if (pSrc && pDst) { + size_t origSize = *pCopySize; + *pCopySize = mvkCopyStruct(pDst, pSrc, origSize); + return (*pCopySize == origSize) ? VK_SUCCESS : VK_INCOMPLETE; + } else { + *pCopySize = sizeof(S); + return VK_SUCCESS; + } +} MVK_PUBLIC_SYMBOL VkResult vkGetMoltenVKConfigurationMVK( - uint32_t mvkSpecVersion, VkInstance instance, - MVKConfiguration* pConfiguration) { - - MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetMoltenVKConfigurationMVK"); + MVKConfiguration* pConfiguration, + size_t* pConfigurationSize) { MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance); - if (pConfiguration) { *pConfiguration = *(MVKConfiguration*)mvkInst->getMoltenVKConfiguration(); } - return VK_SUCCESS; + return mvkCopyStruct(pConfiguration, mvkInst->getMoltenVKConfiguration(), pConfigurationSize); } MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKConfigurationMVK( - uint32_t mvkSpecVersion, VkInstance instance, - MVKConfiguration* pConfiguration) { - - MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkSetMoltenVKConfigurationMVK"); + const MVKConfiguration* pConfiguration, + size_t* pConfigurationSize) { MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance); - if (pConfiguration) { mvkInst->setMoltenVKConfiguration(pConfiguration); } - return VK_SUCCESS; + return mvkCopyStruct((MVKConfiguration*)mvkInst->getMoltenVKConfiguration(), pConfiguration, pConfigurationSize); } MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceMetalFeaturesMVK( - uint32_t mvkSpecVersion, VkPhysicalDevice physicalDevice, - MVKPhysicalDeviceMetalFeatures* pMetalFeatures) { + MVKPhysicalDeviceMetalFeatures* pMetalFeatures, + size_t* pMetalFeaturesSize) { - MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetPhysicalDeviceMetalFeaturesMVK"); - - MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice); - mvkPD->getMetalFeatures(pMetalFeatures); - return VK_SUCCESS; + MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice); + return mvkCopyStruct(pMetalFeatures, mvkPD->getMetalFeatures(), pMetalFeaturesSize); } MVK_PUBLIC_SYMBOL VkResult vkGetSwapchainPerformanceMVK( - uint32_t mvkSpecVersion, VkDevice device, VkSwapchainKHR swapchain, - MVKSwapchainPerformance* pSwapchainPerf) { + MVKSwapchainPerformance* pSwapchainPerf, + size_t* pSwapchainPerfSize) { - MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetSwapchainPerformanceMVK"); - - MVKSwapchain* mvkSwapchain = (MVKSwapchain*)swapchain; - mvkSwapchain->getPerformanceStatistics(pSwapchainPerf); - return VK_SUCCESS; + MVKSwapchain* mvkSC = (MVKSwapchain*)swapchain; + return mvkCopyStruct(pSwapchainPerf, mvkSC->getPerformanceStatistics(), pSwapchainPerfSize); } MVK_PUBLIC_SYMBOL VkResult vkGetPerformanceStatisticsMVK( - uint32_t mvkSpecVersion, VkDevice device, - MVKPerformanceStatistics* pPerf) { + MVKPerformanceStatistics* pPerf, + size_t* pPerfSize) { - MVK_VALIDATE_SPEC_VERSION(mvkSpecVersion, "vkGetPerformanceStatisticsMVK"); - - MVKDevice::getMVKDevice(device)->getPerformanceStatistics(pPerf); - return VK_SUCCESS; + MVKPerformanceStatistics mvkPerf; + MVKDevice::getMVKDevice(device)->getPerformanceStatistics(&mvkPerf); + return mvkCopyStruct(pPerf, &mvkPerf, pPerfSize); } MVK_PUBLIC_SYMBOL void vkGetVersionStringsMVK( @@ -164,19 +157,3 @@ MVK_PUBLIC_SYMBOL void vkGetIOSurfaceMVK( MVKImage* mvkImg = (MVKImage*)image; *pIOSurface = mvkImg->getIOSurface(); } - - -// Deprecated functions -MVK_PUBLIC_SYMBOL void vkGetMoltenVKDeviceConfigurationMVK( - VkDevice device, - MVKDeviceConfiguration* pConfiguration) { - mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkGetMoltenVKDeviceConfigurationMVK(): This function is no longer supported. Use vkGetMoltenVKConfigurationMVK() instead."); -} - -MVK_PUBLIC_SYMBOL VkResult vkSetMoltenVKDeviceConfigurationMVK( - VkDevice device, - MVKDeviceConfiguration* pConfiguration) { - return mvkNotifyErrorWithText(VK_ERROR_FEATURE_NOT_PRESENT, "vkSetMoltenVKDeviceConfigurationMVK(): This function is no longer supported. Use vkSetMoltenVKConfigurationMVK() instead."); -} - - From 209ed01acc4aab2e581e7b8dca5d3f6135e1e8a9 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 9 Oct 2018 15:18:48 -0400 Subject: [PATCH 5/5] Update VulkanSamples to latest version, and update What's New document. --- Docs/Whats_New.md | 1 + ExternalRevisions/VulkanSamples_repo_revision | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 0c91f29f..dc1cac4c 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -23,6 +23,7 @@ Released TBD - Allocate MVKDescriptorSets from a pool within MVKDescriptorPool - Support copying between textures of compatible-sized formats - Support VK_FORMAT_A2B10G10R10_UNORM_PACKED vertex format +- Build scripts support SRCROOT path containing spaces. MoltenVK 1.0.23 diff --git a/ExternalRevisions/VulkanSamples_repo_revision b/ExternalRevisions/VulkanSamples_repo_revision index 073ad43c..ee1ae7b3 100644 --- a/ExternalRevisions/VulkanSamples_repo_revision +++ b/ExternalRevisions/VulkanSamples_repo_revision @@ -1 +1 @@ -e268a7b7bf799b92410f35f6fea29cedb021bac1 +7cca1899215bbb043914cc5ef74924dc7f189b64