From 3fb74dc69fcee10735bf2366d6cc1173dcfde0dc Mon Sep 17 00:00:00 2001 From: sean Date: Fri, 5 Jan 2024 14:41:11 +0100 Subject: [PATCH] Add: KHR_maintenance4 --- MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 14 +++++- MoltenVK/MoltenVK/GPUObjects/MVKImage.h | 29 +++++++----- MoltenVK/MoltenVK/GPUObjects/MVKImage.mm | 45 ++++++++++++------- MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 4 +- MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 49 +++++++++++++++++++-- 9 files changed, 110 insertions(+), 40 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h index 95fdf681b..710cf0916 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h @@ -44,7 +44,7 @@ class MVKBuffer : public MVKResource { /** Returns the memory requirements of this resource by populating the specified structure. */ VkResult getMemoryRequirements(const void* pInfo, VkMemoryRequirements2* pMemoryRequirements); - + /** Binds this resource to the specified offset within the specified memory allocation. */ VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm index e14ff7d53..afc000174 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm @@ -346,7 +346,7 @@ // Multiple rows will automatically align with PoT max texture dimension, but need to align upwards if less than full single row. size_t maxBlocksPerRow = _device->_pMetalFeatures->maxTextureDimension / fmtBlockSize.width; size_t blocksPerRow = min(blockCount, maxBlocksPerRow); - _mtlBytesPerRow = mvkAlignByteCount(blocksPerRow * bytesPerBlock, _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this)); + _mtlBytesPerRow = mvkAlignByteCount(blocksPerRow * bytesPerBlock, _device->getVkFormatTexelBufferAlignment(pCreateInfo->format)); size_t rowCount = blockCount / blocksPerRow; if (blockCount % blocksPerRow) { rowCount++; } @@ -358,7 +358,7 @@ // We can just use a simple 1D texel array. _textureSize.width = uint32_t(blockCount * fmtBlockSize.width); _textureSize.height = 1; - _mtlBytesPerRow = mvkAlignByteCount(byteCount, _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this)); + _mtlBytesPerRow = mvkAlignByteCount(byteCount, _device->getVkFormatTexelBufferAlignment(pCreateInfo->format)); } if ( !_device->_pMetalFeatures->texelBuffers ) { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 1591fdddb..19ddc0851 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -766,7 +766,7 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { uint32_t getMetalBufferIndexForVertexAttributeBinding(uint32_t binding); /** Returns the memory alignment required for the format when used in a texel buffer. */ - VkDeviceSize getVkFormatTexelBufferAlignment(VkFormat format, MVKBaseObject* mvkObj); + VkDeviceSize getVkFormatTexelBufferAlignment(VkFormat format); /** * Returns the MTLBuffer used to hold occlusion query results, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index e6abcc0bf..4078aa624 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -257,6 +257,11 @@ inlineUniformBlockFeatures->descriptorBindingInlineUniformBlockUpdateAfterBind = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES: { + auto* maintenace4Features = (VkPhysicalDeviceMaintenance4Features*)next; + maintenace4Features->maintenance4 = true; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: { auto* multiviewFeatures = (VkPhysicalDeviceMultiviewFeatures*)next; multiviewFeatures->multiview = supportedFeats11.multiview; @@ -645,7 +650,11 @@ maint3Props->maxMemoryAllocationSize = supportedProps11.maxMemoryAllocationSize; break; } - + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES: { + auto* maintenance4Props = (VkPhysicalDeviceMaintenance4Properties*)next; + maintenance4Props->maxBufferSize = _metalFeatures.maxMTLBufferSize; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES: { auto* depthStencilResolveProps = (VkPhysicalDeviceDepthStencilResolveProperties*)next; depthStencilResolveProps->supportedDepthResolveModes = supportedProps12.supportedDepthResolveModes; @@ -3730,6 +3739,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope *pMaxDeviation = cpuEnd - cpuStart; } + #pragma mark Object lifecycle uint32_t MVKDevice::getVulkanMemoryTypeIndex(MTLStorageMode mtlStorageMode) { @@ -4488,7 +4498,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope return ((_pMetalFeatures->maxPerStageBufferCount - 1) - binding); } -VkDeviceSize MVKDevice::getVkFormatTexelBufferAlignment(VkFormat format, MVKBaseObject* mvkObj) { +VkDeviceSize MVKDevice::getVkFormatTexelBufferAlignment(VkFormat format) { VkDeviceSize deviceAlignment = 0; id mtlDev = getMTLDevice(); MVKPixelFormats* mvkPixFmts = getPixelFormats(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index 9c56d6f8b..34228dbe8 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -188,6 +188,9 @@ class MVKImage : public MVKVulkanAPIDeviceObject { /** Returns the 3D extent of this image at the specified mipmap level. */ VkExtent3D getExtent3D(uint8_t planeIndex = 0, uint32_t mipLevel = 0); + /** Returns the 3D extent of this image at the specified mipmap level. */ + static VkExtent3D getExtent3D(VkExtent3D extent, VkExtent2D blockTexelSize, bool hasChromaSubsampling, uint32_t mipLevel = 0); + /** Returns the number of mipmap levels in this image. */ uint32_t getMipLevelCount() { return _mipLevels; } @@ -200,22 +203,22 @@ class MVKImage : public MVKVulkanAPIDeviceObject { /** Returns the number of samples for each pixel of this image. */ VkSampleCountFlagBits getSampleCount() { return _samples; } - /** - * Returns the number of bytes per image row at the specified zero-based mip level. - * For non-compressed formats, this is the number of bytes in a row of texels. - * For compressed formats, this is the number of bytes in a row of blocks, which - * will typically span more than one row of texels. - */ - VkDeviceSize getBytesPerRow(uint8_t planeIndex, uint32_t mipLevel); - + /** + * Returns the number of bytes per image row for the mip with the given width. + * For non-compressed formats, this is the number of bytes in a row of texels. + * For compressed formats, this is the number of bytes in a row of blocks, which + * will typically span more than one row of texels. + */ + VkDeviceSize getBytesPerRow(MTLPixelFormat planePixelFormat, uint32_t mipWidth); + /** * Returns the number of bytes per image layer (for cube, array, or 3D images) - * at the specified zero-based mip level. This value will normally be the number - * of bytes per row (as returned by the getBytesPerRow() function, multiplied by + * for the mip with the given extent. This value will normally be the number + * of bytes per row (as returned by the getBytesPerRow() function, multiplied by * the height of each 2D image. */ - VkDeviceSize getBytesPerLayer(uint8_t planeIndex, uint32_t mipLevel); - + VkDeviceSize getBytesPerLayer(uint8_t planeIndex, VkExtent3D mipExtent); + /** Returns the number of planes of this image view. */ uint8_t getPlaneCount() { return _planes.size(); } @@ -237,6 +240,8 @@ class MVKImage : public MVKVulkanAPIDeviceObject { /** Returns the memory requirements of this resource by populating the specified structure. */ VkResult getMemoryRequirements(const void* pInfo, VkMemoryRequirements2* pMemoryRequirements); + + VkResult getMemoryRequirements(VkMemoryRequirements2* pMemoryRequirements, uint8_t planeIndex); /** Binds this resource to the specified offset within the specified memory allocation. */ virtual VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset, uint8_t planeIndex); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index d9d6a8bbf..ce4be5c53 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -167,10 +167,10 @@ for (uint32_t mipLvl = 0; mipLvl < _image->_mipLevels; mipLvl++) { subRez.subresource.mipLevel = mipLvl; - VkDeviceSize rowPitch = _image->getBytesPerRow(_planeIndex, mipLvl); - VkDeviceSize depthPitch = _image->getBytesPerLayer(_planeIndex, mipLvl); - - VkExtent3D mipExtent = _image->getExtent3D(_planeIndex, mipLvl); + VkExtent3D mipExtent = _image->getExtent3D(_planeIndex, mipLvl); + auto planeMTLPixFmt = _image->getPixelFormats()->getChromaSubsamplingPlaneMTLPixelFormat(_image->_vkFormat, _planeIndex); + VkDeviceSize rowPitch = _image->getBytesPerRow(planeMTLPixFmt, mipExtent.width); + VkDeviceSize depthPitch = _image->getPixelFormats()->getBytesPerLayer(planeMTLPixFmt, rowPitch, mipExtent.height); for (uint32_t layer = 0; layer < _image->_arrayLayers; layer++) { subRez.subresource.arrayLayer = layer; @@ -575,17 +575,23 @@ return mvkMipmapLevelSizeFromBaseSize3D(extent, mipLevel); } -VkDeviceSize MVKImage::getBytesPerRow(uint8_t planeIndex, uint32_t mipLevel) { - MTLPixelFormat planeMTLPixFmt = getPixelFormats()->getChromaSubsamplingPlaneMTLPixelFormat(_vkFormat, planeIndex); - size_t bytesPerRow = getPixelFormats()->getBytesPerRow(planeMTLPixFmt, getExtent3D(planeIndex, mipLevel).width); +VkExtent3D MVKImage::getExtent3D(VkExtent3D extent, VkExtent2D blockTexelSize, bool hasChromaSubsampling, uint32_t mipLevel) { + if (hasChromaSubsampling) { + extent.width /= blockTexelSize.width; + extent.height /= blockTexelSize.height; + } + return mvkMipmapLevelSizeFromBaseSize3D(extent, mipLevel); +} + +VkDeviceSize MVKImage::getBytesPerRow(MTLPixelFormat planePixelFormat, uint32_t mipWidth) { + size_t bytesPerRow = getPixelFormats()->getBytesPerRow(planePixelFormat, mipWidth); return mvkAlignByteCount(bytesPerRow, _rowByteAlignment); } -VkDeviceSize MVKImage::getBytesPerLayer(uint8_t planeIndex, uint32_t mipLevel) { - MTLPixelFormat planeMTLPixFmt = getPixelFormats()->getChromaSubsamplingPlaneMTLPixelFormat(_vkFormat, planeIndex); - VkExtent3D extent = getExtent3D(planeIndex, mipLevel); - size_t bytesPerRow = getBytesPerRow(planeIndex, mipLevel); - return getPixelFormats()->getBytesPerLayer(planeMTLPixFmt, bytesPerRow, extent.height); +VkDeviceSize MVKImage::getBytesPerLayer(uint8_t planeIndex, VkExtent3D mipExtent) { + MTLPixelFormat planeMTLPixFmt = getPixelFormats()->getChromaSubsamplingPlaneMTLPixelFormat(_vkFormat, planeIndex); + VkDeviceSize bytesPerRow = getBytesPerRow(planeMTLPixFmt, mipExtent.width); + return getPixelFormats()->getBytesPerLayer(planeMTLPixFmt, bytesPerRow, mipExtent.height); } VkResult MVKImage::getSubresourceLayout(const VkImageSubresource* pSubresource, @@ -618,7 +624,6 @@ return _viewFormats.empty(); } - #pragma mark Resource memory void MVKImage::applyImageMemoryBarrier(MVKPipelineBarrier& barrier, @@ -672,6 +677,12 @@ return _memoryBindings[planeIndex]->getMemoryRequirements(pInfo, pMemoryRequirements); } +VkResult MVKImage::getMemoryRequirements(VkMemoryRequirements2 *pMemoryRequirements, uint8_t planeIndex) { + VkResult rslt = getMemoryRequirements(&pMemoryRequirements->memoryRequirements, planeIndex); + if (rslt != VK_SUCCESS) { return rslt; } + return _memoryBindings[planeIndex]->getMemoryRequirements(nullptr, pMemoryRequirements); +} + VkResult MVKImage::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset, uint8_t planeIndex) { return _memoryBindings[planeIndex]->bindDeviceMemory(mvkMem, memOffset); } @@ -933,7 +944,7 @@ _isDepthStencilAttachment = (mvkAreAllFlagsEnabled(pCreateInfo->usage, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) || mvkAreAllFlagsEnabled(pixFmts->getVkFormatProperties3(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)); _canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews; - _rowByteAlignment = _isLinear || _isLinearForAtomics ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this) : mvkEnsurePowerOfTwo(pixFmts->getBytesPerBlock(pCreateInfo->format)); + _rowByteAlignment = _isLinear || _isLinearForAtomics ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format) : mvkEnsurePowerOfTwo(pixFmts->getBytesPerBlock(pCreateInfo->format)); VkExtent2D blockTexelSizeOfPlane[3]; uint32_t bytesPerBlockOfPlane[3]; @@ -970,15 +981,15 @@ NSUInteger bufferLength = 0; for (uint32_t mipLvl = 0; mipLvl < _mipLevels; mipLvl++) { VkExtent3D mipExtent = getExtent3D(planeIndex, mipLvl); - bufferLength += getBytesPerLayer(planeIndex, mipLvl) * mipExtent.depth * _arrayLayers; + bufferLength += getBytesPerLayer(planeIndex, mipExtent) * mipExtent.depth * _arrayLayers; } MTLSizeAndAlign sizeAndAlign = [_device->getMTLDevice() heapBufferSizeAndAlignWithLength: bufferLength options: MTLResourceStorageModePrivate]; - memoryBinding->_byteCount += sizeAndAlign.size; + memoryBinding->_byteCount = sizeAndAlign.size; memoryBinding->_byteAlignment = std::max(std::max(memoryBinding->_byteAlignment, _rowByteAlignment), (VkDeviceSize)sizeAndAlign.align); } else { for (uint32_t mipLvl = 0; mipLvl < _mipLevels; mipLvl++) { VkExtent3D mipExtent = getExtent3D(planeIndex, mipLvl); - memoryBinding->_byteCount += getBytesPerLayer(planeIndex, mipLvl) * mipExtent.depth * _arrayLayers; + memoryBinding->_byteCount += getBytesPerLayer(planeIndex, mipExtent) * mipExtent.depth * _arrayLayers; } memoryBinding->_byteAlignment = std::max(memoryBinding->_byteAlignment, _rowByteAlignment); } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 989fcc0fc..713c5ed68 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -1674,7 +1674,7 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3 shaderConfig.options.mslOptions.msl_version = _device->_pMetalFeatures->mslVersion; shaderConfig.options.mslOptions.texel_buffer_texture_width = _device->_pMetalFeatures->maxTextureDimension; - shaderConfig.options.mslOptions.r32ui_linear_texture_alignment = (uint32_t)_device->getVkFormatTexelBufferAlignment(VK_FORMAT_R32_UINT, this); + shaderConfig.options.mslOptions.r32ui_linear_texture_alignment = (uint32_t)_device->getVkFormatTexelBufferAlignment(VK_FORMAT_R32_UINT); shaderConfig.options.mslOptions.texture_buffer_native = _device->_pMetalFeatures->textureBuffers; bool useMetalArgBuff = isUsingMetalArgumentBuffers(); @@ -2113,7 +2113,7 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3 shaderConfig.options.entryPointStage = spv::ExecutionModelGLCompute; shaderConfig.options.mslOptions.msl_version = _device->_pMetalFeatures->mslVersion; shaderConfig.options.mslOptions.texel_buffer_texture_width = _device->_pMetalFeatures->maxTextureDimension; - shaderConfig.options.mslOptions.r32ui_linear_texture_alignment = (uint32_t)_device->getVkFormatTexelBufferAlignment(VK_FORMAT_R32_UINT, this); + shaderConfig.options.mslOptions.r32ui_linear_texture_alignment = (uint32_t)_device->getVkFormatTexelBufferAlignment(VK_FORMAT_R32_UINT); shaderConfig.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle; shaderConfig.options.mslOptions.texture_buffer_native = _device->_pMetalFeatures->textureBuffers; shaderConfig.options.mslOptions.dispatch_base = _allowsDispatchBase; diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 72796655b..426f9d512 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -74,6 +74,7 @@ MVK_EXTENSION(KHR_incremental_present, KHR_INCREMENTAL_PRESENT, MVK_EXTENSION(KHR_maintenance1, KHR_MAINTENANCE1, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_maintenance2, KHR_MAINTENANCE2, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_maintenance3, KHR_MAINTENANCE3, DEVICE, 10.11, 8.0, 1.0) +MVK_EXTENSION(KHR_maintenance4, KHR_MAINTENANCE_4, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_map_memory2, KHR_MAP_MEMORY_2, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_multiview, KHR_MULTIVIEW, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_portability_subset, KHR_PORTABILITY_SUBSET, DEVICE, 10.11, 8.0, 1.0) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 8c1c24f4c..62fb3e321 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2814,9 +2814,44 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyPrivateDataSlot( MVKTraceVulkanCallEnd(); } -MVK_PUBLIC_VULKAN_STUB(vkGetDeviceBufferMemoryRequirements, void, VkDevice, const VkDeviceBufferMemoryRequirements*, VkMemoryRequirements2*) -MVK_PUBLIC_VULKAN_STUB(vkGetDeviceImageMemoryRequirements, void, VkDevice, const VkDeviceImageMemoryRequirements*, VkMemoryRequirements2*) -MVK_PUBLIC_VULKAN_STUB(vkGetDeviceImageSparseMemoryRequirements, void, VkDevice, const VkDeviceImageMemoryRequirements*, uint32_t*, VkSparseImageMemoryRequirements2*) +MVK_PUBLIC_VULKAN_SYMBOL void vkGetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements) { + + MVKTraceVulkanCallStart(); + auto* mvkDev = MVKDevice::getMVKDevice(device); + auto* buffer = new MVKBuffer(mvkDev, pInfo->pCreateInfo); + buffer->getMemoryRequirements(nullptr, pMemoryRequirements); + buffer->destroy(); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_VULKAN_SYMBOL void vkGetDeviceImageMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements) { + + MVKTraceVulkanCallStart(); + auto* mvkDev = MVKDevice::getMVKDevice(device); + auto* image = new MVKImage(mvkDev, pInfo->pCreateInfo); + image->getMemoryRequirements(pMemoryRequirements, MVKImage::getPlaneFromVkImageAspectFlags(pInfo->planeAspect)); + image->destroy(); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_VULKAN_SYMBOL void vkGetDeviceImageSparseMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) { + + MVKTraceVulkanCallStart(); + // Metal does not support sparse images + *pSparseMemoryRequirementCount = 0; + MVKTraceVulkanCallEnd(); +} + MVK_PUBLIC_VULKAN_STUB_VKRESULT(vkGetPhysicalDeviceToolProperties, VkPhysicalDevice, uint32_t*, VkPhysicalDeviceToolProperties*) MVK_PUBLIC_VULKAN_SYMBOL void vkGetPrivateData( @@ -3067,6 +3102,14 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyDeferredOperationKHR( MVK_PUBLIC_VULKAN_CORE_ALIAS(vkGetDescriptorSetLayoutSupport, KHR); +#pragma mark - +#pragma mark VK_KHR_maintenance4 extension + +MVK_PUBLIC_VULKAN_CORE_ALIAS(vkGetDeviceBufferMemoryRequirements, KHR); +MVK_PUBLIC_VULKAN_CORE_ALIAS(vkGetDeviceImageMemoryRequirements, KHR); +MVK_PUBLIC_VULKAN_CORE_ALIAS(vkGetDeviceImageSparseMemoryRequirements, KHR); + + #pragma mark - #pragma mark VK_KHR_map_memory2 extension