Clean up MVKLogging

* Replaced ASL levels with MVKConfigLogLevel.
* Moved MVKLogging.h to Utility/ directory.
* Added MVKConfigLogLevel Warning and Debug levels.
This commit is contained in:
Nikita Fediuchin 2021-11-25 09:47:43 +02:00
parent 80256771f7
commit 6ac92fbacf
7 changed files with 64 additions and 83 deletions

View File

@ -680,6 +680,7 @@
A98149401FB6A3F7005F00B4 /* Utility */ = { A98149401FB6A3F7005F00B4 /* Utility */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */,
A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */, A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */,
A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */, A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */,
A9D7104E25CDE05E00E38106 /* MVKBitArray.h */, A9D7104E25CDE05E00E38106 /* MVKBitArray.h */,
@ -751,7 +752,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */, A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */,
A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */,
A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */, A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */,
A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */, A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */,
A981496A1FB6A998005F00B4 /* MVKStrings.h */, A981496A1FB6A998005F00B4 /* MVKStrings.h */,

View File

@ -62,7 +62,9 @@ typedef unsigned long MTLLanguageVersion;
typedef enum MVKConfigLogLevel { typedef enum MVKConfigLogLevel {
MVK_CONFIG_LOG_LEVEL_NONE = 0, /**< No logging. */ MVK_CONFIG_LOG_LEVEL_NONE = 0, /**< No logging. */
MVK_CONFIG_LOG_LEVEL_ERROR = 1, /**< Log errors only. */ MVK_CONFIG_LOG_LEVEL_ERROR = 1, /**< Log errors only. */
MVK_CONFIG_LOG_LEVEL_INFO = 2, /**< Log errors and informational messages. */ MVK_CONFIG_LOG_LEVEL_WARNING = 2, /**< Log errors and warning messages. */
MVK_CONFIG_LOG_LEVEL_INFO = 3, /**< Log errors, warnings and informational messages. */
MVK_CONFIG_LOG_LEVEL_DEBUG = 4, /**< Log errors, warnings, infos and debug messages. */
MVK_CONFIG_LOG_LEVEL_MAX_ENUM = 0x7FFFFFFF MVK_CONFIG_LOG_LEVEL_MAX_ENUM = 0x7FFFFFFF
} MVKConfigLogLevel; } MVKConfigLogLevel;

View File

@ -144,7 +144,7 @@ public:
VkDebugUtilsMessageTypeFlagsEXT messageTypes, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData);
void debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, int aslLvl, const char* pMessage); void debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, MVKConfigLogLevel logLevel, const char* pMessage);
/** Returns whether debug callbacks are being used. */ /** Returns whether debug callbacks are being used. */
bool hasDebugCallbacks() { return _hasDebugReportCallbacks || _hasDebugUtilsMessengers; } bool hasDebugCallbacks() { return _hasDebugReportCallbacks || _hasDebugUtilsMessengers; }
@ -181,8 +181,8 @@ protected:
void initProcAddrs(); void initProcAddrs();
void initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo); void initDebugCallbacks(const VkInstanceCreateInfo* pCreateInfo);
NSArray<id<MTLDevice>>* getAvailableMTLDevicesArray(); NSArray<id<MTLDevice>>* getAvailableMTLDevicesArray();
VkDebugReportFlagsEXT getVkDebugReportFlagsFromASLLevel(int aslLvl); VkDebugReportFlagsEXT getVkDebugReportFlagsFromLogLevel(MVKConfigLogLevel logLevel);
VkDebugUtilsMessageSeverityFlagBitsEXT getVkDebugUtilsMessageSeverityFlagBitsFromASLLevel(int aslLvl); VkDebugUtilsMessageSeverityFlagBitsEXT getVkDebugUtilsMessageSeverityFlagBitsFromLogLevel(MVKConfigLogLevel logLevel);
MVKEntryPoint* getEntryPoint(const char* pName); MVKEntryPoint* getEntryPoint(const char* pName);
void logVersions(); void logVersions();
VkResult verifyLayers(uint32_t count, const char* const* names); VkResult verifyLayers(uint32_t count, const char* const* names);

View File

