Reduce memory used by MVKPixelFormats lookups.
- Add MVKInflectionMap collection to manage lookups based on enums that have a large set of consecutive elements, plus additional enum values that are more sparsely assigned. - Recognize every MTLPixelFormat value can be held in uint16_t. - Reduce inflection-map sizes by calling shrink_to_fit(). - runcts script log completion time (unrelated).
This commit is contained in:
parent
fe65485bfb
commit
88799cf255
@ -318,6 +318,10 @@
|
|||||||
A9A5E9C725C0822700E9085E /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
A9A5E9C725C0822700E9085E /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
||||||
A9A5E9C825C0822700E9085E /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
A9A5E9C825C0822700E9085E /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
||||||
A9A5E9C925C0822700E9085E /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
A9A5E9C925C0822700E9085E /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
||||||
|
A9AB952B2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */; };
|
||||||
|
A9AB952C2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */; };
|
||||||
|
A9AB952D2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */; };
|
||||||
|
A9AB952E2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */; };
|
||||||
A9B3D73B29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */; };
|
A9B3D73B29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */; };
|
||||||
A9B3D73C29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */; };
|
A9B3D73C29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */; };
|
||||||
A9B3D73D29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */; };
|
A9B3D73D29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */; };
|
||||||
@ -667,6 +671,7 @@
|
|||||||
A99C91002295FAC500A061DA /* MVKVulkanAPIObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKVulkanAPIObject.mm; sourceTree = "<group>"; };
|
A99C91002295FAC500A061DA /* MVKVulkanAPIObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKVulkanAPIObject.mm; sourceTree = "<group>"; };
|
||||||
A99C91012295FAC500A061DA /* MVKVulkanAPIObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKVulkanAPIObject.h; sourceTree = "<group>"; };
|
A99C91012295FAC500A061DA /* MVKVulkanAPIObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKVulkanAPIObject.h; sourceTree = "<group>"; };
|
||||||
A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKEnvironment.cpp; sourceTree = "<group>"; };
|
A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKEnvironment.cpp; sourceTree = "<group>"; };
|
||||||
|
A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKInflectionMap.h; sourceTree = "<group>"; };
|
||||||
A9AD67C72054DD6C00ED3C08 /* vulkan */ = {isa = PBXFileReference; lastKnownFileType = folder; path = vulkan; sourceTree = "<group>"; };
|
A9AD67C72054DD6C00ED3C08 /* vulkan */ = {isa = PBXFileReference; lastKnownFileType = folder; path = vulkan; sourceTree = "<group>"; };
|
||||||
A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mvk_deprecated_api.h; sourceTree = "<group>"; };
|
A9B3D73829F9B3B100745CD4 /* mvk_deprecated_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mvk_deprecated_api.h; sourceTree = "<group>"; };
|
||||||
A9B3D73A29F9B3B100745CD4 /* mvk_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mvk_config.h; sourceTree = "<group>"; };
|
A9B3D73A29F9B3B100745CD4 /* mvk_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mvk_config.h; sourceTree = "<group>"; };
|
||||||
@ -840,7 +845,6 @@
|
|||||||
A98149401FB6A3F7005F00B4 /* Utility */ = {
|
A98149401FB6A3F7005F00B4 /* Utility */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */,
|
|
||||||
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
|
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
|
||||||
A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */,
|
A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */,
|
||||||
A9D7104E25CDE05E00E38106 /* MVKBitArray.h */,
|
A9D7104E25CDE05E00E38106 /* MVKBitArray.h */,
|
||||||
@ -854,6 +858,8 @@
|
|||||||
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
|
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
|
||||||
A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */,
|
A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */,
|
||||||
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */,
|
A98149441FB6A3F7005F00B4 /* MVKFoundation.h */,
|
||||||
|
A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */,
|
||||||
|
A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */,
|
||||||
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
|
A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */,
|
||||||
A9F3D9DB24732A4D00745190 /* MVKSmallVector.h */,
|
A9F3D9DB24732A4D00745190 /* MVKSmallVector.h */,
|
||||||
A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */,
|
A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */,
|
||||||
@ -981,6 +987,7 @@
|
|||||||
2FEA0A5924902F9F00EEF3AD /* MVKDevice.h in Headers */,
|
2FEA0A5924902F9F00EEF3AD /* MVKDevice.h in Headers */,
|
||||||
2FEA0A5A24902F9F00EEF3AD /* MVKSmallVector.h in Headers */,
|
2FEA0A5A24902F9F00EEF3AD /* MVKSmallVector.h in Headers */,
|
||||||
2FEA0A5C24902F9F00EEF3AD /* MVKCommandPool.h in Headers */,
|
2FEA0A5C24902F9F00EEF3AD /* MVKCommandPool.h in Headers */,
|
||||||
|
A9AB952C2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */,
|
||||||
A9B3D74329F9BDEE00745CD4 /* mvk_private_api.h in Headers */,
|
A9B3D74329F9BDEE00745CD4 /* mvk_private_api.h in Headers */,
|
||||||
2FEA0A5D24902F9F00EEF3AD /* MVKShaderModule.h in Headers */,
|
2FEA0A5D24902F9F00EEF3AD /* MVKShaderModule.h in Headers */,
|
||||||
2FEA0A5E24902F9F00EEF3AD /* MVKVulkanAPIObject.h in Headers */,
|
2FEA0A5E24902F9F00EEF3AD /* MVKVulkanAPIObject.h in Headers */,
|
||||||
@ -1060,6 +1067,7 @@
|
|||||||
A9F3D9DE24732A4D00745190 /* MVKSmallVector.h in Headers */,
|
A9F3D9DE24732A4D00745190 /* MVKSmallVector.h in Headers */,
|
||||||
A94FB7D41C7DFB4800632CA3 /* MVKCommandPool.h in Headers */,
|
A94FB7D41C7DFB4800632CA3 /* MVKCommandPool.h in Headers */,
|
||||||
A94FB80C1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */,
|
A94FB80C1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */,
|
||||||
|
A9AB952B2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */,
|
||||||
A99C91042295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */,
|
A99C91042295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */,
|
||||||
A94FB7C01C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */,
|
A94FB7C01C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */,
|
||||||
A9B3D73B29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */,
|
A9B3D73B29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */,
|
||||||
@ -1138,6 +1146,7 @@
|
|||||||
A94FB7D51C7DFB4800632CA3 /* MVKCommandPool.h in Headers */,
|
A94FB7D51C7DFB4800632CA3 /* MVKCommandPool.h in Headers */,
|
||||||
A94FB80D1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */,
|
A94FB80D1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */,
|
||||||
A99C91052295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */,
|
A99C91052295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */,
|
||||||
|
A9AB952D2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */,
|
||||||
A94FB7C11C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */,
|
A94FB7C11C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */,
|
||||||
A94FB7CD1C7DFB4800632CA3 /* MVKCommand.h in Headers */,
|
A94FB7CD1C7DFB4800632CA3 /* MVKCommand.h in Headers */,
|
||||||
A9B3D73D29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */,
|
A9B3D73D29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */,
|
||||||
@ -1237,6 +1246,7 @@
|
|||||||
DCFD7F142A45BC6E007BBBF7 /* MVKCmdTransfer.h in Headers */,
|
DCFD7F142A45BC6E007BBBF7 /* MVKCmdTransfer.h in Headers */,
|
||||||
DCFD7F152A45BC6E007BBBF7 /* MVKDescriptor.h in Headers */,
|
DCFD7F152A45BC6E007BBBF7 /* MVKDescriptor.h in Headers */,
|
||||||
DCFD7F162A45BC6E007BBBF7 /* MVKCmdDraw.h in Headers */,
|
DCFD7F162A45BC6E007BBBF7 /* MVKCmdDraw.h in Headers */,
|
||||||
|
A9AB952E2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */,
|
||||||
DCFD7F172A45BC6E007BBBF7 /* MVKCommandBuffer.h in Headers */,
|
DCFD7F172A45BC6E007BBBF7 /* MVKCommandBuffer.h in Headers */,
|
||||||
DCFD7F182A45BC6E007BBBF7 /* MTLRenderPassDescriptor+MoltenVK.h in Headers */,
|
DCFD7F182A45BC6E007BBBF7 /* MTLRenderPassDescriptor+MoltenVK.h in Headers */,
|
||||||
DCFD7F192A45BC6E007BBBF7 /* MVKCmdDebug.h in Headers */,
|
DCFD7F192A45BC6E007BBBF7 /* MVKCmdDebug.h in Headers */,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "MVKBaseObject.h"
|
#include "MVKBaseObject.h"
|
||||||
#include "MVKOSExtensions.h"
|
#include "MVKOSExtensions.h"
|
||||||
|
#include "MVKInflectionMap.h"
|
||||||
#include "mvk_datatypes.hpp"
|
#include "mvk_datatypes.hpp"
|
||||||
#include <spirv_msl.hpp>
|
#include <spirv_msl.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -29,14 +30,6 @@
|
|||||||
class MVKPhysicalDevice;
|
class MVKPhysicalDevice;
|
||||||
|
|
||||||
|
|
||||||
// Validate these values periodically as new formats are added over time.
|
|
||||||
static const uint32_t _vkFormatCount = 256;
|
|
||||||
static const uint32_t _vkFormatCoreCount = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
|
|
||||||
static const uint32_t _mtlPixelFormatCount = 256;
|
|
||||||
static const uint32_t _mtlPixelFormatCoreCount = MTLPixelFormatX32_Stencil8 + 2; // The actual last enum value is not available on iOS
|
|
||||||
static const uint32_t _mtlVertexFormatCount = MTLVertexFormatHalf + 1;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark Metal format capabilities
|
#pragma mark Metal format capabilities
|
||||||
|
|
||||||
@ -418,7 +411,6 @@ protected:
|
|||||||
void initVkFormatCapabilities();
|
void initVkFormatCapabilities();
|
||||||
void initMTLPixelFormatCapabilities();
|
void initMTLPixelFormatCapabilities();
|
||||||
void initMTLVertexFormatCapabilities();
|
void initMTLVertexFormatCapabilities();
|
||||||
void buildMTLFormatMaps();
|
|
||||||
void buildVkFormatMaps();
|
void buildVkFormatMaps();
|
||||||
void setFormatProperties(MVKVkFormatDesc& vkDesc);
|
void setFormatProperties(MVKVkFormatDesc& vkDesc);
|
||||||
void modifyMTLFormatCapabilities();
|
void modifyMTLFormatCapabilities();
|
||||||
@ -446,17 +438,7 @@ protected:
|
|||||||
MVKMTLFmtCaps mtlFmtCaps);
|
MVKMTLFmtCaps mtlFmtCaps);
|
||||||
|
|
||||||
MVKPhysicalDevice* _physicalDevice;
|
MVKPhysicalDevice* _physicalDevice;
|
||||||
MVKVkFormatDesc _vkFormatDescriptions[_vkFormatCount];
|
MVKInflectionMap<VkFormat, MVKVkFormatDesc, VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1> _vkFormatDescriptions;
|
||||||
MVKMTLFormatDesc _mtlPixelFormatDescriptions[_mtlPixelFormatCount];
|
MVKInflectionMap<uint16_t, MVKMTLFormatDesc, MTLPixelFormatX32_Stencil8 + 2> _mtlPixelFormatDescriptions; // The actual last enum value is not available on iOS
|
||||||
MVKMTLFormatDesc _mtlVertexFormatDescriptions[_mtlVertexFormatCount];
|
MVKSmallVector<MVKMTLFormatDesc> _mtlVertexFormatDescriptions;
|
||||||
|
|
||||||
// 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 _vkFormatDescIndicesByVkFormatsCore[_vkFormatCoreCount];
|
|
||||||
std::unordered_map<uint32_t, uint32_t> _vkFormatDescIndicesByVkFormatsExt;
|
|
||||||
|
|
||||||
// Most Metal formats have small values and are mapped by simple lookup array.
|
|
||||||
// Outliers are mapped by a map.
|
|
||||||
uint16_t _mtlFormatDescIndicesByMTLPixelFormatsCore[_mtlPixelFormatCoreCount];
|
|
||||||
std::unordered_map<NSUInteger, uint32_t> _mtlFormatDescIndicesByMTLPixelFormatsExt;
|
|
||||||
};
|
};
|
||||||
|
@ -762,10 +762,7 @@ MTLTextureUsage MVKPixelFormats::getMTLTextureUsage(VkImageUsageFlags vkImageUsa
|
|||||||
|
|
||||||
// Return a reference to the Vulkan format descriptor corresponding to the VkFormat.
|
// Return a reference to the Vulkan format descriptor corresponding to the VkFormat.
|
||||||
MVKVkFormatDesc& MVKPixelFormats::getVkFormatDesc(VkFormat vkFormat) {
|
MVKVkFormatDesc& MVKPixelFormats::getVkFormatDesc(VkFormat vkFormat) {
|
||||||
uint16_t fmtIdx = ((vkFormat < _vkFormatCoreCount)
|
return _vkFormatDescriptions[vkFormat];
|
||||||
? _vkFormatDescIndicesByVkFormatsCore[vkFormat]
|
|
||||||
: _vkFormatDescIndicesByVkFormatsExt[vkFormat]);
|
|
||||||
return _vkFormatDescriptions[fmtIdx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a reference to the Vulkan format descriptor corresponding to the MTLPixelFormat.
|
// Return a reference to the Vulkan format descriptor corresponding to the MTLPixelFormat.
|
||||||
@ -775,15 +772,12 @@ MVKVkFormatDesc& MVKPixelFormats::getVkFormatDesc(MTLPixelFormat mtlFormat) {
|
|||||||
|
|
||||||
// Return a reference to the Metal format descriptor corresponding to the MTLPixelFormat.
|
// Return a reference to the Metal format descriptor corresponding to the MTLPixelFormat.
|
||||||
MVKMTLFormatDesc& MVKPixelFormats::getMTLPixelFormatDesc(MTLPixelFormat mtlFormat) {
|
MVKMTLFormatDesc& MVKPixelFormats::getMTLPixelFormatDesc(MTLPixelFormat mtlFormat) {
|
||||||
uint16_t fmtIdx = ((mtlFormat < _mtlPixelFormatCoreCount)
|
return _mtlPixelFormatDescriptions[mtlFormat];
|
||||||
? _mtlFormatDescIndicesByMTLPixelFormatsCore[mtlFormat]
|
|
||||||
: _mtlFormatDescIndicesByMTLPixelFormatsExt[mtlFormat]);
|
|
||||||
return _mtlPixelFormatDescriptions[fmtIdx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a reference to the Metal format descriptor corresponding to the MTLVertexFormat.
|
// Return a reference to the Metal format descriptor corresponding to the MTLVertexFormat.
|
||||||
MVKMTLFormatDesc& MVKPixelFormats::getMTLVertexFormatDesc(MTLVertexFormat mtlFormat) {
|
MVKMTLFormatDesc& MVKPixelFormats::getMTLVertexFormatDesc(MTLVertexFormat mtlFormat) {
|
||||||
return _mtlVertexFormatDescriptions[mtlFormat < _mtlVertexFormatCount ? mtlFormat : 0];
|
return _mtlVertexFormatDescriptions[mtlFormat];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -794,7 +788,6 @@ MVKPixelFormats::MVKPixelFormats(MVKPhysicalDevice* physicalDevice) : _physicalD
|
|||||||
// Build and update the Metal formats
|
// Build and update the Metal formats
|
||||||
initMTLPixelFormatCapabilities();
|
initMTLPixelFormatCapabilities();
|
||||||
initMTLVertexFormatCapabilities();
|
initMTLVertexFormatCapabilities();
|
||||||
buildMTLFormatMaps();
|
|
||||||
modifyMTLFormatCapabilities();
|
modifyMTLFormatCapabilities();
|
||||||
|
|
||||||
// Build the Vulkan formats and link them to the Metal formats
|
// Build the Vulkan formats and link them to the Metal formats
|
||||||
@ -803,11 +796,11 @@ MVKPixelFormats::MVKPixelFormats(MVKPhysicalDevice* physicalDevice) : _physicalD
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define addVkFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, SWIZ_R, SWIZ_G, SWIZ_B, SWIZ_A) \
|
#define addVkFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, SWIZ_R, SWIZ_G, SWIZ_B, SWIZ_A) \
|
||||||
MVKAssert(fmtIdx < _vkFormatCount, "Attempting to describe %d VkFormats, but only have space for %d. Increase the value of _vkFormatCount", fmtIdx + 1, _vkFormatCount); \
|
vkFmt = VK_FORMAT_ ##VK_FMT; \
|
||||||
_vkFormatDescriptions[fmtIdx++] = { VK_FORMAT_ ##VK_FMT, MTLPixelFormat ##MTL_FMT, MTLPixelFormat ##MTL_FMT_ALT, MTLVertexFormat ##MTL_VTX_FMT, MTLVertexFormat ##MTL_VTX_FMT_ALT, \
|
_vkFormatDescriptions[vkFmt] = { vkFmt, MTLPixelFormat ##MTL_FMT, MTLPixelFormat ##MTL_FMT_ALT, MTLVertexFormat ##MTL_VTX_FMT, MTLVertexFormat ##MTL_VTX_FMT_ALT, \
|
||||||
CSPC, CSCB, { BLK_W, BLK_H }, BLK_BYTE_CNT, kMVKFormat ##MVK_FMT_TYPE, { 0, 0, 0 }, \
|
CSPC, CSCB, { BLK_W, BLK_H }, BLK_BYTE_CNT, kMVKFormat ##MVK_FMT_TYPE, { 0, 0, 0 }, \
|
||||||
{ VK_COMPONENT_SWIZZLE_ ##SWIZ_R, VK_COMPONENT_SWIZZLE_ ##SWIZ_G, VK_COMPONENT_SWIZZLE_ ##SWIZ_B, VK_COMPONENT_SWIZZLE_ ##SWIZ_A }, \
|
{ VK_COMPONENT_SWIZZLE_ ##SWIZ_R, VK_COMPONENT_SWIZZLE_ ##SWIZ_G, VK_COMPONENT_SWIZZLE_ ##SWIZ_B, VK_COMPONENT_SWIZZLE_ ##SWIZ_A }, \
|
||||||
"VK_FORMAT_" #VK_FMT, false }
|
"VK_FORMAT_" #VK_FMT, false }
|
||||||
|
|
||||||
#define addVkFormatDesc(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE) \
|
#define addVkFormatDesc(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE) \
|
||||||
addVkFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, 0, 0, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, IDENTITY, IDENTITY, IDENTITY, IDENTITY)
|
addVkFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, 0, 0, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, IDENTITY, IDENTITY, IDENTITY, IDENTITY)
|
||||||
@ -819,12 +812,7 @@ MVKPixelFormats::MVKPixelFormats(MVKPhysicalDevice* physicalDevice) : _physicalD
|
|||||||
addVkFormatDescFull(VK_FMT, MTL_FMT, Invalid, Invalid, Invalid, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, ColorFloat, IDENTITY, IDENTITY, IDENTITY, IDENTITY)
|
addVkFormatDescFull(VK_FMT, MTL_FMT, Invalid, Invalid, Invalid, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, ColorFloat, IDENTITY, IDENTITY, IDENTITY, IDENTITY)
|
||||||
|
|
||||||
void MVKPixelFormats::initVkFormatCapabilities() {
|
void MVKPixelFormats::initVkFormatCapabilities() {
|
||||||
|
VkFormat vkFmt;
|
||||||
mvkClear(_vkFormatDescriptions, _vkFormatCount);
|
|
||||||
|
|
||||||
uint32_t fmtIdx = 0;
|
|
||||||
|
|
||||||
// When adding to this list, be sure to ensure _vkFormatCount is large enough for the format count
|
|
||||||
|
|
||||||
// UNDEFINED must come first.
|
// UNDEFINED must come first.
|
||||||
addVkFormatDesc( UNDEFINED, Invalid, Invalid, Invalid, Invalid, 1, 1, 0, None );
|
addVkFormatDesc( UNDEFINED, Invalid, Invalid, Invalid, Invalid, 1, 1, 0, None );
|
||||||
@ -1115,15 +1103,14 @@ void MVKPixelFormats::initVkFormatCapabilities() {
|
|||||||
addVkFormatDescChromaSubsampling( G16_B16R16_2PLANE_422_UNORM, Invalid, 2, 16, 2, 1, 8 );
|
addVkFormatDescChromaSubsampling( G16_B16R16_2PLANE_422_UNORM, Invalid, 2, 16, 2, 1, 8 );
|
||||||
addVkFormatDescChromaSubsampling( G16_B16_R16_3PLANE_444_UNORM, Invalid, 3, 16, 1, 1, 6 );
|
addVkFormatDescChromaSubsampling( G16_B16_R16_3PLANE_444_UNORM, Invalid, 3, 16, 1, 1, 6 );
|
||||||
|
|
||||||
// When adding to this list, be sure to ensure _vkFormatCount is large enough for the format count
|
_vkFormatDescriptions.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define addMTLPixelFormatDescFull(MTL_FMT, VIEW_CLASS, IOS_CAPS, MACOS_CAPS, MTL_FMT_LINEAR) \
|
#define addMTLPixelFormatDescFull(MTL_FMT, VIEW_CLASS, IOS_CAPS, MACOS_CAPS, MTL_FMT_LINEAR) \
|
||||||
MVKAssert(fmtIdx < _mtlPixelFormatCount, "Attempting to describe %d MTLPixelFormats, but only have space for %d. Increase the value of _mtlPixelFormatCount", fmtIdx + 1, _mtlPixelFormatCount); \
|
mtlPixFmt = MTLPixelFormat ##MTL_FMT; \
|
||||||
_mtlPixelFormatDescriptions[fmtIdx++] = { .mtlPixelFormat = MTLPixelFormat ##MTL_FMT, VK_FORMAT_UNDEFINED, \
|
_mtlPixelFormatDescriptions[mtlPixFmt] = { .mtlPixelFormat = mtlPixFmt, VK_FORMAT_UNDEFINED, \
|
||||||
mvkSelectPlatformValue<MVKMTLFmtCaps>(kMVKMTLFmtCaps ##MACOS_CAPS, kMVKMTLFmtCaps ##IOS_CAPS), \
|
mvkSelectPlatformValue<MVKMTLFmtCaps>(kMVKMTLFmtCaps ##MACOS_CAPS, kMVKMTLFmtCaps ##IOS_CAPS), \
|
||||||
MVKMTLViewClass:: VIEW_CLASS, MTLPixelFormat ##MTL_FMT_LINEAR, "MTLPixelFormat" #MTL_FMT }
|
MVKMTLViewClass:: VIEW_CLASS, MTLPixelFormat ##MTL_FMT_LINEAR, "MTLPixelFormat" #MTL_FMT }
|
||||||
|
|
||||||
#define addMTLPixelFormatDesc(MTL_FMT, VIEW_CLASS, IOS_CAPS, MACOS_CAPS) \
|
#define addMTLPixelFormatDesc(MTL_FMT, VIEW_CLASS, IOS_CAPS, MACOS_CAPS) \
|
||||||
addMTLPixelFormatDescFull(MTL_FMT, VIEW_CLASS, IOS_CAPS, MACOS_CAPS, MTL_FMT)
|
addMTLPixelFormatDescFull(MTL_FMT, VIEW_CLASS, IOS_CAPS, MACOS_CAPS, MTL_FMT)
|
||||||
@ -1133,12 +1120,7 @@ void MVKPixelFormats::initVkFormatCapabilities() {
|
|||||||
|
|
||||||
|
|
||||||
void MVKPixelFormats::initMTLPixelFormatCapabilities() {
|
void MVKPixelFormats::initMTLPixelFormatCapabilities() {
|
||||||
|
MTLPixelFormat mtlPixFmt;
|
||||||
mvkClear(_mtlPixelFormatDescriptions, _mtlPixelFormatCount);
|
|
||||||
|
|
||||||
uint32_t fmtIdx = 0;
|
|
||||||
|
|
||||||
// When adding to this list, be sure to ensure _mtlPixelFormatCount is large enough for the format count
|
|
||||||
|
|
||||||
// MTLPixelFormatInvalid must come first.
|
// MTLPixelFormatInvalid must come first.
|
||||||
addMTLPixelFormatDesc ( Invalid, None, None, None );
|
addMTLPixelFormatDesc ( Invalid, None, None, None );
|
||||||
@ -1307,26 +1289,21 @@ void MVKPixelFormats::initMTLPixelFormatCapabilities() {
|
|||||||
addMTLPixelFormatDesc ( X24_Stencil8, Depth24_Stencil8, None, DRMR );
|
addMTLPixelFormatDesc ( X24_Stencil8, Depth24_Stencil8, None, DRMR );
|
||||||
addMTLPixelFormatDesc ( X32_Stencil8, Depth32_Stencil8, DRM, DRMR );
|
addMTLPixelFormatDesc ( X32_Stencil8, Depth32_Stencil8, DRM, DRMR );
|
||||||
|
|
||||||
// When adding to this list, be sure to ensure _mtlPixelFormatCount is large enough for the format count
|
_mtlPixelFormatDescriptions.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If necessary, resize vector with empty elements
|
||||||
#define addMTLVertexFormatDesc(MTL_VTX_FMT, IOS_CAPS, MACOS_CAPS) \
|
#define addMTLVertexFormatDesc(MTL_VTX_FMT, IOS_CAPS, MACOS_CAPS) \
|
||||||
mtlVtxFmt = MTLVertexFormat ##MTL_VTX_FMT; \
|
mtlVtxFmt = MTLVertexFormat ##MTL_VTX_FMT; \
|
||||||
if (mtlVtxFmt < _mtlVertexFormatCount) { \
|
if (mtlVtxFmt >= _mtlVertexFormatDescriptions.size()) { _mtlVertexFormatDescriptions.resize(mtlVtxFmt + 1, {}); } \
|
||||||
_mtlVertexFormatDescriptions[mtlVtxFmt] = { .mtlVertexFormat = mtlVtxFmt, VK_FORMAT_UNDEFINED, \
|
_mtlVertexFormatDescriptions[mtlVtxFmt] = { .mtlVertexFormat = mtlVtxFmt, VK_FORMAT_UNDEFINED, \
|
||||||
mvkSelectPlatformValue<MVKMTLFmtCaps>(kMVKMTLFmtCaps ##MACOS_CAPS, kMVKMTLFmtCaps ##IOS_CAPS), \
|
mvkSelectPlatformValue<MVKMTLFmtCaps>(kMVKMTLFmtCaps ##MACOS_CAPS, kMVKMTLFmtCaps ##IOS_CAPS), \
|
||||||
MVKMTLViewClass::None, MTLPixelFormatInvalid, "MTLVertexFormat" #MTL_VTX_FMT }; \
|
MVKMTLViewClass::None, MTLPixelFormatInvalid, "MTLVertexFormat" #MTL_VTX_FMT };
|
||||||
} else { \
|
|
||||||
MVKAssert(false, "Attempting to describe at least %lu MTLVertexFormats, but only have space for %d. Increase the value of _mtlVertexFormatCount", mtlVtxFmt + 1, _mtlVertexFormatCount); \
|
|
||||||
}
|
|
||||||
|
|
||||||
void MVKPixelFormats::initMTLVertexFormatCapabilities() {
|
void MVKPixelFormats::initMTLVertexFormatCapabilities() {
|
||||||
|
MTLVertexFormat mtlVtxFmt;
|
||||||
|
|
||||||
mvkClear(_mtlVertexFormatDescriptions, _mtlVertexFormatCount);
|
_mtlVertexFormatDescriptions.reserve(MTLVertexFormatHalf + 3);
|
||||||
|
|
||||||
MTLVertexFormat mtlVtxFmt = MTLVertexFormatInvalid;
|
|
||||||
|
|
||||||
// When adding to this list, be sure to ensure _mtlVertexFormatCount is large enough for the format count
|
|
||||||
|
|
||||||
addMTLVertexFormatDesc( Invalid, None, None ); // MTLVertexFormatInvalid must come first.
|
addMTLVertexFormatDesc( Invalid, None, None ); // MTLVertexFormatInvalid must come first.
|
||||||
|
|
||||||
@ -1395,28 +1372,7 @@ void MVKPixelFormats::initMTLVertexFormatCapabilities() {
|
|||||||
|
|
||||||
addMTLVertexFormatDesc( UChar4Normalized_BGRA, None, None );
|
addMTLVertexFormatDesc( UChar4Normalized_BGRA, None, None );
|
||||||
|
|
||||||
// When adding to this list, be sure to ensure _mtlVertexFormatCount is large enough for the format count
|
_mtlVertexFormatDescriptions.shrink_to_fit();
|
||||||
}
|
|
||||||
|
|
||||||
// Populates the Metal lookup maps
|
|
||||||
void MVKPixelFormats::buildMTLFormatMaps() {
|
|
||||||
|
|
||||||
// Set all MTLPixelFormats lookups to undefined/invalid
|
|
||||||
mvkClear(_mtlFormatDescIndicesByMTLPixelFormatsCore, _mtlPixelFormatCoreCount);
|
|
||||||
|
|
||||||
// Build lookup table for MTLPixelFormat specs.
|
|
||||||
// For most Metal format values, which are small and consecutive, use a simple lookup array.
|
|
||||||
// For outlier format values, which can be large, use a map.
|
|
||||||
for (uint32_t fmtIdx = 0; fmtIdx < _mtlPixelFormatCount; fmtIdx++) {
|
|
||||||
MTLPixelFormat fmt = _mtlPixelFormatDescriptions[fmtIdx].mtlPixelFormat;
|
|
||||||
if (fmt) {
|
|
||||||
if (fmt < _mtlPixelFormatCoreCount) {
|
|
||||||
_mtlFormatDescIndicesByMTLPixelFormatsCore[fmt] = fmtIdx;
|
|
||||||
} else {
|
|
||||||
_mtlFormatDescIndicesByMTLPixelFormatsExt[fmt] = fmtIdx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the device supports the feature set, add additional capabilities to a MTLPixelFormat
|
// If the device supports the feature set, add additional capabilities to a MTLPixelFormat
|
||||||
@ -1985,69 +1941,50 @@ void MVKPixelFormats::modifyMTLFormatCapabilities(id<MTLDevice> mtlDevice) {
|
|||||||
#undef addFeatSetMTLVtxFmtCaps
|
#undef addFeatSetMTLVtxFmtCaps
|
||||||
#undef addGPUOSMTLVtxFmtCaps
|
#undef addGPUOSMTLVtxFmtCaps
|
||||||
|
|
||||||
// Populates the VkFormat lookup maps and connects Vulkan and Metal pixel formats to one-another.
|
// Connects Vulkan and Metal pixel formats to one-another.
|
||||||
void MVKPixelFormats::buildVkFormatMaps() {
|
void MVKPixelFormats::buildVkFormatMaps() {
|
||||||
|
for (auto& vkDesc : _vkFormatDescriptions) {
|
||||||
// Set the VkFormats to undefined/invalid
|
if (vkDesc.needsSwizzle()) {
|
||||||
mvkClear(_vkFormatDescIndicesByVkFormatsCore, _vkFormatCoreCount);
|
if (_physicalDevice) {
|
||||||
|
id<MTLDevice> mtlDev = _physicalDevice->getMTLDevice();
|
||||||
// Iterate through the VkFormat descriptions, populate the lookup maps and back pointers,
|
|
||||||
// and validate the Metal formats for the platform and OS.
|
|
||||||
for (uint32_t fmtIdx = 0; fmtIdx < _vkFormatCount; fmtIdx++) {
|
|
||||||
MVKVkFormatDesc& vkDesc = _vkFormatDescriptions[fmtIdx];
|
|
||||||
VkFormat vkFmt = vkDesc.vkFormat;
|
|
||||||
if (vkFmt) {
|
|
||||||
// Create a lookup between the Vulkan format and an index to the format info.
|
|
||||||
// For core Vulkan format values, which are small and consecutive, use a simple lookup array.
|
|
||||||
// For extension format values, which can be large, use a map.
|
|
||||||
if (vkFmt < _vkFormatCoreCount) {
|
|
||||||
_vkFormatDescIndicesByVkFormatsCore[vkFmt] = fmtIdx;
|
|
||||||
} else {
|
|
||||||
_vkFormatDescIndicesByVkFormatsExt[vkFmt] = fmtIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vkDesc.needsSwizzle()) {
|
|
||||||
if (_physicalDevice) {
|
|
||||||
id<MTLDevice> mtlDev = _physicalDevice->getMTLDevice();
|
|
||||||
#if MVK_MACCAT
|
#if MVK_MACCAT
|
||||||
bool supportsNativeTextureSwizzle = [mtlDev supportsFamily: MTLGPUFamilyMacCatalyst2];
|
bool supportsNativeTextureSwizzle = [mtlDev supportsFamily: MTLGPUFamilyMacCatalyst2];
|
||||||
#elif MVK_MACOS
|
#elif MVK_MACOS
|
||||||
bool supportsNativeTextureSwizzle = mvkOSVersionIsAtLeast(10.15) && [mtlDev supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily2_v1];
|
bool supportsNativeTextureSwizzle = mvkOSVersionIsAtLeast(10.15) && [mtlDev supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily2_v1];
|
||||||
#endif
|
#endif
|
||||||
#if MVK_IOS || MVK_TVOS
|
#if MVK_IOS || MVK_TVOS
|
||||||
bool supportsNativeTextureSwizzle = mtlDev && mvkOSVersionIsAtLeast(13.0);
|
bool supportsNativeTextureSwizzle = mtlDev && mvkOSVersionIsAtLeast(13.0);
|
||||||
#endif
|
#endif
|
||||||
if (!supportsNativeTextureSwizzle && !getMVKConfig().fullImageViewSwizzle) {
|
if (!supportsNativeTextureSwizzle && !getMVKConfig().fullImageViewSwizzle) {
|
||||||
vkDesc.mtlPixelFormat = vkDesc.mtlPixelFormatSubstitute = MTLPixelFormatInvalid;
|
vkDesc.mtlPixelFormat = vkDesc.mtlPixelFormatSubstitute = MTLPixelFormatInvalid;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate the back reference from the Metal formats to the Vulkan format.
|
|
||||||
// Validate the corresponding Metal formats for the platform, and clear them
|
|
||||||
// in the Vulkan format if not supported.
|
|
||||||
if (vkDesc.mtlPixelFormat) {
|
|
||||||
auto& mtlDesc = getMTLPixelFormatDesc(vkDesc.mtlPixelFormat);
|
|
||||||
if ( !mtlDesc.vkFormat ) { mtlDesc.vkFormat = vkFmt; }
|
|
||||||
if ( !mtlDesc.isSupported() ) { vkDesc.mtlPixelFormat = MTLPixelFormatInvalid; }
|
|
||||||
}
|
|
||||||
if (vkDesc.mtlPixelFormatSubstitute) {
|
|
||||||
auto& mtlDesc = getMTLPixelFormatDesc(vkDesc.mtlPixelFormatSubstitute);
|
|
||||||
if ( !mtlDesc.isSupported() ) { vkDesc.mtlPixelFormatSubstitute = MTLPixelFormatInvalid; }
|
|
||||||
}
|
|
||||||
if (vkDesc.mtlVertexFormat) {
|
|
||||||
auto& mtlDesc = getMTLVertexFormatDesc(vkDesc.mtlVertexFormat);
|
|
||||||
if ( !mtlDesc.vkFormat ) { mtlDesc.vkFormat = vkFmt; }
|
|
||||||
if ( !mtlDesc.isSupported() ) { vkDesc.mtlVertexFormat = MTLVertexFormatInvalid; }
|
|
||||||
}
|
|
||||||
if (vkDesc.mtlVertexFormatSubstitute) {
|
|
||||||
auto& mtlDesc = getMTLVertexFormatDesc(vkDesc.mtlVertexFormatSubstitute);
|
|
||||||
if ( !mtlDesc.isSupported() ) { vkDesc.mtlVertexFormatSubstitute = MTLVertexFormatInvalid; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Vulkan format properties
|
|
||||||
setFormatProperties(vkDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate the back reference from the Metal formats to the Vulkan format.
|
||||||
|
// Validate the corresponding Metal formats for the platform, and clear them
|
||||||
|
// if the Vulkan format if not supported.
|
||||||
|
if (vkDesc.mtlPixelFormat) {
|
||||||
|
auto& mtlDesc = getMTLPixelFormatDesc(vkDesc.mtlPixelFormat);
|
||||||
|
if ( !mtlDesc.vkFormat ) { mtlDesc.vkFormat = vkDesc.vkFormat; }
|
||||||
|
if ( !mtlDesc.isSupported() ) { vkDesc.mtlPixelFormat = MTLPixelFormatInvalid; }
|
||||||
|
}
|
||||||
|
if (vkDesc.mtlPixelFormatSubstitute) {
|
||||||
|
auto& mtlDesc = getMTLPixelFormatDesc(vkDesc.mtlPixelFormatSubstitute);
|
||||||
|
if ( !mtlDesc.isSupported() ) { vkDesc.mtlPixelFormatSubstitute = MTLPixelFormatInvalid; }
|
||||||
|
}
|
||||||
|
if (vkDesc.mtlVertexFormat) {
|
||||||
|
auto& mtlDesc = getMTLVertexFormatDesc(vkDesc.mtlVertexFormat);
|
||||||
|
if ( !mtlDesc.vkFormat ) { mtlDesc.vkFormat = vkDesc.vkFormat; }
|
||||||
|
if ( !mtlDesc.isSupported() ) { vkDesc.mtlVertexFormat = MTLVertexFormatInvalid; }
|
||||||
|
}
|
||||||
|
if (vkDesc.mtlVertexFormatSubstitute) {
|
||||||
|
auto& mtlDesc = getMTLVertexFormatDesc(vkDesc.mtlVertexFormatSubstitute);
|
||||||
|
if ( !mtlDesc.isSupported() ) { vkDesc.mtlVertexFormatSubstitute = MTLVertexFormatInvalid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Vulkan format properties
|
||||||
|
setFormatProperties(vkDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
105
MoltenVK/MoltenVK/Utility/MVKInflectionMap.h
Executable file
105
MoltenVK/MoltenVK/Utility/MVKInflectionMap.h
Executable file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* MVKInflectionMap.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MVKSmallVector.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unordered map that splits elements between a fast-access vector of LinearCount consecutively
|
||||||
|
* indexed elements, and a slower-access map holding sparse indexes larger than LinearCount.
|
||||||
|
*
|
||||||
|
* This design can be useful for a collection that is indexed by an enum that has a large
|
||||||
|
* set of consecutive elements, plus additional enum values that are more sparsely assigned.
|
||||||
|
* Examples of these enums are VkFormat and MTLPixelFormat.
|
||||||
|
*
|
||||||
|
* KeyType is used to lookup values, and must be a type that is convertable to an unsigned integer.
|
||||||
|
* ValueType must have an empty constructor (default or otherwise).
|
||||||
|
* IndexType must be a type that is convertable to an unsigned integer (eg. uint8_t...uint64_t),
|
||||||
|
* and which is large enough to represent the number of values in this map.
|
||||||
|
* Iteration can be accomplished as
|
||||||
|
*/
|
||||||
|
template<typename KeyType, typename ValueType, size_t LinearCount, typename IndexType = uint16_t>
|
||||||
|
class MVKInflectionMap {
|
||||||
|
|
||||||
|
public:
|
||||||
|
using value_type = ValueType;
|
||||||
|
class iterator {
|
||||||
|
MVKInflectionMap* map;
|
||||||
|
IndexType index;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using value_type = ValueType;
|
||||||
|
using pointer = value_type*;
|
||||||
|
using reference = value_type&;
|
||||||
|
|
||||||
|
iterator() : map(nullptr), index(0) {}
|
||||||
|
iterator(MVKInflectionMap& m, const IndexType i) : map(&m), index(i) {}
|
||||||
|
|
||||||
|
iterator &operator=( const iterator &it ) {
|
||||||
|
map = it.map;
|
||||||
|
index = it.index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType* operator->() { return &map->_values[index]; }
|
||||||
|
ValueType& operator*() { return map->_values[index]; }
|
||||||
|
operator ValueType*() { return &map->_values[index]; }
|
||||||
|
|
||||||
|
bool operator==(const iterator& it) const { return map == it.map && index == it.index; }
|
||||||
|
bool operator!=(const iterator& it) const { return map != it.map || index != it.index; }
|
||||||
|
|
||||||
|
iterator& operator++() { index++; return *this; }
|
||||||
|
iterator operator++( int ) { auto t = *this; index++; return t; }
|
||||||
|
|
||||||
|
bool is_valid() const { return index < map->_values.size(); }
|
||||||
|
};
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
|
||||||
|
const ValueType& operator[](const KeyType idx) const { return getValue(idx); }
|
||||||
|
ValueType& operator[](const KeyType idx) { return getValue(idx); }
|
||||||
|
|
||||||
|
iterator begin() { return iterator(*this, 0); }
|
||||||
|
iterator end() { return iterator(*this, _values.size()); }
|
||||||
|
|
||||||
|
bool empty() { return _values.size() == 0; }
|
||||||
|
size_t size() { return _values.size(); }
|
||||||
|
void shrink_to_fit() { _values.shrink_to_fit(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static constexpr IndexType kMVKInflectionMapValueMissing = std::numeric_limits<IndexType>::max();
|
||||||
|
typedef struct IndexValue { IndexType value = kMVKInflectionMapValueMissing; } IndexValue;
|
||||||
|
|
||||||
|
// Returns a refrence to the value at the index.
|
||||||
|
// If the index has not been initialized, add an empty element at
|
||||||
|
// the end of the values array, and set the index to its position.
|
||||||
|
ValueType& getValue(KeyType idx) {
|
||||||
|
IndexValue& valIdx = idx < LinearCount ? _linearIndexes[idx] : _inflectionIndexes[idx];
|
||||||
|
if (valIdx.value == kMVKInflectionMapValueMissing) {
|
||||||
|
_values.push_back({});
|
||||||
|
valIdx.value = _values.size() - 1;
|
||||||
|
}
|
||||||
|
return _values[valIdx.value];
|
||||||
|
}
|
||||||
|
|
||||||
|
MVKSmallVector<ValueType> _values;
|
||||||
|
std::unordered_map<KeyType, IndexValue> _inflectionIndexes;
|
||||||
|
IndexValue _linearIndexes[LinearCount];
|
||||||
|
};
|
@ -131,4 +131,4 @@ start_time=${SECONDS}
|
|||||||
--deqp-caselist-file="${caselist_file}" \
|
--deqp-caselist-file="${caselist_file}" \
|
||||||
&> "${results_file}"
|
&> "${results_file}"
|
||||||
|
|
||||||
echo Testing complete in $(($SECONDS - $start_time)) seconds
|
echo Testing complete in $(($SECONDS - $start_time)) seconds at `date +%r`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user