Add configurable lowpass filter for VkPhysicalDeviceLimits::timestampPeriod.

- Add MVKConfiguration::timestampPeriodLowPassAlpha, along with matching
  MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA env var.
- Add MVKConfigMembers.def file to describe MVKConfiguration members,
  to support consistent batch handling of members.
- Add env var & build settings MVK_CONFIG_DEBUG, plus legacy
  MVK_CONFIG_ALLOW_METAL_EVENTS & MVK_CONFIG_ALLOW_METAL_FENCES.
- Simplify environment variable retrieval functions and macros.
- Rename MVKDevice::updateTimestampsAndPeriod() to updateTimestampPeriod().
This commit is contained in:
Bill Hollings 2023-09-11 20:14:23 -04:00
parent a2d5b25a5c
commit 62e0368e21
12 changed files with 214 additions and 120 deletions

View File

@ -108,62 +108,22 @@ void mvkDispatchToMainAndWait(dispatch_block_t block);
#pragma mark Process environment
/**
* Returns the value of the environment variable at the given name,
* or an empty string if no environment variable with that name exists.
*
* If pWasFound is not null, its value is set to true if the environment
* variable exists, or false if not.
* Sets the value of the environment variable at the given name, into the
* std::string, and returns whether the environment variable was found.
*/
std::string mvkGetEnvVar(std::string varName, bool* pWasFound = nullptr);
bool mvkGetEnvVar(const char* evName, std::string& evStr);
/**
* Returns a pointer to a string containing the value of the environment variable at
* the given name, or returns the default value if the environment variable was not set.
*/
const char* mvkGetEnvVarString(const char* evName, std::string& evStr, const char* defaultValue = "");
/**
* Returns the value of the environment variable at the given name,
* or zero if no environment variable with that name exists.
*
* If pWasFound is not null, its value is set to true if the environment
* variable exists, or false if not.
* or returns the default value if the environment variable was not set.
*/
int64_t mvkGetEnvVarInt64(std::string varName, bool* pWasFound = nullptr);
/**
* Returns the value of the environment variable at the given name,
* or false if no environment variable with that name exists.
*
* If pWasFound is not null, its value is set to true if the environment
* variable exists, or false if not.
*/
bool mvkGetEnvVarBool(std::string varName, bool* pWasFound = nullptr);
#define MVK_SET_FROM_ENV_OR_BUILD_BOOL(cfgVal, EV) \
do { \
bool wasFound = false; \
bool ev = mvkGetEnvVarBool(#EV, &wasFound); \
cfgVal = wasFound ? ev : EV; \
} while(false)
#define MVK_SET_FROM_ENV_OR_BUILD_INT64(cfgVal, EV) \
do { \
bool wasFound = false; \
int64_t ev = mvkGetEnvVarInt64(#EV, &wasFound); \
cfgVal = wasFound ? ev : EV; \
} while(false)
// Pointer cast permits cfgVal to be an enum var
#define MVK_SET_FROM_ENV_OR_BUILD_INT32(cfgVal, EV) \
do { \
bool wasFound = false; \
int64_t ev = mvkGetEnvVarInt64(#EV, &wasFound); \
int64_t val = wasFound ? ev : EV; \
*(int32_t*)&cfgVal = (int32_t)std::min(std::max(val, (int64_t)INT32_MIN), (int64_t)INT32_MAX); \
} while(false)
#define MVK_SET_FROM_ENV_OR_BUILD_STRING(cfgVal, EV, strObj) \
do { \
bool wasFound = false; \
std::string ev = mvkGetEnvVar(#EV, &wasFound); \
strObj = wasFound ? std::move(ev) : EV; \
cfgVal = strObj.c_str(); \
} while(false)
double mvkGetEnvVarNumber(const char* evName, double defaultValue = 0.0);
#pragma mark -

View File

@ -81,21 +81,22 @@ void mvkDispatchToMainAndWait(dispatch_block_t block) {
#pragma mark -
#pragma mark Process environment
string mvkGetEnvVar(string varName, bool* pWasFound) {
bool mvkGetEnvVar(const char* varName, string& evStr) {
@autoreleasepool {
NSDictionary* nsEnv = [[NSProcessInfo processInfo] environment];
NSString* envStr = nsEnv[@(varName.c_str())];
if (pWasFound) { *pWasFound = envStr != nil; }
return envStr ? envStr.UTF8String : "";
NSString* nsStr = nsEnv[@(varName)];
if (nsStr) { evStr = nsStr.UTF8String; }
return nsStr != nil;
}
}
int64_t mvkGetEnvVarInt64(string varName, bool* pWasFound) {
return strtoll(mvkGetEnvVar(varName, pWasFound).c_str(), NULL, 0);
const char* mvkGetEnvVarString(const char* varName, string& evStr, const char* defaultValue) {
return mvkGetEnvVar(varName, evStr) ? evStr.c_str() : defaultValue;
}
bool mvkGetEnvVarBool(std::string varName, bool* pWasFound) {
return mvkGetEnvVarInt64(varName, pWasFound) != 0;
double mvkGetEnvVarNumber(const char* varName, double defaultValue) {
string evStr;
return mvkGetEnvVar(varName, evStr) ? strtod(evStr.c_str(), nullptr) : defaultValue;
}

View File

@ -517,8 +517,8 @@ you can address the issue as follows:
- Errors encountered during **Runtime Shader Conversion** are logged to the console.
- To help understand conversion issues during **Runtime Shader Conversion**, you can enable the
logging of the *SPIR-V* and *MSL* shader source code during shader conversion, by turning on
the `MVKConfiguration::debugMode` configuration parameter, or setting the value of the `MVK_DEBUG`
logging of the *SPIR-V* and *MSL* shader source code during shader conversion, by turning on the
`MVKConfiguration::debugMode` configuration parameter, or setting the value of the `MVK_CONFIG_DEBUG`
runtime environment variable to `1`. See the [*MoltenVK Configuration*](#moltenvk_config)
description above.

View File

@ -24,6 +24,8 @@ Released TBD
- Fix case where a `CAMetalDrawable` with invalid pixel format causes onscreen flickering.
- Improve behavior of swapchain image presentation stalls caused by Metal regression.
- Add several additional performance trackers, available via logging, or the `mvk_private_api.h` API.
- Add configurable lowpass filter for `VkPhysicalDeviceLimits::timestampPeriod`.
- Deprecate `MVK_DEBUG` env var, and add `MVK_CONFIG_DEBUG` env var to replace it.
- Update `MVK_CONFIGURATION_API_VERSION` and `MVK_PRIVATE_API_VERSION` to `38`.

View File

@ -331,6 +331,10 @@
A9B51BD8225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */; };
A9B51BD9225E986A00AC74D2 /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */; };
A9B51BDA225E986A00AC74D2 /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */; };
A9C327562AAFBD390025EE79 /* MVKConfigMembers.def in Headers */ = {isa = PBXBuildFile; fileRef = A9C327542AAF8A770025EE79 /* MVKConfigMembers.def */; };
A9C327572AAFBD3A0025EE79 /* MVKConfigMembers.def in Headers */ = {isa = PBXBuildFile; fileRef = A9C327542AAF8A770025EE79 /* MVKConfigMembers.def */; };
A9C327582AAFBD3A0025EE79 /* MVKConfigMembers.def in Headers */ = {isa = PBXBuildFile; fileRef = A9C327542AAF8A770025EE79 /* MVKConfigMembers.def */; };
A9C327592AAFBD3B0025EE79 /* MVKConfigMembers.def in Headers */ = {isa = PBXBuildFile; fileRef = A9C327542AAF8A770025EE79 /* MVKConfigMembers.def */; };
A9C96DD01DDC20C20053187F /* MVKMTLBufferAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A9C96DCE1DDC20C20053187F /* MVKMTLBufferAllocation.h */; };
A9C96DD11DDC20C20053187F /* MVKMTLBufferAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A9C96DCE1DDC20C20053187F /* MVKMTLBufferAllocation.h */; };
A9C96DD21DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9C96DCF1DDC20C20053187F /* MVKMTLBufferAllocation.mm */; };
@ -670,6 +674,7 @@
A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKOSExtensions.mm; sourceTree = "<group>"; };
A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKOSExtensions.h; sourceTree = "<group>"; };
A9B8EE0A1A98D796009C5A02 /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; };
A9C327542AAF8A770025EE79 /* MVKConfigMembers.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKConfigMembers.def; sourceTree = "<group>"; };
A9C83DCD24533E22003E5261 /* MVKCommandTypePools.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKCommandTypePools.def; sourceTree = "<group>"; };
A9C86CB61C55B8350096CAF2 /* MoltenVKShaderConverter.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MoltenVKShaderConverter.xcodeproj; path = ../MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj; sourceTree = "<group>"; };
A9C96DCE1DDC20C20053187F /* MVKMTLBufferAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKMTLBufferAllocation.h; sourceTree = "<group>"; };
@ -843,6 +848,7 @@
4553AEF62251617100E8EBCD /* MVKBlockObserver.m */,
45557A5121C9EFF3008868BD /* MVKCodec.h */,
45557A4D21C9EFF3008868BD /* MVKCodec.mm */,
A9C327542AAF8A770025EE79 /* MVKConfigMembers.def */,
45557A5721CD83C3008868BD /* MVKDXTnCodec.def */,
A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */,
A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */,
@ -1008,6 +1014,7 @@
2FEA0A7824902F9F00EEF3AD /* MVKDeviceMemory.h in Headers */,
2FEA0A7924902F9F00EEF3AD /* MVKMTLResourceBindings.h in Headers */,
2FEA0A7A24902F9F00EEF3AD /* MVKExtensions.def in Headers */,
A9C327572AAFBD3A0025EE79 /* MVKConfigMembers.def in Headers */,
2FEA0A7B24902F9F00EEF3AD /* mvk_datatypes.hpp in Headers */,
2FEA0A7C24902F9F00EEF3AD /* MVKCommandEncodingPool.h in Headers */,
2FEA0A7D24902F9F00EEF3AD /* MVKResource.h in Headers */,
@ -1070,6 +1077,7 @@
A94FB7C41C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */,
A94FB7BC1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
A9F3D9DC24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */,
A9C327562AAFBD390025EE79 /* MVKConfigMembers.def in Headers */,
A94FB7F81C7DFB4800632CA3 /* MVKPipeline.h in Headers */,
A94FB7F01C7DFB4800632CA3 /* MVKImage.h in Headers */,
4553AEFD2251617100E8EBCD /* MVKBlockObserver.h in Headers */,
@ -1147,6 +1155,7 @@
A94FB7BD1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
A9F3D9DD24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */,
A94FB7F91C7DFB4800632CA3 /* MVKPipeline.h in Headers */,
A9C327582AAFBD3A0025EE79 /* MVKConfigMembers.def in Headers */,
A94FB7F11C7DFB4800632CA3 /* MVKImage.h in Headers */,
4553AEFE2251617100E8EBCD /* MVKBlockObserver.h in Headers */,
A94FB7B91C7DFB4800632CA3 /* MVKCmdTransfer.h in Headers */,
@ -1204,6 +1213,7 @@
DCFD7EFD2A45BC6E007BBBF7 /* MVKSync.h in Headers */,
DCFD7EFE2A45BC6E007BBBF7 /* MVKDevice.h in Headers */,
DCFD7EFF2A45BC6E007BBBF7 /* MVKSmallVector.h in Headers */,
A9C327592AAFBD3B0025EE79 /* MVKConfigMembers.def in Headers */,
DCFD7F002A45BC6E007BBBF7 /* MVKCommandPool.h in Headers */,
DCFD7F012A45BC6E007BBBF7 /* MVKShaderModule.h in Headers */,
DCFD7F022A45BC6E007BBBF7 /* MVKVulkanAPIObject.h in Headers */,

