Reduce memory footprint of retained MSL source code.

- Add MVKCompressor template class, and mvkCompress() & mvkDecompress()
  functions to support general data compression.
- Add MVKConfiguration::shaderSourceCompressionAlgorithm and
  env var MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM to support
  compressing MSL shader source code held in a pipeline cache.
- Add MVKShaderCompilationPerformance::mslCompress and mslDecompress
  to allow performance of MSL compression to be tracked and queried.
- Add support for logging performance stats accumulated in a VkDevice,
  when it is destroyed. Good for CTS testing.
- Change MVKConfiguration::logActivityPerformanceInline boolean to
  activityPerformanceLoggingStyle enumeration value.
- Add MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE environment variable and
  build setting to set MVKConfiguration::activityPerformanceLoggingStyle value.
This commit is contained in:
Bill Hollings 2023-03-03 10:39:26 -05:00
parent 46d46f5191
commit c205c53ad9
15 changed files with 370 additions and 88 deletions

View File

@ -32,8 +32,17 @@ Released TBA
- Change rounding of surface size provided by Metal from truncation to rounding-with-half-to-even.
- Queue submissions retain wait semaphores until `MTLCommandBuffer` finishes.
- Use a different visibility buffer for each `MTLCommandBuffer` in a queue submit.
- Reduce memory footprint of retained MSL source code.
- Work around problems with using explicit LoD with arrayed depth images on Apple Silicon.
- Reduce memory footprint of MSL source code retained in pipeline cache.
- Add `MVKConfiguration::shaderSourceCompressionAlgorithm` and
env var `MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM` to support
compressing MSL shader source code held in a pipeline cache.
- Add `MVKShaderCompilationPerformance::mslCompress` and `mslDecompress`
to allow performance of MSL compression to be tracked and queried.
- Add support for logging performance stats accumulated in a `VkDevice`, when it is destroyed.
- Change `MVKConfiguration::logActivityPerformanceInline` boolean to `activityPerformanceLoggingStyle` enumeration value.
- Add `MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE` environment variable and
build setting to set `MVKConfiguration::activityPerformanceLoggingStyle` value.
- Update `VK_MVK_MOLTENVK_SPEC_VERSION` to version `37`.

View File

@ -112,7 +112,7 @@
2FEA0AAA24902F9F00EEF3AD /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */; };
2FEA0AAB24902F9F00EEF3AD /* MVKShaderModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7981C7DFB4800632CA3 /* MVKShaderModule.mm */; };
2FEA0AAC24902F9F00EEF3AD /* MVKSync.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB79E1C7DFB4800632CA3 /* MVKSync.mm */; };
2FEA0AAD24902F9F00EEF3AD /* MVKCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.cpp */; };
2FEA0AAD24902F9F00EEF3AD /* MVKCodec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.mm */; };
2FEA0AAE24902F9F00EEF3AD /* MVKCmdPipeline.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB76F1C7DFB4800632CA3 /* MVKCmdPipeline.mm */; };
2FEA0AAF24902F9F00EEF3AD /* MVKLayers.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7A11C7DFB4800632CA3 /* MVKLayers.mm */; };
2FEA0AB024902F9F00EEF3AD /* MVKFramebuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7881C7DFB4800632CA3 /* MVKFramebuffer.mm */; };
@ -136,8 +136,8 @@
4553AEFC2251617100E8EBCD /* MVKBlockObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 4553AEF62251617100E8EBCD /* MVKBlockObserver.m */; };
4553AEFD2251617100E8EBCD /* MVKBlockObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4553AEFA2251617100E8EBCD /* MVKBlockObserver.h */; };
4553AEFE2251617100E8EBCD /* MVKBlockObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4553AEFA2251617100E8EBCD /* MVKBlockObserver.h */; };
45557A5221C9EFF3008868BD /* MVKCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.cpp */; };
45557A5321C9EFF3008868BD /* MVKCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.cpp */; };
45557A5221C9EFF3008868BD /* MVKCodec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.mm */; };
45557A5321C9EFF3008868BD /* MVKCodec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45557A4D21C9EFF3008868BD /* MVKCodec.mm */; };
45557A5421C9EFF3008868BD /* MVKCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 45557A5121C9EFF3008868BD /* MVKCodec.h */; };
45557A5521C9EFF3008868BD /* MVKCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 45557A5121C9EFF3008868BD /* MVKCodec.h */; };
A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
@ -428,7 +428,7 @@
453638312508A4C7000EFFD3 /* MTLRenderPassDepthAttachmentDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPassDepthAttachmentDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
4553AEF62251617100E8EBCD /* MVKBlockObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVKBlockObserver.m; sourceTree = "<group>"; };
4553AEFA2251617100E8EBCD /* MVKBlockObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKBlockObserver.h; sourceTree = "<group>"; };
45557A4D21C9EFF3008868BD /* MVKCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKCodec.cpp; sourceTree = "<group>"; };
45557A4D21C9EFF3008868BD /* MVKCodec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCodec.mm; sourceTree = "<group>"; };
45557A5121C9EFF3008868BD /* MVKCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCodec.h; sourceTree = "<group>"; };
45557A5721CD83C3008868BD /* MVKDXTnCodec.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKDXTnCodec.def; sourceTree = "<group>"; };
A9096E5C1F81E16300DFBEA6 /* MVKCmdDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdDispatch.h; sourceTree = "<group>"; };
@ -691,8 +691,8 @@
A9D7104E25CDE05E00E38106 /* MVKBitArray.h */,
4553AEFA2251617100E8EBCD /* MVKBlockObserver.h */,
4553AEF62251617100E8EBCD /* MVKBlockObserver.m */,
45557A4D21C9EFF3008868BD /* MVKCodec.cpp */,
45557A5121C9EFF3008868BD /* MVKCodec.h */,
45557A4D21C9EFF3008868BD /* MVKCodec.mm */,
45557A5721CD83C3008868BD /* MVKDXTnCodec.def */,
A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */,
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
@ -1368,7 +1368,7 @@
2FEA0AAA24902F9F00EEF3AD /* MVKOSExtensions.mm in Sources */,
2FEA0AAB24902F9F00EEF3AD /* MVKShaderModule.mm in Sources */,
2FEA0AAC24902F9F00EEF3AD /* MVKSync.mm in Sources */,
2FEA0AAD24902F9F00EEF3AD /* MVKCodec.cpp in Sources */,
2FEA0AAD24902F9F00EEF3AD /* MVKCodec.mm in Sources */,
2FEA0AAE24902F9F00EEF3AD /* MVKCmdPipeline.mm in Sources */,
2FEA0AAF24902F9F00EEF3AD /* MVKLayers.mm in Sources */,
2FEA0AB024902F9F00EEF3AD /* MVKFramebuffer.mm in Sources */,
@ -1427,7 +1427,7 @@
A9B51BD7225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */,
A94FB80E1C7DFB4800632CA3 /* MVKShaderModule.mm in Sources */,
A94FB81A1C7DFB4800632CA3 /* MVKSync.mm in Sources */,
45557A5221C9EFF3008868BD /* MVKCodec.cpp in Sources */,
45557A5221C9EFF3008868BD /* MVKCodec.mm in Sources */,
A94FB7BE1C7DFB4800632CA3 /* MVKCmdPipeline.mm in Sources */,
A94FB81E1C7DFB4800632CA3 /* MVKLayers.mm in Sources */,
A94FB7EE1C7DFB4800632CA3 /* MVKFramebuffer.mm in Sources */,
@ -1487,7 +1487,7 @@
A9B51BD8225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */,
A94FB80F1C7DFB4800632CA3 /* MVKShaderModule.mm in Sources */,
A94FB81B1C7DFB4800632CA3 /* MVKSync.mm in Sources */,
45557A5321C9EFF3008868BD /* MVKCodec.cpp in Sources */,
45557A5321C9EFF3008868BD /* MVKCodec.mm in Sources */,
A94FB7BF1C7DFB4800632CA3 /* MVKCmdPipeline.mm in Sources */,
A94FB81F1C7DFB4800632CA3 /* MVKLayers.mm in Sources */,
A94FB7EF1C7DFB4800632CA3 /* MVKFramebuffer.mm in Sources */,

