Merge pull request #867 from billhollings/master
MVKPixelFormats enables atomic capabilities only when applicable.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
index 5a1317f..a1cba32 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
@@ -44,12 +44,13 @@
kMVKMTLFmtCapsRead = (1<<0),
kMVKMTLFmtCapsFilter = (1<<1),
kMVKMTLFmtCapsWrite = (1<<2),
- kMVKMTLFmtCapsColorAtt = (1<<3),
- kMVKMTLFmtCapsDSAtt = (1<<4),
- kMVKMTLFmtCapsBlend = (1<<5),
- kMVKMTLFmtCapsMSAA = (1<<6),
- kMVKMTLFmtCapsResolve = (1<<7),
- kMVKMTLFmtCapsVertex = (1<<8),
+ kMVKMTLFmtCapsAtomic = (1<<3),
+ kMVKMTLFmtCapsColorAtt = (1<<4),
+ kMVKMTLFmtCapsDSAtt = (1<<5),
+ kMVKMTLFmtCapsBlend = (1<<6),
+ kMVKMTLFmtCapsMSAA = (1<<7),
+ kMVKMTLFmtCapsResolve = (1<<8),
+ kMVKMTLFmtCapsVertex = (1<<9),
kMVKMTLFmtCapsRF = (kMVKMTLFmtCapsRead | kMVKMTLFmtCapsFilter),
kMVKMTLFmtCapsRC = (kMVKMTLFmtCapsRead | kMVKMTLFmtCapsColorAtt),
@@ -291,14 +292,12 @@
MVKMTLFormatDesc& getMTLPixelFormatDesc(MTLPixelFormat mtlFormat);
MVKMTLFormatDesc& getMTLVertexFormatDesc(VkFormat vkFormat);
MVKMTLFormatDesc& getMTLVertexFormatDesc(MTLVertexFormat mtlFormat);
- VkFormatFeatureFlags getOptimalTilingFeatures(VkFormat vkFormat, MVKMTLFmtCaps mtlFmtCaps);
- VkFormatFeatureFlags getLinearTilingFeatures(VkFormat vkFormat, MVKMTLFmtCaps mtlFmtCaps, MVKFormatType mvkFmtType);
- VkFormatFeatureFlags getBufferFeatures(VkFormat vkFormat, MVKMTLFmtCaps mtlFmtTexCaps, MVKMTLFmtCaps mtlFmtVtxCaps, MVKFormatType mvkFmtType);
void initVkFormatCapabilities();
void initMTLPixelFormatCapabilities();
void initMTLVertexFormatCapabilities();
void buildMTLFormatMaps();
void buildVkFormatMaps();
+ void setFormatProperties(MVKVkFormatDesc& vkDesc);
void modifyMTLFormatCapabilities();
void modifyMTLFormatCapabilities(id<MTLDevice> mtlDevice);
void addMTLPixelFormatCapabilities(id<MTLDevice> mtlDevice,
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
index 927af4b..5197c4d 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
@@ -1072,6 +1072,10 @@
// Modifies the format capability tables based on the capabilities of the specific MTLDevice
#if MVK_MACOS
void MVKPixelFormats::modifyMTLFormatCapabilities(id<MTLDevice> mtlDevice) {
+
+ addMTLPixelFormatCapabilities( macOS_GPUFamily1_v1, R32Uint, Atomic );
+ addMTLPixelFormatCapabilities( macOS_GPUFamily1_v1, R32Sint, Atomic );
+
if (mtlDevice.isDepth24Stencil8PixelFormatSupported) {
addMTLPixelFormatCapabilities( macOS_GPUFamily1_v1, Depth24Unorm_Stencil8, DRFMR );
}
@@ -1105,7 +1109,9 @@
addMTLPixelFormatCapabilities( iOS_GPUFamily2_v1, RG8Snorm, All );
addMTLPixelFormatCapabilities( iOS_GPUFamily1_v2, R32Uint, RWC );
+ addMTLPixelFormatCapabilities( iOS_GPUFamily1_v2, R32Uint, Atomic );
addMTLPixelFormatCapabilities( iOS_GPUFamily1_v2, R32Sint, RWC );
+ addMTLPixelFormatCapabilities( iOS_GPUFamily1_v2, R32Sint, Atomic );
addMTLPixelFormatCapabilities( iOS_GPUFamily1_v2, R32Float, RWCMB );
@@ -1227,13 +1233,8 @@
if ( !mtlDesc.isSupported() ) { vkDesc.mtlVertexFormatSubstitute = MTLVertexFormatInvalid; }
}
- // Vulkan format features
- MVKFormatType fmtType = vkDesc.formatType;
- MVKMTLFmtCaps mtlPixFmtCaps = getMTLPixelFormatDesc(vkFmt).mtlFmtCaps;
- MVKMTLFmtCaps mtlVtxFmtCaps = getMTLVertexFormatDesc(vkFmt).mtlFmtCaps;
- vkDesc.properties = { getLinearTilingFeatures(vkFmt, mtlPixFmtCaps, fmtType),
- getOptimalTilingFeatures(vkFmt, mtlPixFmtCaps),
- getBufferFeatures(vkFmt, mtlPixFmtCaps, mtlVtxFmtCaps, fmtType) };
+ // Set Vulkan format properties
+ setFormatProperties(vkDesc);
}
}
}
@@ -1246,87 +1247,65 @@
VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_BLIT_SRC_BIT),
kMVKVkFormatFeatureFlagsTexFilter = (VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT),
- kMVKVkFormatFeatureFlagsTexWrite = (VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
- VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT),
+ kMVKVkFormatFeatureFlagsTexWrite = (VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT),
+ kMVKVkFormatFeatureFlagsTexAtomic = (VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT),
kMVKVkFormatFeatureFlagsTexColorAtt = (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT),
kMVKVkFormatFeatureFlagsTexDSAtt = (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT),
kMVKVkFormatFeatureFlagsTexBlend = (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT),
kMVKVkFormatFeatureFlagsBufRead = (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT),
- kMVKVkFormatFeatureFlagsBufWrite = (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT |
- VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT),
+ kMVKVkFormatFeatureFlagsBufWrite = (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT),
+ kMVKVkFormatFeatureFlagsBufAtomic = (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT),
kMVKVkFormatFeatureFlagsBufVertex = (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT),
} MVKVkFormatFeatureFlags;
-#define enableTexFormatFeatures(CAP) \
- if (mvkAreAllFlagsEnabled(mtlFmtCaps, kMVKMTLFmtCaps ##CAP)) { \
- vkFeatures |= kMVKVkFormatFeatureFlagsTex ##CAP; \
- }
-VkFormatFeatureFlags MVKPixelFormats::getOptimalTilingFeatures(VkFormat vkFormat,
- MVKMTLFmtCaps mtlFmtCaps) {
- VkFormatFeatureFlags vkFeatures = kMVKVkFormatFeatureFlagsTexNone;
- enableTexFormatFeatures(Read);
- enableTexFormatFeatures(Filter);
- enableTexFormatFeatures(Write);
- enableTexFormatFeatures(ColorAtt);
- enableTexFormatFeatures(DSAtt);
- enableTexFormatFeatures(Blend);
- // Only support atomics on R32UI/R32I images for now. Until Metal supports this
- // for real, we need to use the underlying buffer to support image atomics.
- if (vkFormat != VK_FORMAT_R32_UINT && vkFormat != VK_FORMAT_R32_SINT) {
- mvkDisableFlags(vkFeatures, VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT);
- }
- return vkFeatures;
-}
+// Sets the VkFormatProperties (optimal/linear/buffer) for the Vulkan format.
+void MVKPixelFormats::setFormatProperties(MVKVkFormatDesc& vkDesc) {
-VkFormatFeatureFlags MVKPixelFormats::getLinearTilingFeatures(VkFormat vkFormat,
- MVKMTLFmtCaps mtlFmtCaps,
- MVKFormatType mvkFmtType) {
-
- // Depth-stencil or compressed formats cannot be used for linear textures.
- if (mvkFmtType == kMVKFormatDepthStencil || mvkFmtType == kMVKFormatCompressed) {
- return kMVKVkFormatFeatureFlagsTexNone;
+# define enableFormatFeatures(CAP, TYPE, MTL_FMT_CAPS, VK_FEATS) \
+ if (mvkAreAllFlagsEnabled(MTL_FMT_CAPS, kMVKMTLFmtCaps ##CAP)) { \
+ mvkEnableFlags(VK_FEATS, kMVKVkFormatFeatureFlags ##TYPE ##CAP); \
}
- // Start with the optimal features.
- VkFormatFeatureFlags vkFeatures = getOptimalTilingFeatures(vkFormat, mtlFmtCaps);
+ VkFormat vkFmt = vkDesc.vkFormat;
+ VkFormatProperties& vkProps = vkDesc.properties;
+ MVKMTLFmtCaps mtlPixFmtCaps = getMTLPixelFormatDesc(vkFmt).mtlFmtCaps;
+
+ // Set optimal tiling features first
+ vkProps.optimalTilingFeatures = kMVKVkFormatFeatureFlagsTexNone;
+ enableFormatFeatures(Read, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
+ enableFormatFeatures(Filter, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
+ enableFormatFeatures(Write, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
+ enableFormatFeatures(ColorAtt, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
+ enableFormatFeatures(DSAtt, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
+ enableFormatFeatures(Blend, Tex, mtlPixFmtCaps, vkProps.optimalTilingFeatures);
+
+ // Linear tiling is not available to depth/stencil or compressed formats.
+ vkProps.linearTilingFeatures = kMVKVkFormatFeatureFlagsTexNone;
+ if ( !(vkDesc.formatType == kMVKFormatDepthStencil || vkDesc.formatType == kMVKFormatCompressed) ) {
+
+ // 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_MACOS
- // On macOS, linear textures cannot be used as attachments, so disable those features.
- mvkDisableFlags(vkFeatures, (kMVKVkFormatFeatureFlagsTexColorAtt |
- kMVKVkFormatFeatureFlagsTexDSAtt |
- kMVKVkFormatFeatureFlagsTexBlend));
+ // On macOS, linear textures cannot be used as attachments, so disable those features.
+ mvkDisableFlags(vkProps.linearTilingFeatures, (kMVKVkFormatFeatureFlagsTexColorAtt |
+ kMVKVkFormatFeatureFlagsTexDSAtt |
+ kMVKVkFormatFeatureFlagsTexBlend));
#endif
-
- return vkFeatures;
-}
-
-VkFormatFeatureFlags MVKPixelFormats::getBufferFeatures(VkFormat vkFormat,
- MVKMTLFmtCaps mtlPixFmtCaps,
- MVKMTLFmtCaps mtlVtxFmtCaps,
- MVKFormatType mvkFmtType) {
-
- // Depth-stencil or compressed formats cannot be used for texel buffers.
- if (mvkFmtType == kMVKFormatDepthStencil || mvkFmtType == kMVKFormatCompressed) {
- return kMVKVkFormatFeatureFlagsTexNone;
}
- VkFormatFeatureFlags vkFeatures = kMVKVkFormatFeatureFlagsTexNone;
- if (mvkAreAllFlagsEnabled(mtlPixFmtCaps, kMVKMTLFmtCapsRead)) {
- vkFeatures |= kMVKVkFormatFeatureFlagsBufRead;
+ // Texel buffers are not available to depth/stencil or compressed formats.
+ vkProps.bufferFeatures = kMVKVkFormatFeatureFlagsTexNone;
+ if ( !(vkDesc.formatType == kMVKFormatDepthStencil || vkDesc.formatType == kMVKFormatCompressed) ) {
+ enableFormatFeatures(Read, Buf, mtlPixFmtCaps, vkProps.bufferFeatures);
+ enableFormatFeatures(Write, Buf, mtlPixFmtCaps, vkProps.bufferFeatures);
+ enableFormatFeatures(Atomic, Buf, mtlPixFmtCaps, vkProps.bufferFeatures);
+ enableFormatFeatures(Vertex, Buf, getMTLVertexFormatDesc(vkFmt).mtlFmtCaps, vkProps.bufferFeatures);
}
- if (mvkAreAllFlagsEnabled(mtlPixFmtCaps, kMVKMTLFmtCapsWrite)) {
- vkFeatures |= kMVKVkFormatFeatureFlagsBufWrite;
- }
- if (mvkAreAllFlagsEnabled(mtlVtxFmtCaps, kMVKMTLFmtCapsVertex)) {
- vkFeatures |= kMVKVkFormatFeatureFlagsBufVertex;
- }
- // Only support atomics on R32UI/R32I images for now. Until Metal supports this
- // for real, we need to use the underlying buffer to support image atomics.
- if (vkFormat != VK_FORMAT_R32_UINT && vkFormat != VK_FORMAT_R32_SINT) {
- mvkDisableFlags(vkFeatures, VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT);
- }
- return vkFeatures;
}