From a3f571e89ba967e12c405b10ea3c374fa6808e97 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 2 Oct 2018 12:48:51 -0400 Subject: [PATCH] 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."); }