View File

@ -130,6 +130,24 @@ typedef enum MVKConfigFastMath {
MVK_CONFIG_FAST_MATH_MAX_ENUM = 0x7FFFFFFF
} MVKConfigFastMath;
/** Identifies available system data compression algorithms. */
typedef enum MVKConfigCompressionAlgorithm {
MVK_CONFIG_COMPRESSION_ALGORITHM_NONE = 0, /**< No compression. */
MVK_CONFIG_COMPRESSION_ALGORITHM_LZFSE = 1, /**< Apple proprietary. Good balance of high performance and small compression size, particularly for larger data content. */
MVK_CONFIG_COMPRESSION_ALGORITHM_ZLIB = 2, /**< Open cross-platform ZLib format. For smaller data content, has better performance and smaller size than LZFSE. */
MVK_CONFIG_COMPRESSION_ALGORITHM_LZ4 = 3, /**< Fastest performance. Largest compression size. */
MVK_CONFIG_COMPRESSION_ALGORITHM_LZMA = 4, /**< Slowest performance. Smallest compression size, particular with larger content. */
MVK_CONFIG_COMPRESSION_ALGORITHM_MAX_ENUM = 0x7FFFFFFF,
} MVKConfigCompressionAlgorithm;
/** Identifies the style of activity performance logging to use. */
typedef enum MVKConfigActivityPerformanceLoggingStyle {
MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT = 0, /**< Repeatedly log performance after a configured number of frames. */
MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE = 1, /**< Log immediately after each performance measurement. */
MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_DEVICE_LIFETIME = 2, /**< Log at the end of the VkDevice lifetime. This is useful for one-shot apps such as testing frameworks. */
MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_MAX_ENUM = 0x7FFFFFFF,
} MVKConfigActivityPerformanceLoggingStyle;
/**
* MoltenVK configuration settings.
*
@ -361,8 +379,8 @@ typedef struct {
* If enabled, performance statistics, as defined by the MVKPerformanceStatistics structure,
* are collected, and can be retrieved via the vkGetPerformanceStatisticsMVK() function.
*
* You can also use the performanceLoggingFrameCount or logActivityPerformanceInline
* parameters to automatically log the performance statistics collected by this parameter.
* You can also use the activityPerformanceLoggingStyle and performanceLoggingFrameCount
* parameters to configure when to log the performance statistics collected by this parameter.
*
* The value of this parameter must be changed before creating a VkDevice,
* for the change to take effect.
@ -770,21 +788,20 @@ typedef struct {
VkBool32 useMTLHeap;
/**
* Controls whether MoltenVK should log the performance of individual activities as they happen.
* If this setting is enabled, activity performance will be logged when each activity happens.
* If this setting is disabled, activity performance will be logged when frame peformance is
* logged as determined by the performanceLoggingFrameCount value.
* Controls when MoltenVK should log activity performance events.
*
* The value of this parameter must be changed before creating a VkDevice,
* for the change to take effect.
*
* The initial value or this parameter is set by the
* MVK_CONFIG_PERFORMANCE_LOGGING_INLINE
* MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE
* runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, this setting is disabled by default, and activity
* performance will be logged only when frame activity is logged.
* If neither is set, this setting is set to
* MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT by default,
* and activity performance will be logged when frame activity is logged.
*/
VkBool32 logActivityPerformanceInline;
MVKConfigActivityPerformanceLoggingStyle activityPerformanceLoggingStyle;
#define logActivityPerformanceInline activityPerformanceLoggingStyle
/**
* Controls the Vulkan API version that MoltenVK should advertise in vkEnumerateInstanceVersion().
@ -877,6 +894,27 @@ typedef struct {
*/
MVKUseMetalArgumentBuffers useMetalArgumentBuffers;
/**
* Controls the type of compression to use on the MSL source code that is stored in memory
* for use in a pipeline cache. After being converted from SPIR-V, or loaded directly into
* a VkShaderModule, and then compiled into a MTLLibrary, the MSL source code is no longer
* needed for operation, but it is retained so it can be written out as part of a pipeline
* cache export. When a large number of shaders are loaded, this can consume significant
* memory. In such a case, this parameter can be used to compress the MSL source code that
* is awaiting export as part of a pipeline cache.
*
* The value of this parameter can be changed at any time, and will affect the size of
* the cached MSL from subsequent shader compilations.
*
* The initial value or this parameter is set by the
* MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM
* runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, this setting is set to
* MVK_CONFIG_COMPRESSION_ALGORITHM_NONE by default,
* and MoltenVK will not compress the MSL source code after compilation into a MTLLibrary.
*/
MVKConfigCompressionAlgorithm shaderSourceCompressionAlgorithm;
} MVKConfiguration;
/** Identifies the type of rounding Metal uses for float to integer conversions in particular calculatons. */
@ -999,6 +1037,8 @@ typedef struct {
MVKPerformanceTracker spirvToMSL; /** Convert SPIR-V to MSL source code. */
MVKPerformanceTracker mslCompile; /** Compile MSL source code into a MTLLibrary. */
MVKPerformanceTracker mslLoad; /** Load pre-compiled MSL code into a MTLLibrary. */
MVKPerformanceTracker mslCompress; /** Compress MSL source code after compiling a MTLLibrary, to hold it in a pipeline cache. */
MVKPerformanceTracker mslDecompress; /** Decompress MSL source code to write the MSL when serializing a pipeline cache. */
MVKPerformanceTracker shaderLibraryFromCache; /** Retrieve a shader library from the cache, lazily creating it if needed. */
MVKPerformanceTracker functionRetrieval; /** Retrieve a MTLFunction from a MTLLibrary. */
MVKPerformanceTracker functionSpecialization; /** Specialize a retrieved MTLFunction. */

View File

@ -686,7 +686,9 @@ public:
// Log call not locked. Very minor chance that the tracker data will be updated during log call,
// resulting in an inconsistent report. Not worth taking lock perf hit for rare inline reporting.
if (_logActivityPerformanceInline) { logActivityPerformance(activityTracker, _performanceStatistics, true); }
if (_activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE) {
logActivityPerformance(activityTracker, _performanceStatistics, true);
}
}
};
@ -891,7 +893,7 @@ protected:
id<MTLSamplerState> _defaultMTLSamplerState = nil;
id<MTLBuffer> _dummyBlitMTLBuffer = nil;
uint32_t _globalVisibilityQueryCount = 0;
bool _logActivityPerformanceInline = false;
MVKConfigActivityPerformanceLoggingStyle _activityPerformanceLoggingStyle = MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT;
bool _isPerformanceTracking = false;
bool _isCurrentlyAutoGPUCapturing = false;
bool _isUsingMetalArgumentBuffers = false;

