Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit for VK_KHR_maintenance4 from spnda. #2455

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_KHR_maintenance1`
- `VK_KHR_maintenance2`
- `VK_KHR_maintenance3`
- `VK_KHR_maintenance4`
- `VK_KHR_map_memory2`
- `VK_KHR_multiview`
- `VK_KHR_portability_subset`
Expand Down
12 changes: 11 additions & 1 deletion MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,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;
Expand Down Expand Up @@ -757,7 +762,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;
Expand Down Expand Up @@ -3844,6 +3853,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) {
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ MVK_DEVICE_FEATURE(HostQueryReset, HOST_QUERY_RESET,
MVK_DEVICE_FEATURE(ImagelessFramebuffer, IMAGELESS_FRAMEBUFFER, 1)
MVK_DEVICE_FEATURE(ImageRobustness, IMAGE_ROBUSTNESS, 1)
MVK_DEVICE_FEATURE(InlineUniformBlock, INLINE_UNIFORM_BLOCK, 2)
MVK_DEVICE_FEATURE(Maintenance4, MAINTENANCE_4, 1)
MVK_DEVICE_FEATURE(Multiview, MULTIVIEW, 3)
MVK_DEVICE_FEATURE(PrivateData, PRIVATE_DATA, 1)
MVK_DEVICE_FEATURE(ProtectedMemory, PROTECTED_MEMORY, 1)
Expand Down
26 changes: 14 additions & 12 deletions MoltenVK/MoltenVK/GPUObjects/MVKImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,22 +201,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(); }

Expand All @@ -243,6 +243,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);
Expand Down
33 changes: 18 additions & 15 deletions MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,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;
Expand Down Expand Up @@ -778,17 +778,15 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) {
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);
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,
Expand Down Expand Up @@ -850,7 +848,6 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) {
return _viewFormats.empty();
}


#pragma mark Resource memory

// There may be less memory bindings than planes, but there will always be at least one.
Expand Down Expand Up @@ -922,6 +919,12 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) {
return getMemoryBinding(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 getMemoryBinding(planeIndex)->bindDeviceMemory(mvkMem, memOffset);
}
Expand Down Expand Up @@ -1232,15 +1235,15 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) {
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 = [getMTLDevice() heapBufferSizeAndAlignWithLength: bufferLength options: MTLResourceStorageModePrivate];
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);
}
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/Layers/MVKExtensions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
48 changes: 45 additions & 3 deletions MoltenVK/MoltenVK/Vulkan/vulkan.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2823,9 +2823,43 @@ 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_SYMBOL VkResult vkGetPhysicalDeviceToolProperties(
VkPhysicalDevice physicalDevice,
Expand Down Expand Up @@ -3087,6 +3121,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

Expand Down