moltenvk/Common/MVKLogging.h
Bill Hollings 173d8cc5f3 Add support for the VK_EXT_debug_report extension.
Add MVKDebugReportCallback class.
Add MVKVulkanAPIObject class as base class of classes exposed in Vulkan API.
Remove MVKRefCountedDeviceObject class and move ref-counting to MVKVulkanAPIObject.
Rename MVKDispatchableObject class to MVKDispatchableVulkanAPIObject.
Introduce multiple inheritance mixin classes into class hierarchy.
Add MVKBaseObject::getVulkanAPIObject() function to find Vulkan API object
controlling any subobject that needs to report something.
MVKCommandResourceFactory functions pass in calling object for reporting.
Add MVKBaseObject::reportMessage() & reportError() functions.
Replace mvkNotifyErrorWithText() static function with reportError()
instance function to allow access to debug reporting.
Redefine MVKLog*() functions to call reportError() instance method.
Delete MVKLogging.cpp.
Remove MVKLogging.h from MoltenVKShaderConverter project.
Add mvk_datatypes.hpp to redirect errors in mvk_datatypes.h functions to debug
reporting. Use mvk_datatypes.hpp internally for all references to these functions.
Convert several static methods to instance methods.
Refactor platform defines in MVKSurface.h.
Explicitly count MVKExtensionList extension count to avoid relying on struct size.
Remove MVKCommandBuffer::recordResult() and use setConfigurationResult().
Change log indication of error in logs from [***MoltenVK ERROR***] to [mvk-error],
for consistency with other log level indications.
Update MoltenVK version to 1.0.35.
2019-05-01 22:27:03 -04:00

196 lines
7.9 KiB
C