View File

@ -4000,7 +4000,7 @@ void MVKDevice::logActivityPerformance(MVKPerformanceTracker& activity, MVKPerfo
}
void MVKDevice::logPerformanceSummary() {
if (_logActivityPerformanceInline) { return; }
if (_activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE) { return; }
// Get a copy to minimize time under lock
MVKPerformanceStatistics perfStats;
@ -4014,6 +4014,8 @@ void MVKDevice::logPerformanceSummary() {
logActivityPerformance(perfStats.shaderCompilation.spirvToMSL, perfStats);
logActivityPerformance(perfStats.shaderCompilation.mslCompile, perfStats);
logActivityPerformance(perfStats.shaderCompilation.mslLoad, perfStats);
logActivityPerformance(perfStats.shaderCompilation.mslCompress, perfStats);
logActivityPerformance(perfStats.shaderCompilation.mslDecompress, perfStats);
logActivityPerformance(perfStats.shaderCompilation.shaderLibraryFromCache, perfStats);
logActivityPerformance(perfStats.shaderCompilation.functionRetrieval, perfStats);
logActivityPerformance(perfStats.shaderCompilation.functionSpecialization, perfStats);
@ -4028,6 +4030,8 @@ const char* MVKDevice::getActivityPerformanceDescription(MVKPerformanceTracker&
if (&activity == &perfStats.shaderCompilation.spirvToMSL) { return "Convert SPIR-V to MSL source code"; }
if (&activity == &perfStats.shaderCompilation.mslCompile) { return "Compile MSL source code into a MTLLibrary"; }
if (&activity == &perfStats.shaderCompilation.mslLoad) { return "Load pre-compiled MSL code into a MTLLibrary"; }
if (&activity == &perfStats.shaderCompilation.mslCompress) { return "Compress MSL source code after compiling a MTLLibrary"; }
if (&activity == &perfStats.shaderCompilation.mslDecompress) { return "Decompress MSL source code during pipeline cache write"; }
if (&activity == &perfStats.shaderCompilation.shaderLibraryFromCache) { return "Retrieve shader library from the cache"; }
if (&activity == &perfStats.shaderCompilation.functionRetrieval) { return "Retrieve a MTLFunction from a MTLLibrary"; }
if (&activity == &perfStats.shaderCompilation.functionSpecialization) { return "Specialize a retrieved MTLFunction"; }
@ -4377,29 +4381,25 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
void MVKDevice::initPerformanceTracking() {
_isPerformanceTracking = mvkConfig().performanceTracking;
_logActivityPerformanceInline = mvkConfig().logActivityPerformanceInline;
_activityPerformanceLoggingStyle = mvkConfig().activityPerformanceLoggingStyle;
MVKPerformanceTracker initPerf;
initPerf.count = 0;
initPerf.averageDuration = 0.0;
initPerf.minimumDuration = 0.0;
initPerf.maximumDuration = 0.0;
_performanceStatistics.shaderCompilation.hashShaderCode = initPerf;
_performanceStatistics.shaderCompilation.spirvToMSL = initPerf;
_performanceStatistics.shaderCompilation.mslCompile = initPerf;
_performanceStatistics.shaderCompilation.mslLoad = initPerf;
_performanceStatistics.shaderCompilation.shaderLibraryFromCache = initPerf;
_performanceStatistics.shaderCompilation.functionRetrieval = initPerf;
_performanceStatistics.shaderCompilation.functionSpecialization = initPerf;
_performanceStatistics.shaderCompilation.pipelineCompile = initPerf;
_performanceStatistics.pipelineCache.sizePipelineCache = initPerf;
_performanceStatistics.pipelineCache.writePipelineCache = initPerf;
_performanceStatistics.pipelineCache.readPipelineCache = initPerf;
_performanceStatistics.queue.mtlQueueAccess = initPerf;
_performanceStatistics.queue.mtlCommandBufferCompletion = initPerf;
_performanceStatistics.queue.nextCAMetalDrawable = initPerf;
_performanceStatistics.queue.frameInterval = initPerf;
_performanceStatistics.shaderCompilation.hashShaderCode = {};
_performanceStatistics.shaderCompilation.spirvToMSL = {};
_performanceStatistics.shaderCompilation.mslCompile = {};
_performanceStatistics.shaderCompilation.mslLoad = {};
_performanceStatistics.shaderCompilation.mslCompress = {};
_performanceStatistics.shaderCompilation.mslDecompress = {};
_performanceStatistics.shaderCompilation.shaderLibraryFromCache = {};
_performanceStatistics.shaderCompilation.functionRetrieval = {};
_performanceStatistics.shaderCompilation.functionSpecialization = {};
_performanceStatistics.shaderCompilation.pipelineCompile = {};
_performanceStatistics.pipelineCache.sizePipelineCache = {};
_performanceStatistics.pipelineCache.writePipelineCache = {};
_performanceStatistics.pipelineCache.readPipelineCache = {};
_performanceStatistics.queue.mtlQueueAccess = {};
_performanceStatistics.queue.mtlCommandBufferCompletion = {};
_performanceStatistics.queue.nextCAMetalDrawable = {};
_performanceStatistics.queue.frameInterval = {};
}
void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo* pCreateInfo) {
@ -4666,9 +4666,15 @@ void MVKDevice::reservePrivateData(const VkDeviceCreateInfo* pCreateInfo) {
}
MVKDevice::~MVKDevice() {
if (_activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_DEVICE_LIFETIME) {
MVKLogInfo("Device activity performance summary:");
logPerformanceSummary();
}
for (auto& queues : _queuesByQueueFamilyIndex) {
mvkDestroyContainerContents(queues);
}
if (_commandResourceFactory) { _commandResourceFactory->destroy(); }
[_globalVisibilityResultMTLBuffer release];

View File

@ -2004,7 +2004,7 @@ protected:
bool next() { return (++_index < (_pSLCache ? _pSLCache->_shaderLibraries.size() : 0)); }
SPIRVToMSLConversionConfiguration& getShaderConversionConfig() { return _pSLCache->_shaderLibraries[_index].first; }
std::string& getMSL() { return _pSLCache->_shaderLibraries[_index].second->_msl; }
MVKCompressor<std::string>& getCompressedMSL() { return _pSLCache->_shaderLibraries[_index].second->getCompressedMSL(); }
SPIRVToMSLConversionResultInfo& getShaderConversionResultInfo() { return _pSLCache->_shaderLibraries[_index].second->_shaderConversionResultInfo; }
MVKShaderCacheIterator(MVKShaderLibraryCache* pSLCache) : _pSLCache(pSLCache) {}
@ -2087,7 +2087,7 @@ void MVKPipelineCache::writeData(ostream& outstream, bool isCounting) {
writer(smKey);
writer(cacheIter.getShaderConversionConfig());
writer(cacheIter.getShaderConversionResultInfo());
writer(cacheIter.getMSL());
writer(cacheIter.getCompressedMSL());
_device->addActivityPerformance(activityTracker, startTime);
}
}
@ -2149,14 +2149,16 @@ void MVKPipelineCache::readData(const VkPipelineCacheCreateInfo* pCreateInfo) {
SPIRVToMSLConversionConfiguration shaderConversionConfig;
reader(shaderConversionConfig);
SPIRVToMSLConversionResult shaderConversionResult;
reader(shaderConversionResult.resultInfo);
reader(shaderConversionResult.msl);
SPIRVToMSLConversionResultInfo resultInfo;
reader(resultInfo);
MVKCompressor<std::string> compressedMSL;
reader(compressedMSL);
// Add the shader library to the staging cache.
MVKShaderLibraryCache* slCache = getShaderLibraryCache(smKey);
_device->addActivityPerformance(_device->_performanceStatistics.pipelineCache.readPipelineCache, startTime);
slCache->addShaderLibrary(&shaderConversionConfig, shaderConversionResult);
slCache->addShaderLibrary(&shaderConversionConfig, resultInfo, compressedMSL);
break;
}
@ -2394,6 +2396,13 @@ void serialize(Archive & archive, MVKShaderModuleKey& k) {
k.codeHash);
}
template<class Archive, class C>
void serialize(Archive & archive, MVKCompressor<C>& comp) {
archive(comp._compressed,
comp._uncompressedSize,
comp._algorithm);
}
#pragma mark Construction

View File

@ -20,6 +20,7 @@
#include "MVKDevice.h"
#include "MVKSync.h"
#include "MVKCodec.h"
#include "MVKSmallVector.h"
#include <MoltenVKShaderConverter/SPIRVToMSLConverter.h>
#include <MoltenVKShaderConverter/GLSLToSPIRVConverter.h>
@ -84,10 +85,13 @@ public:
*/
void setWorkgroupSize(uint32_t x, uint32_t y, uint32_t z);
/** Constructs an instance from the specified MSL source code. */
MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner, const SPIRVToMSLConversionResult& conversionResult);
MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
const SPIRVToMSLConversionResult& conversionResult);
MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
const SPIRVToMSLConversionResultInfo& resultInfo,
const MVKCompressor<std::string> compressedMSL);
/** Constructs an instance from the specified compiled MSL code data. */
MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
const void* mslCompiledCodeData,
size_t mslCompiledCodeLength);
@ -106,11 +110,15 @@ protected:
MVKMTLFunction getMTLFunction(const VkSpecializationInfo* pSpecializationInfo, MVKShaderModule* shaderModule);
void handleCompilationError(NSError* err, const char* opDesc);
MTLFunctionConstant* getFunctionConstant(NSArray<MTLFunctionConstant*>* mtlFCs, NSUInteger mtlFCID);
void compileLibrary(const std::string& msl);
void compressMSL(const std::string& msl);
void decompressMSL(std::string& msl);
MVKCompressor<std::string>& getCompressedMSL() { return _compressedMSL; }
MVKVulkanAPIDeviceObject* _owner;
id<MTLLibrary> _mtlLibrary;
MVKCompressor<std::string> _compressedMSL;
SPIRVToMSLConversionResultInfo _shaderConversionResultInfo;
std::string _msl;
};
@ -146,8 +154,11 @@ protected:
friend MVKShaderModule;
MVKShaderLibrary* findShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig);
MVKShaderLibrary* addShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig,
SPIRVToMSLConversionResult& conversionResult);
MVKShaderLibrary* addShaderLibrary(const SPIRVToMSLConversionConfiguration* pShaderConfig,
const SPIRVToMSLConversionResult& conversionResult);
MVKShaderLibrary* addShaderLibrary(const SPIRVToMSLConversionConfiguration* pShaderConfig,
const SPIRVToMSLConversionResultInfo& resultInfo,
const MVKCompressor<std::string> compressedMSL);
void merge(MVKShaderLibraryCache* other);
MVKVulkanAPIDeviceObject* _owner;

