Refactor MVKPixelFormat internals.
Split MVKFormatDesc struct into separate MVKVkFormatDesc & MVKMTLFormatDesc structs. Separate content into Vulkan and Metal format tables.
This commit is contained in:
parent
1f74a6f20d
commit
bb69a5bfc6
@ -16,17 +16,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains functions for converting between Vulkan and Metal data types.
|
||||
*
|
||||
* The functions here are used internally by MoltenVK, and are exposed here
|
||||
* as a convenience for use elsewhere within applications using MoltenVK.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "mvk_datatypes.h"
|
||||
#include "MVKEnvironment.h"
|
||||
#include "MVKBaseObject.h"
|
||||
@ -36,35 +27,47 @@
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKFormatDesc
|
||||
|
||||
/** Validate these values periodically as new formats are added over time. */
|
||||
static const uint32_t _vkSpecFormatCount = 256;
|
||||
static const uint32_t _vkFormatCount = 256;
|
||||
static const uint32_t _vkFormatCoreCount = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
|
||||
static const uint32_t _mtlFormatCount = MTLPixelFormatX32_Stencil8 + 2; // The actual last enum value is not available on iOS
|
||||
static const uint32_t _mtlPixelFormatCount = MTLPixelFormatX32_Stencil8 + 2; // The actual last enum value is not available on iOS
|
||||
static const uint32_t _mtlVertexFormatCount = MTLVertexFormatHalf + 1;
|
||||
|
||||
/** Describes the properties of each VkFormat, including the corresponding Metal pixel format. */
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Format descriptions
|
||||
|
||||
/** Describes the properties of a VkFormat, including the corresponding Metal pixel and vertex format. */
|
||||
typedef struct {
|
||||
VkFormat vk;
|
||||
MTLPixelFormat mtl;
|
||||
MTLPixelFormat mtlSubstitute;
|
||||
MVKOSVersion sinceIOSVersion;
|
||||
MVKOSVersion sinceMacOSVersion;
|
||||
VkExtent2D blockTexelSize;
|
||||
uint32_t bytesPerBlock;
|
||||
VkFormat vkFormat;
|
||||
MTLPixelFormat mtlPixelFormat;
|
||||
MTLPixelFormat mtlPixelFormatSubstitute;
|
||||
MTLVertexFormat mtlVertexFormat;
|
||||
MTLVertexFormat mtlVertexFormatSubstitute;
|
||||
MVKOSVersion vertexSinceIOSVersion;
|
||||
MVKOSVersion vertexSinceMacOSVersion;
|
||||
VkExtent2D blockTexelSize;
|
||||
uint32_t bytesPerBlock;
|
||||
MVKFormatType formatType;
|
||||
VkFormatProperties properties;
|
||||
const char* vkName;
|
||||
const char* mtlName;
|
||||
const char* name;
|
||||
bool hasReportedSubstitution;
|
||||
|
||||
inline double bytesPerTexel() const { return (double)bytesPerBlock / (double)(blockTexelSize.width * blockTexelSize.height); };
|
||||
inline bool isSupported() const { return (mtlPixelFormat != MTLPixelFormatInvalid); };
|
||||
inline bool isSupportedOrSubstitutable() const { return isSupported() || (mtlPixelFormatSubstitute != MTLPixelFormatInvalid); };
|
||||
inline bool vertexIsSupported() const { return (mtlVertexFormat != MTLVertexFormatInvalid); };
|
||||
inline bool vertexIsSupportedOrSubstitutable() const { return vertexIsSupported() || (mtlVertexFormatSubstitute != MTLVertexFormatInvalid); };
|
||||
} MVKVkFormatDesc;
|
||||
|
||||
/** Describes the properties of a MTLPixelFormat or MTLVertexFormat. */
|
||||
typedef struct {
|
||||
union {
|
||||
MTLPixelFormat mtlPixelFormat;
|
||||
MTLVertexFormat mtlVertexFormat;
|
||||
};
|
||||
VkFormat vkFormat;
|
||||
MVKOSVersion sinceIOSVersion;
|
||||
MVKOSVersion sinceMacOSVersion;
|
||||
const char* name;
|
||||
|
||||
inline MVKOSVersion sinceOSVersion() const {
|
||||
#if MVK_IOS
|
||||
@ -74,20 +77,8 @@ typedef struct {
|
||||
return sinceMacOSVersion;
|
||||
#endif
|
||||
}
|
||||
inline bool isSupported() const { return (mtl != MTLPixelFormatInvalid) && (mvkOSVersion() >= sinceOSVersion()); };
|
||||
inline bool isSupportedOrSubstitutable() const { return isSupported() || (mtlSubstitute != MTLPixelFormatInvalid); };
|
||||
|
||||
inline MVKOSVersion vertexSinceOSVersion() const {
|
||||
#if MVK_IOS
|
||||
return vertexSinceIOSVersion;
|
||||
#endif
|
||||
#if MVK_MACOS
|
||||
return vertexSinceMacOSVersion;
|
||||
#endif
|
||||
}
|
||||
inline bool vertexIsSupported() const { return (mtlVertexFormat != MTLVertexFormatInvalid) && (mvkOSVersion() >= vertexSinceOSVersion()); };
|
||||
inline bool vertexIsSupportedOrSubstitutable() const { return vertexIsSupported() || (mtlVertexFormatSubstitute != MTLVertexFormatInvalid); };
|
||||
} MVKFormatDesc;
|
||||
inline bool isSupported() const { return (mtlPixelFormat != MTLPixelFormatInvalid) && (mvkOSVersion() >= sinceOSVersion()); };
|
||||
} MVKMTLFormatDesc;
|
||||
|
||||
|
||||
#pragma mark -
|
||||
@ -247,11 +238,13 @@ public:
|
||||
MVKPixelFormats() : MVKPixelFormats(nullptr, nil) {}
|
||||
|
||||
protected:
|
||||
const MVKFormatDesc& formatDescForVkFormat(VkFormat vkFormat);
|
||||
const MVKFormatDesc& formatDescForMTLPixelFormat(MTLPixelFormat mtlFormat);
|
||||
const MVKFormatDesc& formatDescForMTLVertexFormat(MTLVertexFormat mtlFormat);
|
||||
void initFormatCapabilities();
|
||||
void buidFormatMaps();
|
||||
MVKVkFormatDesc& getDescForVkFormat(VkFormat vkFormat);
|
||||
MVKMTLFormatDesc& getDescForMTLPixelFormat(MTLPixelFormat mtlFormat);
|
||||
MVKMTLFormatDesc& getDescForMTLVertexFormat(MTLVertexFormat mtlFormat);
|
||||
void initVkFormatCapabilities();
|
||||
void initMTLPixelFormatCapabilities();
|
||||
void initMTLVertexFormatCapabilities();
|
||||
void buildFormatMaps();
|
||||
void modifyFormatCapabilitiesForMTLDevice(id<MTLDevice> mtlDevice);
|
||||
void disableMTLPixelFormat(MTLPixelFormat mtlFormat);
|
||||
|
||||
@ -260,16 +253,16 @@ protected:
|
||||
void test();
|
||||
|
||||
MVKVulkanAPIObject* _apiObject;
|
||||
MVKFormatDesc _formatDescriptions[_vkSpecFormatCount];
|
||||
uint32_t _vkFormatCount;
|
||||
MVKVkFormatDesc _vkFormatDescriptions[_vkFormatCount];
|
||||
MVKMTLFormatDesc _mtlPixelFormatDescriptions[_mtlPixelFormatCount];
|
||||
MVKMTLFormatDesc _mtlVertexFormatDescriptions[_mtlVertexFormatCount];
|
||||
|
||||
// Vulkan core formats have small values and are mapped by simple lookup array.
|
||||
// Vulkan extension formats have larger values and are mapped by a map.
|
||||
uint16_t _fmtDescIndicesByVkFormatsCore[_vkFormatCoreCount];
|
||||
std::unordered_map<uint32_t, uint32_t> _fmtDescIndicesByVkFormatsExt;
|
||||
uint16_t _vkFormatDescIndicesByVkFormatsCore[_vkFormatCoreCount];
|
||||
std::unordered_map<uint32_t, uint32_t> _vkFormatDescIndicesByVkFormatsExt;
|
||||
|
||||
// Metal formats have small values and are mapped by simple lookup array.
|
||||
uint16_t _fmtDescIndicesByMTLPixelFormats[_mtlFormatCount];
|
||||
uint16_t _fmtDescIndicesByMTLVertexFormats[_mtlVertexFormatCount];
|
||||
|
||||
uint16_t _mtlFormatDescIndicesByMTLPixelFormats[_mtlPixelFormatCount];
|
||||
uint16_t _mtlFormatDescIndicesByMTLVertexFormats[_mtlVertexFormatCount];
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -485,7 +485,7 @@ static uint16_t _fmtDescIndicesByVkFormatsCore[_vkFormatCoreCount];
|
||||
static MVKFormatIndexByVkFormatMap* _pFmtDescIndicesByVkFormatsExt;
|
||||
|
||||
// Metal formats have small values and are mapped by simple lookup array.
|
||||
static uint16_t _fmtDescIndicesByMTLPixelFormats[_mtlFormatCount];
|
||||
static uint16_t _fmtDescIndicesByMTLPixelFormats[_mtlPixelFormatCount];
|
||||
static uint16_t _fmtDescIndicesByMTLVertexFormats[_mtlVertexFormatCount];
|
||||
|
||||
/**
|
||||
@ -502,7 +502,7 @@ static void MVKInitFormatMaps() {
|
||||
|
||||
// Set all VkFormats and MTLPixelFormats to undefined/invalid
|
||||
mvkClear(_fmtDescIndicesByVkFormatsCore, _vkFormatCoreCount);
|
||||
mvkClear(_fmtDescIndicesByMTLPixelFormats, _mtlFormatCount);
|
||||
mvkClear(_fmtDescIndicesByMTLPixelFormats, _mtlPixelFormatCount);
|
||||
mvkClear(_fmtDescIndicesByMTLVertexFormats, _mtlVertexFormatCount);
|
||||
|
||||
_pFmtDescIndicesByVkFormatsExt = new MVKFormatIndexByVkFormatMap();
|
||||
@ -527,8 +527,12 @@ static void MVKInitFormatMaps() {
|
||||
|
||||
// If the Metal format is defined, create a lookup between the Metal format and an
|
||||
// index to the format info. Metal formats are small, so use a simple lookup array.
|
||||
if (tfm.mtl != MTLPixelFormatInvalid) { _fmtDescIndicesByMTLPixelFormats[tfm.mtl] = fmtIdx; }
|
||||
if (tfm.mtlVertexFormat != MTLVertexFormatInvalid) { _fmtDescIndicesByMTLVertexFormats[tfm.mtlVertexFormat] = fmtIdx; }
|
||||
if (tfm.mtl != MTLPixelFormatInvalid && !_fmtDescIndicesByMTLPixelFormats[tfm.mtl]) {
|
||||
_fmtDescIndicesByMTLPixelFormats[tfm.mtl] = fmtIdx;
|
||||
}
|
||||
if (tfm.mtlVertexFormat != MTLVertexFormatInvalid && !_fmtDescIndicesByMTLVertexFormats[tfm.mtlVertexFormat]) {
|
||||
_fmtDescIndicesByMTLVertexFormats[tfm.mtlVertexFormat] = fmtIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -540,7 +544,7 @@ inline const MVKPlatformFormatDesc& formatDescForVkFormat(VkFormat vkFormat) {
|
||||
|
||||
// Return a reference to the format description corresponding to the MTLPixelFormat.
|
||||
inline const MVKPlatformFormatDesc& formatDescForMTLPixelFormat(MTLPixelFormat mtlFormat) {
|
||||
uint16_t fmtIdx = (mtlFormat < _mtlFormatCount) ? _fmtDescIndicesByMTLPixelFormats[mtlFormat] : 0;
|
||||
uint16_t fmtIdx = (mtlFormat < _mtlPixelFormatCount) ? _fmtDescIndicesByMTLPixelFormats[mtlFormat] : 0;
|
||||
return _formatDescriptions[fmtIdx];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user