/*
* MVKLogging.h
*
* Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <asl.h>
#include <stdbool.h>
/**
* This library adds flexible, non-intrusive logging and assertion capabilities
* that can be efficiently enabled or disabled via compiler switches.
*
* There are four levels of logging: Trace, Info, Error and Debug, and each can be enabled
* independently via the MVK_LOG_LEVEL_TRACE, MVK_LOG_LEVEL_INFO, MVK_LOG_LEVEL_ERROR and
* MVK_LOG_LEVEL_DEBUG switches, respectively.
*
* ALL logging can be enabled or disabled via the MVK_LOGGING_ENABLED switch.
*
* Each logging level also has a conditional logging variation, which outputs a log entry
* only if the specified conditional expression evaluates to YES.
*
* Logging functions are implemented here via macros. Disabling logging, either entirely, or
* at a specific level, completely removes the corresponding log invocations from the compiled
* code, thus eliminating both the memory and CPU overhead that the logging calls would add.
* You might choose, for example, to completely remove all logging from production release code,
* by setting MVK_LOGGING_ENABLED off in your production builds settings. Or, as another example,
* you might choose to include Error logging in your production builds by turning only
* MVK_LOGGING_ENABLED and MVK_LOG_LEVEL_ERROR on, and turning the others off.
*
* To perform logging, use any of the following function calls in your code:
*
* MVKLogError(fmt, ...) - recommended for use only when there is an error to be logged
* - will print if MVK_LOG_LEVEL_ERROR is set on.
* MVKLogErrorIf(cond, fmt, ...) - same as MVKLogError if boolean "cond" condition expression evaluates to YES,
* otherwise logs nothing.
*
* MVKLogInfo(fmt, ...) - recommended for general, infrequent, information messages
* - will print if MVK_LOG_LEVEL_INFO is set on.
* MVKLogInfoIf(cond, fmt, ...) - same as MVKLogInfo if boolean "cond" condition expression evaluates to YES,
* otherwise logs nothing.
*
* MVKLogDebug(fmt, ...) - recommended for temporary use during debugging
* - will print if MVK_LOG_LEVEL_DEBUG is set on.
* MVKLogDebugIf(cond, fmt, ...) - same as MVKLogDebug if boolean "cond" condition expression evaluates to YES,
* otherwise logs nothing.
*
* MVKLogTrace(fmt, ...) - recommended for detailed tracing of program flow
* - will print if MVK_LOG_LEVEL_TRACE is set on.
* MVKLogTraceIf(cond, fmt, ...) - same as MVKLogTrace if boolean "cond" condition expression evaluates to YES,
* otherwise logs nothing.
*
* In each case, the functions follow the general NSLog/printf template, where the first argument
* "fmt" is an NSString that optionally includes embedded Format Specifiers, and subsequent optional
* arguments indicate data to be formatted and inserted into the string. As with NSLog/printf, the number
* of optional arguments must match the number of embedded Format Specifiers. For more info, see the
* core documentation for NSLog and String Format Specifiers.
*
* This library also enchances the assertion functions.
*
* The MVKAssert() function can be used in place of the standard NSAssert() family of functions.
* MVKAssert() improves the NSAssert() family of functions in two ways:
* - MVKAssert ensures that the assertion message is logged to the console.
* - MVKAssert can be used with a variable number of arguments without the need for
* NSAssert1(), NSAssert2(), etc.
*
* Like the NSAssert() functions, you can turn assertions off in production code by either setting
* NS_BLOCK_ASSERTIONS to 1 in your compiler build settings, or setting the ENABLE_NS_ASSERTIONS
* compiler setting to 0. Doing so completely removes the corresponding assertion invocations
* from the compiled code, thus eliminating both the memory and CPU overhead that the assertion
* calls would add
*
* Although you can directly edit this file to turn on or off the switches below, the preferred
* technique is to set these switches via the compiler build setting GCC_PREPROCESSOR_DEFINITIONS
* in your build configuration.
*/
/**
* Set this switch to enable or disable logging capabilities. This can be set either here
* or via the compiler build setting GCC_PREPROCESSOR_DEFINITIONS in your build configuration.
* Using the compiler build setting is preferred for this to ensure that logging is not
* accidentally left enabled by accident in release builds.
*
* Logging is enabled by default.
*/
#ifndef MVK_LOGGING_ENABLED
# define MVK_LOGGING_ENABLED 1
#endif
/**
* Set any or all of these switches to enable or disable logging at specific levels.
* These can be set either here or as a compiler build settings.
*/
#ifndef MVK_LOG_LEVEL_ERROR
# define MVK_LOG_LEVEL_ERROR MVK_LOGGING_ENABLED
#endif
#ifndef MVK_LOG_LEVEL_INFO
# define MVK_LOG_LEVEL_INFO MVK_LOGGING_ENABLED
#endif
#ifndef MVK_LOG_LEVEL_DEBUG
# define MVK_LOG_LEVEL_DEBUG (MVK_LOGGING_ENABLED && MVK_DEBUG)
#endif
#ifndef MVK_LOG_LEVEL_TRACE
# define MVK_LOG_LEVEL_TRACE 0
#endif
// *********** END OF USER SETTINGS - Do not change anything below this line ***********
// Error logging - only when there is an error to be logged
#if MVK_LOG_LEVEL_ERROR
# define MVKLogError(fmt, ...) MVKLogErrorImpl(fmt, ##__VA_ARGS__)
# define MVKLogErrorIf(cond, fmt, ...) if(cond) { MVKLogErrorImpl(fmt, ##__VA_ARGS__); }
#else
# define MVKLogError(...)
# define MVKLogErrorIf(cond, fmt, ...)
#endif
// Info logging - for general, non-performance affecting information messages
#if MVK_LOG_LEVEL_INFO
# define MVKLogInfo(fmt, ...) MVKLogInfoImpl(fmt, ##__VA_ARGS__)
# define MVKLogInfoIf(cond, fmt, ...) if(cond) { MVKLogInfoImpl(fmt, ##__VA_ARGS__); }
#else
# define MVKLogInfo(...)
# define MVKLogInfoIf(cond, fmt, ...)
#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
#if MVK_LOG_LEVEL_DEBUG
# define MVKLogDebug(fmt, ...) MVKLogDebugImpl(fmt, ##__VA_ARGS__)
# define MVKLogDebugIf(cond, fmt, ...) if(cond) { MVKLogDebugImpl(fmt, ##__VA_ARGS__); }
#else
# define MVKLogDebug(...)
# define MVKLogDebugIf(cond, fmt, ...)
#endif
#define MVKLogErrorImpl(fmt, ...) reportMessage(ASL_LEVEL_ERR, fmt, ##__VA_ARGS__)
#define MVKLogInfoImpl(fmt, ...) reportMessage(ASL_LEVEL_NOTICE, fmt, ##__VA_ARGS__)
#define MVKLogTraceImpl(fmt, ...) reportMessage(ASL_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
#define MVKLogDebugImpl(fmt, ...) reportMessage(ASL_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
// Assertions
#ifdef NS_BLOCK_ASSERTIONS
# define MVK_BLOCK_ASSERTIONS 1
#else
# define MVK_BLOCK_ASSERTIONS 0
#endif
#define MVKAssert(test, fmt, ...) \
do { \
bool isErr = !(test); \
MVKLogErrorIf(isErr, fmt, ##__VA_ARGS__); \
assert(!isErr || MVK_BLOCK_ASSERTIONS); \
} while(0)
// Use this macro to open a break-point programmatically.
#ifndef MVK_DEBUGGER
# define MVK_DEBUGGER() { kill( getpid(), SIGINT ) ; }
#endif
#ifdef __cplusplus
}
#endif // __cplusplus