View File

@ -19,7 +19,6 @@
#include "MVKShaderModule.h"
#include "MVKPipeline.h"
#include "MVKFoundation.h"
#include <string>
using namespace std;
@ -140,18 +139,45 @@ void MVKShaderLibrary::setWorkgroupSize(uint32_t x, uint32_t y, uint32_t z) {
wgSize.depth.size = z;
}
// Sets the cached MSL source code, after first compressing it.
void MVKShaderLibrary::compressMSL(const string& msl) {
MVKDevice* mvkDev = _owner->getDevice();
uint64_t startTime = mvkDev->getPerformanceTimestamp();
_compressedMSL.compress(msl, mvkConfig().shaderSourceCompressionAlgorithm);
mvkDev->addActivityPerformance(mvkDev->_performanceStatistics.shaderCompilation.mslCompress, startTime);
}
// Decompresses the cached MSL into the string.
void MVKShaderLibrary::decompressMSL(string& msl) {
MVKDevice* mvkDev = _owner->getDevice();
uint64_t startTime = mvkDev->getPerformanceTimestamp();
_compressedMSL.decompress(msl);
mvkDev->addActivityPerformance(mvkDev->_performanceStatistics.shaderCompilation.mslDecompress, startTime);
}
MVKShaderLibrary::MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
const SPIRVToMSLConversionResult& conversionResult) : _owner(owner) {
MVKShaderLibraryCompiler* slc = new MVKShaderLibraryCompiler(_owner);
NSString* nsSrc = [[NSString alloc] initWithUTF8String: conversionResult.msl.c_str()]; // temp retained
_mtlLibrary = slc->newMTLLibrary(nsSrc, conversionResult.resultInfo); // retained
[nsSrc release]; // release temp string
slc->destroy();
_shaderConversionResultInfo = conversionResult.resultInfo;
_msl = conversionResult.msl;
compressMSL(conversionResult.msl);
compileLibrary(conversionResult.msl);
}
MVKShaderLibrary::MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
const SPIRVToMSLConversionResultInfo& resultInfo,
const MVKCompressor<std::string> compressedMSL) : _owner(owner) {
_shaderConversionResultInfo = resultInfo;
_compressedMSL = compressedMSL;
string msl;
decompressMSL(msl);
compileLibrary(msl);
}
void MVKShaderLibrary::compileLibrary(const string& msl) {
MVKShaderLibraryCompiler* slc = new MVKShaderLibraryCompiler(_owner);
NSString* nsSrc = [[NSString alloc] initWithUTF8String: msl.c_str()]; // temp retained
_mtlLibrary = slc->newMTLLibrary(nsSrc, _shaderConversionResultInfo); // retained
[nsSrc release]; // release temp string
slc->destroy();
}
MVKShaderLibrary::MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
@ -176,7 +202,7 @@ MVKShaderLibrary::MVKShaderLibrary(const MVKShaderLibrary& other) {
_owner = other._owner;
_mtlLibrary = [other._mtlLibrary retain];
_shaderConversionResultInfo = other._shaderConversionResultInfo;
_msl = other._msl;
_compressedMSL = other._compressedMSL;
}
MVKShaderLibrary& MVKShaderLibrary::operator=(const MVKShaderLibrary& other) {
@ -186,7 +212,7 @@ MVKShaderLibrary& MVKShaderLibrary::operator=(const MVKShaderLibrary& other) {
}
_owner = other._owner;
_shaderConversionResultInfo = other._shaderConversionResultInfo;
_msl = other._msl;
_compressedMSL = other._compressedMSL;
return *this;
}
@ -245,13 +271,22 @@ MVKShaderLibrary* MVKShaderLibraryCache::findShaderLibrary(SPIRVToMSLConversionC
}
// Adds and returns a new shader library configured from the specified conversion configuration.
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig,
SPIRVToMSLConversionResult& conversionResult) {
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(const SPIRVToMSLConversionConfiguration* pShaderConfig,
const SPIRVToMSLConversionResult& conversionResult) {
MVKShaderLibrary* shLib = new MVKShaderLibrary(_owner, conversionResult);
_shaderLibraries.emplace_back(*pShaderConfig, shLib);
return shLib;
}
// Adds and returns a new shader library configured from contents read from a pipeline cache.
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(const SPIRVToMSLConversionConfiguration* pShaderConfig,
const SPIRVToMSLConversionResultInfo& resultInfo,
const MVKCompressor<std::string> compressedMSL) {
MVKShaderLibrary* shLib = new MVKShaderLibrary(_owner, resultInfo, compressedMSL);
_shaderLibraries.emplace_back(*pShaderConfig, shLib);
return shLib;
}
// Merge another shader library cache with this one. Handle null input.
void MVKShaderLibraryCache::merge(MVKShaderLibraryCache* other) {
if ( !other ) { return; }

View File

@ -19,7 +19,6 @@
#include "MVKLayers.h"
#include "MVKEnvironment.h"
#include "MVKFoundation.h"
#include "vk_mvk_moltenvk.h"
#include <mutex>
using namespace std;

View File

@ -19,17 +19,18 @@
#pragma once
#include "MVKFoundation.h"
#include "MVKEnvironment.h"
#include <vector>
#include <string>
#pragma mark -
#pragma mark Texture data codecs
/**
* This is the base class implemented by all codecs supported by MoltenVK.
* Objects of this class are used to decompress texture data for upload to a
* 3D texture.
* Objects of this class are used to decompress texture data for upload to a 3D texture.
*/
class MVKCodec {
@ -43,8 +44,89 @@ public:
};
#pragma mark -
#pragma mark General data compressor
/**
* Holds compressed data, along with information allowing it to be decompressed again.
* The template class C must support the basic data container methods data(), size() and resize().
*
* THIS CLASS IS STREAMED OUT AS PART OF THE PIEPLINE CACHE.
* STURCTURAL CHANGES TO THIS CLASS MUST BE CAPTURED IN THE STREAMING LOGIC OF THE PIPELINE CACHE.
*/
template <class C>
class MVKCompressor {
public:
/**
* Compresses the content in the data container using the algorithm, and retains
* the compressed content. If an error occurs, or if the compressed data is actually
* larger (which can happen with some compression algorithms if the source is small),
* the uncompressed content is retained. Returns true if the content was successfully
* compressed, or returns false if the content was retained as uncompressed,
*/
bool compress(const C& uncompressed, MVKConfigCompressionAlgorithm algorithm) {
_uncompressedSize = uncompressed.size();
_compressed.resize(_uncompressedSize);
_algorithm = algorithm;
size_t compSize = mvkCompress((uint8_t*)uncompressed.data(), uncompressed.size(),
_compressed.data(), _compressed.size(),
_algorithm);
bool wasCompressed = (compSize > 0);
if ( !wasCompressed ) {
_algorithm = MVK_CONFIG_COMPRESSION_ALGORITHM_NONE;
compSize = mvkCompress((uint8_t*)uncompressed.data(), uncompressed.size(),
_compressed.data(), _compressed.size(),
_algorithm);
}
_compressed.resize(compSize);
_compressed.shrink_to_fit();
return wasCompressed;
}
/** Decompress the retained compressed content into the data container. */
void decompress(C& uncompressed) {
uncompressed.resize(_uncompressedSize);
mvkDecompress(_compressed.data(), _compressed.size(),
(uint8_t*)uncompressed.data(), uncompressed.size(),
_algorithm);
}
std::vector<uint8_t> _compressed;
size_t _uncompressedSize = 0;
MVKConfigCompressionAlgorithm _algorithm = MVK_CONFIG_COMPRESSION_ALGORITHM_NONE;
};
#pragma mark -
#pragma mark Support functions
/** Returns an appropriate codec for the given format, or nullptr if the format is not supported. */
std::unique_ptr<MVKCodec> mvkCreateCodec(VkFormat format);
/** Returns whether or not the given format can be decompressed. */
bool mvkCanDecodeFormat(VkFormat format);
/**
* Compresses the source bytes into the destination bytes using a compression algorithm,
* and returns the number of bytes written to dstBytes. If an error occurs, or the compressed
* data is larger than dstSize, no data is copied to dstBytes, and zero is returned.
*/
size_t mvkCompress(const uint8_t* srcBytes, size_t srcSize,
uint8_t* dstBytes, size_t dstSize,
MVKConfigCompressionAlgorithm compAlgo);
/**
* Decompresses the source bytes into the destination bytes using a compression algorithm,
* and returns the number of bytes written to dstBytes. If an error occurs, or the decompressed
* data is larger than dstSize, no data is copied to dstBytes, and zero is returned.
*/
size_t mvkDecompress(const uint8_t* srcBytes, size_t srcSize,
uint8_t* dstBytes, size_t dstSize,
MVKConfigCompressionAlgorithm compAlgo);

View File

@ -18,10 +18,13 @@
#include "MVKCodec.h"
#include "MVKBaseObject.h"
#include "MVKFoundation.h"
#include <algorithm>
#include <simd/simd.h>
using namespace std;
using simd::float3;
using simd::float4;
@ -62,8 +65,8 @@ public:
for (uint32_t y = 0; y < extent.height; y += 4) {
for (uint32_t x = 0; x < extent.width; x += 4) {
VkExtent2D blockExtent;
blockExtent.width = std::min(extent.width - x, 4u);
blockExtent.height = std::min(extent.height - y, 4u);
blockExtent.width = min(extent.width - x, 4u);
blockExtent.height = min(extent.height - y, 4u);
decompressDXTnBlock(pSrcRow + x * (blockByteCount / 4),
pDestRow + x * 4, blockExtent, destLayout.rowPitch, _format);
}
@ -90,7 +93,11 @@ private:
VkFormat _format;
};
std::unique_ptr<MVKCodec> mvkCreateCodec(VkFormat format) {
#pragma mark -
#pragma mark Support functions
unique_ptr<MVKCodec> mvkCreateCodec(VkFormat format) {
switch (format) {
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
@ -100,7 +107,7 @@ std::unique_ptr<MVKCodec> mvkCreateCodec(VkFormat format) {
case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK:
return std::unique_ptr<MVKCodec>(new MVKDXTnCodec(format));
return unique_ptr<MVKCodec>(new MVKDXTnCodec(format));
default:
return nullptr;
@ -123,3 +130,63 @@ bool mvkCanDecodeFormat(VkFormat format) {
return false;
}
}
static NSDataCompressionAlgorithm getSystemCompressionAlgo(MVKConfigCompressionAlgorithm compAlgo) {
switch (compAlgo) {
case MVK_CONFIG_COMPRESSION_ALGORITHM_NONE: return NSDataCompressionAlgorithmLZFSE;
case MVK_CONFIG_COMPRESSION_ALGORITHM_LZFSE: return NSDataCompressionAlgorithmLZFSE;
case MVK_CONFIG_COMPRESSION_ALGORITHM_LZ4: return NSDataCompressionAlgorithmLZ4;
case MVK_CONFIG_COMPRESSION_ALGORITHM_LZMA: return NSDataCompressionAlgorithmLZMA;
case MVK_CONFIG_COMPRESSION_ALGORITHM_ZLIB: return NSDataCompressionAlgorithmZlib;
default: return NSDataCompressionAlgorithmLZFSE;
}
}
// Only copy into the dstBytes if it can fit, otherwise the data will be corrupted
static size_t mvkCompressDecompress(const uint8_t* srcBytes, size_t srcSize,
uint8_t* dstBytes, size_t dstSize,
MVKConfigCompressionAlgorithm compAlgo,
bool isCompressing) {
size_t dstByteCount = 0;
if (compAlgo != MVK_CONFIG_COMPRESSION_ALGORITHM_NONE) {
@autoreleasepool {
NSDataCompressionAlgorithm sysCompAlgo = getSystemCompressionAlgo(compAlgo);
NSData* srcData = [NSData dataWithBytesNoCopy: (void*)srcBytes length: srcSize freeWhenDone: NO];
NSError* err = nil;
NSData* dstData = (isCompressing
? [srcData compressedDataUsingAlgorithm: sysCompAlgo error: &err]
: [srcData decompressedDataUsingAlgorithm: sysCompAlgo error: &err]);
if ( !err ) {
size_t dataLen = dstData.length;
if (dstSize >= dataLen) {
[dstData getBytes: dstBytes length: dstSize];
dstByteCount = dataLen;
}
} else {
MVKBaseObject::reportError(nullptr, VK_ERROR_FORMAT_NOT_SUPPORTED,
"Could not %scompress data (Error code %li):\n%s",
(isCompressing ? "" : "de"),
(long)err.code, err.localizedDescription.UTF8String);
}
}
} else if (dstSize >= srcSize) {
mvkCopy(dstBytes, srcBytes, srcSize);
dstByteCount = srcSize;
}
return dstByteCount;
}
size_t mvkCompress(const uint8_t* srcBytes, size_t srcSize,
uint8_t* dstBytes, size_t dstSize,
MVKConfigCompressionAlgorithm compAlgo) {
return mvkCompressDecompress(srcBytes, srcSize, dstBytes, dstSize, compAlgo, true);
}
size_t mvkDecompress(const uint8_t* srcBytes, size_t srcSize,
uint8_t* dstBytes, size_t dstSize,
MVKConfigCompressionAlgorithm compAlgo) {
return mvkCompressDecompress(srcBytes, srcSize, dstBytes, dstSize, compAlgo, false);
}

View File

@ -39,7 +39,7 @@ static void mvkInitConfigFromEnvVars() {
MVK_SET_FROM_ENV_OR_BUILD_INT64 (evCfg.metalCompileTimeout, MVK_CONFIG_METAL_COMPILE_TIMEOUT);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.performanceTracking, MVK_CONFIG_PERFORMANCE_TRACKING);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.performanceLoggingFrameCount, MVK_CONFIG_PERFORMANCE_LOGGING_FRAME_COUNT);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.logActivityPerformanceInline, MVK_CONFIG_PERFORMANCE_LOGGING_INLINE);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.activityPerformanceLoggingStyle, MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.displayWatermark, MVK_CONFIG_DISPLAY_WATERMARK);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.specializedQueueFamilies, MVK_CONFIG_SPECIALIZED_QUEUE_FAMILIES);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.switchSystemGPU, MVK_CONFIG_SWITCH_SYSTEM_GPU);
@ -62,6 +62,7 @@ static void mvkInitConfigFromEnvVars() {
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.advertiseExtensions, MVK_CONFIG_ADVERTISE_EXTENSIONS);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.resumeLostDevice, MVK_CONFIG_RESUME_LOST_DEVICE);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.useMetalArgumentBuffers, MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.shaderSourceCompressionAlgorithm, MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM);
// Deprected legacy VkSemaphore MVK_ALLOW_METAL_FENCES and MVK_ALLOW_METAL_EVENTS config.
// Legacy MVK_ALLOW_METAL_EVENTS is covered by MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE,
@ -75,6 +76,17 @@ static void mvkInitConfigFromEnvVars() {
evCfg.semaphoreUseMTLEvent = (MVKVkSemaphoreSupportStyle)false; // Disabled. Also semaphoreSupportStyle MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE.
}
// Deprecated legacy env var MVK_CONFIG_PERFORMANCE_LOGGING_INLINE config. If legacy
// MVK_CONFIG_PERFORMANCE_LOGGING_INLINE env var was used, and activityPerformanceLoggingStyle
// was not already set by MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE, set
// activityPerformanceLoggingStyle to MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE.
bool logPerfInline;
MVK_SET_FROM_ENV_OR_BUILD_BOOL(logPerfInline, MVK_CONFIG_PERFORMANCE_LOGGING_INLINE);
if (logPerfInline && evCfg.activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT) {
evCfg.activityPerformanceLoggingStyle = MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE;
}
mvkSetConfig(evCfg);
}

