From 10625a86384f0c170101b48bd532753bf6e637a0 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Mon, 4 Sep 2023 21:45:42 -0400 Subject: [PATCH] Add support for VK_EXT_layer_settings extension. --- Common/MVKCommonEnvironment.h | 7 +- Docs/MoltenVK_Runtime_UserGuide.md | 11 +-- Docs/Whats_New.md | 2 + MoltenVK/MoltenVK/API/mvk_config.h | 14 ++-- .../MoltenVK/Commands/MVKCommandBuffer.mm | 4 +- .../MoltenVK/GPUObjects/MVKDescriptorSet.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 48 ++++++------ MoltenVK/MoltenVK/GPUObjects/MVKImage.mm | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKInstance.h | 5 ++ MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 74 ++++++++++++++++++- MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 8 +- .../MoltenVK/GPUObjects/MVKPixelFormats.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm | 20 ++--- .../MoltenVK/GPUObjects/MVKShaderModule.mm | 6 +- MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm | 10 +-- MoltenVK/MoltenVK/GPUObjects/MVKSync.mm | 2 +- MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + MoltenVK/MoltenVK/Layers/MVKLayers.mm | 2 +- MoltenVK/MoltenVK/Utility/MVKBaseObject.h | 7 ++ MoltenVK/MoltenVK/Utility/MVKBaseObject.mm | 9 ++- MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp | 7 +- MoltenVK/MoltenVK/Utility/MVKLogging.h | 2 +- Scripts/runcts | 2 +- 25 files changed, 180 insertions(+), 75 deletions(-) diff --git a/Common/MVKCommonEnvironment.h b/Common/MVKCommonEnvironment.h index a14ba91d..a1bbfd87 100644 --- a/Common/MVKCommonEnvironment.h +++ b/Common/MVKCommonEnvironment.h @@ -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 diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index f236a7e9..47fa35ba 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -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 diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 82e9b155..566c95bc 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -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. diff --git a/MoltenVK/MoltenVK/API/mvk_config.h b/MoltenVK/MoltenVK/API/mvk_config.h index 360007e1..0a4c25e7 100644 --- a/MoltenVK/MoltenVK/API/mvk_config.h +++ b/MoltenVK/MoltenVK/API/mvk_config.h @@ -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); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 5edc13aa..a0abfc71 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -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); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm index 1406ab17..41005c63 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm @@ -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), diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 450fad66..cb6f9b51 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -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; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 0b11d4df..ff575907 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -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 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 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 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 = {}; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 14870221..89b98d91 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -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; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h index 9e41ac71..04aea66e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h @@ -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>* 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 _physicalDevices; MVKSmallVector _debugReportCallbacks; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 5c6e6cb9..b952aefe 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -289,7 +289,7 @@ NSArray>* 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 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()); } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index 13f59b6b..7b1d467b 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -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(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm index 3044f66d..828bca38 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm @@ -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; } } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm index 2e0e1368..5275d74e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm @@ -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 diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm index 0ad14307..786e979f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm @@ -38,7 +38,7 @@ id MVKQueueFamily::getMTLCommandQueue(uint32_t queueIndex) { id 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 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>* 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 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); } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm index a47a65b7..3e7b5c12 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm @@ -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 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 mtlLib, NSError* error) { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm index 601fbc54..e6f3e5c2 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm @@ -138,7 +138,7 @@ void MVKSwapchain::willPresentSurface(id mtlTexture, id mtlTexture, id mtlCmdBuff) { - if (mvkConfig().displayWatermark) { + if (getMVKConfig().displayWatermark) { if ( !_licenseWatermark ) { _licenseWatermark = new MVKWatermarkRandom(getMTLDevice(), __watermarkTextureContent, @@ -159,7 +159,7 @@ void MVKSwapchain::renderWatermark(id mtlTexture, idaddActivityPerformance(_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; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm index efde21cb..d4ebe72f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm @@ -571,7 +571,7 @@ void MVKMetalCompiler::compile(unique_lock& 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 ) { diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 74a00629..ee292a76 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -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) diff --git a/MoltenVK/MoltenVK/Layers/MVKLayers.mm b/MoltenVK/MoltenVK/Layers/MVKLayers.mm index 875722b8..22b2138b 100644 --- a/MoltenVK/MoltenVK/Layers/MVKLayers.mm +++ b/MoltenVK/MoltenVK/Layers/MVKLayers.mm @@ -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(); diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h index 7005e985..d45f4078 100644 --- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.h +++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.h @@ -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 diff --git a/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm b/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm index 427c3227..7783e9ab 100644 --- a/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm +++ b/MoltenVK/MoltenVK/Utility/MVKBaseObject.mm @@ -22,6 +22,7 @@ #include "MVKFoundation.h" #include "MVKOSExtensions.h" #include "MVKStrings.h" +#include 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; } diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp index 5aa6f7db..d8dd7341 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp @@ -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 diff --git a/MoltenVK/MoltenVK/Utility/MVKLogging.h b/MoltenVK/MoltenVK/Utility/MVKLogging.h index bea3a92f..c65127b0 100644 --- a/MoltenVK/MoltenVK/Utility/MVKLogging.h +++ b/MoltenVK/MoltenVK/Utility/MVKLogging.h @@ -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 diff --git a/Scripts/runcts b/Scripts/runcts index 20ae1abe..24cd9baa 100755 --- a/Scripts/runcts +++ b/Scripts/runcts @@ -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