Merge pull request #648 from billhollings/master

Add additional performance and call tracing options.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index fbca82f..024ee5a 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -20,7 +20,9 @@
 
 - On iOS GPU family 2 and earlier, support immutable depth-compare samplers 
   as constexpr samplers hardcoded in MSL.
-- Skip SPIRV-Tools build in Travis.
+- Add MTLCommandBuffer completion timing performance tracking option.
+- Expand `MVK_CONFIG_TRACE_VULKAN_CALLS` to optionally log Vulkan call timings.
+- Skip `SPIRV-Tools` build in Travis because Travis does not support the required Python 3.
 
 
 
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index 31452e2..0198117 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -55,7 +55,7 @@
 #define MVK_MAKE_VERSION(major, minor, patch)    (((major) * 10000) + ((minor) * 100) + (patch))
 #define MVK_VERSION     MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
 
-#define VK_MVK_MOLTENVK_SPEC_VERSION            20
+#define VK_MVK_MOLTENVK_SPEC_VERSION            21
 #define VK_MVK_MOLTENVK_EXTENSION_NAME          "VK_MVK_moltenvk"
 
 /**
@@ -102,8 +102,14 @@
  *      2: Log errors and informational messages.
  *    If neither is set, errors and informational messages are logged.
  *
- * 2. Setting the MVK_CONFIG_TRACE_VULKAN_CALLS runtime environment variable or MoltenVK compile-time
- *    build setting to 1 will cause MoltenVK to log the name of each Vulkan call made by the application.
+ * 2. Setting the MVK_CONFIG_TRACE_VULKAN_CALLS runtime environment variable or MoltenVK compile-time build
+ *    setting will cause MoltenVK to log the name of each Vulkan call made by the application. The logging
+ *    format options can be controlled by setting the value of MVK_CONFIG_TRACE_VULKAN_CALLS as follows:
+ *        0: No Vulkan call logging.
+ *        1: Log the name of each Vulkan call when the call is entered.
+ *        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.
+ *        3: Same as option 2, plus logs the time spent inside the Vulkan function.
  *
  * 3. Setting the MVK_CONFIG_FORCE_LOW_POWER_GPU runtime environment variable or MoltenVK compile-time
  *    build setting to 1 will force MoltenVK to use a low-power GPU, if one is availble on the device.
@@ -584,7 +590,8 @@
 
 /** MoltenVK performance of queue activities. */
 typedef struct {
-	MVKPerformanceTracker mtlQueueAccess;          	/** Create an MTLCommmandQueue or access an existing cached instance. */
+	MVKPerformanceTracker mtlQueueAccess;               /** Create an MTLCommmandQueue or access an existing cached instance. */
+	MVKPerformanceTracker mtlCommandBufferCompletion;   /** Completion of a MTLCommandBuffer on the GPU, from commit to completion callback. */
 } MVKQueuePerformance;
 
 /**
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index b054c9a..e170075 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -530,10 +530,10 @@
      *
      * If endTime is zero or not supplied, the current time is used.
      */
-    inline void addActivityPerformance(MVKPerformanceTracker& shaderCompilationEvent,
+    inline void addActivityPerformance(MVKPerformanceTracker& activityTracker,
 									   uint64_t startTime, uint64_t endTime = 0) {
 		if (_pMVKConfig->performanceTracking) {
-			addActivityPerformanceImpl(shaderCompilationEvent, startTime, endTime);
+			addActivityPerformanceImpl(activityTracker, startTime, endTime);
 		}
 	};
 
@@ -653,9 +653,9 @@
 	void enableFeatures(const VkDeviceCreateInfo* pCreateInfo);
 	void enableFeatures(const VkBool32* pEnable, const VkBool32* pRequested, const VkBool32* pAvailable, uint32_t count);
 	void enableExtensions(const VkDeviceCreateInfo* pCreateInfo);
-    const char* getActivityPerformanceDescription(MVKPerformanceTracker& shaderCompilationEvent);
+    const char* getActivityPerformanceDescription(MVKPerformanceTracker& activityTracker);
 	uint64_t getPerformanceTimestampImpl();
-	void addActivityPerformanceImpl(MVKPerformanceTracker& shaderCompilationEvent,
+	void addActivityPerformanceImpl(MVKPerformanceTracker& activityTracker,
 									uint64_t startTime, uint64_t endTime);
 
 	MVKPhysicalDevice* _physicalDevice;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 5feb961..fd0ab2e 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -896,7 +896,7 @@
 		_features.tessellationShader = true;
 		_features.shaderTessellationAndGeometryPointSize = true;
 	}
-  
+
 	if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1] ) {
 		_features.imageCubeArray = true;
 	}
@@ -1970,43 +1970,44 @@
 
 uint64_t MVKDevice::getPerformanceTimestampImpl() { return mvkGetTimestamp(); }
 
-void MVKDevice::addActivityPerformanceImpl(MVKPerformanceTracker& shaderCompilationEvent,
+void MVKDevice::addActivityPerformanceImpl(MVKPerformanceTracker& activityTracker,
 										   uint64_t startTime, uint64_t endTime) {
     lock_guard<mutex> lock(_perfLock);
 
 	double currInterval = mvkGetElapsedMilliseconds(startTime, endTime);
-	shaderCompilationEvent.minimumDuration = ((shaderCompilationEvent.minimumDuration == 0.0)
+	activityTracker.minimumDuration = ((activityTracker.minimumDuration == 0.0)
 											  ? currInterval :
-											  min(currInterval, shaderCompilationEvent.minimumDuration));
-    shaderCompilationEvent.maximumDuration = max(currInterval, shaderCompilationEvent.maximumDuration);
-    double totalInterval = (shaderCompilationEvent.averageDuration * shaderCompilationEvent.count++) + currInterval;
-    shaderCompilationEvent.averageDuration = totalInterval / shaderCompilationEvent.count;
+											  min(currInterval, activityTracker.minimumDuration));
+    activityTracker.maximumDuration = max(currInterval, activityTracker.maximumDuration);
+    double totalInterval = (activityTracker.averageDuration * activityTracker.count++) + currInterval;
+    activityTracker.averageDuration = totalInterval / activityTracker.count;
 
 	if (_pMVKConfig->performanceLoggingFrameCount) {
 		MVKLogInfo("Performance to %s count: %d curr: %.3f ms, min: %.3f ms, max: %.3f ms, avg: %.3f ms",
-				   getActivityPerformanceDescription(shaderCompilationEvent),
-				   shaderCompilationEvent.count,
+				   getActivityPerformanceDescription(activityTracker),
+				   activityTracker.count,
 				   currInterval,
-				   shaderCompilationEvent.minimumDuration,
-				   shaderCompilationEvent.maximumDuration,
-				   shaderCompilationEvent.averageDuration);
+				   activityTracker.minimumDuration,
+				   activityTracker.maximumDuration,
+				   activityTracker.averageDuration);
 	}
 }
 
-const char* MVKDevice::getActivityPerformanceDescription(MVKPerformanceTracker& shaderCompilationEvent) {
-	if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.hashShaderCode) { return "hash shader SPIR-V code"; }
-    if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.spirvToMSL) { return "convert SPIR-V to MSL source code"; }
-    if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.mslCompile) { return "compile MSL source code into a MTLLibrary"; }
-    if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.mslLoad) { return "load pre-compiled MSL code into a MTLLibrary"; }
-	if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.shaderLibraryFromCache) { return "retrieve shader library from the cache"; }
-    if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.functionRetrieval) { return "retrieve a MTLFunction from a MTLLibrary"; }
-    if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.functionSpecialization) { return "specialize a retrieved MTLFunction"; }
-    if (&shaderCompilationEvent == &_performanceStatistics.shaderCompilation.pipelineCompile) { return "compile MTLFunctions into a pipeline"; }
-	if (&shaderCompilationEvent == &_performanceStatistics.pipelineCache.sizePipelineCache) { return "calculate cache size required to write MSL to pipeline cache"; }
-	if (&shaderCompilationEvent == &_performanceStatistics.pipelineCache.writePipelineCache) { return "write MSL to pipeline cache"; }
-	if (&shaderCompilationEvent == &_performanceStatistics.pipelineCache.readPipelineCache) { return "read MSL from pipeline cache"; }
-	if (&shaderCompilationEvent == &_performanceStatistics.queue.mtlQueueAccess) { return "access MTLCommandQueue"; }
-    return "Unknown shader compile event";
+const char* MVKDevice::getActivityPerformanceDescription(MVKPerformanceTracker& activityTracker) {
+	if (&activityTracker == &_performanceStatistics.shaderCompilation.hashShaderCode) { return "hash shader SPIR-V code"; }
+    if (&activityTracker == &_performanceStatistics.shaderCompilation.spirvToMSL) { return "convert SPIR-V to MSL source code"; }
+    if (&activityTracker == &_performanceStatistics.shaderCompilation.mslCompile) { return "compile MSL source code into a MTLLibrary"; }
+    if (&activityTracker == &_performanceStatistics.shaderCompilation.mslLoad) { return "load pre-compiled MSL code into a MTLLibrary"; }
+	if (&activityTracker == &_performanceStatistics.shaderCompilation.shaderLibraryFromCache) { return "retrieve shader library from the cache"; }
+    if (&activityTracker == &_performanceStatistics.shaderCompilation.functionRetrieval) { return "retrieve a MTLFunction from a MTLLibrary"; }
+    if (&activityTracker == &_performanceStatistics.shaderCompilation.functionSpecialization) { return "specialize a retrieved MTLFunction"; }
+    if (&activityTracker == &_performanceStatistics.shaderCompilation.pipelineCompile) { return "compile MTLFunctions into a pipeline"; }
+	if (&activityTracker == &_performanceStatistics.pipelineCache.sizePipelineCache) { return "calculate cache size required to write MSL to pipeline cache"; }
+	if (&activityTracker == &_performanceStatistics.pipelineCache.writePipelineCache) { return "write MSL to pipeline cache"; }
+	if (&activityTracker == &_performanceStatistics.pipelineCache.readPipelineCache) { return "read MSL from pipeline cache"; }
+	if (&activityTracker == &_performanceStatistics.queue.mtlQueueAccess) { return "access MTLCommandQueue"; }
+	if (&activityTracker == &_performanceStatistics.queue.mtlCommandBufferCompletion) { return "complete MTLCommandBuffer"; }
+    return "Unknown performance activity";
 }
 
 void MVKDevice::getPerformanceStatistics(MVKPerformanceStatistics* pPerf) {
@@ -2123,6 +2124,7 @@
 	_performanceStatistics.pipelineCache.writePipelineCache = initPerf;
 	_performanceStatistics.pipelineCache.readPipelineCache = initPerf;
 	_performanceStatistics.queue.mtlQueueAccess = initPerf;
+	_performanceStatistics.queue.mtlCommandBufferCompletion = initPerf;
 }
 
 void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice) {
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index 5d31a12..0d31459 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -1410,7 +1410,7 @@
 // Serializes the data in this cache to a stream
 void MVKPipelineCache::writeData(ostream& outstream, bool isCounting) {
 
-	MVKPerformanceTracker& shaderCompilationEvent = isCounting
+	MVKPerformanceTracker& activityTracker = isCounting
 		? _device->_performanceStatistics.pipelineCache.sizePipelineCache
 		: _device->_performanceStatistics.pipelineCache.writePipelineCache;
 
@@ -1438,7 +1438,7 @@
 			writer(cacheIter.getShaderContext());
 			writer(cacheIter.getEntryPoint());
 			writer(cacheIter.getMSL());
-			_device->addActivityPerformance(shaderCompilationEvent, startTime);
+			_device->addActivityPerformance(activityTracker, startTime);
 		}
 	}
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
index b661f64..7e326f6 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
@@ -184,6 +184,7 @@
 	MVKQueueSubmission* _next;
 	MVKVectorInline<MVKSemaphore*, 8> _waitSemaphores;
 	bool _isAwaitingSemaphores;