View File

@ -151,8 +151,11 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
# define MVK_CONFIG_PERFORMANCE_LOGGING_FRAME_COUNT 0
#endif
/** Log activity performance every time an activity occurs. Disabled by default. */
# ifndef MVK_CONFIG_PERFORMANCE_LOGGING_INLINE
/** Activity performance logging style. Default is to log after a configured number of frames. */
# ifndef MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE
# define MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT
# endif
# ifndef MVK_CONFIG_PERFORMANCE_LOGGING_INLINE // Deprecated
# define MVK_CONFIG_PERFORMANCE_LOGGING_INLINE 0
# endif
@ -286,3 +289,8 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
#ifndef MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS
# define MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER
#endif
/** Compress MSL shader source code in a pipeline cache. Defaults to no compression. */
#ifndef MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM
# define MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM MVK_CONFIG_COMPRESSION_ALGORITHM_NONE
#endif

View File

@ -279,7 +279,7 @@ namespace mvk {
bool hasSPIRV() { return !_spirv.empty(); }
/**
* Converts SPIR-V code, set using setSPIRV() to MSL code, which can be retrieved using getMSL().
* Converts SPIR-V code, set using setSPIRV() to MSL code.
*
* The boolean flags indicate whether the original SPIR-V code, the resulting MSL code,
* and optionally, the original GLSL (as converted from the SPIR_V), should be logged

View File

@ -94,22 +94,24 @@ if [ "${is_portability}" != "" ]; then
export MVK_CONFIG_ADVERTISE_EXTENSIONS=0xA
fi
# ----- Metal validation settings ------
export METAL_DEVICE_WRAPPER_TYPE=1
export METAL_ERROR_MODE=3
export METAL_DEBUG_ERROR_MODE=3
# ----- MoltenVK config settings ------
export MVK_CONFIG_LOG_LEVEL=1
export MVK_CONFIG_LOG_LEVEL=1 #(1 = Errors only, 3 = Info)
export MVK_DEBUG=0
# Additional MoltenVK configuration can be set here by
# editing below, or can be set before calling this script.
# Additional MoltenVK configuration can be set here by editing below.
export MVK_CONFIG_RESUME_LOST_DEVICE=1
export MVK_CONFIG_FAST_MATH_ENABLED=1
export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=0 #(2 = VK_EXT_descriptor_indexing enabled)
export MVK_CONFIG_FORCE_LOW_POWER_GPU=0
export MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE=2 #(2 = MTLEvents always)
export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=0 #(2 = VK_EXT_descriptor_indexing enabled)
export MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE=2 #(2 = MTLEvents always)
export MVK_CONFIG_SHADER_COMPRESSION_ALGORITHM=0 #(2 = ZLIB, 3 = LZ4)
export MVK_CONFIG_PERFORMANCE_TRACKING=0
export MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE=2 #(2 = Device lifetime)
# -------------- Operation --------------------