Merge pull request #867 from billhollings/master
MVKPixelFormats enables atomic capabilities only when applicable.
This commit is contained in:
commit
e39925f5ee
@ -44,12 +44,13 @@ typedef enum : uint16_t {
|
||||
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 @@ protected:
|
||||
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,
|
||||
|
@ -1072,6 +1072,10 @@ void MVKPixelFormats::modifyMTLFormatCapabilities() {
|
||||
// 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 @@ void MVKPixelFormats::modifyMTLFormatCapabilities(id<MTLDevice> mtlDevice) {
|
||||
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 @@ void MVKPixelFormats::buildVkFormatMaps() {
|
||||
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 @@ typedef enum : VkFormatFeatureFlags {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user