Add support for VK_EXT_layer_settings extension.

This commit is contained in:
Bill Hollings 2023-09-04 21:45:42 -04:00
parent fd418aa7fe
commit 10625a8638
25 changed files with 180 additions and 75 deletions

View File

@ -31,8 +31,8 @@ extern "C" {
* Compiler build setting that ensures a definite value for whether this
* build is a debug build or not.
*
* If the standard DEBUG build setting is defined, MVK_DEBUG is set to true,
* otherwise, it is set to false.
* If the standard DEBUG build setting is defined, MVK_CONFIG_DEBUG is
* set to true, otherwise, it is set to false.
*/
#ifndef MVK_DEBUG
# ifdef DEBUG
@ -41,6 +41,9 @@ extern "C" {
# define MVK_DEBUG 0
# endif
#endif
#ifndef MVK_CONFIG_DEBUG
# define MVK_CONFIG_DEBUG MVK_DEBUG
#endif
/** Building for macOS. */
#ifndef MVK_MACOS

View File

@ -367,6 +367,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_EXT_host_query_reset`
- `VK_EXT_image_robustness`
- `VK_EXT_inline_uniform_block`
- `VK_EXT_layer_settings`
- `VK_EXT_memory_budget` *(requires Metal 2.0)*
- `VK_EXT_metal_objects`
- `VK_EXT_metal_surface`
@ -516,11 +517,11 @@ 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`
runtime environment variable to `1`. See the [*MoltenVK Configuration*](#moltenvk_config)
description above.
- 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_CONFIG_DEBUG` runtime environment variable to `1`. See the
[*MoltenVK Configuration*](#moltenvk_config) description above.
Enabling debug mode in **MoltenVK** includes shader conversion logging, which causes both
the incoming *SPIR-V* code and the converted *MSL* source code to be logged to the console

View File

@ -18,6 +18,8 @@ MoltenVK 1.2.6
Released TBD
- Add support for extensions:
- `VK_EXT_layer_settings`
- Fix rare case where vertex attribute buffers are not bound to Metal
when no other bindings change between pipelines.

View File

@ -190,7 +190,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.
@ -940,7 +940,7 @@ typedef struct {
#ifndef VK_NO_PROTOTYPES
/**
* Populates the pConfiguration structure with the current MoltenVK configuration settings.
* Populates the pConfiguration structure with the current global MoltenVK configuration settings.
*
* To change a specific configuration value, call vkGetMoltenVKConfigurationMVK() to retrieve
* the current configuration, make changes, and call vkSetMoltenVKConfigurationMVK() to
@ -978,7 +978,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMoltenVKConfigurationMVK(
size_t* pConfigurationSize);
/**
* Sets the MoltenVK configuration settings to those found in the pConfiguration structure.
* Sets the global MoltenVK configuration settings to those found in the pConfiguration structure.
*
* To change a specific configuration value, call vkGetMoltenVKConfigurationMVK()
* to retrieve the current configuration, make changes, and call
@ -988,8 +988,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMoltenVKConfigurationMVK(
* This function can be called before the VkInstance has been created. It is safe to call this function
* with a VkInstance retrieved from a different layer in the Vulkan SDK Loader and Layers framework.
*
* To be active, some configuration settings must be set before a VkInstance or VkDevice
* To be active, some global configuration settings must be set before a VkInstance or VkDevice
* is created. See the description of the MVKConfiguration members for more information.
* If the VkInstance has the VK_EXT_layer_settings extension enabled, this call must be
* performed before the VkInstance is created, and subsequent changes here will not apply
* to that VkInstance and its derivative objects. The VK_EXT_layer_settings extension can
* be used to make futher changes to that VkInstance.
*
* If you are linking to an implementation of MoltenVK that was compiled from a different
* MVK_CONFIGURATION_API_VERSION than your app was, the size of the MVKConfiguration structure
@ -1011,7 +1015,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMoltenVKConfigurationMVK(
* expects MVKConfiguration to be.
*/
VKAPI_ATTR VkResult VKAPI_CALL vkSetMoltenVKConfigurationMVK(
VkInstance ignored,
VkInstance instance,
const MVKConfiguration* pConfiguration,
size_t* pConfigurationSize);

View File

@ -121,7 +121,7 @@ VkResult MVKCommandBuffer::begin(const VkCommandBufferBeginInfo* pBeginInfo) {
if(_device->shouldPrefillMTLCommandBuffers() && !(_isSecondary || _supportsConcurrentExecution)) {
@autoreleasepool {
_prefilledMTLCmdBuffer = [_commandPool->getMTLCommandBuffer(0) retain]; // retained
auto prefillStyle = mvkConfig().prefillMetalCommandBuffers;
auto prefillStyle = getMVKConfig().prefillMetalCommandBuffers;
if (prefillStyle == MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS_STYLE_IMMEDIATE_ENCODING ||
prefillStyle == MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS_STYLE_IMMEDIATE_ENCODING_NO_AUTORELEASE ) {
_immediateCmdEncodingContext = new MVKCommandEncodingContext;
@ -193,7 +193,7 @@ VkResult MVKCommandBuffer::end() {
}
void MVKCommandBuffer::checkDeferredEncoding() {
if (mvkConfig().prefillMetalCommandBuffers == MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS_STYLE_DEFERRED_ENCODING) {
if (getMVKConfig().prefillMetalCommandBuffers == MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS_STYLE_DEFERRED_ENCODING) {
@autoreleasepool {
MVKCommandEncodingContext encodingContext;
MVKCommandEncoder encoder(this);

View File

@ -710,7 +710,7 @@ size_t MVKDescriptorPool::getPoolSize(const VkDescriptorPoolCreateInfo* pCreateI
MVKDescriptorPool::MVKDescriptorPool(MVKDevice* device, const VkDescriptorPoolCreateInfo* pCreateInfo) :
MVKVulkanAPIDeviceObject(device),
_hasPooledDescriptors(mvkConfig().preallocateDescriptors), // Set this first! Accessed by MVKDescriptorSet constructor and getPoolSize() in following lines.
_hasPooledDescriptors(getMVKConfig().preallocateDescriptors), // Set this first! Accessed by MVKDescriptorSet constructor and getPoolSize() in following lines.
_descriptorSets(pCreateInfo->maxSets, MVKDescriptorSet(this)),
_descriptorSetAvailablility(pCreateInfo->maxSets, true),
_inlineBlockMTLBufferAllocator(device, device->_pMetalFeatures->dynamicMTLBufferSize, true),

View File

@ -352,8 +352,8 @@ public:
bool mslVersionIsAtLeast(MTLLanguageVersion minVer) { return _metalFeatures.mslVersionEnum >= minVer; }
/** Returns whether this physical device supports Metal argument buffers. */
bool supportsMetalArgumentBuffers() const {
return _metalFeatures.argumentBuffers && mvkConfig().useMetalArgumentBuffers != MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER;
bool supportsMetalArgumentBuffers() {
return _metalFeatures.argumentBuffers && getMVKConfig().useMetalArgumentBuffers != MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER;
};

View File

@ -359,7 +359,7 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
portabilityFeatures->events = true;
portabilityFeatures->imageViewFormatReinterpretation = true;
portabilityFeatures->imageViewFormatSwizzle = (_metalFeatures.nativeTextureSwizzle ||
mvkConfig().fullImageViewSwizzle);
getMVKConfig().fullImageViewSwizzle);
portabilityFeatures->imageView2DOn3DImage = false;
portabilityFeatures->multisampleArrayImage = _metalFeatures.multisampleArrayTextures;
portabilityFeatures->mutableComparisonSamplers = _metalFeatures.depthSampleCompare;
@ -377,7 +377,7 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
auto* formatFeatures = (VkPhysicalDevice4444FormatsFeaturesEXT*)next;
bool canSupport4444 = _metalFeatures.tileBasedDeferredRendering &&
(_metalFeatures.nativeTextureSwizzle ||
mvkConfig().fullImageViewSwizzle);
getMVKConfig().fullImageViewSwizzle);
formatFeatures->formatA4R4G4B4 = canSupport4444;
formatFeatures->formatA4B4G4R4 = canSupport4444;
break;
@ -893,7 +893,7 @@ VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
case VK_IMAGE_TYPE_1D:
maxExt.height = 1;
maxExt.depth = 1;
if (!mvkConfig().texture1DAs2D) {
if (!getMVKConfig().texture1DAs2D) {
maxExt.width = pLimits->maxImageDimension1D;
maxLevels = 1;
sampleCounts = VK_SAMPLE_COUNT_1_BIT;
@ -1490,7 +1490,7 @@ VkResult MVKPhysicalDevice::getPresentRectangles(MVKSurface* surface,
MVKArrayRef<MVKQueueFamily*> MVKPhysicalDevice::getQueueFamilies() {
if (_queueFamilies.empty()) {
VkQueueFamilyProperties qfProps;
bool specialize = mvkConfig().specializedQueueFamilies;
bool specialize = getMVKConfig().specializedQueueFamilies;
uint32_t qfIdx = 0;
qfProps.queueCount = kMVKQueueCountPerQueueFamily;
@ -1646,8 +1646,8 @@ MVKPhysicalDevice::MVKPhysicalDevice(MVKInstance* mvkInstance, id<MTLDevice> mtl
void MVKPhysicalDevice::initMTLDevice() {
#if MVK_XCODE_14_3 && MVK_MACOS && !MVK_MACCAT
if ([_mtlDevice respondsToSelector: @selector(setShouldMaximizeConcurrentCompilation:)]) {
[_mtlDevice setShouldMaximizeConcurrentCompilation: mvkConfig().shouldMaximizeConcurrentCompilation];
MVKLogInfoIf(mvkConfig().debugMode, "maximumConcurrentCompilationTaskCount %lu", _mtlDevice.maximumConcurrentCompilationTaskCount);
[_mtlDevice setShouldMaximizeConcurrentCompilation: getMVKConfig().shouldMaximizeConcurrentCompilation];
MVKLogInfoIf(getMVKConfig().debugMode, "maximumConcurrentCompilationTaskCount %lu", _mtlDevice.maximumConcurrentCompilationTaskCount);
}
#endif
}
@ -1656,7 +1656,7 @@ void MVKPhysicalDevice::initMTLDevice() {
void MVKPhysicalDevice::initProperties() {
mvkClear(&_properties); // Start with everything cleared
_properties.apiVersion = mvkConfig().apiVersionToAdvertise;
_properties.apiVersion = getMVKConfig().apiVersionToAdvertise;
_properties.driverVersion = MVK_VERSION;
initGPUInfoProperties();
@ -1757,7 +1757,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
if ( mvkOSVersionIsAtLeast(13.0) ) {
_metalFeatures.mslVersionEnum = MTLLanguageVersion2_2;
_metalFeatures.placementHeaps = mvkConfig().useMTLHeap;
_metalFeatures.placementHeaps = getMVKConfig().useMTLHeap;
_metalFeatures.nativeTextureSwizzle = true;
if (supportsMTLGPUFamily(Apple3)) {
_metalFeatures.native3DCompressedTextures = true;
@ -1865,7 +1865,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
if ( mvkOSVersionIsAtLeast(13.0) ) {
_metalFeatures.mslVersionEnum = MTLLanguageVersion2_2;
_metalFeatures.placementHeaps = mvkConfig().useMTLHeap;
_metalFeatures.placementHeaps = getMVKConfig().useMTLHeap;
#if MVK_OS_SIMULATOR
_metalFeatures.nativeTextureSwizzle = false;
#else
@ -1982,7 +1982,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
}
if (supportsMTLGPUFamily(Mac2)) {
_metalFeatures.nativeTextureSwizzle = true;
_metalFeatures.placementHeaps = mvkConfig().useMTLHeap;
_metalFeatures.placementHeaps = getMVKConfig().useMTLHeap;
_metalFeatures.renderWithoutAttachments = true;
}
}
@ -3206,7 +3206,7 @@ void MVKPhysicalDevice::initVkSemaphoreStyle() {
// Default to single queue if other options unavailable.
_vkSemaphoreStyle = MVKSemaphoreStyleSingleQueue;
switch (mvkConfig().semaphoreSupportStyle) {
switch (getMVKConfig().semaphoreSupportStyle) {
case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE: {
bool isNVIDIA = _properties.vendorID == kNVVendorId;
bool isRosetta2 = _properties.vendorID == kAppleVendorId && !MVK_APPLE_SILICON;
@ -4035,7 +4035,7 @@ void MVKDevice::destroyRenderPass(MVKRenderPass* mvkRP,
MVKCommandPool* MVKDevice::createCommandPool(const VkCommandPoolCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return new MVKCommandPool(this, pCreateInfo, mvkConfig().useCommandPooling);
return new MVKCommandPool(this, pCreateInfo, getMVKConfig().useCommandPooling);
}
void MVKDevice::destroyCommandPool(MVKCommandPool* mvkCmdPool,
@ -4417,8 +4417,8 @@ id<MTLBuffer> MVKDevice::getDummyBlitMTLBuffer() {
MTLCompileOptions* MVKDevice::getMTLCompileOptions(bool requestFastMath, bool preserveInvariance) {
MTLCompileOptions* mtlCompOpt = [MTLCompileOptions new];
mtlCompOpt.languageVersion = _pMetalFeatures->mslVersionEnum;
mtlCompOpt.fastMathEnabled = (mvkConfig().fastMathEnabled == MVK_CONFIG_FAST_MATH_ALWAYS ||
(mvkConfig().fastMathEnabled == MVK_CONFIG_FAST_MATH_ON_DEMAND && requestFastMath));
mtlCompOpt.fastMathEnabled = (getMVKConfig().fastMathEnabled == MVK_CONFIG_FAST_MATH_ALWAYS ||
(getMVKConfig().fastMathEnabled == MVK_CONFIG_FAST_MATH_ON_DEMAND && requestFastMath));
#if MVK_XCODE_12
if ([mtlCompOpt respondsToSelector: @selector(setPreserveInvariance:)]) {
[mtlCompOpt setPreserveInvariance: preserveInvariance];
@ -4429,7 +4429,7 @@ MTLCompileOptions* MVKDevice::getMTLCompileOptions(bool requestFastMath, bool pr
// Can't use prefilled Metal command buffers if any of the resource descriptors can be updated after binding.
bool MVKDevice::shouldPrefillMTLCommandBuffers() {
return (mvkConfig().prefillMetalCommandBuffers &&
return (getMVKConfig().prefillMetalCommandBuffers &&
!(_enabledDescriptorIndexingFeatures.descriptorBindingUniformBufferUpdateAfterBind ||
_enabledDescriptorIndexingFeatures.descriptorBindingSampledImageUpdateAfterBind ||
_enabledDescriptorIndexingFeatures.descriptorBindingStorageImageUpdateAfterBind ||
@ -4441,7 +4441,7 @@ bool MVKDevice::shouldPrefillMTLCommandBuffers() {
void MVKDevice::startAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope, id mtlCaptureObject) {
if (_isCurrentlyAutoGPUCapturing || (mvkConfig().autoGPUCaptureScope != autoGPUCaptureScope)) { return; }
if (_isCurrentlyAutoGPUCapturing || (getMVKConfig().autoGPUCaptureScope != autoGPUCaptureScope)) { return; }
_isCurrentlyAutoGPUCapturing = true;
@ -4453,7 +4453,7 @@ void MVKDevice::startAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureS
captureDesc.captureObject = mtlCaptureObject;
captureDesc.destination = MTLCaptureDestinationDeveloperTools;
const char* filePath = mvkConfig().autoGPUCaptureOutputFilepath;
const char* filePath = getMVKConfig().autoGPUCaptureOutputFilepath;
if (strlen(filePath)) {
if ([captureMgr respondsToSelector: @selector(supportsDestination:)] &&
[captureMgr supportsDestination: MTLCaptureDestinationGPUTraceDocument] ) {
@ -4489,7 +4489,7 @@ void MVKDevice::startAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureS
}
void MVKDevice::stopAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope) {
if (_isCurrentlyAutoGPUCapturing && mvkConfig().autoGPUCaptureScope == autoGPUCaptureScope) {
if (_isCurrentlyAutoGPUCapturing && getMVKConfig().autoGPUCaptureScope == autoGPUCaptureScope) {
[[MTLCaptureManager sharedCaptureManager] stopCapture];
_isCurrentlyAutoGPUCapturing = false;
}
@ -4565,8 +4565,8 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
return;
}
initPerformanceTracking();
initPhysicalDevice(physicalDevice, pCreateInfo);
initPerformanceTracking();
enableExtensions(pCreateInfo);
enableFeatures(pCreateInfo);
initQueues(pCreateInfo);
@ -4578,7 +4578,7 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
// In a multi-GPU system, if we are using the high-power GPU and want the window system
// to also use that GPU to avoid copying content between GPUs, force the window system
// to use the high-power GPU by calling the MTLCreateSystemDefaultDevice() function.
if (_enabledExtensions.vk_KHR_swapchain.enabled && mvkConfig().switchSystemGPU &&
if (_enabledExtensions.vk_KHR_swapchain.enabled && getMVKConfig().switchSystemGPU &&
!(_physicalDevice->_mtlDevice.isLowPower || _physicalDevice->_mtlDevice.isHeadless) ) {
MTLCreateSystemDefaultDevice();
}
@ -4588,8 +4588,8 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
// Use Metal arg buffs if available, and either config wants them always,
// or config wants them with descriptor indexing and descriptor indexing has been enabled.
_isUsingMetalArgumentBuffers = (_physicalDevice->supportsMetalArgumentBuffers() &&
(mvkConfig().useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_ALWAYS ||
(mvkConfig().useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING &&
(getMVKConfig().useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_ALWAYS ||
(getMVKConfig().useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING &&
(_enabledVulkan12FeaturesNoExt.descriptorIndexing || _enabledExtensions.vk_EXT_descriptor_indexing.enabled))));
_commandResourceFactory = new MVKCommandResourceFactory(this);
@ -4604,8 +4604,8 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
void MVKDevice::initPerformanceTracking() {
_isPerformanceTracking = mvkConfig().performanceTracking;
_activityPerformanceLoggingStyle = mvkConfig().activityPerformanceLoggingStyle;
_isPerformanceTracking = getMVKConfig().performanceTracking;
_activityPerformanceLoggingStyle = getMVKConfig().activityPerformanceLoggingStyle;
_performanceStatistics.shaderCompilation.hashShaderCode = {};
_performanceStatistics.shaderCompilation.spirvToMSL = {};

View File

@ -1030,7 +1030,7 @@ VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreate
if (validSamples == VK_SAMPLE_COUNT_1_BIT) { return validSamples; }
// Don't use getImageType() because it hasn't been set yet.
if ( !((pCreateInfo->imageType == VK_IMAGE_TYPE_2D) || ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && mvkConfig().texture1DAs2D)) ) {
if ( !((pCreateInfo->imageType == VK_IMAGE_TYPE_2D) || ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && getMVKConfig().texture1DAs2D)) ) {
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, multisampling can only be used with a 2D image type. Setting sample count to 1."));
validSamples = VK_SAMPLE_COUNT_1_BIT;
}
@ -1809,7 +1809,7 @@ VkResult MVKImageViewPlane::initSwizzledMTLPixelFormat(const VkImageViewCreateIn
// Enable either native or shader swizzling, depending on what is available, preferring native, and return whether successful.
bool MVKImageViewPlane::enableSwizzling() {
_useNativeSwizzle = _device->_pMetalFeatures->nativeTextureSwizzle;
_useShaderSwizzle = !_useNativeSwizzle && mvkConfig().fullImageViewSwizzle;
_useShaderSwizzle = !_useNativeSwizzle && getMVKConfig().fullImageViewSwizzle;
return _useNativeSwizzle || _useShaderSwizzle;
}

View File

@ -66,6 +66,9 @@ public:
/** Returns a pointer to the Vulkan instance. */
MVKInstance* getInstance() override { return this; }
/** Return the MoltenVK configuration info for this VkInstance. */
const MVKConfiguration& getMVKConfig() override { return _enabledExtensions.vk_EXT_layer_settings.enabled ? _mvkConfig : mvkConfig(); }
/** Returns the maximum version of Vulkan the application supports. */
inline uint32_t getAPIVersion() { return _appInfo.apiVersion; }
@ -179,6 +182,7 @@ protected:
void propagateDebugName() override {}
void initProcAddrs();
void initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo);
void initMVKConfig(const VkInstanceCreateInfo* pCreateInfo);
NSArray<id<MTLDevice>>* getAvailableMTLDevicesArray();
VkDebugReportFlagsEXT getVkDebugReportFlagsFromLogLevel(MVKConfigLogLevel logLevel);
VkDebugUtilsMessageSeverityFlagBitsEXT getVkDebugUtilsMessageSeverityFlagBitsFromLogLevel(MVKConfigLogLevel logLevel);
@ -187,6 +191,7 @@ protected:
void logVersions();
VkResult verifyLayers(uint32_t count, const char* const* names);
MVKConfiguration _mvkConfig;
VkApplicationInfo _appInfo;
MVKSmallVector<MVKPhysicalDevice*, 2> _physicalDevices;
MVKSmallVector<MVKDebugReportCallback*> _debugReportCallbacks;

View File

@ -289,7 +289,7 @@ NSArray<id<MTLDevice>>* MVKInstance::getAvailableMTLDevicesArray() {
#if MVK_MACOS
NSArray* rawMTLDevs = [MTLCopyAllDevices() autorelease];
if (rawMTLDevs) {
bool forceLowPower = mvkConfig().forceLowPowerGPU;
bool forceLowPower = getMVKConfig().forceLowPowerGPU;
// Populate the array of appropriate MTLDevices
for (id<MTLDevice> md in rawMTLDevs) {
@ -368,6 +368,7 @@ MVKInstance::MVKInstance(const VkInstanceCreateInfo* pCreateInfo) : _enabledExte
setConfigurationResult(pWritableExtns->enable(pCreateInfo->enabledExtensionCount,
pCreateInfo->ppEnabledExtensionNames,
getDriverLayer()->getSupportedInstanceExtensions()));
initMVKConfig(pCreateInfo);
MVKLogInfo("Created VkInstance for Vulkan version %s, as requested by app, with the following %d Vulkan extensions enabled:%s",
mvkGetVulkanVersionString(_appInfo.apiVersion).c_str(),
@ -397,6 +398,75 @@ void MVKInstance::initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo) {
}
}
#define STR(NAME) #NAME
#define CHECK_CONFIG(name, configSetting, type) \
if(mvkStringsAreEqual(pSetting->pSettingName, STR(MVK_CONFIG_##name))) { \
_mvkConfig.configSetting = *(type*)(pSetting->pValues); \
continue; \
}
// If the VK_EXT_layer_settings extension is enabled, initialize the local
// MVKConfiguration from the global version built from environment variables.
void MVKInstance::initMVKConfig(const VkInstanceCreateInfo* pCreateInfo) {
if ( !_enabledExtensions.vk_EXT_layer_settings.enabled ) { return; }
_mvkConfig = getMVKConfig();
VkLayerSettingsCreateInfoEXT* pLSCreateInfo = nil;
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT:
pLSCreateInfo = (VkLayerSettingsCreateInfoEXT*)next;
break;
default:
break;
}
}
if ( !pLSCreateInfo ) { return; }
for (uint32_t lsIdx = 0; lsIdx < pLSCreateInfo->settingCount; lsIdx++) {
const auto* pSetting = &pLSCreateInfo->pSettings[lsIdx];
CHECK_CONFIG(DEBUG, debugMode, VkBool32);
CHECK_CONFIG(SHADER_CONVERSION_FLIP_VERTEX_Y, shaderConversionFlipVertexY, VkBool32);
CHECK_CONFIG(SYNCHRONOUS_QUEUE_SUBMITS, synchronousQueueSubmits, VkBool32);
CHECK_CONFIG(PREFILL_METAL_COMMAND_BUFFERS, prefillMetalCommandBuffers, MVKPrefillMetalCommandBuffersStyle);
CHECK_CONFIG(MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE, maxActiveMetalCommandBuffersPerQueue, uint32_t);
CHECK_CONFIG(SUPPORT_LARGE_QUERY_POOLS, supportLargeQueryPools, VkBool32);
CHECK_CONFIG(PRESENT_WITH_COMMAND_BUFFER, presentWithCommandBuffer, VkBool32);
CHECK_CONFIG(SWAPCHAIN_MIN_MAG_FILTER_USE_NEAREST, swapchainMinMagFilterUseNearest, VkBool32);
CHECK_CONFIG(METAL_COMPILE_TIMEOUT, metalCompileTimeout, uint64_t);
CHECK_CONFIG(PERFORMANCE_TRACKING, performanceTracking, VkBool32);
CHECK_CONFIG(PERFORMANCE_LOGGING_FRAME_COUNT, performanceLoggingFrameCount, uint32_t);
CHECK_CONFIG(ACTIVITY_PERFORMANCE_LOGGING_STYLE, activityPerformanceLoggingStyle, MVKConfigActivityPerformanceLoggingStyle);
CHECK_CONFIG(DISPLAY_WATERMARK, displayWatermark, VkBool32);
CHECK_CONFIG(SPECIALIZED_QUEUE_FAMILIES, specializedQueueFamilies, VkBool32);
CHECK_CONFIG(SWITCH_SYSTEM_GPU, switchSystemGPU, VkBool32);
CHECK_CONFIG(FULL_IMAGE_VIEW_SWIZZLE, fullImageViewSwizzle, VkBool32);
CHECK_CONFIG(DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_FAMILY_INDEX, defaultGPUCaptureScopeQueueFamilyIndex, VkBool32);
CHECK_CONFIG(DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_INDEX, defaultGPUCaptureScopeQueueIndex, VkBool32);
CHECK_CONFIG(FAST_MATH_ENABLED, fastMathEnabled, MVKConfigFastMath);
CHECK_CONFIG(LOG_LEVEL, logLevel, MVKConfigLogLevel);
CHECK_CONFIG(TRACE_VULKAN_CALLS, traceVulkanCalls, MVKConfigTraceVulkanCalls);
CHECK_CONFIG(FORCE_LOW_POWER_GPU, forceLowPowerGPU, VkBool32);
CHECK_CONFIG(VK_SEMAPHORE_SUPPORT_STYLE, semaphoreSupportStyle, MVKVkSemaphoreSupportStyle);
CHECK_CONFIG(AUTO_GPU_CAPTURE_SCOPE, autoGPUCaptureScope, MVKConfigAutoGPUCaptureScope);
CHECK_CONFIG(AUTO_GPU_CAPTURE_OUTPUT_FILE, autoGPUCaptureOutputFilepath, const char*);
CHECK_CONFIG(TEXTURE_1D_AS_2D, texture1DAs2D, VkBool32);
CHECK_CONFIG(PREALLOCATE_DESCRIPTORS, preallocateDescriptors, VkBool32);
CHECK_CONFIG(USE_COMMAND_POOLING, useCommandPooling, VkBool32);
CHECK_CONFIG(USE_MTLHEAP, useMTLHeap, VkBool32);
CHECK_CONFIG(API_VERSION_TO_ADVERTISE, apiVersionToAdvertise, uint32_t);
CHECK_CONFIG(ADVERTISE_EXTENSIONS, advertiseExtensions, uint32_t);
CHECK_CONFIG(RESUME_LOST_DEVICE, resumeLostDevice, VkBool32);
CHECK_CONFIG(USE_METAL_ARGUMENT_BUFFERS, useMetalArgumentBuffers, MVKUseMetalArgumentBuffers);
CHECK_CONFIG(SHADER_COMPRESSION_ALGORITHM, shaderSourceCompressionAlgorithm, MVKConfigCompressionAlgorithm);
CHECK_CONFIG(SHOULD_MAXIMIZE_CONCURRENT_COMPILATION, shouldMaximizeConcurrentCompilation, VkBool32);
}
}
#define ADD_ENTRY_POINT_MAP(name, func, api, ext1, ext2, isDev) \
_entryPoints[""#name] = { (PFN_vkVoidFunction)&func, api, ext1, ext2, isDev }
@ -761,7 +831,7 @@ void MVKInstance::logVersions() {
MVKExtensionList allExtns(this, true);
MVKLogInfo("MoltenVK version %s, supporting Vulkan version %s.\n\tThe following %d Vulkan extensions are supported:%s",
mvkGetMoltenVKVersionString(MVK_VERSION).c_str(),
mvkGetVulkanVersionString(mvkConfig().apiVersionToAdvertise).c_str(),
mvkGetVulkanVersionString(getMVKConfig().apiVersionToAdvertise).c_str(),
allExtns.getEnabledCount(),
allExtns.enabledNamesString("\n\t\t", true).c_str());
}

View File

@ -215,7 +215,7 @@ MVKPipeline::MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVK
_pipelineCache(pipelineCache),
_flags(flags),
_descriptorSetCount(layout->getDescriptorSetCount()),
_fullImageViewSwizzle(mvkConfig().fullImageViewSwizzle) {
_fullImageViewSwizzle(getMVKConfig().fullImageViewSwizzle) {
// Establish descriptor counts and push constants use.
for (uint32_t stage = kMVKShaderStageVertex; stage < kMVKShaderStageCount; stage++) {
@ -1691,11 +1691,11 @@ void MVKGraphicsPipeline::initShaderConversionConfig(SPIRVToMSLConversionConfigu
}
shaderConfig.options.mslOptions.ios_support_base_vertex_instance = getDevice()->_pMetalFeatures->baseVertexInstanceDrawing;
shaderConfig.options.mslOptions.texture_1D_as_2D = mvkConfig().texture1DAs2D;
shaderConfig.options.mslOptions.texture_1D_as_2D = getMVKConfig().texture1DAs2D;
shaderConfig.options.mslOptions.enable_point_size_builtin = isRenderingPoints(pCreateInfo) || reflectData.pointMode;
shaderConfig.options.mslOptions.enable_frag_depth_builtin = pixFmts->isDepthFormat(pixFmts->getMTLPixelFormat(pRendInfo->depthAttachmentFormat));
shaderConfig.options.mslOptions.enable_frag_stencil_ref_builtin = pixFmts->isStencilFormat(pixFmts->getMTLPixelFormat(pRendInfo->stencilAttachmentFormat));
shaderConfig.options.shouldFlipVertexY = mvkConfig().shaderConversionFlipVertexY;
shaderConfig.options.shouldFlipVertexY = getMVKConfig().shaderConversionFlipVertexY;
shaderConfig.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle;
shaderConfig.options.mslOptions.tess_domain_origin_lower_left = pTessDomainOriginState && pTessDomainOriginState->domainOrigin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
shaderConfig.options.mslOptions.multiview = mvkIsMultiview(pRendInfo->viewMask);
@ -2070,7 +2070,7 @@ MVKMTLFunction MVKComputePipeline::getMTLFunction(const VkComputePipelineCreateI
shaderConfig.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle;
shaderConfig.options.mslOptions.texture_buffer_native = _device->_pMetalFeatures->textureBuffers;
shaderConfig.options.mslOptions.dispatch_base = _allowsDispatchBase;
shaderConfig.options.mslOptions.texture_1D_as_2D = mvkConfig().texture1DAs2D;
shaderConfig.options.mslOptions.texture_1D_as_2D = getMVKConfig().texture1DAs2D;
shaderConfig.options.mslOptions.fixed_subgroup_size = mvkIsAnyFlagEnabled(pSS->flags, VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT) ? 0 : _device->_pMetalFeatures->maxSubgroupSize;
bool useMetalArgBuff = isUsingMetalArgumentBuffers();

View File

@ -2026,7 +2026,7 @@ void MVKPixelFormats::buildVkFormatMaps() {
#if MVK_IOS || MVK_TVOS
bool supportsNativeTextureSwizzle = mtlDev && mvkOSVersionIsAtLeast(13.0);
#endif
if (!supportsNativeTextureSwizzle && !mvkConfig().fullImageViewSwizzle) {
if (!supportsNativeTextureSwizzle && !getMVKConfig().fullImageViewSwizzle) {
vkDesc.mtlPixelFormat = vkDesc.mtlPixelFormatSubstitute = MTLPixelFormatInvalid;
}
}

View File

@ -307,7 +307,7 @@ void MVKOcclusionQueryPool::beginQueryAddedTo(uint32_t query, MVKCommandBuffer*
MVKOcclusionQueryPool::MVKOcclusionQueryPool(MVKDevice* device,
const VkQueryPoolCreateInfo* pCreateInfo) : MVKQueryPool(device, pCreateInfo, 1) {
if (mvkConfig().supportLargeQueryPools) {
if (getMVKConfig().supportLargeQueryPools) {
_queryIndexOffset = 0;
// Ensure we don't overflow the maximum number of queries

View File

@ -38,7 +38,7 @@ id<MTLCommandQueue> MVKQueueFamily::getMTLCommandQueue(uint32_t queueIndex) {
id<MTLCommandQueue> mtlQ = _mtlQueues[queueIndex];
if ( !mtlQ ) {
@autoreleasepool { // Catch any autoreleased objects created during MTLCommandQueue creation
uint32_t maxCmdBuffs = mvkConfig().maxActiveMetalCommandBuffersPerQueue;
uint32_t maxCmdBuffs = getMVKConfig().maxActiveMetalCommandBuffersPerQueue;
mtlQ = [_physicalDevice->getMTLDevice() newCommandQueueWithMaxCommandBufferCount: maxCmdBuffs]; // retained
_mtlQueues[queueIndex] = mtlQ;
}
@ -155,7 +155,7 @@ id<MTLCommandBuffer> MVKQueue::getMTLCommandBuffer(MVKCommandUse cmdUse, bool re
if ([_mtlQueue respondsToSelector: @selector(commandBufferWithDescriptor:)]) {
MTLCommandBufferDescriptor* mtlCmdBuffDesc = [MTLCommandBufferDescriptor new]; // temp retain
mtlCmdBuffDesc.retainedReferences = retainRefs;
if (mvkConfig().debugMode) {
if (getMVKConfig().debugMode) {
mtlCmdBuffDesc.errorOptions |= MTLCommandBufferErrorOptionEncoderExecutionStatus;
}
mtlCmdBuff = [_mtlQueue commandBufferWithDescriptor: mtlCmdBuffDesc];
@ -225,7 +225,7 @@ void MVKQueue::initName() {
void MVKQueue::initExecQueue() {
_execQueue = nil;
if ( !mvkConfig().synchronousQueueSubmits ) {
if ( !getMVKConfig().synchronousQueueSubmits ) {
// Determine the dispatch queue priority
dispatch_qos_class_t dqQOS = MVK_DISPATCH_QUEUE_QOS_CLASS;
int dqPriority = (1.0 - _priority) * QOS_MIN_RELATIVE_PRIORITY;
@ -247,8 +247,8 @@ void MVKQueue::initMTLCommandQueue() {
void MVKQueue::initGPUCaptureScopes() {
_submissionCaptureScope = new MVKGPUCaptureScope(this);
if (_queueFamily->getIndex() == mvkConfig().defaultGPUCaptureScopeQueueFamilyIndex &&
_index == mvkConfig().defaultGPUCaptureScopeQueueIndex) {
if (_queueFamily->getIndex() == getMVKConfig().defaultGPUCaptureScopeQueueFamilyIndex &&
_index == getMVKConfig().defaultGPUCaptureScopeQueueIndex) {
getDevice()->startAutoGPUCapture(MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME, _mtlQueue);
_submissionCaptureScope->makeDefault();
@ -404,11 +404,11 @@ void MVKQueueCommandBufferSubmission::commitActiveMTLCommandBuffer(bool signalCo
mvkDev->markLost(true);
break;
default:
if ( !mvkConfig().resumeLostDevice ) { mvkDev->markLost(); }
if ( !getMVKConfig().resumeLostDevice ) { mvkDev->markLost(); }
break;
}
#if MVK_XCODE_12
if (mvkConfig().debugMode) {
if (getMVKConfig().debugMode) {
if (&MTLCommandBufferEncoderInfoErrorKey != nullptr) {
if (NSArray<id<MTLCommandBufferEncoderInfo>>* mtlEncInfo = mtlCB.error.userInfo[MTLCommandBufferEncoderInfoErrorKey]) {
MVKLogInfo("Encoders for %p \"%s\":", mtlCB, mtlCB.label ? mtlCB.label.UTF8String : "");
@ -427,7 +427,7 @@ void MVKQueueCommandBufferSubmission::commitActiveMTLCommandBuffer(bool signalCo
#endif
}
#if MVK_XCODE_12
if (mvkConfig().debugMode && [mtlCB respondsToSelector: @selector(logs)]) {
if (getMVKConfig().debugMode && [mtlCB respondsToSelector: @selector(logs)]) {
bool isFirstMsg = true;
for (id<MTLFunctionLog> log in mtlCB.logs) {
if (isFirstMsg) {
@ -561,8 +561,8 @@ void MVKQueuePresentSurfaceSubmission::finish() {
auto cs = _queue->_submissionCaptureScope;
cs->endScope();
cs->beginScope();
if (_queue->_queueFamily->getIndex() == mvkConfig().defaultGPUCaptureScopeQueueFamilyIndex &&
_queue->_index == mvkConfig().defaultGPUCaptureScopeQueueIndex) {
if (_queue->_queueFamily->getIndex() == getMVKConfig().defaultGPUCaptureScopeQueueFamilyIndex &&
_queue->_index == getMVKConfig().defaultGPUCaptureScopeQueueIndex) {
_queue->getDevice()->stopAutoGPUCapture(MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME);
}

View File

@ -155,7 +155,7 @@ void MVKShaderLibrary::setWorkgroupSize(uint32_t x, uint32_t y, uint32_t z) {
void MVKShaderLibrary::compressMSL(const string& msl) {
MVKDevice* mvkDev = _owner->getDevice();
uint64_t startTime = mvkDev->getPerformanceTimestamp();
_compressedMSL.compress(msl, mvkConfig().shaderSourceCompressionAlgorithm);
_compressedMSL.compress(msl, getMVKConfig().shaderSourceCompressionAlgorithm);
mvkDev->addActivityPerformance(mvkDev->_performanceStatistics.shaderCompilation.mslCompress, startTime);
}
@ -353,7 +353,7 @@ MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConversionConfiguration
bool MVKShaderModule::convert(SPIRVToMSLConversionConfiguration* pShaderConfig,
SPIRVToMSLConversionResult& conversionResult) {
bool shouldLogCode = mvkConfig().debugMode;
bool shouldLogCode = getMVKConfig().debugMode;
bool shouldLogEstimatedGLSL = shouldLogCode;
// If the SPIR-V converter does not have any code, but the GLSL converter does,
@ -508,7 +508,7 @@ id<MTLLibrary> MVKShaderLibraryCompiler::newMTLLibrary(NSString* mslSourceCode,
@synchronized (mtlDev) {
auto mtlCompileOptions = _owner->getDevice()->getMTLCompileOptions(shaderConversionResults.entryPoint.supportsFastMath,
shaderConversionResults.isPositionInvariant);
MVKLogInfoIf(mvkConfig().debugMode, "Compiling Metal shader%s.", mtlCompileOptions.fastMathEnabled ? " with FastMath enabled" : "");
MVKLogInfoIf(getMVKConfig().debugMode, "Compiling Metal shader%s.", mtlCompileOptions.fastMathEnabled ? " with FastMath enabled" : "");
[mtlDev newLibraryWithSource: mslSourceCode
options: mtlCompileOptions
completionHandler: ^(id<MTLLibrary> mtlLib, NSError* error) {

View File

@ -138,7 +138,7 @@ void MVKSwapchain::willPresentSurface(id<MTLTexture> mtlTexture, id<MTLCommandBu
// If the product has not been fully licensed, renders the watermark image to the surface.
void MVKSwapchain::renderWatermark(id<MTLTexture> mtlTexture, id<MTLCommandBuffer> mtlCmdBuff) {
if (mvkConfig().displayWatermark) {
if (getMVKConfig().displayWatermark) {
if ( !_licenseWatermark ) {
_licenseWatermark = new MVKWatermarkRandom(getMTLDevice(),
__watermarkTextureContent,
@ -159,7 +159,7 @@ void MVKSwapchain::renderWatermark(id<MTLTexture> mtlTexture, id<MTLCommandBuffe
// Calculates and remembers the time interval between frames.
void MVKSwapchain::markFrameInterval() {
if ( !(mvkConfig().performanceTracking || _licenseWatermark) ) { return; }
if ( !(getMVKConfig().performanceTracking || _licenseWatermark) ) { return; }
uint64_t prevFrameTime = _lastFrameTime;
_lastFrameTime = mvkGetTimestamp();
@ -168,14 +168,14 @@ void MVKSwapchain::markFrameInterval() {
_device->addActivityPerformance(_device->_performanceStatistics.queue.frameInterval, prevFrameTime, _lastFrameTime);
uint32_t perfLogCntLimit = mvkConfig().performanceLoggingFrameCount;
uint32_t perfLogCntLimit = getMVKConfig().performanceLoggingFrameCount;
if ((perfLogCntLimit > 0) && (++_currentPerfLogFrameCount >= perfLogCntLimit)) {
_currentPerfLogFrameCount = 0;
MVKLogInfo("Performance statistics reporting every: %d frames, avg FPS: %.2f, elapsed time: %.3f seconds:",
perfLogCntLimit,
(1000.0 / _device->_performanceStatistics.queue.frameInterval.averageDuration),
mvkGetElapsedMilliseconds() / 1000.0);
if (mvkConfig().activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT) {
if (getMVKConfig().activityPerformanceLoggingStyle == MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE_FRAME_COUNT) {
_device->logPerformanceSummary();
}
}
@ -341,7 +341,7 @@ void MVKSwapchain::initCAMetalLayer(const VkSwapchainCreateInfoKHR* pCreateInfo,
return;
}
auto minMagFilter = mvkConfig().swapchainMinMagFilterUseNearest ? kCAFilterNearest : kCAFilterLinear;
auto minMagFilter = getMVKConfig().swapchainMinMagFilterUseNearest ? kCAFilterNearest : kCAFilterLinear;
_mtlLayer.device = getMTLDevice();
_mtlLayer.pixelFormat = getPixelFormats()->getMTLPixelFormat(pCreateInfo->imageFormat);
_mtlLayer.maximumDrawableCountMVK = imgCnt;

View File

@ -571,7 +571,7 @@ void MVKMetalCompiler::compile(unique_lock<mutex>& lock, dispatch_block_t block)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @autoreleasepool { block(); } });
// Limit timeout to avoid overflow since wait_for() uses wait_until()
chrono::nanoseconds nanoTimeout(min(mvkConfig().metalCompileTimeout, kMVKUndefinedLargeUInt64));
chrono::nanoseconds nanoTimeout(min(getMVKConfig().metalCompileTimeout, kMVKUndefinedLargeUInt64));
_blocker.wait_for(lock, nanoTimeout, [this]{ return _isCompileDone; });
if ( !_isCompileDone ) {

View File

@ -108,6 +108,7 @@ MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA,
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(EXT_image_robustness, EXT_IMAGE_ROBUSTNESS, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(EXT_inline_uniform_block, EXT_INLINE_UNIFORM_BLOCK, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(EXT_layer_settings, EXT_LAYER_SETTINGS, INSTANCE, 10.11, 8.0, 1.0)
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET, DEVICE, 10.13, 11.0, 1.0)
MVK_EXTENSION(EXT_metal_objects, EXT_METAL_OBJECTS, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE, INSTANCE, 10.11, 8.0, 1.0)

View File

@ -43,7 +43,7 @@ MVKLayer::MVKLayer() : _supportedInstanceExtensions(nullptr, true) {
strcpy(_layerProperties.layerName, "MoltenVK");
mvkClear(_layerProperties.description, VK_MAX_DESCRIPTION_SIZE);
strcpy(_layerProperties.description, "MoltenVK driver layer");
_layerProperties.specVersion = mvkConfig().apiVersionToAdvertise;
_layerProperties.specVersion = getMVKConfig().apiVersionToAdvertise;
_layerProperties.implementationVersion = MVK_VERSION;
((MVKExtensionList*)&_supportedInstanceExtensions)->disableAllButEnabledInstanceExtensions();

View File

@ -42,6 +42,13 @@ public:
/** Returns the Vulkan API opaque object controlling this object. */
virtual MVKVulkanAPIObject* getVulkanAPIObject() = 0;
/**
* If getVulkanAPIObject() does not return NULL, this function returns the MoltenVK
* configuration info for the VkInstance that created the API object, otherwise
* this function returns the global configuration info.
*/
virtual const MVKConfiguration& getMVKConfig();
/**
* Report a message. This includes logging to a standard system logging stream,
* and some subclasses will also forward the message to their VkInstance for

View File

@ -22,6 +22,7 @@
#include "MVKFoundation.h"
#include "MVKOSExtensions.h"
#include "MVKStrings.h"
#include <MoltenVK/mvk_config.h>
using namespace std;
@ -46,6 +47,12 @@ static const char* getReportingLevelString(MVKConfigLogLevel logLevel) {
string MVKBaseObject::getClassName() { return mvk::getTypeName(this); }
const MVKConfiguration& MVKBaseObject::getMVKConfig() {
MVKVulkanAPIObject* mvkAPIObj = getVulkanAPIObject();
MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr;
return mvkInst ? mvkInst->getMVKConfig() : mvkConfig();
}
void MVKBaseObject::reportMessage(MVKConfigLogLevel logLevel, const char* format, ...) {
va_list args;
va_start(args, format);
@ -66,7 +73,7 @@ void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, MVKConfigLogLevel logLe
MVKVulkanAPIObject* mvkAPIObj = mvkObj ? mvkObj->getVulkanAPIObject() : nullptr;
MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr;
bool hasDebugCallbacks = mvkInst && mvkInst->hasDebugCallbacks();
bool shouldLog = logLevel <= mvkConfig().logLevel;
bool shouldLog = logLevel <= (mvkInst ? mvkInst->getMVKConfig() : mvkConfig()).logLevel;
// Fail fast to avoid further unnecessary processing.
if ( !(shouldLog || hasDebugCallbacks) ) { return; }

View File

@ -27,7 +27,7 @@ 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.debugMode, MVK_CONFIG_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);
@ -65,6 +65,11 @@ static void mvkInitConfigFromEnvVars() {
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);
// Support legacy environment variable MVK_DEBUG, but only if it has been explicitly set as an environment variable.
bool legacyDebugWasFound = false;
bool legacyDebugEV = mvkGetEnvVarBool("MVK_DEBUG", &legacyDebugWasFound);
if (legacyDebugWasFound) { evCfg.debugMode = legacyDebugEV; }
// 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,
// but for backwards compatibility, if legacy MVK_ALLOW_METAL_EVENTS is explicitly

View File

@ -128,7 +128,7 @@ extern "C" {
# define MVK_LOG_LEVEL_INFO MVK_LOGGING_ENABLED
#endif
#ifndef MVK_LOG_LEVEL_DEBUG
# define MVK_LOG_LEVEL_DEBUG (MVK_LOGGING_ENABLED && MVK_DEBUG)
# define MVK_LOG_LEVEL_DEBUG (MVK_LOGGING_ENABLED && MVK_CONFIG_DEBUG)
#endif
#ifndef MVK_LOG_LEVEL_TRACE
# define MVK_LOG_LEVEL_TRACE 0

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