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:
parent
46d46f5191
commit
c205c53ad9
@ -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`.
|
||||
|
||||
|
||||
|
@ -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 */,
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "MVKLayers.h"
|
||||
#include "MVKEnvironment.h"
|
||||
#include "MVKFoundation.h"
|
||||
#include "vk_mvk_moltenvk.h"
|
||||
#include <mutex>
|
||||
|
||||
using namespace std;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 --------------------
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user