Skip to content

Commit

Permalink
MVKImage: Always use a texel buffer for atomic storage images.
Browse files Browse the repository at this point in the history
Do this even if `OPTIMAL` tiling were requested. Vulkan mandates support
for image atomics on `OPTIMAL`-tiled `R32_UINT` and `R32_SINT` images.
In a way, this is "optimal"; image atomics won't work without this.

Advertise support for atomics on `OPTIMAL` tiled images now.

Fixes at least two CTS tests under
`dEQP-VK.compute.basic.image_atomic_op_*`.
  • Loading branch information
cdavis5e committed Nov 12, 2022
1 parent 5ebeac7 commit 94b1ea3
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 8 deletions.
10 changes: 5 additions & 5 deletions MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
Expand Up @@ -144,7 +144,7 @@

VkDeviceSize offset = 0;
if (_planeIndex > 0 && _image->_memoryBindings.size() == 1) {
if (!_image->_isLinear && _image->getDevice()->_pMetalFeatures->placementHeaps) {
if (!_image->_isLinear && !_image->_isLinearForAtomics && _image->getDevice()->_pMetalFeatures->placementHeaps) {
// For textures allocated directly on the heap, we need to obey the size and alignment
// requirements reported by the device.
MTLTextureDescriptor* mtlTexDesc = _image->_planes[_planeIndex-1]->newMTLTextureDescriptor(); // temp retain
Expand Down Expand Up @@ -856,7 +856,7 @@
needsReinterpretation = needsReinterpretation || !pixFmts->compatibleAsLinearOrSRGB(mtlPixFmt, viewFmt);
}

MTLTextureUsage mtlUsage = pixFmts->getMTLTextureUsage(getCombinedUsage(), mtlPixFmt, _samples, _isLinear, needsReinterpretation, _hasExtendedUsage);
MTLTextureUsage mtlUsage = pixFmts->getMTLTextureUsage(getCombinedUsage(), mtlPixFmt, _samples, _isLinear || _isLinearForAtomics, needsReinterpretation, _hasExtendedUsage);

// Metal before 3.0 doesn't support 3D compressed textures, so we'll
// decompress the texture ourselves, and we need to be able to write to it.
Expand Down Expand Up @@ -930,7 +930,7 @@
// If this is a storage image of format R32_UINT or R32_SINT, or MUTABLE_FORMAT is set
// and R32_UINT is in the set of possible view formats, then we must use a texel buffer,
// or image atomics won't work.
_isLinearForAtomics = (_isLinear && mvkIsAnyFlagEnabled(getCombinedUsage(), VK_IMAGE_USAGE_STORAGE_BIT) &&
_isLinearForAtomics = (_arrayLayers == 1 && _mipLevels == 1 && getImageType() == VK_IMAGE_TYPE_2D && mvkIsAnyFlagEnabled(getCombinedUsage(), VK_IMAGE_USAGE_STORAGE_BIT) &&
((_vkFormat == VK_FORMAT_R32_UINT || _vkFormat == VK_FORMAT_R32_SINT) ||
(_hasMutableFormat && pixFmts->getViewClass(_vkFormat) == MVKMTLViewClass::Color32 &&
(getIsValidViewFormat(VK_FORMAT_R32_UINT) || getIsValidViewFormat(VK_FORMAT_R32_SINT)))));
Expand All @@ -939,7 +939,7 @@
_isDepthStencilAttachment = (mvkAreAllFlagsEnabled(pCreateInfo->usage, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ||
mvkAreAllFlagsEnabled(pixFmts->getVkFormatProperties(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT));
_canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews;
_rowByteAlignment = _isLinear ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this) : mvkEnsurePowerOfTwo(pixFmts->getBytesPerBlock(pCreateInfo->format));
_rowByteAlignment = _isLinear || _isLinearForAtomics ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this) : mvkEnsurePowerOfTwo(pixFmts->getBytesPerBlock(pCreateInfo->format));

VkExtent2D blockTexelSizeOfPlane[3];
uint32_t bytesPerBlockOfPlane[3];
Expand All @@ -964,7 +964,7 @@
}
_planes[planeIndex]->initSubresources(pCreateInfo);
MVKImageMemoryBinding* memoryBinding = _planes[planeIndex]->getMemoryBinding();
if (!_isLinear && _device->_pMetalFeatures->placementHeaps) {
if (!_isLinear && !_isLinearForAtomics && _device->_pMetalFeatures->placementHeaps) {
MTLTextureDescriptor* mtlTexDesc = _planes[planeIndex]->newMTLTextureDescriptor(); // temp retain
MTLSizeAndAlign sizeAndAlign = [_device->getMTLDevice() heapTextureSizeAndAlignWithDescriptor: mtlTexDesc];
[mtlTexDesc release];
Expand Down
4 changes: 1 addition & 3 deletions MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
Expand Up @@ -2051,6 +2051,7 @@
enableFormatFeatures(Read, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
enableFormatFeatures(Filter, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
enableFormatFeatures(Write, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
enableFormatFeatures(Atomic, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
enableFormatFeatures(ColorAtt, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
enableFormatFeatures(DSAtt, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
enableFormatFeatures(Blend, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
Expand Down Expand Up @@ -2084,9 +2085,6 @@
// Start with optimal tiling features, and modify.
vkProps.linearTilingFeatures = vkProps.optimalTilingFeatures;

// Linear tiling can support atomic writing for some formats, even though optimal tiling does not.
enableFormatFeatures(Atomic, Tex, mtlPixFmtCaps, vkProps.linearTilingFeatures);

#if !MVK_APPLE_SILICON
// On macOS IMR GPUs, linear textures cannot be used as attachments, so disable those features.
mvkDisableFlags(vkProps.linearTilingFeatures, (kMVKVkFormatFeatureFlagsTexColorAtt |
Expand Down

0 comments on commit 94b1ea3

Please sign in to comment.