View File

@ -191,7 +191,7 @@ typedef struct {
* and the changed value will immediately effect subsequent MoltenVK behaviour.
*
* The initial value or this parameter is set by the
* MVK_DEBUG
* MVK_CONFIG_DEBUG
* runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, the value of this parameter is false if MoltenVK was
* built in Release mode, and true if MoltenVK was built in Debug mode.
@ -919,6 +919,9 @@ typedef struct {
/**
* Maximize the concurrent executing compilation tasks.
*
* The value of this parameter must be changed before creating a VkInstance,
* for the change to take effect.
*
* The initial value or this parameter is set by the
* MVK_CONFIG_SHOULD_MAXIMIZE_CONCURRENT_COMPILATION
* runtime environment variable or MoltenVK compile-time build setting.
@ -926,6 +929,38 @@ typedef struct {
*/
VkBool32 shouldMaximizeConcurrentCompilation;
/**
* This parameter is ignored on Apple Silicon devices.
*
* Non-Apple GPUs can have a dynamic timestamp period, which varies over time according to GPU
* workload. Depending on how often the app samples the VkPhysicalDeviceLimits::timestampPeriod
* value using vkGetPhysicalDeviceProperties(), the app may want up-to-date, but potentially
* volatile values, or it may find average values more useful.
*
* The value of this parameter sets the alpha (A) value of a simple lowpass filter
* on the timestampPeriod value, of the form:
*
* TPout = (1 - A)TPout + (A * TPin)
*
* The alpha value can be set to a float between 0.0 and 1.0. Values of alpha closer to
* 0.0 cause the value of timestampPeriod to vary slowly over time and be less volatile,
* and values of alpha closer to 1.0 cause the value of timestampPeriod to vary quickly
* and be more volatile.
*
* Apps that query the timestampPeriod value infrequently will prefer low volatility, whereas
* apps that query frequently may prefer higher volatility, to track more recent changes.
*
* The value of this parameter can be changed at any time, and will affect subsequent queries.
*
* The initial value or this parameter is set by the
* MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA
* runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, this parameter is set to 0.05 by default,
* indicating that the timestampPeriod will vary relatively slowly,
* with the expectation that the app is querying this value infrequently.
*/
float timestampPeriodLowPassAlpha;
} MVKConfiguration;

View File

@ -401,7 +401,7 @@ protected:
void initExtensions();
void initCounterSets();
bool needsCounterSetRetained();
void updateTimestampsAndPeriod();
void updateTimestampPeriod();
MVKArrayRef<MVKQueueFamily*> getQueueFamilies();
void initPipelineCacheUUID();
uint32_t getHighestGPUCapability();

View File

@ -451,7 +451,7 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
}
void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties* properties) {
updateTimestampsAndPeriod();
updateTimestampPeriod();
*properties = _properties;
}
@ -1570,10 +1570,10 @@ VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount,
// If needed, update the timestamp period for this device, using a crude lowpass filter to level out
// wild temporary changes, particularly during initial queries before much GPU activity has occurred.
// On Apple GPUs, CPU & GPU timestamps are the same, and timestamp period never changes.
void MVKPhysicalDevice::updateTimestampsAndPeriod() {
if (_properties.vendorID == kAppleVendorId) { return; }
if ([_mtlDevice respondsToSelector: @selector(sampleTimestamps:gpuTimestamp:)]) {
void MVKPhysicalDevice::updateTimestampPeriod() {
if (_properties.vendorID != kAppleVendorId &&
[_mtlDevice respondsToSelector: @selector(sampleTimestamps:gpuTimestamp:)]) {
MTLTimestamp earlierCPUTs = _prevCPUTimestamp;
MTLTimestamp earlierGPUTs = _prevGPUTimestamp;
[_mtlDevice sampleTimestamps: &_prevCPUTimestamp gpuTimestamp: &_prevGPUTimestamp];
@ -1582,9 +1582,9 @@ void MVKPhysicalDevice::updateTimestampsAndPeriod() {
if (elapsedCPUNanos && elapsedGPUTicks) { // Ensure not zero
float tsPeriod = elapsedCPUNanos / elapsedGPUTicks;
// Basic lowpass filter Y = (1 - a)Y + a*X.
// The lower a is, the slower Y will change over time.
static const float a = 0.05;
// Basic lowpass filter TPout = (1 - A)TPout + (A * TPin).
// The lower A is, the slower TPout will change over time.
float a = mvkConfig().timestampPeriodLowPassAlpha;
_properties.limits.timestampPeriod = ((1.0 - a) * _properties.limits.timestampPeriod) + (a * tsPeriod);
}
}

View File

@ -0,0 +1,86 @@
/*
* MVKConfigMembers.def
*
* Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
* Licensed under the Apache License, Version 2.0 (the "License", Int64)
* 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.
*/
// The items in the list below describe the members of the MVKConfiguration struct.
// When a new member is added to the MVKConfiguration struct, a corresponding description
// must be added here.
//
// To use this file, define the macros:
//
// MVK_CONFIG_MEMBER(member, mbrType, name)
// MVK_CONFIG_MEMBER_STRING(member, strObj, name)
//
// then #include this file inline with your code.
//
// The name prameter is the name of the configuration parameter, which is used as the name
// of the environment variable, and build setting, that sets the config value, and is entered
// here without the "MVK_CONFIG_" prefix.
//
// Since string members are set from char pointers, the text must be copied to a std::string
// object, which is passed as a parameter to MVK_CONFIG_MEMBER_STRING.
#ifndef MVK_CONFIG_MEMBER
#error MVK_CONFIG_MEMBER must be defined before including this file
#endif
#ifndef MVK_CONFIG_MEMBER_STRING
#error MVK_CONFIG_MEMBER_STRING must be defined before including this file
#endif
MVK_CONFIG_MEMBER(debugMode, VkBool32, DEBUG)
MVK_CONFIG_MEMBER(shaderConversionFlipVertexY, VkBool32, SHADER_CONVERSION_FLIP_VERTEX_Y)
MVK_CONFIG_MEMBER(synchronousQueueSubmits, VkBool32, SYNCHRONOUS_QUEUE_SUBMITS)
MVK_CONFIG_MEMBER(prefillMetalCommandBuffers, MVKPrefillMetalCommandBuffersStyle, PREFILL_METAL_COMMAND_BUFFERS)
MVK_CONFIG_MEMBER(maxActiveMetalCommandBuffersPerQueue, uint32_t, MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE)
MVK_CONFIG_MEMBER(supportLargeQueryPools, VkBool32, SUPPORT_LARGE_QUERY_POOLS)
MVK_CONFIG_MEMBER(presentWithCommandBuffer, VkBool32, PRESENT_WITH_COMMAND_BUFFER)
MVK_CONFIG_MEMBER(swapchainMinMagFilterUseNearest, VkBool32, SWAPCHAIN_MAG_FILTER_USE_NEAREST) // Deprecated legacy renaming
MVK_CONFIG_MEMBER(swapchainMinMagFilterUseNearest, VkBool32, SWAPCHAIN_MIN_MAG_FILTER_USE_NEAREST)
MVK_CONFIG_MEMBER(metalCompileTimeout, uint64_t, METAL_COMPILE_TIMEOUT)
MVK_CONFIG_MEMBER(performanceTracking, VkBool32, PERFORMANCE_TRACKING)
MVK_CONFIG_MEMBER(performanceLoggingFrameCount, uint32_t, PERFORMANCE_LOGGING_FRAME_COUNT)
MVK_CONFIG_MEMBER(activityPerformanceLoggingStyle, MVKConfigActivityPerformanceLoggingStyle, ACTIVITY_PERFORMANCE_LOGGING_STYLE)
MVK_CONFIG_MEMBER(displayWatermark, VkBool32, DISPLAY_WATERMARK)
MVK_CONFIG_MEMBER(specializedQueueFamilies, VkBool32, SPECIALIZED_QUEUE_FAMILIES)
MVK_CONFIG_MEMBER(switchSystemGPU, VkBool32, SWITCH_SYSTEM_GPU)
MVK_CONFIG_MEMBER(fullImageViewSwizzle, VkBool32, FULL_IMAGE_VIEW_SWIZZLE)
MVK_CONFIG_MEMBER(defaultGPUCaptureScopeQueueFamilyIndex, VkBool32, DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX)
MVK_CONFIG_MEMBER(defaultGPUCaptureScopeQueueIndex, VkBool32, DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_INDEX)
MVK_CONFIG_MEMBER(fastMathEnabled, MVKConfigFastMath, FAST_MATH_ENABLED)
MVK_CONFIG_MEMBER(logLevel, MVKConfigLogLevel, LOG_LEVEL)
MVK_CONFIG_MEMBER(traceVulkanCalls, MVKConfigTraceVulkanCalls, TRACE_VULKAN_CALLS)
MVK_CONFIG_MEMBER(forceLowPowerGPU, VkBool32, FORCE_LOW_POWER_GPU)
MVK_CONFIG_MEMBER(semaphoreUseMTLFence, VkBool32, ALLOW_METAL_FENCES) // Deprecated legacy
MVK_CONFIG_MEMBER(semaphoreSupportStyle, MVKVkSemaphoreSupportStyle, VK_SEMAPHORE_SUPPORT_STYLE)
MVK_CONFIG_MEMBER(autoGPUCaptureScope, MVKConfigAutoGPUCaptureScope, AUTO_GPU_CAPTURE_SCOPE)
MVK_CONFIG_MEMBER_STRING(autoGPUCaptureOutputFilepath, evGPUCapFileStrObj, AUTO_GPU_CAPTURE_OUTPUT_FILE)
MVK_CONFIG_MEMBER(texture1DAs2D, VkBool32, TEXTURE_1D_AS_2D)
MVK_CONFIG_MEMBER(preallocateDescriptors, VkBool32, PREALLOCATE_DESCRIPTORS)
MVK_CONFIG_MEMBER(useCommandPooling, VkBool32, USE_COMMAND_POOLING)
MVK_CONFIG_MEMBER(useMTLHeap, VkBool32, USE_MTLHEAP)
MVK_CONFIG_MEMBER(apiVersionToAdvertise, uint32_t, API_VERSION_TO_ADVERTISE)
MVK_CONFIG_MEMBER(advertiseExtensions, uint32_t, ADVERTISE_EXTENSIONS)
MVK_CONFIG_MEMBER(resumeLostDevice, VkBool32, RESUME_LOST_DEVICE)
MVK_CONFIG_MEMBER(useMetalArgumentBuffers, MVKUseMetalArgumentBuffers, USE_METAL_ARGUMENT_BUFFERS)
MVK_CONFIG_MEMBER(shaderSourceCompressionAlgorithm, MVKConfigCompressionAlgorithm, SHADER_COMPRESSION_ALGORITHM)
MVK_CONFIG_MEMBER(shouldMaximizeConcurrentCompilation, VkBool32, SHOULD_MAXIMIZE_CONCURRENT_COMPILATION)
MVK_CONFIG_MEMBER(timestampPeriodLowPassAlpha, float, TIMESTAMP_PERIOD_LOWPASS_ALPHA)
#undef MVK_CONFIG_MEMBER
#undef MVK_CONFIG_MEMBER_STRING

View File

@ -18,7 +18,7 @@
#include "MVKEnvironment.h"
#include "MVKOSExtensions.h"
#include "MVKFoundation.h"
static bool _mvkConfigInitialized = false;
static void mvkInitConfigFromEnvVars() {
@ -27,43 +27,22 @@ static void mvkInitConfigFromEnvVars() {
MVKConfiguration evCfg;
std::string evGPUCapFileStrObj;
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.debugMode, MVK_DEBUG);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.shaderConversionFlipVertexY, MVK_CONFIG_SHADER_CONVERSION_FLIP_VERTEX_Y);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.synchronousQueueSubmits, MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.prefillMetalCommandBuffers, MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.maxActiveMetalCommandBuffersPerQueue, MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.supportLargeQueryPools, MVK_CONFIG_SUPPORT_LARGE_QUERY_POOLS);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.presentWithCommandBuffer, MVK_CONFIG_PRESENT_WITH_COMMAND_BUFFER);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.swapchainMinMagFilterUseNearest, MVK_CONFIG_SWAPCHAIN_MAG_FILTER_USE_NEAREST); // Deprecated legacy env var
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.swapchainMinMagFilterUseNearest, MVK_CONFIG_SWAPCHAIN_MIN_MAG_FILTER_USE_NEAREST);
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_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);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.fullImageViewSwizzle, MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.defaultGPUCaptureScopeQueueFamilyIndex, MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.defaultGPUCaptureScopeQueueIndex, MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_INDEX);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.fastMathEnabled, MVK_CONFIG_FAST_MATH_ENABLED);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.logLevel, MVK_CONFIG_LOG_LEVEL);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.traceVulkanCalls, MVK_CONFIG_TRACE_VULKAN_CALLS);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.forceLowPowerGPU, MVK_CONFIG_FORCE_LOW_POWER_GPU);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.semaphoreUseMTLFence, MVK_ALLOW_METAL_FENCES);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.semaphoreSupportStyle, MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.autoGPUCaptureScope, MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE);
MVK_SET_FROM_ENV_OR_BUILD_STRING(evCfg.autoGPUCaptureOutputFilepath, MVK_CONFIG_AUTO_GPU_CAPTURE_OUTPUT_FILE, evGPUCapFileStrObj);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.texture1DAs2D, MVK_CONFIG_TEXTURE_1D_AS_2D);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.preallocateDescriptors, MVK_CONFIG_PREALLOCATE_DESCRIPTORS);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.useCommandPooling, MVK_CONFIG_USE_COMMAND_POOLING);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.useMTLHeap, MVK_CONFIG_USE_MTLHEAP);
MVK_SET_FROM_ENV_OR_BUILD_INT32 (evCfg.apiVersionToAdvertise, MVK_CONFIG_API_VERSION_TO_ADVERTISE);
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);
MVK_SET_FROM_ENV_OR_BUILD_BOOL (evCfg.shouldMaximizeConcurrentCompilation, MVK_CONFIG_SHOULD_MAXIMIZE_CONCURRENT_COMPILATION);
#define STR(name) #name
#define MVK_CONFIG_MEMBER(member, mbrType, name) \
evCfg.member = (mbrType)mvkGetEnvVarNumber(STR(MVK_CONFIG_##name), MVK_CONFIG_##name);
#define MVK_CONFIG_MEMBER_STRING(member, strObj, name) \
evCfg.member = mvkGetEnvVarString(STR(MVK_CONFIG_##name), strObj, MVK_CONFIG_##name);
#include "MVKConfigMembers.def"
// At this point, debugMode has been set by env var MVK_CONFIG_DEBUG.
// MVK_CONFIG_DEBUG replaced the deprecataed MVK_DEBUG env var, so for
// legacy use, if the MVK_DEBUG env var is explicitly set, override debugMode.
double noEV = -3.1415; // An unlikely env var value.
double cvMVKDebug = mvkGetEnvVarNumber("MVK_DEBUG", noEV);
if (cvMVKDebug != noEV) { evCfg.debugMode = cvMVKDebug; }
// 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,
@ -71,9 +50,7 @@ static void mvkInitConfigFromEnvVars() {
// disabled, disable semaphoreUseMTLEvent (aliased as semaphoreSupportStyle value
// MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE), and let mvkSetConfig()
// further process legacy behavior of MVK_ALLOW_METAL_FENCES.
bool sem4UseMTLEvent;
MVK_SET_FROM_ENV_OR_BUILD_BOOL(sem4UseMTLEvent, MVK_ALLOW_METAL_EVENTS);
if ( !sem4UseMTLEvent ) {
if ( !mvkGetEnvVarNumber("MVK_CONFIG_ALLOW_METAL_EVENTS", 1.0) ) {
evCfg.semaphoreUseMTLEvent = (MVKVkSemaphoreSupportStyle)false; // Disabled. Also semaphoreSupportStyle MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE.
}
@ -81,13 +58,11 @@ static void mvkInitConfigFromEnvVars() {
// 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);
bool logPerfInline = mvkGetEnvVarNumber("MVK_CONFIG_PERFORMANCE_LOGGING_INLINE", 0.0);
if (logPerfInline && evCfg.activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT) {
evCfg.activityPerformanceLoggingStyle = MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_IMMEDIATE;
}
mvkSetConfig(evCfg);
}
@ -129,4 +104,7 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig) {
_autoGPUCaptureOutputFile = _mvkConfig.autoGPUCaptureOutputFilepath;
}
_mvkConfig.autoGPUCaptureOutputFilepath = (char*)_autoGPUCaptureOutputFile.c_str();
// Clamp timestampPeriodLowPassAlpha between 0.0 and 1.0.
_mvkConfig.timestampPeriodLowPassAlpha = mvkClamp(_mvkConfig.timestampPeriodLowPassAlpha, 0.0f, 1.0f);
}

View File

@ -82,6 +82,14 @@ const MVKConfiguration& mvkConfig();
/** Global function to update MoltenVK configuration info. */
void mvkSetConfig(const MVKConfiguration& mvkConfig);
/**
* Enable debug mode.
* By default, disabled for Release builds and enabled for Debug builds.
*/
#ifndef MVK_CONFIG_DEBUG
# define MVK_CONFIG_DEBUG MVK_DEBUG
#endif
/** Flip the vertex coordinate in shaders. Enabled by default. */
#ifndef MVK_CONFIG_SHADER_CONVERSION_FLIP_VERTEX_Y
# define MVK_CONFIG_SHADER_CONVERSION_FLIP_VERTEX_Y 1
@ -244,11 +252,17 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
#ifndef MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE
# define MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE
#endif
#ifndef MVK_ALLOW_METAL_EVENTS // Deprecated
# define MVK_ALLOW_METAL_EVENTS 1
#ifndef MVK_CONFIG_ALLOW_METAL_EVENTS
# define MVK_CONFIG_ALLOW_METAL_EVENTS 1
#endif
#ifndef MVK_ALLOW_METAL_FENCES // Deprecated
# define MVK_ALLOW_METAL_FENCES 1
#ifndef MVK_ALLOW_METAL_EVENTS // Deprecated
# define MVK_ALLOW_METAL_EVENTS MVK_CONFIG_ALLOW_METAL_EVENTS
#endif
#ifndef MVK_CONFIG_ALLOW_METAL_FENCES
# define MVK_CONFIG_ALLOW_METAL_FENCES 1
#endif
#ifndef MVK_ALLOW_METAL_FENCES // Deprecated
# define MVK_ALLOW_METAL_FENCES MVK_CONFIG_ALLOW_METAL_FENCES
#endif
/** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */
@ -303,3 +317,11 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
#ifndef MVK_CONFIG_SHOULD_MAXIMIZE_CONCURRENT_COMPILATION
# define MVK_CONFIG_SHOULD_MAXIMIZE_CONCURRENT_COMPILATION 0
#endif
/**
* The alpha value of a lowpass filter tracking VkPhysicalDeviceLimits::timestampPeriod.
* This can be set to a float between 0.0 and 1.0.
*/
#ifndef MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA
# define MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA 0.05
#endif

View File

@ -103,7 +103,7 @@ export METAL_DEBUG_ERROR_MODE=3
# ----- MoltenVK config settings ------
export MVK_CONFIG_LOG_LEVEL=1 #(1 = Errors only, 3 = Info)
export MVK_DEBUG=0
export MVK_CONFIG_DEBUG=0
# Additional MoltenVK configuration can be set here by editing below.
export MVK_CONFIG_RESUME_LOST_DEVICE=1