+	bool _trackPerformance;
 };
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
index ecffbdb..bdb6015 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
@@ -202,8 +202,9 @@
 									   uint32_t waitSemaphoreCount,
 									   const VkSemaphore* pWaitSemaphores) {
 	_queue = queue;
-	_prev = VK_NULL_HANDLE;
-	_next = VK_NULL_HANDLE;
+	_prev = nullptr;
+	_next = nullptr;
+	_trackPerformance = _queue->_device->_pMVKConfig->performanceTracking;
 
 	_isAwaitingSemaphores = waitSemaphoreCount > 0;
 	_waitSemaphores.reserve(waitSemaphoreCount);
@@ -280,9 +281,13 @@
 		for (auto& ws : _waitSemaphores) { ws->wait(); }
 	}
 
-	if (signalCompletion) {
+	MVKDevice* mkvDev = _queue->_device;
+	uint64_t startTime = mkvDev->getPerformanceTimestamp();
+
+	if (signalCompletion || _trackPerformance) {
 		[_activeMTLCommandBuffer addCompletedHandler: ^(id<MTLCommandBuffer> mtlCmdBuff) {
-			this->finish();
+			_queue->_device->addActivityPerformance(mkvDev->_performanceStatistics.queue.mtlCommandBufferCompletion, startTime);
+			if (signalCompletion) { this->finish(); }
 		}];
 	}
 
diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm
index fb5ffac..6c4610a 100644
--- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm
+++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm
@@ -40,29 +40,89 @@
 #include "MVKSwapchain.h"
 #include "MVKSurface.h"
 #include "MVKFoundation.h"
+#include "MVKOSExtensions.h"
 #include "MVKLogging.h"
 
-static bool _mvkTraceVulkanCalls = false;
-#define MVKTraceVulkanCall()	if (_mvkTraceVulkanCalls) { fprintf(stderr, "[mvk-trace] %s()\n", __FUNCTION__); }
+
+#pragma mark -
+#pragma mark Tracing Vulkan calls
+
+#ifndef MVK_CONFIG_TRACE_VULKAN_CALLS
+#   define MVK_CONFIG_TRACE_VULKAN_CALLS    0
+#endif
+
+static uint32_t _mvkTraceVulkanCalls = 0;
+static bool _mvkVulkanCallTracingInitialized = false;
+__attribute__((constructor)) static void MVKInitVulkanCallTracing() {
+	if (_mvkVulkanCallTracingInitialized ) { return; }
+	_mvkVulkanCallTracingInitialized = true;
+
+	MVK_SET_FROM_ENV_OR_BUILD_INT32(_mvkTraceVulkanCalls, MVK_CONFIG_TRACE_VULKAN_CALLS);
+}
+
+// Optionally log start of function calls to stderr
+static inline uint64_t MVKTraceVulkanCallStartImpl(const char* funcName) {
+	uint64_t timestamp = 0;
+	switch(_mvkTraceVulkanCalls) {
+		case 3:			// Fall through
+			timestamp = mvkGetTimestamp();
+		case 2:
+			fprintf(stderr, "[mvk-trace] %s() {\n", funcName);
+			break;
+		case 1:
+			fprintf(stderr, "[mvk-trace] %s()\n", funcName);
+			break;
+		case 0:
+		default:
+			break;
+	}
+	return timestamp;
+}
+
+// Optionally log end of function calls and timings to stderr
+static inline void MVKTraceVulkanCallEndImpl(const char* funcName, uint64_t startTime) {
+	switch(_mvkTraceVulkanCalls) {
+		case 3:
+			fprintf(stderr, "[mvk-trace] } %s() (%.4f ms)\n", funcName, mvkGetElapsedMilliseconds(startTime));
+			break;
+		case 2:
+			fprintf(stderr, "[mvk-trace] } %s()\n", funcName);
+			break;
+		case 1:
+		case 0:
+		default:
+			break;
+	}
+}
+
+#define MVKTraceVulkanCallStart()	uint64_t tvcStartTime = MVKTraceVulkanCallStartImpl(__FUNCTION__)
+#define MVKTraceVulkanCallEnd()		MVKTraceVulkanCallEndImpl(__FUNCTION__, tvcStartTime)
+
+
+#pragma mark -
+#pragma mark Vulkan calls
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateInstance(
     const VkInstanceCreateInfo*                 pCreateInfo,
 	const VkAllocationCallbacks*                pAllocator,
     VkInstance*                                 pInstance) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKInstance* mvkInst = new MVKInstance(pCreateInfo);
 	*pInstance = mvkInst->getVkInstance();
-	return mvkInst->getConfigurationResult();
+	VkResult rslt = mvkInst->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyInstance(
     VkInstance                                  instance,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !instance ) { return; }
 	MVKInstance::getMVKInstance(instance)->destroy();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkEnumeratePhysicalDevices(
@@ -70,18 +130,21 @@
     uint32_t*                                   pPhysicalDeviceCount,
     VkPhysicalDevice*                           pPhysicalDevices) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
-	return mvkInst->getPhysicalDevices(pPhysicalDeviceCount, pPhysicalDevices);
+	VkResult rslt = mvkInst->getPhysicalDevices(pPhysicalDeviceCount, pPhysicalDevices);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceFeatures(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceFeatures*                   pFeatures) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	mvkPD->getFeatures(pFeatures);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceFormatProperties(
@@ -89,9 +152,10 @@
     VkFormat                                    format,
     VkFormatProperties*                         pFormatProperties) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	mvkPD->getFormatProperties(format, pFormatProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceImageFormatProperties(
@@ -103,18 +167,21 @@
     VkImageCreateFlags                          flags,
     VkImageFormatProperties*                    pImageFormatProperties) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
-    return mvkPD->getImageFormatProperties(format, type, tiling, usage, flags, pImageFormatProperties);
+    VkResult rslt = mvkPD->getImageFormatProperties(format, type, tiling, usage, flags, pImageFormatProperties);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceProperties(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceProperties*                 pProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	mvkPD->getProperties(pProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceQueueFamilyProperties(
@@ -122,43 +189,53 @@
 	uint32_t*                                   pQueueFamilyPropertyCount,
 	VkQueueFamilyProperties*                    pQueueFamilyProperties) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	mvkPD->getQueueFamilyProperties(pQueueFamilyPropertyCount, pQueueFamilyProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceMemoryProperties(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceMemoryProperties*           pMemoryProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	mvkPD->getPhysicalDeviceMemoryProperties(pMemoryProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL PFN_vkVoidFunction vkGetInstanceProcAddr(
     VkInstance                                  instance,
     const char*                                 pName) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 
 	// Handle the special platform functions where the instance parameter may be NULL.
-	if (strcmp(pName, "vkCreateInstance") == 0) { return (PFN_vkVoidFunction)vkCreateInstance; }
-	if (strcmp(pName, "vkEnumerateInstanceExtensionProperties") == 0) { return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties; }
-	if (strcmp(pName, "vkEnumerateInstanceLayerProperties") == 0) { return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties; }
-	if ( !instance ) { return nullptr; }
-
-	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
-	return mvkInst->getProcAddr(pName);
+	PFN_vkVoidFunction func = nullptr;
+	if (strcmp(pName, "vkCreateInstance") == 0) {
+		func = (PFN_vkVoidFunction)vkCreateInstance;
+	} else if (strcmp(pName, "vkEnumerateInstanceExtensionProperties") == 0) {
+		func = (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
+	} else if (strcmp(pName, "vkEnumerateInstanceLayerProperties") == 0) {
+		func = (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
+	} else if (instance) {
+		MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
+		func = mvkInst->getProcAddr(pName);
+	}
+	MVKTraceVulkanCallEnd();
+	return func;
 }
 
 MVK_PUBLIC_SYMBOL PFN_vkVoidFunction vkGetDeviceProcAddr(
     VkDevice                                    device,
     const char*                                 pName) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->getProcAddr(pName);
+	PFN_vkVoidFunction func = mvkDev->getProcAddr(pName);
+	MVKTraceVulkanCallEnd();
+	return func;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateDevice(
@@ -167,20 +244,23 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkDevice*                                   pDevice) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	MVKDevice* mvkDev = new MVKDevice(mvkPD, pCreateInfo);
 	*pDevice = mvkDev->getVkDevice();
-	return mvkDev->getConfigurationResult();
+	VkResult rslt = mvkDev->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyDevice(
 	VkDevice                                    device,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !device ) { return; }
 	MVKDevice::getMVKDevice(device)->destroy();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkEnumerateInstanceExtensionProperties(
@@ -188,8 +268,10 @@
     uint32_t*                                   pCount,
     VkExtensionProperties*                      pProperties) {
 
-	MVKTraceVulkanCall();
-	return MVKLayerManager::globalManager()->getLayerNamed(pLayerName)->getExtensionProperties(pCount, pProperties);
+	MVKTraceVulkanCallStart();
+	VkResult rslt = MVKLayerManager::globalManager()->getLayerNamed(pLayerName)->getExtensionProperties(pCount, pProperties);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkEnumerateDeviceExtensionProperties(
@@ -198,17 +280,21 @@
     uint32_t*                                   pCount,
     VkExtensionProperties*                      pProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
-	return mvkPD->getInstance()->getLayerManager()->getLayerNamed(pLayerName)->getExtensionProperties(pCount, pProperties);
+	VkResult rslt = mvkPD->getInstance()->getLayerManager()->getLayerNamed(pLayerName)->getExtensionProperties(pCount, pProperties);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkEnumerateInstanceLayerProperties(
     uint32_t*                                   pCount,
     VkLayerProperties*                          pProperties) {
 
-	MVKTraceVulkanCall();
-	return MVKLayerManager::globalManager()->getLayerProperties(pCount, pProperties);
+	MVKTraceVulkanCallStart();
+	VkResult rslt = MVKLayerManager::globalManager()->getLayerProperties(pCount, pProperties);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkEnumerateDeviceLayerProperties(
@@ -216,9 +302,11 @@
     uint32_t*                                   pCount,
     VkLayerProperties*                          pProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
-	return mvkPD->getInstance()->getLayerManager()->getLayerProperties(pCount, pProperties);
+	VkResult rslt = mvkPD->getInstance()->getLayerManager()->getLayerProperties(pCount, pProperties);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkGetDeviceQueue(
@@ -227,11 +315,12 @@
     uint32_t                                    queueIndex,
     VkQueue*                                    pQueue) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if (pQueue) {
 		MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 		*pQueue = mvkDev->getQueue(queueFamilyIndex, queueIndex)->getVkQueue();
 	}
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkQueueSubmit(
@@ -240,25 +329,31 @@
 	const VkSubmitInfo*                         pSubmits,
 	VkFence                                     fence) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKQueue* mvkQ = MVKQueue::getMVKQueue(queue);
-	return mvkQ->submit(submitCount, pSubmits, fence);
+	VkResult rslt = mvkQ->submit(submitCount, pSubmits, fence);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkQueueWaitIdle(
     VkQueue                                     queue) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKQueue* mvkQ = MVKQueue::getMVKQueue(queue);
-	return mvkQ->waitIdle();
+	VkResult rslt = mvkQ->waitIdle();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkDeviceWaitIdle(
     VkDevice                                    device) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->waitIdle();
+	VkResult rslt = mvkDev->waitIdle();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkAllocateMemory(
@@ -267,11 +362,12 @@
     const VkAllocationCallbacks*                pAllocator,
     VkDeviceMemory*                             pMem) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKDeviceMemory* mvkMem = mvkDev->allocateMemory(pAllocateInfo, pAllocator);
 	VkResult rslt = mvkMem->getConfigurationResult();
 	*pMem = (VkDeviceMemory)((rslt == VK_SUCCESS) ? mvkMem : VK_NULL_HANDLE);
+	MVKTraceVulkanCallEnd();
 	return rslt;
 }
 
@@ -280,10 +376,11 @@
 	VkDeviceMemory                              mem,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !mem ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->freeMemory((MVKDeviceMemory*)mem, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkMapMemory(
@@ -294,18 +391,21 @@
    VkMemoryMapFlags                            flags,
    void**                                      ppData) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)mem;
-	return mvkMem->map(offset, size, flags, ppData);
+	VkResult rslt = mvkMem->map(offset, size, flags, ppData);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkUnmapMemory(
     VkDevice                                    device,
     VkDeviceMemory                              mem) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)mem;
-	return mvkMem->unmap();
+	mvkMem->unmap();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkFlushMappedMemoryRanges(
@@ -313,7 +413,7 @@
     uint32_t                                    memRangeCount,
     const VkMappedMemoryRange*                  pMemRanges) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	VkResult rslt = VK_SUCCESS;
 	for (uint32_t i = 0; i < memRangeCount; i++) {
 		const VkMappedMemoryRange* pMem = &pMemRanges[i];
@@ -321,6 +421,7 @@
 		VkResult r = mvkMem->flushToDevice(pMem->offset, pMem->size);
 		if (rslt == VK_SUCCESS) { rslt = r; }
 	}
+	MVKTraceVulkanCallEnd();
 	return rslt;
 }
 
@@ -329,7 +430,7 @@
     uint32_t                                    memRangeCount,
     const VkMappedMemoryRange*                  pMemRanges) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	VkResult rslt = VK_SUCCESS;
 	for (uint32_t i = 0; i < memRangeCount; i++) {
 		const VkMappedMemoryRange* pMem = &pMemRanges[i];
@@ -337,6 +438,7 @@
 		VkResult r = mvkMem->pullFromDevice(pMem->offset, pMem->size);
 		if (rslt == VK_SUCCESS) { rslt = r; }
 	}
+	MVKTraceVulkanCallEnd();
 	return rslt;
 }
 
@@ -345,11 +447,12 @@
     VkDeviceMemory                              memory,
     VkDeviceSize*                               pCommittedMemoryInBytes) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     if ( !pCommittedMemoryInBytes ) { return; }
 
     MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)memory;
     *pCommittedMemoryInBytes = mvkMem->getDeviceMemoryCommitment();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkBindBufferMemory(
@@ -358,10 +461,12 @@
     VkDeviceMemory                              mem,
     VkDeviceSize                                memOffset) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKBuffer* mvkBuff = (MVKBuffer*)buffer;
 	MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)mem;
-	return mvkBuff->bindDeviceMemory(mvkMem, memOffset);
+	VkResult rslt = mvkBuff->bindDeviceMemory(mvkMem, memOffset);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkBindImageMemory(
@@ -370,10 +475,12 @@
     VkDeviceMemory                              mem,
     VkDeviceSize                                memOffset) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKImage* mvkImg = (MVKImage*)image;
 	MVKDeviceMemory* mvkMem = (MVKDeviceMemory*)mem;
-	return mvkImg->bindDeviceMemory(mvkMem, memOffset);
+	VkResult rslt = mvkImg->bindDeviceMemory(mvkMem, memOffset);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkGetBufferMemoryRequirements(
@@ -381,9 +488,10 @@
     VkBuffer                                    buffer,
     VkMemoryRequirements*                       pMemoryRequirements) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKBuffer* mvkBuff = (MVKBuffer*)buffer;
 	mvkBuff->getMemoryRequirements(pMemoryRequirements);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetImageMemoryRequirements(
@@ -391,9 +499,10 @@
     VkImage                                     image,
     VkMemoryRequirements*                       pMemoryRequirements) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKImage* mvkImg = (MVKImage*)image;
 	mvkImg->getMemoryRequirements(pMemoryRequirements);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetImageSparseMemoryRequirements(
@@ -402,13 +511,14 @@
     uint32_t*                                   pNumRequirements,
     VkSparseImageMemoryRequirements*            pSparseMemoryRequirements) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 
 	// Metal does not support sparse images.
 	// Vulkan spec: "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then
 	// pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to.".
 
 	*pNumRequirements = 0;
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceSparseImageFormatProperties(
@@ -421,13 +531,14 @@
 	uint32_t*                                   pPropertyCount,
 	VkSparseImageFormatProperties*              pProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 
 	// Metal does not support sparse images.
 	// Vulkan spec: "If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported for the given arguments,
 	// pPropertyCount will be set to zero upon return, and no data will be written to pProperties.".
 
 	*pPropertyCount = 0;
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkQueueBindSparse(
@@ -436,9 +547,11 @@
 	const VkBindSparseInfo*                     pBindInfo,
 	VkFence                                     fence) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKQueue* mvkQ = MVKQueue::getMVKQueue(queue);
-	return mvkQ->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkQueueBindSparse(): Sparse binding is not supported.");
+	VkResult rslt = mvkQ->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkQueueBindSparse(): Sparse binding is not supported.");
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateFence(
@@ -447,11 +560,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkFence*                                    pFence) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKFence* mvkFence = mvkDev->createFence(pCreateInfo, pAllocator);
 	*pFence = (VkFence)mvkFence;
-	return mvkFence->getConfigurationResult();
+	VkResult rslt = mvkFence->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyFence(
@@ -459,10 +574,11 @@
 	VkFence                                     fence,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !fence ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyFence((MVKFence*)fence, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkResetFences(
@@ -470,17 +586,21 @@
     uint32_t                                    fenceCount,
     const VkFence*                              pFences) {
 	
-	MVKTraceVulkanCall();
-	return mvkResetFences(fenceCount, pFences);
+	MVKTraceVulkanCallStart();
+	VkResult rslt = mvkResetFences(fenceCount, pFences);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetFenceStatus(
     VkDevice                                    device,
     VkFence                                     fence) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKFence* mvkFence = (MVKFence*)fence;
-	return mvkFence->getIsSignaled() ? VK_SUCCESS : VK_NOT_READY;
+	VkResult rslt = mvkFence->getIsSignaled() ? VK_SUCCESS : VK_NOT_READY;
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkWaitForFences(
@@ -490,9 +610,11 @@
     VkBool32                                    waitAll,
     uint64_t                                    timeout) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkWaitForFences(mvkDev, fenceCount, pFences, waitAll, timeout);
+	VkResult rslt = mvkWaitForFences(mvkDev, fenceCount, pFences, waitAll, timeout);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateSemaphore(
@@ -501,11 +623,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkSemaphore*                                pSemaphore) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKSemaphore* mvkSem4 = mvkDev->createSemaphore(pCreateInfo, pAllocator);
 	*pSemaphore = (VkSemaphore)mvkSem4;
-	return mvkSem4->getConfigurationResult();
+	VkResult rslt = mvkSem4->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroySemaphore(
@@ -513,10 +637,11 @@
 	VkSemaphore                                 semaphore,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !semaphore ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroySemaphore((MVKSemaphore*)semaphore, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateEvent(
@@ -525,10 +650,12 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkEvent*                                    pEvent) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	//VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateEvent(): Vukan events are not supported.");
+	VkResult rslt = mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateEvent(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyEvent(
@@ -536,37 +663,44 @@
 	VkEvent                                     event,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !event ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkDestroyEvent(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetEventStatus(
     VkDevice                                    device,
     VkEvent                                     event) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkGetEventStatus(): Vukan events are not supported.");
+	VkResult rslt = mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkGetEventStatus(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkSetEvent(
     VkDevice                                    device,
     VkEvent                                     event) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkSetEvent(): Vukan events are not supported.");
+	VkResult rslt = mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkSetEvent(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkResetEvent(
     VkDevice                                    device,
     VkEvent                                     event) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkResetEvent(): Vukan events are not supported.");
+	VkResult rslt = mvkDev->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkResetEvent(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateQueryPool(
@@ -575,11 +709,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkQueryPool*                                pQueryPool) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKQueryPool* mvkQP = mvkDev->createQueryPool(pCreateInfo, pAllocator);
 	*pQueryPool = (VkQueryPool)mvkQP;
-	return mvkQP->getConfigurationResult();
+	VkResult rslt = mvkQP->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyQueryPool(
@@ -587,10 +723,11 @@
 	VkQueryPool                                 queryPool,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !queryPool ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyQueryPool((MVKQueryPool*)queryPool, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetQueryPoolResults(
@@ -603,9 +740,11 @@
 	VkDeviceSize                                stride,
 	VkQueryResultFlags                          flags) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKQueryPool* mvkQP = (MVKQueryPool*)queryPool;
-	return mvkQP->getResults(firstQuery, queryCount, dataSize, pData, stride, flags);
+	VkResult rslt = mvkQP->getResults(firstQuery, queryCount, dataSize, pData, stride, flags);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateBuffer(
@@ -614,11 +753,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkBuffer*                                   pBuffer) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKBuffer* mvkBuff = mvkDev->createBuffer(pCreateInfo, pAllocator);
 	*pBuffer = (VkBuffer)mvkBuff;
-	return mvkBuff->getConfigurationResult();
+	VkResult rslt = mvkBuff->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyBuffer(
@@ -626,10 +767,11 @@
 	VkBuffer                                    buffer,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !buffer ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyBuffer((MVKBuffer*)buffer, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateBufferView(
@@ -638,11 +780,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkBufferView*                               pView) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     MVKBufferView* mvkBuffView = mvkDev->createBufferView(pCreateInfo, pAllocator);
     *pView = (VkBufferView)mvkBuffView;
-    return mvkBuffView->getConfigurationResult();
+    VkResult rslt = mvkBuffView->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyBufferView(
@@ -650,10 +794,11 @@
 	VkBufferView                                bufferView,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !bufferView ) { return; }
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     mvkDev->destroyBufferView((MVKBufferView*)bufferView, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateImage(
@@ -662,11 +807,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkImage*                                    pImage) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKImage* mvkImg = mvkDev->createImage(pCreateInfo, pAllocator);
 	*pImage = (VkImage)mvkImg;
-	return mvkImg->getConfigurationResult();
+	VkResult rslt = mvkImg->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyImage(
@@ -674,10 +821,11 @@
 	VkImage                                     image,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !image ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyImage((MVKImage*)image, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetImageSubresourceLayout(
@@ -686,9 +834,10 @@
     const VkImageSubresource*                   pSubresource,
     VkSubresourceLayout*                        pLayout) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKImage* mvkImg = (MVKImage*)image;
 	mvkImg->getSubresourceLayout(pSubresource, pLayout);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateImageView(
@@ -697,11 +846,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkImageView*                                pView) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKImageView* mvkImgView = mvkDev->createImageView(pCreateInfo, pAllocator);
 	*pView = (VkImageView)mvkImgView;
-	return mvkImgView->getConfigurationResult();
+	VkResult rslt = mvkImgView->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyImageView(
@@ -709,10 +860,11 @@
 	VkImageView                                 imageView,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !imageView ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyImageView((MVKImageView*)imageView, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateShaderModule(
@@ -721,11 +873,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkShaderModule*                             pShaderModule) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKShaderModule* mvkShdrMod = mvkDev->createShaderModule(pCreateInfo, pAllocator);
 	*pShaderModule = (VkShaderModule)mvkShdrMod;
-	return mvkShdrMod->getConfigurationResult();
+	VkResult rslt = mvkShdrMod->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyShaderModule(
@@ -733,10 +887,11 @@
 	VkShaderModule                              shaderModule,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !shaderModule ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyShaderModule((MVKShaderModule*)shaderModule, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreatePipelineCache(
@@ -745,11 +900,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkPipelineCache*                            pPipelineCache) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKPipelineCache* mvkPLC = mvkDev->createPipelineCache(pCreateInfo, pAllocator);
 	*pPipelineCache = (VkPipelineCache)mvkPLC;
-	return mvkPLC->getConfigurationResult();
+	VkResult rslt = mvkPLC->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyPipelineCache(
@@ -757,10 +914,11 @@
 	VkPipelineCache                             pipelineCache,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !pipelineCache ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyPipelineCache((MVKPipelineCache*)pipelineCache, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPipelineCacheData(
@@ -769,9 +927,11 @@
 	size_t*                                     pDataSize,
 	void*                                       pData) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPipelineCache* mvkPLC = (MVKPipelineCache*)pipelineCache;
-	return mvkPLC->writeData(pDataSize, pData);
+	VkResult rslt = mvkPLC->writeData(pDataSize, pData);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkMergePipelineCaches(
@@ -780,9 +940,11 @@
     uint32_t                                    srcCacheCount,
     const VkPipelineCache*                      pSrcCaches) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPipelineCache* mvkPLC = (MVKPipelineCache*)destCache;
-	return mvkPLC->mergePipelineCaches(srcCacheCount, pSrcCaches);
+	VkResult rslt = mvkPLC->mergePipelineCaches(srcCacheCount, pSrcCaches);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateGraphicsPipelines(
@@ -793,9 +955,11 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkPipeline*                                 pPipelines) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-	return mvkDev->createPipelines<MVKGraphicsPipeline, VkGraphicsPipelineCreateInfo>(pipelineCache, count, pCreateInfos, pAllocator, pPipelines);
+	VkResult rslt = mvkDev->createPipelines<MVKGraphicsPipeline, VkGraphicsPipelineCreateInfo>(pipelineCache, count, pCreateInfos, pAllocator, pPipelines);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateComputePipelines(
@@ -806,9 +970,11 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkPipeline*                                 pPipelines) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
-    return mvkDev->createPipelines<MVKComputePipeline, VkComputePipelineCreateInfo>(pipelineCache, count, pCreateInfos, pAllocator, pPipelines);
+    VkResult rslt = mvkDev->createPipelines<MVKComputePipeline, VkComputePipelineCreateInfo>(pipelineCache, count, pCreateInfos, pAllocator, pPipelines);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyPipeline(
@@ -816,10 +982,11 @@
 	VkPipeline                                  pipeline,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !pipeline ) { return; }
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     mvkDev->destroyPipeline((MVKPipeline*)pipeline, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreatePipelineLayout(
@@ -828,11 +995,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkPipelineLayout*                           pPipelineLayout) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKPipelineLayout* mvkPLL = mvkDev->createPipelineLayout(pCreateInfo, pAllocator);
 	*pPipelineLayout = (VkPipelineLayout)mvkPLL;
-	return mvkPLL->getConfigurationResult();
+	VkResult rslt = mvkPLL->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyPipelineLayout(
@@ -840,10 +1009,11 @@
 	VkPipelineLayout                            pipelineLayout,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !pipelineLayout ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyPipelineLayout((MVKPipelineLayout*)pipelineLayout, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateSampler(
@@ -852,11 +1022,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkSampler*                                  pSampler) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKSampler* mvkSamp = mvkDev->createSampler(pCreateInfo, pAllocator);
 	*pSampler = (VkSampler)mvkSamp;
-	return mvkSamp->getConfigurationResult();
+	VkResult rslt = mvkSamp->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroySampler(
@@ -864,10 +1036,11 @@
 	VkSampler                                   sampler,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !sampler ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroySampler((MVKSampler*)sampler, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateDescriptorSetLayout(
@@ -876,11 +1049,13 @@
 	const VkAllocationCallbacks*                pAllocator,
 	VkDescriptorSetLayout*                      pSetLayout) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKDescriptorSetLayout* mvkDSL = mvkDev->createDescriptorSetLayout(pCreateInfo, pAllocator);
 	*pSetLayout = (VkDescriptorSetLayout)mvkDSL;
-	return mvkDSL->getConfigurationResult();
+	VkResult rslt = mvkDSL->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyDescriptorSetLayout(
@@ -888,10 +1063,11 @@
 	VkDescriptorSetLayout                       descriptorSetLayout,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !descriptorSetLayout ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyDescriptorSetLayout((MVKDescriptorSetLayout*)descriptorSetLayout, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateDescriptorPool(
@@ -900,11 +1076,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkDescriptorPool*                           pDescriptorPool) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKDescriptorPool* mvkDP = mvkDev->createDescriptorPool(pCreateInfo, pAllocator);
 	*pDescriptorPool = (VkDescriptorPool)mvkDP;
-	return mvkDP->getConfigurationResult();
+	VkResult rslt = mvkDP->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyDescriptorPool(
@@ -912,10 +1090,11 @@
 	VkDescriptorPool                            descriptorPool,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !descriptorPool ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyDescriptorPool((MVKDescriptorPool*)descriptorPool, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkResetDescriptorPool(
@@ -923,9 +1102,11 @@
 	VkDescriptorPool                            descriptorPool,
 	VkDescriptorPoolResetFlags                  flags) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDescriptorPool* mvkDP = (MVKDescriptorPool*)descriptorPool;
-	return mvkDP->reset(flags);
+	VkResult rslt = mvkDP->reset(flags);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkAllocateDescriptorSets(
@@ -933,11 +1114,13 @@
 	const VkDescriptorSetAllocateInfo*          pAllocateInfo,
 	VkDescriptorSet*                            pDescriptorSets) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDescriptorPool* mvkDP = (MVKDescriptorPool*)pAllocateInfo->descriptorPool;
-	return mvkDP->allocateDescriptorSets(pAllocateInfo->descriptorSetCount,
-										 pAllocateInfo->pSetLayouts,
-										 pDescriptorSets);
+	VkResult rslt = mvkDP->allocateDescriptorSets(pAllocateInfo->descriptorSetCount,
+												  pAllocateInfo->pSetLayouts,
+												  pDescriptorSets);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkFreeDescriptorSets(
@@ -946,9 +1129,11 @@
     uint32_t                                    count,
 	const VkDescriptorSet*                      pDescriptorSets) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDescriptorPool* mvkDP = (MVKDescriptorPool*)descriptorPool;
-	return mvkDP->freeDescriptorSets(count, pDescriptorSets);
+	VkResult rslt = mvkDP->freeDescriptorSets(count, pDescriptorSets);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkUpdateDescriptorSets(
@@ -958,8 +1143,9 @@
     uint32_t                                    copyCount,
     const VkCopyDescriptorSet*                  pDescriptorCopies) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	mvkUpdateDescriptorSets(writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateFramebuffer(
@@ -968,11 +1154,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkFramebuffer*                              pFramebuffer) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKFramebuffer* mvkFB = mvkDev->createFramebuffer(pCreateInfo, pAllocator);
 	*pFramebuffer = (VkFramebuffer)mvkFB;
-	return mvkFB->getConfigurationResult();
+	VkResult rslt = mvkFB->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyFramebuffer(
@@ -980,10 +1168,11 @@
 	VkFramebuffer                               framebuffer,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !framebuffer ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyFramebuffer((MVKFramebuffer*)framebuffer, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateRenderPass(
@@ -992,11 +1181,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkRenderPass*                               pRenderPass) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKRenderPass* mvkRendPass = mvkDev->createRenderPass(pCreateInfo, pAllocator);
 	*pRenderPass = (VkRenderPass)mvkRendPass;
-	return mvkRendPass->getConfigurationResult();
+	VkResult rslt = mvkRendPass->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyRenderPass(
@@ -1004,10 +1195,11 @@
 	VkRenderPass                                renderPass,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !renderPass ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyRenderPass((MVKRenderPass*)renderPass, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetRenderAreaGranularity(
@@ -1015,11 +1207,12 @@
     VkRenderPass                                renderPass,
     VkExtent2D*                                 pGranularity) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     if ( !pGranularity ) { return; }
 
     MVKRenderPass* mvkRendPass = (MVKRenderPass*)renderPass;
     *pGranularity = mvkRendPass->getRenderAreaGranularity();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateCommandPool(
@@ -1028,11 +1221,13 @@
 	const VkAllocationCallbacks*                pAllocator,
     VkCommandPool*                              pCmdPool) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	MVKCommandPool* mvkCmdPool = mvkDev->createCommandPool(pCreateInfo, pAllocator);
 	*pCmdPool = (VkCommandPool)mvkCmdPool;
-	return mvkCmdPool->getConfigurationResult();
+	VkResult rslt = mvkCmdPool->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyCommandPool(
@@ -1040,10 +1235,11 @@
 	VkCommandPool                               commandPool,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !commandPool ) { return; }
 	MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
 	mvkDev->destroyCommandPool((MVKCommandPool*)commandPool, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkResetCommandPool(
@@ -1051,9 +1247,11 @@
 	VkCommandPool                               commandPool,
 	VkCommandPoolResetFlags                     flags) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandPool* mvkCmdPool = (MVKCommandPool*)commandPool;
-	return mvkCmdPool->reset(flags);
+	VkResult rslt = mvkCmdPool->reset(flags);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkAllocateCommandBuffers(
@@ -1061,9 +1259,11 @@
 	const VkCommandBufferAllocateInfo*          pAllocateInfo,
 	VkCommandBuffer*                            pCmdBuffer) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandPool* mvkCmdPool = (MVKCommandPool*)pAllocateInfo->commandPool;
-	return mvkCmdPool->allocateCommandBuffers(pAllocateInfo, pCmdBuffer);
+	VkResult rslt = mvkCmdPool->allocateCommandBuffers(pAllocateInfo, pCmdBuffer);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkFreeCommandBuffers(
@@ -1072,35 +1272,42 @@
 	uint32_t                                    commandBufferCount,
 	const VkCommandBuffer*                      pCommandBuffers) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandPool* mvkCmdPool = (MVKCommandPool*)commandPool;
 	mvkCmdPool->freeCommandBuffers(commandBufferCount, pCommandBuffers);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkBeginCommandBuffer(
     VkCommandBuffer                             commandBuffer,
     const VkCommandBufferBeginInfo*             pBeginInfo) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
-	return cmdBuff->begin(pBeginInfo);
+	VkResult rslt = cmdBuff->begin(pBeginInfo);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkEndCommandBuffer(
     VkCommandBuffer                             commandBuffer) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
-	return cmdBuff->end();
+	VkResult rslt = cmdBuff->end();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkResetCommandBuffer(
     VkCommandBuffer                             commandBuffer,
     VkCommandBufferResetFlags                   flags) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
-	return cmdBuff->reset(flags);
+	VkResult rslt = cmdBuff->reset(flags);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBindPipeline(
@@ -1108,9 +1315,10 @@
     VkPipelineBindPoint                         pipelineBindPoint,
     VkPipeline                                  pipeline) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBindPipeline(cmdBuff, pipelineBindPoint, pipeline);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetViewport(
@@ -1119,9 +1327,10 @@
 	uint32_t                                    viewportCount,
 	const VkViewport*                           pViewports) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdSetViewport(cmdBuff, firstViewport, viewportCount, pViewports);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetScissor(
@@ -1130,18 +1339,20 @@
 	uint32_t                                    scissorCount,
 	const VkRect2D*                             pScissors) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdSetScissor(cmdBuff, firstScissor, scissorCount, pScissors);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetLineWidth(
 	VkCommandBuffer                             commandBuffer,
 	float                                       lineWidth) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetLineWidth(cmdBuff, lineWidth);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetDepthBias(
@@ -1150,18 +1361,20 @@
 	float                                       depthBiasClamp,
 	float                                       depthBiasSlopeFactor) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetDepthBias(cmdBuff,depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetBlendConstants(
 	VkCommandBuffer                             commandBuffer,
 	const float                                 blendConst[4]) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetBlendConstants(cmdBuff, blendConst);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetDepthBounds(
@@ -1169,9 +1382,10 @@
 	float                                       minDepthBounds,
 	float                                       maxDepthBounds) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetDepthBounds(cmdBuff, minDepthBounds, maxDepthBounds);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetStencilCompareMask(
@@ -1179,9 +1393,10 @@
 	VkStencilFaceFlags                          faceMask,
 	uint32_t                                    stencilCompareMask) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetStencilCompareMask(cmdBuff, faceMask, stencilCompareMask);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetStencilWriteMask(
@@ -1189,9 +1404,10 @@
 	VkStencilFaceFlags                          faceMask,
 	uint32_t                                    stencilWriteMask) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetStencilWriteMask(cmdBuff, faceMask, stencilWriteMask);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetStencilReference(
@@ -1199,12 +1415,12 @@
 	VkStencilFaceFlags                          faceMask,
 	uint32_t                                    stencilReference) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdSetStencilReference(cmdBuff, faceMask, stencilReference);
+	MVKTraceVulkanCallEnd();
 }
 
-
 MVK_PUBLIC_SYMBOL void vkCmdBindDescriptorSets(
     VkCommandBuffer                             commandBuffer,
     VkPipelineBindPoint                         pipelineBindPoint,
@@ -1215,10 +1431,11 @@
     uint32_t                                    dynamicOffsetCount,
     const uint32_t*                             pDynamicOffsets) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBindDescriptorSets(cmdBuff, pipelineBindPoint, layout, firstSet, setCount,
 							 pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBindIndexBuffer(
@@ -1227,9 +1444,10 @@
     VkDeviceSize                                offset,
     VkIndexType                                 indexType) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBindIndexBuffer(cmdBuff, buffer, offset, indexType);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBindVertexBuffers(
@@ -1239,9 +1457,10 @@
     const VkBuffer*                             pBuffers,
     const VkDeviceSize*                         pOffsets) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBindVertexBuffers(cmdBuff, startBinding, bindingCount, pBuffers, pOffsets);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDraw(
@@ -1251,9 +1470,10 @@
 	uint32_t                                    firstVertex,
 	uint32_t                                    firstInstance) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDraw(cmdBuff, vertexCount, instanceCount, firstVertex, firstInstance);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDrawIndexed(
@@ -1264,9 +1484,10 @@
 	int32_t                                     vertexOffset,
 	uint32_t                                    firstInstance) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDrawIndexed(cmdBuff, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDrawIndirect(
@@ -1276,9 +1497,10 @@
     uint32_t                                    drawCount,
     uint32_t                                    stride) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDrawIndirect(cmdBuff, buffer, offset, drawCount, stride);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDrawIndexedIndirect(
@@ -1288,9 +1510,10 @@
     uint32_t                                    drawCount,
     uint32_t                                    stride) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDrawIndexedIndirect(cmdBuff, buffer, offset, drawCount, stride);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDispatch(
@@ -1299,9 +1522,10 @@
     uint32_t                                    y,
     uint32_t                                    z) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDispatch(cmdBuff, x, y, z);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDispatchIndirect(
@@ -1309,9 +1533,10 @@
     VkBuffer                                    buffer,
     VkDeviceSize                                offset) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdDispatchIndirect(cmdBuff, buffer, offset);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdCopyBuffer(
@@ -1321,9 +1546,10 @@
     uint32_t                                    regionCount,
     const VkBufferCopy*                         pRegions) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdCopyBuffer(cmdBuff, srcBuffer, destBuffer, regionCount, pRegions);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdCopyImage(
@@ -1335,12 +1561,13 @@
     uint32_t                                    regionCount,
     const VkImageCopy*                          pRegions) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdCopyImage(cmdBuff,
 					srcImage, srcImageLayout,
 					dstImage, dstImageLayout,
 					regionCount, pRegions);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBlitImage(
@@ -1353,12 +1580,13 @@
     const VkImageBlit*                          pRegions,
     VkFilter                                    filter) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBlitImage(cmdBuff,
 					srcImage, srcImageLayout,
 					dstImage, dstImageLayout,
 					regionCount, pRegions, filter);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdCopyBufferToImage(
@@ -1369,10 +1597,11 @@
     uint32_t                                    regionCount,
     const VkBufferImageCopy*                    pRegions) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdCopyBufferToImage(cmdBuff, srcBuffer, dstImage,
                             dstImageLayout, regionCount, pRegions);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdCopyImageToBuffer(
@@ -1383,10 +1612,11 @@
     uint32_t                                    regionCount,
     const VkBufferImageCopy*                    pRegions) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdCopyImageToBuffer(cmdBuff, srcImage, srcImageLayout,
                             dstBuffer, regionCount, pRegions);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdUpdateBuffer(
@@ -1396,9 +1626,10 @@
     VkDeviceSize                                dataSize,
     const void*                                 pData) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdUpdateBuffer(cmdBuff, dstBuffer, dstOffset, dataSize, pData);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdFillBuffer(
@@ -1408,9 +1639,10 @@
     VkDeviceSize                                size,
     uint32_t                                    data) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdFillBuffer(cmdBuff, dstBuffer, dstOffset, size, data);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdClearColorImage(
@@ -1421,9 +1653,10 @@
     uint32_t                                    rangeCount,
     const VkImageSubresourceRange*              pRanges) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdClearColorImage(cmdBuff, image, imageLayout, pColor, rangeCount, pRanges);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdClearDepthStencilImage(
@@ -1434,9 +1667,10 @@
     uint32_t                                    rangeCount,
     const VkImageSubresourceRange*              pRanges) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdClearDepthStencilImage(cmdBuff, image, imageLayout, pDepthStencil, rangeCount, pRanges);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdClearAttachments(
@@ -1446,9 +1680,10 @@
 	uint32_t                                    rectCount,
 	const VkClearRect*                          pRects) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdClearAttachments(cmdBuff, attachmentCount, pAttachments, rectCount, pRects);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdResolveImage(
@@ -1460,10 +1695,11 @@
     uint32_t                                    regionCount,
     const VkImageResolve*                       pRegions) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdResolveImage(cmdBuff, srcImage, srcImageLayout,
                        dstImage, dstImageLayout, regionCount, pRegions);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdSetEvent(
@@ -1471,9 +1707,10 @@
     VkEvent                                     event,
     VkPipelineStageFlags                        stageMask) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetEvent(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdResetEvent(
@@ -1481,9 +1718,10 @@
     VkEvent                                     event,
     VkPipelineStageFlags                        stageMask) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdResetEvent(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdWaitEvents(
@@ -1499,9 +1737,10 @@
 	uint32_t                                    imageMemoryBarrierCount,
 	const VkImageMemoryBarrier*                 pImageMemoryBarriers) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdWaitEvents(): Vukan events are not supported.");
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdPipelineBarrier(
@@ -1516,12 +1755,13 @@
 	uint32_t                                    imageMemoryBarrierCount,
 	const VkImageMemoryBarrier*                 pImageMemoryBarriers) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdPipelineBarrier(cmdBuff, srcStageMask, dstStageMask,
 						  dependencyFlags, memoryBarrierCount, pMemoryBarriers,
 						  bufferMemoryBarrierCount, pBufferMemoryBarriers,
 						  imageMemoryBarrierCount, pImageMemoryBarriers);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBeginQuery(
@@ -1530,9 +1770,10 @@
     uint32_t                                    query,
     VkQueryControlFlags                         flags) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdBeginQuery(cmdBuff, queryPool, query, flags);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdEndQuery(
@@ -1540,9 +1781,10 @@
     VkQueryPool                                 queryPool,
     uint32_t                                    query) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdEndQuery(cmdBuff, queryPool, query);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdResetQueryPool(
@@ -1551,9 +1793,10 @@
     uint32_t                                    firstQuery,
     uint32_t                                    queryCount) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdResetQueryPool(cmdBuff, queryPool, firstQuery, queryCount);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdWriteTimestamp(
@@ -1562,9 +1805,10 @@
 	VkQueryPool                                 queryPool,
 	uint32_t                                    query) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdWriteTimestamp(cmdBuff, pipelineStage, queryPool, query);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdCopyQueryPoolResults(
@@ -1577,10 +1821,11 @@
     VkDeviceSize                                destStride,
     VkQueryResultFlags                          flags) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdCopyQueryPoolResults(cmdBuff, queryPool, firstQuery, queryCount,
                                destBuffer, destOffset, destStride, flags);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdPushConstants(
@@ -1591,9 +1836,10 @@
     uint32_t                                    size,
     const void*                                 pValues) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdPushConstants(cmdBuff, layout, stageFlags, offset, size, pValues);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBeginRenderPass(
@@ -1601,26 +1847,29 @@
     const VkRenderPassBeginInfo*                pRenderPassBegin,
     VkSubpassContents							contents) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBeginRenderPass(cmdBuff,pRenderPassBegin, contents);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdNextSubpass(
     VkCommandBuffer                             commandBuffer,
     VkSubpassContents							contents) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdNextSubpass(cmdBuff, contents);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdEndRenderPass(
     VkCommandBuffer                             commandBuffer) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdEndRenderPass(cmdBuff);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdExecuteCommands(
@@ -1628,9 +1877,10 @@
     uint32_t                                    cmdBuffersCount,
     const VkCommandBuffer*						pCommandBuffers) {
 	
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdExecuteCommands(cmdBuff, cmdBuffersCount, pCommandBuffers);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1642,13 +1892,14 @@
 	uint32_t									bindInfoCount,
 	const VkBindBufferMemoryInfoKHR*			pBindInfos) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	VkResult rslt = VK_SUCCESS;
 	for (uint32_t i = 0; i < bindInfoCount; ++i) {
 		MVKBuffer* mvkBuff = (MVKBuffer*)pBindInfos[i].buffer;
 		VkResult r = mvkBuff->bindDeviceMemory2(&pBindInfos[i]);
 		if (rslt == VK_SUCCESS) { rslt = r; }
 	}
+	MVKTraceVulkanCallEnd();
 	return rslt;
 }
 
@@ -1657,13 +1908,14 @@
 	uint32_t									bindInfoCount,
 	const VkBindImageMemoryInfoKHR*				pBindInfos) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	VkResult rslt = VK_SUCCESS;
 	for (uint32_t i = 0; i < bindInfoCount; ++i) {
 		MVKImage* mvkImg = (MVKImage*)pBindInfos[i].image;
 		VkResult r = mvkImg->bindDeviceMemory2(&pBindInfos[i]);
 		if (rslt == VK_SUCCESS) { rslt = r; }
 	}
+	MVKTraceVulkanCallEnd();
 	return rslt;
 }
 
@@ -1677,12 +1929,14 @@
     const VkAllocationCallbacks*                   pAllocator,
     VkDescriptorUpdateTemplateKHR*                 pDescriptorUpdateTemplate) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     auto *mvkDUT = mvkDev->createDescriptorUpdateTemplate(pCreateInfo,
                                                           pAllocator);
     *pDescriptorUpdateTemplate = (VkDescriptorUpdateTemplateKHR)mvkDUT;
-    return mvkDUT->getConfigurationResult();
+    VkResult rslt = mvkDUT->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyDescriptorUpdateTemplateKHR(
@@ -1690,10 +1944,11 @@
     VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
     const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     if (!descriptorUpdateTemplate) { return; }
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     mvkDev->destroyDescriptorUpdateTemplate((MVKDescriptorUpdateTemplate*)descriptorUpdateTemplate, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkUpdateDescriptorSetWithTemplateKHR(
@@ -1702,8 +1957,9 @@
     VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
     const void*                                 pData) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     mvkUpdateDescriptorSetWithTemplate(descriptorSet, descriptorUpdateTemplate, pData);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1715,9 +1971,10 @@
     const VkBufferMemoryRequirementsInfo2KHR*   pInfo,
     VkMemoryRequirements2KHR*                   pMemoryRequirements) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKBuffer* mvkBuff = (MVKBuffer*)pInfo->buffer;
     mvkBuff->getMemoryRequirements(pInfo, pMemoryRequirements);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetImageMemoryRequirements2KHR(
@@ -1725,9 +1982,10 @@
     const VkImageMemoryRequirementsInfo2KHR*    pInfo,
     VkMemoryRequirements2KHR*                   pMemoryRequirements) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     auto* mvkImg = (MVKImage*)pInfo->image;
     mvkImg->getMemoryRequirements(pInfo, pMemoryRequirements);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetImageSparseMemoryRequirements2KHR(
@@ -1736,13 +1994,14 @@
     uint32_t*                                       pSparseMemoryRequirementCount,
     VkSparseImageMemoryRequirements2KHR*            pSparseMemoryRequirements) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 
 	// Metal does not support sparse images.
 	// Vulkan spec: "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then
 	// pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to.".
 
     *pSparseMemoryRequirementCount = 0;
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1753,18 +2012,20 @@
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceFeatures2KHR*               pFeatures) {
     
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     mvkPD->getFeatures(pFeatures);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceProperties2KHR(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceProperties2KHR*             pProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     mvkPD->getProperties(pProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceFormatProperties2KHR(
@@ -1772,9 +2033,10 @@
     VkFormat                                    format,
     VkFormatProperties2KHR*                     pFormatProperties) {
     
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     mvkPD->getFormatProperties(format, pFormatProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceImageFormatProperties2KHR(
@@ -1782,9 +2044,11 @@
     const VkPhysicalDeviceImageFormatInfo2KHR*  pImageFormatInfo,
     VkImageFormatProperties2KHR*                pImageFormatProperties) {
     
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
-    return mvkPD->getImageFormatProperties(pImageFormatInfo, pImageFormatProperties);
+    VkResult rslt = mvkPD->getImageFormatProperties(pImageFormatInfo, pImageFormatProperties);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceQueueFamilyProperties2KHR(
@@ -1792,18 +2056,20 @@
     uint32_t*                                   pQueueFamilyPropertyCount,
     VkQueueFamilyProperties2KHR*                pQueueFamilyProperties) {
     
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     mvkPD->getQueueFamilyProperties(pQueueFamilyPropertyCount, pQueueFamilyProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceMemoryProperties2KHR(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceMemoryProperties2KHR*       pMemoryProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     mvkPD->getPhysicalDeviceMemoryProperties(pMemoryProperties);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
@@ -1812,13 +2078,14 @@
     uint32_t*                                   pPropertyCount,
     VkSparseImageFormatProperties2KHR*          pProperties) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 
 	// Metal does not support sparse images.
 	// Vulkan spec: "If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported for the given arguments,
 	// pPropertyCount will be set to zero upon return, and no data will be written to pProperties.".
 
     *pPropertyCount = 0;
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1830,9 +2097,10 @@
     VkCommandPool                               commandPool,
     VkCommandPoolTrimFlagsKHR                   flags) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandPool* mvkCmdPool = (MVKCommandPool*)commandPool;
     mvkCmdPool->trim();
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1844,9 +2112,10 @@
     const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
     VkDescriptorSetLayoutSupportKHR*            pSupport) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDevice = MVKDevice::getMVKDevice(device);
     mvkDevice->getDescriptorSetLayoutSupport(pCreateInfo, pSupport);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1861,9 +2130,10 @@
     uint32_t                                    descriptorWriteCount,
     const VkWriteDescriptorSet*                 pDescriptorWrites) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdPushDescriptorSet(cmdBuff, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdPushDescriptorSetWithTemplateKHR(
@@ -1873,9 +2143,10 @@
     uint32_t                                   set,
     const void*                                pData) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
     mvkCmdPushDescriptorSetWithTemplate(cmdBuff, descriptorUpdateTemplate, layout, set, pData);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -1888,11 +2159,13 @@
     const VkAllocationCallbacks*             pAllocator,
     VkSwapchainKHR*                          pSwapchain) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     MVKSwapchain* mvkSwpChn = mvkDev->createSwapchain(pCreateInfo, pAllocator);
     *pSwapchain = (VkSwapchainKHR)(mvkSwpChn);
-    return mvkSwpChn->getConfigurationResult();
+    VkResult rslt = mvkSwpChn->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroySwapchainKHR(
@@ -1900,10 +2173,11 @@
     VkSwapchainKHR                           swapchain,
     const VkAllocationCallbacks*             pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !swapchain ) { return; }
     MVKDevice* mvkDev = MVKDevice::getMVKDevice(device);
     mvkDev->destroySwapchain((MVKSwapchain*)swapchain, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetSwapchainImagesKHR(
@@ -1912,9 +2186,11 @@
     uint32_t*                                pCount,
     VkImage*                                 pSwapchainImages) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKSwapchain* mvkSwapchain = (MVKSwapchain*)swapchain;
-    return mvkSwapchain->getImages(pCount, pSwapchainImages);
+    VkResult rslt = mvkSwapchain->getImages(pCount, pSwapchainImages);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkAcquireNextImageKHR(
@@ -1925,27 +2201,33 @@
     VkFence                                      fence,
     uint32_t*                                    pImageIndex) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKSwapchain* mvkSwapchain = (MVKSwapchain*)swapchain;
-    return mvkSwapchain->acquireNextImageKHR(timeout, semaphore, fence, ~0u, pImageIndex);
+    VkResult rslt = mvkSwapchain->acquireNextImageKHR(timeout, semaphore, fence, ~0u, pImageIndex);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkQueuePresentKHR(
     VkQueue                                      queue,
     const VkPresentInfoKHR*                      pPresentInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKQueue* mvkQ = MVKQueue::getMVKQueue(queue);
-    return mvkQ->submit(pPresentInfo);
+    VkResult rslt = mvkQ->submit(pPresentInfo);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetDeviceGroupPresentCapabilitiesKHR(
 	VkDevice                                    device,
 	VkDeviceGroupPresentCapabilitiesKHR*        pDeviceGroupPresentCapabilities) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDevice = MVKDevice::getMVKDevice(device);
-	return mvkDevice->getDeviceGroupPresentCapabilities(pDeviceGroupPresentCapabilities);
+	VkResult rslt = mvkDevice->getDeviceGroupPresentCapabilities(pDeviceGroupPresentCapabilities);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetDeviceGroupSurfacePresentModesKHR(
@@ -1953,10 +2235,12 @@
 	VkSurfaceKHR                                surface,
 	VkDeviceGroupPresentModeFlagsKHR*           pModes) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKDevice* mvkDevice = MVKDevice::getMVKDevice(device);
 	MVKSurface* mvkSrfc = (MVKSurface*)surface;
-	return mvkDevice->getDeviceGroupSurfacePresentModes(mvkSrfc, pModes);
+	VkResult rslt = mvkDevice->getDeviceGroupSurfacePresentModes(mvkSrfc, pModes);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDevicePresentRectanglesKHR(
@@ -1965,10 +2249,12 @@
 	uint32_t*                                   pRectCount,
 	VkRect2D*                                   pRects) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	MVKSurface* mvkSrfc = (MVKSurface*)surface;
-	return mvkPD->getPresentRectangles(mvkSrfc, pRectCount, pRects);
+	VkResult rslt = mvkPD->getPresentRectangles(mvkSrfc, pRectCount, pRects);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkAcquireNextImage2KHR(
@@ -1976,13 +2262,15 @@
 	const VkAcquireNextImageInfoKHR*            pAcquireInfo,
 	uint32_t*                                   pImageIndex) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKSwapchain* mvkSwapchain = (MVKSwapchain*)pAcquireInfo->swapchain;
-	return mvkSwapchain->acquireNextImageKHR(pAcquireInfo->timeout,
-											 pAcquireInfo->semaphore,
-											 pAcquireInfo->fence,
-											 pAcquireInfo->deviceMask,
-											 pImageIndex);
+	VkResult rslt = mvkSwapchain->acquireNextImageKHR(pAcquireInfo->timeout,
+													  pAcquireInfo->semaphore,
+													  pAcquireInfo->fence,
+													  pAcquireInfo->deviceMask,
+													  pImageIndex);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 
@@ -1994,10 +2282,11 @@
     VkSurfaceKHR                                 surface,
     const VkAllocationCallbacks*                 pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !surface ) { return; }
     MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
     mvkInst->destroySurface((MVKSurface*)surface, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceSurfaceSupportKHR(
@@ -2006,10 +2295,12 @@
     VkSurfaceKHR                                surface,
     VkBool32*                                   pSupported) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     MVKSurface* mvkSrfc = (MVKSurface*)surface;
-    return mvkPD->getSurfaceSupport(queueFamilyIndex, mvkSrfc, pSupported);
+    VkResult rslt = mvkPD->getSurfaceSupport(queueFamilyIndex, mvkSrfc, pSupported);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
@@ -2017,10 +2308,12 @@
     VkSurfaceKHR                                surface,
     VkSurfaceCapabilitiesKHR*                   pSurfaceCapabilities) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     MVKSurface* mvkSrfc = (MVKSurface*)surface;
-    return mvkPD->getSurfaceCapabilities(mvkSrfc, pSurfaceCapabilities);
+    VkResult rslt = mvkPD->getSurfaceCapabilities(mvkSrfc, pSurfaceCapabilities);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceSurfaceFormatsKHR(
@@ -2029,10 +2322,12 @@
     uint32_t*                                   pSurfaceFormatCount,
     VkSurfaceFormatKHR*                         pSurfaceFormats) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     MVKSurface* mvkSrfc = (MVKSurface*)surface;
-    return mvkPD->getSurfaceFormats(mvkSrfc, pSurfaceFormatCount, pSurfaceFormats);
+    VkResult rslt = mvkPD->getSurfaceFormats(mvkSrfc, pSurfaceFormatCount, pSurfaceFormats);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceSurfacePresentModesKHR(
@@ -2041,10 +2336,12 @@
     uint32_t*                                   pPresentModeCount,
     VkPresentModeKHR*                           pPresentModes) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
     MVKSurface* mvkSrfc = (MVKSurface*)surface;
-    return mvkPD->getSurfacePresentModes(mvkSrfc, pPresentModeCount, pPresentModes);
+    VkResult rslt = mvkPD->getSurfacePresentModes(mvkSrfc, pPresentModeCount, pPresentModes);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 
@@ -2056,10 +2353,12 @@
 	const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
 	VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	MVKSurface* mvkSrfc = (MVKSurface*)pSurfaceInfo->surface;
-	return mvkPD->getSurfaceCapabilities(mvkSrfc, &pSurfaceCapabilities->surfaceCapabilities);
+	VkResult rslt = mvkPD->getSurfaceCapabilities(mvkSrfc, &pSurfaceCapabilities->surfaceCapabilities);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkGetPhysicalDeviceSurfaceFormats2KHR(
@@ -2068,10 +2367,12 @@
 	uint32_t*                                   pSurfaceFormatCount,
 	VkSurfaceFormat2KHR*                        pSurfaceFormats) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKPhysicalDevice* mvkPD = MVKPhysicalDevice::getMVKPhysicalDevice(physicalDevice);
 	MVKSurface* mvkSrfc = (MVKSurface*)pSurfaceInfo->surface;
-	return mvkPD->getSurfaceFormats(mvkSrfc, pSurfaceFormatCount, pSurfaceFormats);
+	VkResult rslt = mvkPD->getSurfaceFormats(mvkSrfc, pSurfaceFormatCount, pSurfaceFormats);
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 
@@ -2084,9 +2385,10 @@
     uint32_t                                    firstQuery,
     uint32_t                                    queryCount) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     auto* mvkQueryPool = (MVKQueryPool*)queryPool;
     mvkQueryPool->resetResults(firstQuery, queryCount, nullptr);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -2099,11 +2401,13 @@
 	const VkAllocationCallbacks*                pAllocator,
 	VkDebugReportCallbackEXT*                   pCallback) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
 	MVKDebugReportCallback* mvkDRCB = mvkInst->createDebugReportCallback(pCreateInfo, pAllocator);
 	*pCallback = (VkDebugReportCallbackEXT)mvkDRCB;
-	return mvkDRCB->getConfigurationResult();
+	VkResult rslt = mvkDRCB->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyDebugReportCallbackEXT(
@@ -2111,10 +2415,11 @@
 	VkDebugReportCallbackEXT                    callback,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !callback ) { return; }
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
 	mvkInst->destroyDebugReportCallback((MVKDebugReportCallback*)callback, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkDebugReportMessageEXT(
@@ -2127,9 +2432,10 @@
 	const char*                                 pLayerPrefix,
 	const char*                                 pMessage) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
 	mvkInst->debugReportMessage(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -2140,43 +2446,50 @@
 	VkDevice                                    device,
 	const VkDebugMarkerObjectTagInfoEXT*        pTagInfo) {
 
-	MVKTraceVulkanCall();
-	return VK_SUCCESS;
+	MVKTraceVulkanCallStart();
+	VkResult rslt = VK_SUCCESS;
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkDebugMarkerSetObjectNameEXT(
 	VkDevice                                    device,
 	const VkDebugMarkerObjectNameInfoEXT*       pNameInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKVulkanAPIObject* mvkObj = MVKVulkanAPIObject::getMVKVulkanAPIObject(pNameInfo->objectType, pNameInfo->object);
-	return mvkObj ? mvkObj->setDebugName(pNameInfo->pObjectName) : VK_SUCCESS;
+	VkResult rslt = mvkObj ? mvkObj->setDebugName(pNameInfo->pObjectName) : VK_SUCCESS;
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDebugMarkerBeginEXT(
 	VkCommandBuffer                             commandBuffer,
 	const VkDebugMarkerMarkerInfoEXT*           pMarkerInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDebugMarkerBegin(cmdBuff, pMarkerInfo);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDebugMarkerEndEXT(
 	VkCommandBuffer                             commandBuffer) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDebugMarkerEnd(cmdBuff);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdDebugMarkerInsertEXT(
 	VkCommandBuffer                             commandBuffer,
 	const VkDebugMarkerMarkerInfoEXT*           pMarkerInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdDebugMarkerInsert(cmdBuff, pMarkerInfo);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -2187,63 +2500,73 @@
 	VkDevice                                    device,
 	const VkDebugUtilsObjectNameInfoEXT*        pNameInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKVulkanAPIObject* mvkObj = MVKVulkanAPIObject::getMVKVulkanAPIObject(pNameInfo->objectType, pNameInfo->objectHandle);
-	return mvkObj ? mvkObj->setDebugName(pNameInfo->pObjectName) : VK_SUCCESS;
+	VkResult rslt = mvkObj ? mvkObj->setDebugName(pNameInfo->pObjectName) : VK_SUCCESS;
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkSetDebugUtilsObjectTagEXT(
 	VkDevice                                    device,
 	const VkDebugUtilsObjectTagInfoEXT*         pTagInfo) {
 
-	MVKTraceVulkanCall();
-	return VK_SUCCESS;
+	MVKTraceVulkanCallStart();
+	VkResult rslt = VK_SUCCESS;
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkQueueBeginDebugUtilsLabelEXT(
 	VkQueue                                     queue,
 	const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkQueueEndDebugUtilsLabelEXT(
 	VkQueue                                     queue) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkQueueInsertDebugUtilsLabelEXT(
 	VkQueue                                     queue,
 	const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdBeginDebugUtilsLabelEXT(
 	VkCommandBuffer                             commandBuffer,
 	const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdBeginDebugUtilsLabel(cmdBuff, pLabelInfo);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdEndDebugUtilsLabelEXT(
 	VkCommandBuffer                             commandBuffer) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdEndDebugUtilsLabel(cmdBuff);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkCmdInsertDebugUtilsLabelEXT(
 	VkCommandBuffer                             commandBuffer,
 	const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKCommandBuffer* cmdBuff = MVKCommandBuffer::getMVKCommandBuffer(commandBuffer);
 	mvkCmdInsertDebugUtilsLabel(cmdBuff, pLabelInfo);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL VkResult vkCreateDebugUtilsMessengerEXT(
@@ -2252,11 +2575,13 @@
 	const VkAllocationCallbacks*                pAllocator,
 	VkDebugUtilsMessengerEXT*                   pMessenger) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
 	MVKDebugUtilsMessenger* mvkDUM = mvkInst->createDebugUtilsMessenger(pCreateInfo, pAllocator);
 	*pMessenger = (VkDebugUtilsMessengerEXT)mvkDUM;
-	return mvkDUM->getConfigurationResult();
+	VkResult rslt = mvkDUM->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL void vkDestroyDebugUtilsMessengerEXT(
@@ -2264,10 +2589,11 @@
 	VkDebugUtilsMessengerEXT                    messenger,
 	const VkAllocationCallbacks*                pAllocator) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	if ( !messenger ) { return; }
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
 	mvkInst->destroyDebugUtilsMessenger((MVKDebugUtilsMessenger*)messenger, pAllocator);
+	MVKTraceVulkanCallEnd();
 }
 
 MVK_PUBLIC_SYMBOL void vkSubmitDebugUtilsMessageEXT(
@@ -2276,9 +2602,10 @@
 	VkDebugUtilsMessageTypeFlagsEXT             messageTypes,
 	const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 	MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
 	mvkInst->debugUtilsMessage(messageSeverity, messageTypes, pCallbackData);
+	MVKTraceVulkanCallEnd();
 }
 
 
@@ -2291,11 +2618,13 @@
     const VkAllocationCallbacks*                pAllocator,
     VkSurfaceKHR*                               pSurface) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
     MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
     MVKSurface* mvkSrfc = mvkInst->createSurface(pCreateInfo, pAllocator);
     *pSurface = (VkSurfaceKHR)mvkSrfc;
-    return mvkSrfc->getConfigurationResult();
+    VkResult rslt = mvkSrfc->getConfigurationResult();
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 
@@ -2318,46 +2647,44 @@
 MVK_PUBLIC_SYMBOL VkResult vk_icdNegotiateLoaderICDInterfaceVersion(
 	uint32_t*                                   pSupportedVersion) {
 
-	MVKTraceVulkanCall();
+	MVKTraceVulkanCallStart();
 
 	// This ICD expects to be loaded by a loader of at least version 5.
+	VkResult rslt = VK_SUCCESS;
 	if (pSupportedVersion && *pSupportedVersion >= 5) {
 		*pSupportedVersion = 5;
-		return VK_SUCCESS;
+	} else {
+		rslt = VK_ERROR_INCOMPATIBLE_DRIVER;
 	}
-
-	return VK_ERROR_INCOMPATIBLE_DRIVER;
+	MVKTraceVulkanCallEnd();
+	return rslt;
 }
 
 MVK_PUBLIC_SYMBOL PFN_vkVoidFunction vk_icdGetInstanceProcAddr(
 	VkInstance                                  instance,
 	const char*                                 pName) {
 
-	MVKTraceVulkanCall();
-	if (strcmp(pName, "vk_icdNegotiateLoaderICDInterfaceVersion") == 0) { return (PFN_vkVoidFunction)vk_icdNegotiateLoaderICDInterfaceVersion; }
-	if (strcmp(pName, "vk_icdGetPhysicalDeviceProcAddr") == 0) { return (PFN_vkVoidFunction)vk_icdGetPhysicalDeviceProcAddr; }
+	MVKTraceVulkanCallStart();
 
-	return vkGetInstanceProcAddr(instance, pName);
+	PFN_vkVoidFunction func = nullptr;
+	if (strcmp(pName, "vk_icdNegotiateLoaderICDInterfaceVersion") == 0) {
+		func = (PFN_vkVoidFunction)vk_icdNegotiateLoaderICDInterfaceVersion;
+	} else if (strcmp(pName, "vk_icdGetPhysicalDeviceProcAddr") == 0) {
+		func = (PFN_vkVoidFunction)vk_icdGetPhysicalDeviceProcAddr;
+	} else {
+		func = vkGetInstanceProcAddr(instance, pName);
+	}
+	MVKTraceVulkanCallEnd();
+	return func;
 }
 
 MVK_PUBLIC_SYMBOL PFN_vkVoidFunction vk_icdGetPhysicalDeviceProcAddr(
 	VkInstance                                  instance,
 	const char*                                 pName) {
 
-	MVKTraceVulkanCall();
-	return vk_icdGetInstanceProcAddr(instance, pName);
-}
-
-
-#include "MVKOSExtensions.h"
-#ifndef MVK_CONFIG_TRACE_VULKAN_CALLS
-#   define MVK_CONFIG_TRACE_VULKAN_CALLS    false
-#endif
-static bool _mvkVulkanCallTracingInitialized = false;
-__attribute__((constructor)) static void MVKInitVulkanCallTracing() {
-	if (_mvkVulkanCallTracingInitialized ) { return; }
-	_mvkVulkanCallTracingInitialized = true;
-
-	MVK_SET_FROM_ENV_OR_BUILD_BOOL(_mvkTraceVulkanCalls, MVK_CONFIG_TRACE_VULKAN_CALLS);
+	MVKTraceVulkanCallStart();
+	PFN_vkVoidFunction func = vk_icdGetInstanceProcAddr(instance, pName);
+	MVKTraceVulkanCallEnd();
+	return func;
 }