From f191b0a31a0e1d2011153f84d6ceaf3733cac833 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Wed, 8 Mar 2023 19:04:52 -0500 Subject: [PATCH] Various maintenance updates. - Cleanup VkPhysicalDeviceShaderAtomicFloatFeaturesEXT enablement and documentation. - Cleanup VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT enablement. - Expand MVK_CONFIG_TRACE_VULKAN_CALLS to log thread ID only if requested. --- Docs/MoltenVK_Runtime_UserGuide.md | 6 +- Docs/Whats_New.md | 4 +- MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h | 13 +++-- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 37 +++++++----- .../GPUObjects/MVKDeviceFeatureStructs.def | 3 +- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 58 +++++++++++++------ 6 files changed, 79 insertions(+), 42 deletions(-) diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index a015c857..cfa4e142 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -22,7 +22,7 @@ Table of Contents - [Installing **MoltenVK** in Your *Vulkan* Application](#install) - [Install *MoltenVK* as a Universal `XCFramework`](#install_xcfwk) - [Install *MoltenVK* as a Dynamic Library](#install_dylib) - - [Install *MoltenVK* replacing the Vulkan SDK .dylib](#install_vksdk) + - [Install *MoltenVK* replacing the Vulkan SDK `libMoltenVK.dylib`](#install_vksdk) - [Build and Runtime Requirements](#requirements) - [Interacting with the **MoltenVK** Runtime](#interaction) - [MoltenVK `VK_MVK_moltenvk` Extension](#moltenvk_extension) @@ -221,7 +221,7 @@ To link **MoltenVK** to your application as a dynamic library (`.dylib`), follow -### Install *MoltenVK* replacing the Vulkan SDK .dylib +### Install *MoltenVK* replacing the Vulkan SDK `libMoltenVK.dylib` There are a few potential issues when building **MoltenVK** to replace the version installed via the *[Vulkan SDK](https://vulkan.lunarg.com/sdk/home)* standard install process, which lives in @@ -337,7 +337,6 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_KHR_sampler_mirror_clamp_to_edge` *(requires a Mac GPU or Apple family 7 GPU)* - `VK_KHR_sampler_ycbcr_conversion` - `VK_KHR_separate_depth_stencil_layouts` -- `VK_EXT_shader_atomic_float` *(requires Metal 3.0)* - `VK_KHR_shader_draw_parameters` - `VK_KHR_shader_float_controls` - `VK_KHR_shader_float16_int8` @@ -371,6 +370,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_EXT_sample_locations` - `VK_EXT_scalar_block_layout` - `VK_EXT_separate_stencil_usage` +- `VK_EXT_shader_atomic_float` *(requires Metal 3.0)* - `VK_EXT_shader_stencil_export` *(requires Mac GPU family 2 or iOS GPU family 5)* - `VK_EXT_shader_viewport_index_layer` - `VK_EXT_subgroup_size_control` *(requires Metal 2.1 on Mac or Metal 2.2 and Apple family 4 on iOS)* diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 5c895704..0bba8b25 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -20,8 +20,9 @@ Released TBA - Add support for extensions: - `VK_EXT_pipeline_creation_cache_control` - - `VK_EXT_swapchain_maintenance1` + - `VK_EXT_shader_atomic_float` - `VK_EXT_surface_maintenance1` + - `VK_EXT_swapchain_maintenance1` - Fix crash when `VkCommandBufferInheritanceInfo::renderPass` is `VK_NULL_HANDLE` during dynamic rendering. - Do not clear attachments when dynamic rendering is resumed. - Allow ending dynamic rendering to trigger next multiview pass if needed. @@ -44,6 +45,7 @@ Released TBA - Change `MVKConfiguration::logActivityPerformanceInline` boolean to `activityPerformanceLoggingStyle` enumeration value. - Add `MVK_CONFIG_ACTIVITY_PERFORMANCE_LOGGING_STYLE` environment variable and build setting to set `MVKConfiguration::activityPerformanceLoggingStyle` value. +- Expand `MVK_CONFIG_TRACE_VULKAN_CALLS` to log thread ID only if requested. - Update `VK_MVK_MOLTENVK_SPEC_VERSION` to version `37`. diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index 7377f05f..66a3fede 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -71,11 +71,14 @@ typedef enum MVKConfigLogLevel { /** Identifies the level of Vulkan call trace logging MoltenVK should perform. */ typedef enum MVKConfigTraceVulkanCalls { - MVK_CONFIG_TRACE_VULKAN_CALLS_NONE = 0, /**< No Vulkan call logging. */ - MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER = 1, /**< Log the name of each Vulkan call when the call is entered. */ - MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT = 2, /**< Log the name of each Vulkan call when the call is entered and exited. This effectively brackets any other logging activity within the scope of the Vulkan call. */ - MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION = 3, /**< Same as MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT, plus logs the time spent inside the Vulkan function. */ - MVK_CONFIG_TRACE_VULKAN_CALLS_MAX_ENUM = 0x7FFFFFFF + MVK_CONFIG_TRACE_VULKAN_CALLS_NONE = 0, /**< No Vulkan call logging. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER = 1, /**< Log the name of each Vulkan call when the call is entered. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_THREAD_ID = 2, /**< Log the name and thread ID of each Vulkan call when the call is entered. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT = 3, /**< Log the name of each Vulkan call when the call is entered and exited. This effectively brackets any other logging activity within the scope of the Vulkan call. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT_THREAD_ID = 4, /**< Log the name and thread ID of each Vulkan call when the call is entered and name when exited. This effectively brackets any other logging activity within the scope of the Vulkan call. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION = 5, /**< Same as MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT, plus logs the time spent inside the Vulkan function. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION_THREAD_ID = 6, /**< Same as MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT_THREAD_ID, plus logs the time spent inside the Vulkan function. */ + MVK_CONFIG_TRACE_VULKAN_CALLS_MAX_ENUM = 0x7FFFFFFF } MVKConfigTraceVulkanCalls; /** Identifies the scope for Metal to run an automatic GPU capture for diagnostic debugging purposes. */ diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 9fdf44d0..6a0bd6f2 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -378,6 +378,11 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) { interlockFeatures->fragmentShaderShadingRateInterlock = false; // Requires variable rate shading; not supported yet in Metal break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT: { + auto* pipelineCreationCacheControlFeatures = (VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT*)next; + pipelineCreationCacheControlFeatures->pipelineCreationCacheControl = true; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: { auto* robustness2Features = (VkPhysicalDeviceRobustness2FeaturesEXT*)next; robustness2Features->robustBufferAccess2 = false; @@ -385,16 +390,28 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) { robustness2Features->nullDescriptor = false; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT: { + auto* atomicFloatFeatures = (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT*)next; + bool atomicFloatEnabled = _metalFeatures.mslVersion >= 030000; + atomicFloatFeatures->shaderBufferFloat32Atomics = atomicFloatEnabled; + atomicFloatFeatures->shaderBufferFloat32AtomicAdd = atomicFloatEnabled; + atomicFloatFeatures->shaderBufferFloat64Atomics = false; + atomicFloatFeatures->shaderBufferFloat64AtomicAdd = false; + atomicFloatFeatures->shaderSharedFloat32Atomics = atomicFloatEnabled; + atomicFloatFeatures->shaderSharedFloat32AtomicAdd = atomicFloatEnabled; + atomicFloatFeatures->shaderSharedFloat64Atomics = false; + atomicFloatFeatures->shaderSharedFloat64AtomicAdd = false; + atomicFloatFeatures->shaderImageFloat32Atomics = false; + atomicFloatFeatures->shaderImageFloat32AtomicAdd = false; + atomicFloatFeatures->sparseImageFloat32Atomics = false; + atomicFloatFeatures->sparseImageFloat32AtomicAdd = false; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT: { auto* swapchainMaintenance1Features = (VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT*)next; swapchainMaintenance1Features->swapchainMaintenance1 = true; break; } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT: { - auto* pipelineCreationCacheControlFeatures = (VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT*)next; - pipelineCreationCacheControlFeatures->pipelineCreationCacheControl = true; - break; - } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: { auto* texelBuffAlignFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next; texelBuffAlignFeatures->texelBufferAlignment = _metalFeatures.texelBuffers && [_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)]; @@ -411,16 +428,6 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) { shaderIntFuncsFeatures->shaderIntegerFunctions2 = true; break; } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT: { - auto* atomicFloatFeatures = (VkPhysicalDeviceShaderAtomicFloatFeaturesEXT*)next; - mvkClear(atomicFloatFeatures); - bool atomicFloatEnabled = _metalFeatures.mslVersion >= 030000; - atomicFloatFeatures->shaderBufferFloat32Atomics = atomicFloatEnabled; - atomicFloatFeatures->shaderBufferFloat32AtomicAdd = atomicFloatEnabled; - atomicFloatFeatures->shaderSharedFloat32Atomics = atomicFloatEnabled; - atomicFloatFeatures->shaderSharedFloat32AtomicAdd = atomicFloatEnabled; - break; - } default: break; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def index 05086327..0674e4c1 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def @@ -63,8 +63,9 @@ MVK_DEVICE_FEATURE(VulkanMemoryModel, VULKAN_MEMORY_MODEL, MVK_DEVICE_FEATURE_EXTN(FragmentShaderBarycentric, FRAGMENT_SHADER_BARYCENTRIC, KHR, 1) MVK_DEVICE_FEATURE_EXTN(PortabilitySubset, PORTABILITY_SUBSET, KHR, 15) MVK_DEVICE_FEATURE_EXTN(FragmentShaderInterlock, FRAGMENT_SHADER_INTERLOCK, EXT, 3) -MVK_DEVICE_FEATURE_EXTN(Robustness2, ROBUSTNESS_2, EXT, 3) MVK_DEVICE_FEATURE_EXTN(PipelineCreationCacheControl, PIPELINE_CREATION_CACHE_CONTROL, EXT, 1) +MVK_DEVICE_FEATURE_EXTN(Robustness2, ROBUSTNESS_2, EXT, 3) +MVK_DEVICE_FEATURE_EXTN(ShaderAtomicFloat, SHADER_ATOMIC_FLOAT, EXT, 12) MVK_DEVICE_FEATURE_EXTN(SwapchainMaintenance1, SWAPCHAIN_MAINTENANCE_1, EXT, 1) MVK_DEVICE_FEATURE_EXTN(TexelBufferAlignment, TEXEL_BUFFER_ALIGNMENT, EXT, 1) MVK_DEVICE_FEATURE_EXTN(VertexAttributeDivisor, VERTEX_ATTRIBUTE_DIVISOR, EXT, 2) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index dfea51b2..03abf9b9 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -50,35 +50,59 @@ // Optionally log start of function calls to stderr static inline uint64_t MVKTraceVulkanCallStartImpl(const char* funcName) { - MVKConfigTraceVulkanCalls traceLvl = mvkConfig().traceVulkanCalls; - if (traceLvl == MVK_CONFIG_TRACE_VULKAN_CALLS_NONE || - traceLvl > MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION) { return 0; } + bool includeThread = false; + bool includeExit = false; + bool includeDuration = false; - uint64_t gtid, mtid; - const uint32_t kThreadNameBuffSize = 256; - char threadName[kThreadNameBuffSize]; - pthread_t tid = pthread_self(); - mtid = pthread_mach_thread_np(tid); // Mach thread ID - pthread_threadid_np(tid, >id); // Global system-wide thead ID - pthread_getname_np(tid, threadName, kThreadNameBuffSize); + switch (mvkConfig().traceVulkanCalls) { + case MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION: + includeDuration = true; // fallthrough + case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT: + includeExit = true; // fallthrough + case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER: + break; - fprintf(stderr, "[mvk-trace] %s()%s [%llu/%llu/%s]\n", - funcName, (traceLvl >= MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT) ? " {" : "", - mtid, gtid, threadName); + case MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION_THREAD_ID: + includeDuration = true; // fallthrough + case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT_THREAD_ID: + includeExit = true; // fallthrough + case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_THREAD_ID: + includeThread = true; // fallthrough + break; - return (traceLvl == MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION) ? mvkGetTimestamp() : 0; + case MVK_CONFIG_TRACE_VULKAN_CALLS_NONE: + default: + return 0; + } + + if (includeThread) { + uint64_t gtid, mtid; + const uint32_t kThreadNameBuffSize = 256; + char threadName[kThreadNameBuffSize]; + pthread_t tid = pthread_self(); + mtid = pthread_mach_thread_np(tid); // Mach thread ID + pthread_threadid_np(tid, >id); // Global system-wide thead ID + pthread_getname_np(tid, threadName, kThreadNameBuffSize); + fprintf(stderr, "[mvk-trace] %s()%s [%llu/%llu/%s]\n", funcName, includeExit ? " {" : "", mtid, gtid, threadName); + } else { + fprintf(stderr, "[mvk-trace] %s()%s\n", funcName, includeExit ? " {" : ""); + } + + return includeDuration ? mvkGetTimestamp() : 0; } // Optionally log end of function calls and timings to stderr static inline void MVKTraceVulkanCallEndImpl(const char* funcName, uint64_t startTime) { switch(mvkConfig().traceVulkanCalls) { - case MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION: - fprintf(stderr, "[mvk-trace] } %s [%.4f ms]\n", funcName, mvkGetElapsedMilliseconds(startTime)); - break; case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT: + case MVK_CONFIG_TRACE_VULKAN_CALLS_ENTER_EXIT_THREAD_ID: fprintf(stderr, "[mvk-trace] } %s\n", funcName); break; + case MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION: + case MVK_CONFIG_TRACE_VULKAN_CALLS_DURATION_THREAD_ID: + fprintf(stderr, "[mvk-trace] } %s [%.4f ms]\n", funcName, mvkGetElapsedMilliseconds(startTime)); + break; default: break; }