@ -198,17 +198,17 @@ void MVKInstance::debugUtilsMessage(VkDebugUtilsMessageSeverityFlagBitsEXT messa
} }
} }
void MVKInstance::debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, int aslLvl, const char* pMessage) { void MVKInstance::debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, MVKConfigLogLevel logLevel, const char* pMessage) {
if (_hasDebugReportCallbacks) { if (_hasDebugReportCallbacks) {
VkDebugReportFlagsEXT flags = getVkDebugReportFlagsFromASLLevel(aslLvl); VkDebugReportFlagsEXT flags = getVkDebugReportFlagsFromLogLevel(logLevel);
uint64_t object = (uint64_t)(mvkAPIObj ? mvkAPIObj->getVkHandle() : nullptr); uint64_t object = (uint64_t)(mvkAPIObj ? mvkAPIObj->getVkHandle() : nullptr);
VkDebugReportObjectTypeEXT objectType = mvkAPIObj ? mvkAPIObj->getVkDebugReportObjectType() : VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; VkDebugReportObjectTypeEXT objectType = mvkAPIObj ? mvkAPIObj->getVkDebugReportObjectType() : VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
debugReportMessage(flags, objectType, object, 0, 0, _debugReportCallbackLayerPrefix, pMessage); debugReportMessage(flags, objectType, object, 0, 0, _debugReportCallbackLayerPrefix, pMessage);
} }
if (_hasDebugUtilsMessengers) { if (_hasDebugUtilsMessengers) {
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity = getVkDebugUtilsMessageSeverityFlagBitsFromASLLevel(aslLvl); VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity = getVkDebugUtilsMessageSeverityFlagBitsFromLogLevel(logLevel);
uint64_t objectHandle = (uint64_t)(mvkAPIObj ? mvkAPIObj->getVkHandle() : nullptr); uint64_t objectHandle = (uint64_t)(mvkAPIObj ? mvkAPIObj->getVkHandle() : nullptr);
VkObjectType objectType = mvkAPIObj ? mvkAPIObj->getVkObjectType() : VK_OBJECT_TYPE_UNKNOWN; VkObjectType objectType = mvkAPIObj ? mvkAPIObj->getVkObjectType() : VK_OBJECT_TYPE_UNKNOWN;
@ -237,43 +237,29 @@ void MVKInstance::debugReportMessage(MVKVulkanAPIObject* mvkAPIObj, int aslLvl,
} }
} }
VkDebugReportFlagsEXT MVKInstance::getVkDebugReportFlagsFromASLLevel(int aslLvl) { VkDebugReportFlagsEXT MVKInstance::getVkDebugReportFlagsFromLogLevel(MVKConfigLogLevel logLevel) {
switch (aslLvl) { switch (logLevel) {
case ASL_LEVEL_DEBUG: case MVK_CONFIG_LOG_LEVEL_DEBUG:
return VK_DEBUG_REPORT_DEBUG_BIT_EXT; return VK_DEBUG_REPORT_DEBUG_BIT_EXT;
case MVK_CONFIG_LOG_LEVEL_INFO:
case ASL_LEVEL_INFO:
case ASL_LEVEL_NOTICE:
return VK_DEBUG_REPORT_INFORMATION_BIT_EXT; return VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
case MVK_CONFIG_LOG_LEVEL_WARNING:
case ASL_LEVEL_WARNING:
return VK_DEBUG_REPORT_WARNING_BIT_EXT; return VK_DEBUG_REPORT_WARNING_BIT_EXT;
case MVK_CONFIG_LOG_LEVEL_ERROR:
case ASL_LEVEL_ERR:
case ASL_LEVEL_CRIT:
case ASL_LEVEL_ALERT:
case ASL_LEVEL_EMERG:
default: default:
return VK_DEBUG_REPORT_ERROR_BIT_EXT; return VK_DEBUG_REPORT_ERROR_BIT_EXT;
} }
} }
VkDebugUtilsMessageSeverityFlagBitsEXT MVKInstance::getVkDebugUtilsMessageSeverityFlagBitsFromASLLevel(int aslLvl) { VkDebugUtilsMessageSeverityFlagBitsEXT MVKInstance::getVkDebugUtilsMessageSeverityFlagBitsFromLogLevel(MVKConfigLogLevel logLevel) {
switch (aslLvl) { switch (logLevel) {
case ASL_LEVEL_DEBUG: case MVK_CONFIG_LOG_LEVEL_DEBUG:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; return VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
case MVK_CONFIG_LOG_LEVEL_INFO:
case ASL_LEVEL_INFO:
case ASL_LEVEL_NOTICE:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; return VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
case MVK_CONFIG_LOG_LEVEL_WARNING:
case ASL_LEVEL_WARNING:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT; return VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
case MVK_CONFIG_LOG_LEVEL_ERROR:
case ASL_LEVEL_ERR:
case ASL_LEVEL_CRIT:
case ASL_LEVEL_ALERT:
case ASL_LEVEL_EMERG:
default: default:
return VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; return VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
} }

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "mvk_vulkan.h" #include "mvk_vulkan.h"
#include "vk_mvk_moltenvk.h"
#include <string> #include <string>
#include <atomic> #include <atomic>
@ -47,7 +48,7 @@ public:
* and some subclasses will also forward the message to their VkInstance for * and some subclasses will also forward the message to their VkInstance for
* output to the Vulkan debug report messaging API. * output to the Vulkan debug report messaging API.
*/ */
void reportMessage(int aslLvl, const char* format, ...) __printflike(3, 4); void reportMessage(MVKConfigLogLevel logLevel, const char* format, ...) __printflike(3, 4);
/** /**
* Report a Vulkan error message, on behalf of the object, which may be nil. * Report a Vulkan error message, on behalf of the object, which may be nil.
@ -55,7 +56,7 @@ public:
* is not nil and has access to the VkInstance, the message will also be forwarded * is not nil and has access to the VkInstance, the message will also be forwarded
* to the VkInstance for output to the Vulkan debug report messaging API. * to the VkInstance for output to the Vulkan debug report messaging API.
*/ */
static void reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char* format, ...) __printflike(3, 4); static void reportMessage(MVKBaseObject* mvkObj, MVKConfigLogLevel logLevel, const char* format, ...) __printflike(3, 4);
/** /**
* Report a Vulkan error message, on behalf of the object, which may be nil. * Report a Vulkan error message, on behalf of the object, which may be nil.
@ -65,7 +66,7 @@ public:
* *
* This is the core reporting implementation. Other similar functions delegate here. * This is the core reporting implementation. Other similar functions delegate here.
*/ */
static void reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char* format, va_list args) __printflike(3, 0); static void reportMessage(MVKBaseObject* mvkObj, MVKConfigLogLevel logLevel, const char* format, va_list args) __printflike(3, 0);
/** /**
* Report a Vulkan error message. This includes logging to a standard system logging stream, * Report a Vulkan error message. This includes logging to a standard system logging stream,

View File

@ -26,22 +26,15 @@
using namespace std; using namespace std;
static const char* getReportingLevelString(int aslLvl) { static const char* getReportingLevelString(MVKConfigLogLevel logLevel) {
switch (aslLvl) { switch (logLevel) {
case ASL_LEVEL_DEBUG: case MVK_CONFIG_LOG_LEVEL_DEBUG:
return "mvk-debug"; return "mvk-debug";
case MVK_CONFIG_LOG_LEVEL_INFO:
case ASL_LEVEL_INFO:
case ASL_LEVEL_NOTICE:
return "mvk-info"; return "mvk-info";
case MVK_CONFIG_LOG_LEVEL_WARNING:
case ASL_LEVEL_WARNING:
return "mvk-warn"; return "mvk-warn";
case MVK_CONFIG_LOG_LEVEL_ERROR:
case ASL_LEVEL_ERR:
case ASL_LEVEL_CRIT:
case ASL_LEVEL_ALERT:
case ASL_LEVEL_EMERG:
default: default:
return "mvk-error"; return "mvk-error";
} }
@ -59,27 +52,27 @@ string MVKBaseObject::getClassName() {
return clzName; return clzName;
} }
void MVKBaseObject::reportMessage(int aslLvl, const char* format, ...) { void MVKBaseObject::reportMessage(MVKConfigLogLevel logLevel, const char* format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
reportMessage(this, aslLvl, format, args); reportMessage(this, logLevel, format, args);
va_end(args); va_end(args);
} }
void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char* format, ...) { void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, MVKConfigLogLevel logLevel, const char* format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
reportMessage(mvkObj, aslLvl, format, args); reportMessage(mvkObj, logLevel, format, args);
va_end(args); va_end(args);
} }
// This is the core reporting implementation. Other similar functions delegate here. // This is the core reporting implementation. Other similar functions delegate here.
void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char* format, va_list args) { void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, MVKConfigLogLevel logLevel, const char* format, va_list args) {
MVKVulkanAPIObject* mvkAPIObj = mvkObj ? mvkObj->getVulkanAPIObject() : nullptr; MVKVulkanAPIObject* mvkAPIObj = mvkObj ? mvkObj->getVulkanAPIObject() : nullptr;
MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr; MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr;
bool hasDebugCallbacks = mvkInst && mvkInst->hasDebugCallbacks(); bool hasDebugCallbacks = mvkInst && mvkInst->hasDebugCallbacks();
bool shouldLog = (aslLvl < (mvkConfig().logLevel << 2)); bool shouldLog = logLevel <= mvkConfig().logLevel;
// Fail fast to avoid further unnecessary processing. // Fail fast to avoid further unnecessary processing.
if ( !(shouldLog || hasDebugCallbacks) ) { return; } if ( !(shouldLog || hasDebugCallbacks) ) { return; }
@ -107,10 +100,10 @@ void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char*
va_end(origArgs); va_end(origArgs);
// Log the message to the standard error stream // Log the message to the standard error stream
if (shouldLog) { fprintf(stderr, "[%s] %s\n", getReportingLevelString(aslLvl), pMessage); } if (shouldLog) { fprintf(stderr, "[%s] %s\n", getReportingLevelString(logLevel), pMessage); }
// Broadcast the message to any Vulkan debug report callbacks // Broadcast the message to any Vulkan debug report callbacks
if (hasDebugCallbacks) { mvkInst->debugReportMessage(mvkAPIObj, aslLvl, pMessage); } if (hasDebugCallbacks) { mvkInst->debugReportMessage(mvkAPIObj, logLevel, pMessage); }
free(redoBuff); free(redoBuff);
} }
@ -138,11 +131,11 @@ VkResult MVKBaseObject::reportError(MVKBaseObject* mvkObj, VkResult vkErr, const
const char* vkRsltName = mvkVkResultName(vkErr); const char* vkRsltName = mvkVkResultName(vkErr);
char fmtStr[strlen(vkRsltName) + strlen(format) + 4]; char fmtStr[strlen(vkRsltName) + strlen(format) + 4];
sprintf(fmtStr, "%s: %s", vkRsltName, format); sprintf(fmtStr, "%s: %s", vkRsltName, format);
// Report the error // Report the error
va_list lclArgs; va_list lclArgs;
va_copy(lclArgs, args); va_copy(lclArgs, args);
reportMessage(mvkObj, ASL_LEVEL_ERR, fmtStr, lclArgs); reportMessage(mvkObj, MVK_CONFIG_LOG_LEVEL_ERROR, fmtStr, lclArgs);
va_end(lclArgs); va_end(lclArgs);
return vkErr; return vkErr;

View File

@ -28,7 +28,6 @@ extern "C" {
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <asl.h>
#include <stdbool.h> #include <stdbool.h>
/** /**
@ -36,8 +35,8 @@ extern "C" {
* that can be efficiently enabled or disabled via compiler switches. * that can be efficiently enabled or disabled via compiler switches.
* *
* There are five levels of logging: Trace, Info, Warning, Error and Debug, and each can be enabled * There are five levels of logging: Trace, Info, Warning, Error and Debug, and each can be enabled
* independently via the MVK_LOG_LEVEL_TRACE, MVK_LOG_LEVEL_INFO, MVK_LOG_LEVEL_WARNING, * independently via the MVK_LOG_LEVEL_TRACE, MVK_LOG_LEVEL_DEBUG, MVK_LOG_LEVEL_INFO,
* MVK_LOG_LEVEL_ERROR and MVK_LOG_LEVEL_DEBUG switches, respectively. * MVK_LOG_LEVEL_WARNING анд MVK_LOG_LEVEL_ERROR switches, respectively.
* *
* ALL logging can be enabled or disabled via the MVK_LOGGING_ENABLED switch. * ALL logging can be enabled or disabled via the MVK_LOGGING_ENABLED switch.
* *
@ -59,10 +58,10 @@ extern "C" {
* MVKLogErrorIf(cond, fmt, ...) - same as MVKLogError if boolean "cond" condition expression evaluates to YES, * MVKLogErrorIf(cond, fmt, ...) - same as MVKLogError if boolean "cond" condition expression evaluates to YES,
* otherwise logs nothing. * otherwise logs nothing.
* *
* MVKLogWarning(fmt, ...) - recommended for not immediately harmful errors * MVKLogWarning(fmt, ...) - recommended for not immediately harmful errors
* - will print if MVK_LOG_LEVEL_WARNING is set on. * - will print if MVK_LOG_LEVEL_WARNING is set on.
* MVKLogWarningIf(cond, fmt, ...) - same as MVKLogWarning if boolean "cond" condition expression evaluates to YES, * MVKLogWarningIf(cond, fmt, ...) - same as MVKLogWarning if boolean "cond" condition expression evaluates to YES,
* otherwise logs nothing. * otherwise logs nothing.
* *
* MVKLogInfo(fmt, ...) - recommended for general, infrequent, information messages * MVKLogInfo(fmt, ...) - recommended for general, infrequent, information messages
* - will print if MVK_LOG_LEVEL_INFO is set on. * - will print if MVK_LOG_LEVEL_INFO is set on.
@ -150,8 +149,8 @@ extern "C" {
// Warning logging - for not immediately harmful errors // Warning logging - for not immediately harmful errors
#if MVK_LOG_LEVEL_WARNING #if MVK_LOG_LEVEL_WARNING
# define MVKLogWarning(fmt, ...) MVKLogWarningImpl(fmt, ##__VA_ARGS__) # define MVKLogWarning(fmt, ...) MVKLogWarningImpl(fmt, ##__VA_ARGS__)
# define MVKLogWarningIf(cond, fmt, ...) if(cond) { MVKLogWarningImpl(fmt, ##__VA_ARGS__); } # define MVKLogWarningIf(cond, fmt, ...) if(cond) { MVKLogWarningImpl(fmt, ##__VA_ARGS__); }
#else #else
# define MVKLogWarning(...) # define MVKLogWarning(...)
# define MVKLogWarningIf(cond, fmt, ...) # define MVKLogWarningIf(cond, fmt, ...)
@ -166,15 +165,6 @@ extern "C" {
# define MVKLogInfoIf(cond, fmt, ...) # define MVKLogInfoIf(cond, fmt, ...)
#endif #endif
// Trace logging - for detailed tracing
#if MVK_LOG_LEVEL_TRACE
# define MVKLogTrace(fmt, ...) MVKLogTraceImpl(fmt, ##__VA_ARGS__)
# define MVKLogTraceIf(cond, fmt, ...) if(cond) { MVKLogTraceImpl(fmt, ##__VA_ARGS__); }
#else
# define MVKLogTrace(...)
# define MVKLogTraceIf(cond, fmt, ...)
#endif
// Debug logging - use only temporarily for highlighting and tracking down problems // Debug logging - use only temporarily for highlighting and tracking down problems
#if MVK_LOG_LEVEL_DEBUG #if MVK_LOG_LEVEL_DEBUG
# define MVKLogDebug(fmt, ...) MVKLogDebugImpl(fmt, ##__VA_ARGS__) # define MVKLogDebug(fmt, ...) MVKLogDebugImpl(fmt, ##__VA_ARGS__)
@ -184,11 +174,20 @@ extern "C" {
# define MVKLogDebugIf(cond, fmt, ...) # define MVKLogDebugIf(cond, fmt, ...)
#endif #endif
#define MVKLogErrorImpl(fmt, ...) reportMessage(ASL_LEVEL_ERR, fmt, ##__VA_ARGS__) // Trace logging - for detailed tracing
#define MVKLogWarningImpl(fmt, ...) reportMessage(ASL_LEVEL_WARNING, fmt, ##__VA_ARGS__) #if MVK_LOG_LEVEL_TRACE
#define MVKLogInfoImpl(fmt, ...) reportMessage(ASL_LEVEL_NOTICE, fmt, ##__VA_ARGS__) # define MVKLogTrace(fmt, ...) MVKLogTraceImpl(fmt, ##__VA_ARGS__)
#define MVKLogTraceImpl(fmt, ...) reportMessage(ASL_LEVEL_DEBUG, fmt, ##__VA_ARGS__) # define MVKLogTraceIf(cond, fmt, ...) if(cond) { MVKLogTraceImpl(fmt, ##__VA_ARGS__); }
#define MVKLogDebugImpl(fmt, ...) reportMessage(ASL_LEVEL_DEBUG, fmt, ##__VA_ARGS__) #else
# define MVKLogTrace(...)
# define MVKLogTraceIf(cond, fmt, ...)
#endif
#define MVKLogErrorImpl(fmt, ...) reportMessage(MVK_CONFIG_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
#define MVKLogWarningImpl(fmt, ...) reportMessage(MVK_CONFIG_LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
#define MVKLogInfoImpl(fmt, ...) reportMessage(MVK_CONFIG_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
#define MVKLogDebugImpl(fmt, ...) reportMessage(MVK_CONFIG_LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
#define MVKLogTraceImpl(fmt, ...) reportMessage(MVK_CONFIG_LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
// Assertions // Assertions
#ifdef NS_BLOCK_ASSERTIONS #ifdef NS_BLOCK_ASSERTIONS