Log: Add fmt overloads

This commit is contained in:
Stenzek 2023-09-21 00:11:55 +10:00
parent ac0601f408
commit 92440bdfcf
8 changed files with 145 additions and 126 deletions

View file

@ -6,6 +6,9 @@
#include "file_system.h" #include "file_system.h"
#include "small_string.h" #include "small_string.h"
#include "timer.h" #include "timer.h"
#include "fmt/format.h"
#include <cstdio> #include <cstdio>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@ -18,13 +21,13 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
namespace Log { using namespace std::string_view_literals;
static const char s_log_level_characters[LOGLEVEL_COUNT] = {'X', 'E', 'W', 'P', 'I', 'V', 'D', 'R', 'B', 'T'}; static const char s_log_level_characters[LOGLEVEL_COUNT] = {'X', 'E', 'W', 'P', 'I', 'V', 'D', 'R', 'B', 'T'};
struct RegisteredCallback struct RegisteredCallback
{ {
CallbackFunctionType Function; Log::CallbackFunctionType Function;
void* Parameter; void* Parameter;
}; };
@ -60,7 +63,7 @@ std::unique_ptr<std::FILE, void (*)(std::FILE*)> s_fileOutputHandle(nullptr, [](
} }
}); });
void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam) void Log::RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam)
{ {
RegisteredCallback Callback; RegisteredCallback Callback;
Callback.Function = callbackFunction; Callback.Function = callbackFunction;
@ -70,7 +73,7 @@ void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam)
s_callbacks.push_back(std::move(Callback)); s_callbacks.push_back(std::move(Callback));
} }
void UnregisterCallback(CallbackFunctionType callbackFunction, void* pUserParam) void Log::UnregisterCallback(CallbackFunctionType callbackFunction, void* pUserParam)
{ {
std::lock_guard<std::mutex> guard(s_callback_mutex); std::lock_guard<std::mutex> guard(s_callback_mutex);
@ -84,43 +87,47 @@ void UnregisterCallback(CallbackFunctionType callbackFunction, void* pUserParam)
} }
} }
bool IsConsoleOutputEnabled() bool Log::IsConsoleOutputEnabled()
{ {
return s_console_output_enabled; return s_console_output_enabled;
} }
bool IsDebugOutputEnabled() bool Log::IsDebugOutputEnabled()
{ {
return s_debug_output_enabled; return s_debug_output_enabled;
} }
static void ExecuteCallbacks(const char* channelName, const char* functionName, LOGLEVEL level, const char* message) static void ExecuteCallbacks(const char* channelName, const char* functionName, LOGLEVEL level,
std::string_view message)
{ {
std::lock_guard<std::mutex> guard(s_callback_mutex); std::lock_guard<std::mutex> guard(s_callback_mutex);
for (RegisteredCallback& callback : s_callbacks) for (RegisteredCallback& callback : s_callbacks)
callback.Function(callback.Parameter, channelName, functionName, level, message); callback.Function(callback.Parameter, channelName, functionName, level, message);
} }
static int FormatLogMessageForDisplay(char* buffer, size_t buffer_size, const char* channelName, ALWAYS_INLINE_RELEASE static void FormatLogMessageForDisplay(fmt::memory_buffer& buffer, const char* channelName,
const char* functionName, LOGLEVEL level, const char* message, bool timestamp, const char* functionName, LOGLEVEL level,
bool ansi_color_code, bool newline) std::string_view message, bool timestamp,
bool ansi_color_code, bool newline)
{ {
static const char* s_ansi_color_codes[LOGLEVEL_COUNT] = { static constexpr std::string_view s_ansi_color_codes[LOGLEVEL_COUNT] = {
"\033[0m", // NONE "\033[0m"sv, // NONE
"\033[1;31m", // ERROR "\033[1;31m"sv, // ERROR
"\033[1;33m", // WARNING "\033[1;33m"sv, // WARNING
"\033[1;35m", // PERF "\033[1;35m"sv, // PERF
"\033[1;37m", // INFO "\033[1;37m"sv, // INFO
"\033[1;32m", // VERBOSE "\033[1;32m"sv, // VERBOSE
"\033[0;37m", // DEV "\033[0;37m"sv, // DEV
"\033[1;36m", // PROFILE "\033[1;36m"sv, // PROFILE
"\033[0;32m", // DEBUG "\033[0;32m"sv, // DEBUG
"\033[0;34m", // TRACE "\033[0;34m"sv, // TRACE
}; };
const char* color_start = ansi_color_code ? s_ansi_color_codes[level] : ""; std::string_view color_start = ansi_color_code ? s_ansi_color_codes[level] : ""sv;
const char* color_end = ansi_color_code ? s_ansi_color_codes[0] : ""; std::string_view color_end = ansi_color_code ? s_ansi_color_codes[0] : ""sv;
const char* message_end = newline ? "\n" : ""; std::string_view message_end = newline ? "\n"sv : ""sv;
auto appender = std::back_inserter(buffer);
if (timestamp) if (timestamp)
{ {
@ -130,97 +137,71 @@ static int FormatLogMessageForDisplay(char* buffer, size_t buffer_size, const ch
if (level <= LOGLEVEL_PERF) if (level <= LOGLEVEL_PERF)
{ {
return std::snprintf(buffer, buffer_size, "[%10.4f] %s%c(%s): %s%s%s", message_time, color_start, fmt::format_to(appender, "[{:10.4f}] {}{}({}): {}{}{}", message_time, color_start, s_log_level_characters[level],
s_log_level_characters[level], functionName, message, color_end, message_end); functionName, message, color_end, message_end);
} }
else else
{ {
return std::snprintf(buffer, buffer_size, "[%10.4f] %s%c/%s: %s%s%s", message_time, color_start, fmt::format_to(appender, "[{:10.4f}] {}{}/{}: {}{}{}", message_time, color_start, s_log_level_characters[level],
s_log_level_characters[level], channelName, message, color_end, message_end); channelName, message, color_end, message_end);
} }
} }
else else
{ {
if (level <= LOGLEVEL_PERF) if (level <= LOGLEVEL_PERF)
{ {
return std::snprintf(buffer, buffer_size, "%s%c(%s): %s%s%s", color_start, s_log_level_characters[level], fmt::format_to(appender, "{}{}({}): {}{}{}", color_start, s_log_level_characters[level], functionName, message,
functionName, message, color_end, message_end); color_end, message_end);
} }
else else
{ {
return std::snprintf(buffer, buffer_size, "%s%c/%s: %s%s%s", color_start, s_log_level_characters[level], fmt::format_to(appender, "{}{}/{}: {}{}{}", color_start, s_log_level_characters[level], channelName, message,
channelName, message, color_end, message_end); color_end, message_end);
} }
} }
} }
template<typename T> template<typename T>
static ALWAYS_INLINE void FormatLogMessageAndPrint(const char* channelName, const char* functionName, LOGLEVEL level, ALWAYS_INLINE_RELEASE static void FormatLogMessageAndPrint(const char* channelName, const char* functionName,
const char* message, bool timestamp, bool ansi_color_code, LOGLEVEL level, std::string_view message, bool timestamp,
bool newline, const T& callback) bool ansi_color_code, bool newline, const T& callback)
{ {
char buf[512]; fmt::memory_buffer buffer;
char* message_buf = buf; FormatLogMessageForDisplay(buffer, channelName, functionName, level, message, timestamp, ansi_color_code, newline);
int message_len; callback(std::string_view(buffer.data(), buffer.size()));
if ((message_len = FormatLogMessageForDisplay(message_buf, sizeof(buf), channelName, functionName, level, message,
timestamp, ansi_color_code, newline)) >
static_cast<int>(sizeof(buf) - 1))
{
message_buf = static_cast<char*>(std::malloc(message_len + 1));
message_len = FormatLogMessageForDisplay(message_buf, message_len + 1, channelName, functionName, level, message,
timestamp, ansi_color_code, newline);
}
callback(message_buf, message_len);
if (message_buf != buf)
std::free(message_buf);
} }
#ifdef _WIN32 #ifdef _WIN32
template<typename T> template<typename T>
static ALWAYS_INLINE void FormatLogMessageAndPrintW(const char* channelName, const char* functionName, LOGLEVEL level, ALWAYS_INLINE_RELEASE static void FormatLogMessageAndPrintW(const char* channelName, const char* functionName,
const char* message, bool timestamp, bool ansi_color_code, LOGLEVEL level, std::string_view message, bool timestamp,
bool newline, const T& callback) bool ansi_color_code, bool newline, const T& callback)
{ {
char buf[512]; fmt::memory_buffer buffer;
char* message_buf = buf; FormatLogMessageForDisplay(buffer, channelName, functionName, level, message, timestamp, ansi_color_code, newline);
int message_len;
if ((message_len = FormatLogMessageForDisplay(message_buf, sizeof(buf), channelName, functionName, level, message,
timestamp, ansi_color_code, newline)) >
static_cast<int>(sizeof(buf) - 1))
{
message_buf = static_cast<char*>(std::malloc(message_len + 1));
message_len = FormatLogMessageForDisplay(message_buf, message_len + 1, channelName, functionName, level, message,
timestamp, ansi_color_code, newline);
}
if (message_len <= 0)
return;
// Convert to UTF-16 first so unicode characters display correctly. NT is going to do it // Convert to UTF-16 first so unicode characters display correctly. NT is going to do it
// anyway... // anyway...
wchar_t wbuf[512]; wchar_t wbuf[512];
wchar_t* wmessage_buf = wbuf; wchar_t* wmessage_buf = wbuf;
int wmessage_buflen = static_cast<int>(std::size(wbuf) - 1); int wmessage_buflen = static_cast<int>(std::size(wbuf) - 1);
if (message_len >= static_cast<int>(std::size(wbuf))) if (buffer.size() >= std::size(wbuf))
{ {
wmessage_buflen = message_len; wmessage_buflen = static_cast<int>(buffer.size());
wmessage_buf = static_cast<wchar_t*>(std::malloc((wmessage_buflen + 1) * sizeof(wchar_t))); wmessage_buf = static_cast<wchar_t*>(std::malloc((buffer.size() + 1) * sizeof(wchar_t)));
} }
wmessage_buflen = MultiByteToWideChar(CP_UTF8, 0, message_buf, message_len, wmessage_buf, wmessage_buflen); wmessage_buflen =
MultiByteToWideChar(CP_UTF8, 0, buffer.data(), static_cast<int>(buffer.size()), wmessage_buf, wmessage_buflen);
if (wmessage_buflen <= 0) if (wmessage_buflen <= 0)
return; return;
wmessage_buf[wmessage_buflen] = '\0'; wmessage_buf[wmessage_buflen] = '\0';
callback(wmessage_buf, wmessage_buflen); callback(std::wstring_view(wmessage_buf, wmessage_buflen));
if (wmessage_buf != wbuf) if (wmessage_buf != wbuf)
std::free(wmessage_buf); std::free(wmessage_buf);
if (message_buf != buf)
std::free(message_buf);
} }
static bool EnableVirtualTerminalProcessing(HANDLE hConsole) static bool EnableVirtualTerminalProcessing(HANDLE hConsole)
@ -239,7 +220,7 @@ static bool EnableVirtualTerminalProcessing(HANDLE hConsole)
#endif #endif
static void ConsoleOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, static void ConsoleOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName,
LOGLEVEL level, const char* message) LOGLEVEL level, std::string_view message)
{ {
if (!s_console_output_enabled || level > s_console_output_level_filter || if (!s_console_output_enabled || level > s_console_output_level_filter ||
s_console_output_channel_filter.find(channelName) != std::string::npos) s_console_output_channel_filter.find(channelName) != std::string::npos)
@ -248,23 +229,23 @@ static void ConsoleOutputLogCallback(void* pUserParam, const char* channelName,
} }
#if defined(_WIN32) #if defined(_WIN32)
FormatLogMessageAndPrintW(channelName, functionName, level, message, true, true, true, FormatLogMessageAndPrintW(
[level](const wchar_t* message, int message_len) { channelName, functionName, level, message, true, true, true, [level](const std::wstring_view& message) {
HANDLE hOutput = (level <= LOGLEVEL_WARNING) ? s_hConsoleStdErr : s_hConsoleStdOut; HANDLE hOutput = (level <= LOGLEVEL_WARNING) ? s_hConsoleStdErr : s_hConsoleStdOut;
DWORD chars_written; DWORD chars_written;
WriteConsoleW(hOutput, message, message_len, &chars_written, nullptr); WriteConsoleW(hOutput, message.data(), static_cast<DWORD>(message.length()), &chars_written, nullptr);
}); });
#elif !defined(__ANDROID__) #elif !defined(__ANDROID__)
FormatLogMessageAndPrint(channelName, functionName, level, message, true, true, true, FormatLogMessageAndPrint(channelName, functionName, level, message, true, true, true,
[level](const char* message, int message_len) { [level](const std::string_view& message) {
const int outputFd = (level <= LOGLEVEL_WARNING) ? STDERR_FILENO : STDOUT_FILENO; const int outputFd = (level <= LOGLEVEL_WARNING) ? STDERR_FILENO : STDOUT_FILENO;
write(outputFd, message, message_len); write(outputFd, message.data(), message.length());
}); });
#endif #endif
} }
static void DebugOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level, static void DebugOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level,
const char* message) std::string_view message)
{ {
if (!s_debug_output_enabled || level > s_debug_output_level_filter || if (!s_debug_output_enabled || level > s_debug_output_level_filter ||
s_debug_output_channel_filter.find(functionName) != std::string::npos) s_debug_output_channel_filter.find(functionName) != std::string::npos)
@ -274,7 +255,7 @@ static void DebugOutputLogCallback(void* pUserParam, const char* channelName, co
#if defined(_WIN32) #if defined(_WIN32)
FormatLogMessageAndPrintW(channelName, functionName, level, message, true, false, true, FormatLogMessageAndPrintW(channelName, functionName, level, message, true, false, true,
[](const wchar_t* message, int message_len) { OutputDebugStringW(message); }); [](const std::wstring_view& message) { OutputDebugStringW(message.data()); });
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
static const int logPriority[LOGLEVEL_COUNT] = { static const int logPriority[LOGLEVEL_COUNT] = {
ANDROID_LOG_INFO, // NONE ANDROID_LOG_INFO, // NONE
@ -294,7 +275,7 @@ static void DebugOutputLogCallback(void* pUserParam, const char* channelName, co
#endif #endif
} }
void SetConsoleOutputParams(bool Enabled, const char* ChannelFilter, LOGLEVEL LevelFilter) void Log::SetConsoleOutputParams(bool Enabled, const char* ChannelFilter, LOGLEVEL LevelFilter)
{ {
s_console_output_channel_filter = (ChannelFilter != NULL) ? ChannelFilter : ""; s_console_output_channel_filter = (ChannelFilter != NULL) ? ChannelFilter : "";
s_console_output_level_filter = LevelFilter; s_console_output_level_filter = LevelFilter;
@ -374,8 +355,8 @@ void SetConsoleOutputParams(bool Enabled, const char* ChannelFilter, LOGLEVEL Le
UnregisterCallback(ConsoleOutputLogCallback, nullptr); UnregisterCallback(ConsoleOutputLogCallback, nullptr);
} }
void SetDebugOutputParams(bool enabled, const char* channelFilter /* = nullptr */, void Log::SetDebugOutputParams(bool enabled, const char* channelFilter /* = nullptr */,
LOGLEVEL levelFilter /* = LOGLEVEL_TRACE */) LOGLEVEL levelFilter /* = LOGLEVEL_TRACE */)
{ {
if (s_debug_output_enabled != enabled) if (s_debug_output_enabled != enabled)
{ {
@ -391,18 +372,18 @@ void SetDebugOutputParams(bool enabled, const char* channelFilter /* = nullptr *
} }
static void FileOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level, static void FileOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level,
const char* message) std::string_view message)
{ {
if (level > s_file_output_level_filter || s_file_output_channel_filter.find(channelName) != std::string::npos) if (level > s_file_output_level_filter || s_file_output_channel_filter.find(channelName) != std::string::npos)
return; return;
FormatLogMessageAndPrint( FormatLogMessageAndPrint(
channelName, functionName, level, message, true, false, true, channelName, functionName, level, message, true, false, true,
[](const char* message, int message_len) { std::fwrite(message, 1, message_len, s_fileOutputHandle.get()); }); [](const std::string_view& message) { std::fwrite(message.data(), 1, message.size(), s_fileOutputHandle.get()); });
} }
void SetFileOutputParams(bool enabled, const char* filename, bool timestamps /* = true */, void Log::SetFileOutputParams(bool enabled, const char* filename, bool timestamps /* = true */,
const char* channelFilter /* = nullptr */, LOGLEVEL levelFilter /* = LOGLEVEL_TRACE */) const char* channelFilter /* = nullptr */, LOGLEVEL levelFilter /* = LOGLEVEL_TRACE */)
{ {
if (s_file_output_enabled != enabled) if (s_file_output_enabled != enabled)
{ {
@ -432,13 +413,13 @@ void SetFileOutputParams(bool enabled, const char* filename, bool timestamps /*
s_file_output_timestamp = timestamps; s_file_output_timestamp = timestamps;
} }
void SetFilterLevel(LOGLEVEL level) void Log::SetFilterLevel(LOGLEVEL level)
{ {
DebugAssert(level < LOGLEVEL_COUNT); DebugAssert(level < LOGLEVEL_COUNT);
s_filter_level = level; s_filter_level = level;
} }
void Write(const char* channelName, const char* functionName, LOGLEVEL level, const char* message) void Log::Write(const char* channelName, const char* functionName, LOGLEVEL level, std::string_view message)
{ {
if (level > s_filter_level) if (level > s_filter_level)
return; return;
@ -446,7 +427,7 @@ void Write(const char* channelName, const char* functionName, LOGLEVEL level, co
ExecuteCallbacks(channelName, functionName, level, message); ExecuteCallbacks(channelName, functionName, level, message);
} }
void Writef(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, ...) void Log::Writef(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, ...)
{ {
if (level > s_filter_level) if (level > s_filter_level)
return; return;
@ -457,7 +438,7 @@ void Writef(const char* channelName, const char* functionName, LOGLEVEL level, c
va_end(ap); va_end(ap);
} }
void Writev(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, va_list ap) void Log::Writev(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, va_list ap)
{ {
if (level > s_filter_level) if (level > s_filter_level)
return; return;
@ -487,4 +468,14 @@ void Writev(const char* channelName, const char* functionName, LOGLEVEL level, c
} }
} }
} // namespace Log void Log::WriteFmtArgs(const char* channelName, const char* functionName, LOGLEVEL level, fmt::string_view fmt,
fmt::format_args args)
{
if (level > s_filter_level)
return;
fmt::memory_buffer buffer;
fmt::vformat_to(std::back_inserter(buffer), fmt, args);
ExecuteCallbacks(channelName, functionName, level, std::string_view(buffer.data(), buffer.size()));
}

View file

@ -1,11 +1,16 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once #pragma once
#include "types.h" #include "types.h"
#include "fmt/core.h"
#include <cinttypes> #include <cinttypes>
#include <cstdarg> #include <cstdarg>
#include <mutex> #include <mutex>
#include <string_view>
enum LOGLEVEL enum LOGLEVEL
{ {
@ -25,7 +30,7 @@ enum LOGLEVEL
namespace Log { namespace Log {
// log message callback type // log message callback type
using CallbackFunctionType = void (*)(void* pUserParam, const char* channelName, const char* functionName, using CallbackFunctionType = void (*)(void* pUserParam, const char* channelName, const char* functionName,
LOGLEVEL level, const char* message); LOGLEVEL level, std::string_view message);
// registers a log callback // registers a log callback
void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam); void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam);
@ -49,33 +54,52 @@ void SetFileOutputParams(bool enabled, const char* filename, bool timestamps = t
void SetFilterLevel(LOGLEVEL level); void SetFilterLevel(LOGLEVEL level);
// writes a message to the log // writes a message to the log
void Write(const char* channelName, const char* functionName, LOGLEVEL level, const char* message); void Write(const char* channelName, const char* functionName, LOGLEVEL level, std::string_view message);
void Writef(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, ...) printflike(4, 5); void Writef(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, ...)
printflike(4, 5);
void Writev(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, va_list ap); void Writev(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, va_list ap);
void WriteFmtArgs(const char* channelName, const char* functionName, LOGLEVEL level, fmt::string_view fmt,
fmt::format_args args);
template<typename... T>
ALWAYS_INLINE static void WriteFmt(const char* channelName, const char* functionName, LOGLEVEL level,
fmt::format_string<T...> fmt, T&&... args)
{
return WriteFmtArgs(channelName, functionName, level, fmt, fmt::make_format_args(args...));
}
} // namespace Log } // namespace Log
// log wrappers // log wrappers
#define Log_SetChannel(ChannelName) static const char* ___LogChannel___ = #ChannelName; #define Log_SetChannel(ChannelName) static const char* ___LogChannel___ = #ChannelName;
#define Log_ErrorPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_ERROR, msg) #define Log_ErrorPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_ERROR, msg)
#define Log_ErrorPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_ERROR, __VA_ARGS__) #define Log_ErrorPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_ERROR, __VA_ARGS__)
#define Log_ErrorFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_ERROR, __VA_ARGS__)
#define Log_WarningPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_WARNING, msg) #define Log_WarningPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_WARNING, msg)
#define Log_WarningPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_WARNING, __VA_ARGS__) #define Log_WarningPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_WARNING, __VA_ARGS__)
#define Log_WarningFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_WARNING, __VA_ARGS__)
#define Log_PerfPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_PERF, msg) #define Log_PerfPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_PERF, msg)
#define Log_PerfPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_PERF, __VA_ARGS__) #define Log_PerfPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_PERF, __VA_ARGS__)
#define Log_PerfFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_PERF, __VA_ARGS__)
#define Log_InfoPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_INFO, msg) #define Log_InfoPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_INFO, msg)
#define Log_InfoPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_INFO, __VA_ARGS__) #define Log_InfoPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_INFO, __VA_ARGS__)
#define Log_InfoFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_INFO, __VA_ARGS__)
#define Log_VerbosePrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_VERBOSE, msg) #define Log_VerbosePrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_VERBOSE, msg)
#define Log_VerbosePrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_VERBOSE, __VA_ARGS__) #define Log_VerbosePrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_VERBOSE, __VA_ARGS__)
#define Log_VerboseFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_VERBOSE, __VA_ARGS__)
#define Log_DevPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_DEV, msg) #define Log_DevPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_DEV, msg)
#define Log_DevPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_DEV, __VA_ARGS__) #define Log_DevPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_DEV, __VA_ARGS__)
#define Log_DevFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_DEV, __VA_ARGS__)
#define Log_ProfilePrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_PROFILE, msg) #define Log_ProfilePrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_PROFILE, msg)
#define Log_ProfilePrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_PROFILE, __VA_ARGS__) #define Log_ProfilePrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_PROFILE, __VA_ARGS__)
#define Log_ProfileFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_PROFILE, __VA_ARGS__)
#ifdef _DEBUG #ifdef _DEBUG
#define Log_DebugPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_DEBUG, msg) #define Log_DebugPrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_DEBUG, msg)
#define Log_DebugPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_DEBUG, __VA_ARGS__) #define Log_DebugPrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_DEBUG, __VA_ARGS__)
#define Log_DebugFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_DEBUG, __VA_ARGS__)
#define Log_TracePrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_TRACE, msg) #define Log_TracePrint(msg) Log::Write(___LogChannel___, __func__, LOGLEVEL_TRACE, msg)
#define Log_TracePrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_TRACE, __VA_ARGS__) #define Log_TracePrintf(...) Log::Writef(___LogChannel___, __func__, LOGLEVEL_TRACE, __VA_ARGS__)
#define Log_TraceFmt(...) Log::WriteFmt(___LogChannel___, __func__, LOGLEVEL_TRACE, __VA_ARGS__)
#else #else
#define Log_DebugPrint(msg) \ #define Log_DebugPrint(msg) \
do \ do \
@ -85,6 +109,10 @@ void Writev(const char* channelName, const char* functionName, LOGLEVEL level, c
do \ do \
{ \ { \
} while (0) } while (0)
#define Log_DebugFmt(...) \
do \
{ \
} while (0)
#define Log_TracePrint(msg) \ #define Log_TracePrint(msg) \
do \ do \
{ \ { \
@ -93,4 +121,8 @@ void Writev(const char* channelName, const char* functionName, LOGLEVEL level, c
do \ do \
{ \ { \
} while (0) } while (0)
#define Log_TraceFmt(...) \
do \
{ \
} while (0)
#endif #endif

View file

@ -616,7 +616,7 @@ void Achievements::ClientServerCall(const rc_api_request_t* request, rc_client_s
if (request->post_data) if (request->post_data)
{ {
// const auto pd = std::string_view(request->post_data); // const auto pd = std::string_view(request->post_data);
// Log_DevPrint(fmt::format("Server POST: {}", pd.substr(0, std::min<size_t>(pd.length(), 10))).c_str()); // Log_DevFmt("Server POST: {}", pd.substr(0, std::min<size_t>(pd.length(), 10)));
http->CreatePostRequest(request->url, request->post_data, std::move(hd_callback)); http->CreatePostRequest(request->url, request->post_data, std::move(hd_callback));
} }
else else

View file

@ -258,7 +258,7 @@ Microsoft::WRL::ComPtr<IDXGIAdapter1> D3DCommon::GetAdapterByName(IDXGIFactory5*
adapter_names.push_back(std::move(adapter_name)); adapter_names.push_back(std::move(adapter_name));
} }
Log_ErrorPrintf(fmt::format("Adapter '{}' not found.", name).c_str()); Log_ErrorFmt("Adapter '{}' not found.", name);
return {}; return {};
} }

View file

@ -142,7 +142,7 @@ bool MetalDevice::CreateDevice(const std::string_view& adapter, bool threaded_pr
} }
if (device == nil) if (device == nil)
Log_ErrorPrint(fmt::format("Failed to find device named '{}'. Trying default.", adapter).c_str()); Log_ErrorFmt("Failed to find device named '{}'. Trying default.", adapter);
} }
if (device == nil) if (device == nil)

View file

@ -401,7 +401,7 @@ std::unique_ptr<PostProcessing::Shader> PostProcessing::TryLoadingShader(const s
return shader; return shader;
} }
Log_ErrorPrint(fmt::format("Failed to load shader '{}'", shader_name).c_str()); Log_ErrorFmt("Failed to load shader '{}'", shader_name);
return {}; return {};
} }
@ -611,7 +611,7 @@ GPUSampler* PostProcessing::GetSampler(const GPUSampler::Config& config)
std::unique_ptr<GPUSampler> sampler = g_gpu_device->CreateSampler(config); std::unique_ptr<GPUSampler> sampler = g_gpu_device->CreateSampler(config);
if (!sampler) if (!sampler)
Log_ErrorPrint(fmt::format("Failed to create GPU sampler with config={:X}", config.key).c_str()); Log_ErrorFmt("Failed to create GPU sampler with config={:X}", config.key);
it = s_samplers.emplace(config.key, std::move(sampler)).first; it = s_samplers.emplace(config.key, std::move(sampler)).first;
return it->second.get(); return it->second.get();

View file

@ -448,9 +448,8 @@ GetVectorAnnotationValue(const reshadefx::uniform_info& uniform, const std::stri
} }
else else
{ {
Log_ErrorPrint(fmt::format("Unhandled string value for '{}' (annotation type: {}, uniform type {})", Log_ErrorFmt("Unhandled string value for '{}' (annotation type: {}, uniform type {})", uniform.name,
uniform.name, an.type.description(), uniform.type.description()) an.type.description(), uniform.type.description());
.c_str());
} }
break; break;
@ -499,7 +498,7 @@ bool PostProcessing::ReShadeFXShader::CreateOptions(const reshadefx::module& mod
return false; return false;
if (so != SourceOptionType::None) if (so != SourceOptionType::None)
{ {
Log_DevPrintf("Add source based option %u at offset %u (%s)", static_cast<u32>(so), ui.offset, ui.name.c_str()); Log_DevFmt("Add source based option {} at offset {} ({})", static_cast<u32>(so), ui.offset, ui.name);
SourceOption sopt; SourceOption sopt;
sopt.source = so; sopt.source = so;
@ -758,15 +757,14 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
if (!ti.semantic.empty()) if (!ti.semantic.empty())
{ {
Log_DevPrint(fmt::format("Ignoring semantic {} texture {}", ti.semantic, ti.unique_name).c_str()); Log_DevFmt("Ignoring semantic {} texture {}", ti.semantic, ti.unique_name);
continue; continue;
} }
if (ti.render_target) if (ti.render_target)
{ {
tex.rt_scale = 1.0f; tex.rt_scale = 1.0f;
tex.format = MapTextureFormat(ti.format); tex.format = MapTextureFormat(ti.format);
Log_DevPrint( Log_DevFmt("Creating render target '{}' {}", ti.unique_name, GPUTexture::GetFormatName(tex.format));
fmt::format("Creating render target '{}' {}", ti.unique_name, GPUTexture::GetFormatName(tex.format)).c_str());
} }
else else
{ {
@ -796,7 +794,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
return false; return false;
} }
Log_DevPrint(fmt::format("Loaded {}x{} texture ({})", image.GetWidth(), image.GetHeight(), source).c_str()); Log_DevFmt("Loaded {}x{} texture ({})", image.GetWidth(), image.GetHeight(), source);
} }
tex.reshade_name = ti.unique_name; tex.reshade_name = ti.unique_name;
@ -863,9 +861,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
} }
else if (ti.semantic == "DEPTH") else if (ti.semantic == "DEPTH")
{ {
Log_WarningPrint( Log_WarningFmt("Shader '{}' uses input depth as '{}' which is not supported.", m_name, si.texture_name);
fmt::format("Shader '{}' uses input depth as '{}' which is not supported.", m_name, si.texture_name)
.c_str());
sampler.texture_id = INPUT_DEPTH_TEXTURE; sampler.texture_id = INPUT_DEPTH_TEXTURE;
break; break;
} }
@ -896,7 +892,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
return false; return false;
} }
Log_DevPrint(fmt::format("Pass {} Texture {} => {}", pi.name, si.texture_name, sampler.texture_id).c_str()); Log_DevFmt("Pass {} Texture {} => {}", pi.name, si.texture_name, sampler.texture_id);
sampler.sampler = GetSampler(MapSampler(si)); sampler.sampler = GetSampler(MapSampler(si));
if (!sampler.sampler) if (!sampler.sampler)

View file

@ -1557,12 +1557,12 @@ bool VulkanDevice::IsSuitableDefaultRenderer()
// Check the first GPU, should be enough. // Check the first GPU, should be enough.
const std::string& name = aml.adapter_names.front(); const std::string& name = aml.adapter_names.front();
Log_InfoPrintf(fmt::format("Using Vulkan GPU '{}' for automatic renderer check.", name).c_str()); Log_InfoFmt("Using Vulkan GPU '{}' for automatic renderer check.", name);
// Any software rendering (LLVMpipe, SwiftShader). // Any software rendering (LLVMpipe, SwiftShader).
if (StringUtil::StartsWithNoCase(name, "llvmpipe") || StringUtil::StartsWithNoCase(name, "SwiftShader")) if (StringUtil::StartsWithNoCase(name, "llvmpipe") || StringUtil::StartsWithNoCase(name, "SwiftShader"))
{ {
Log_InfoPrintf("Not using Vulkan for software renderer."); Log_InfoPrint("Not using Vulkan for software renderer.");
return false; return false;
} }
@ -1570,11 +1570,11 @@ bool VulkanDevice::IsSuitableDefaultRenderer()
// Plus, the Ivy Bridge and Haswell drivers are incomplete. // Plus, the Ivy Bridge and Haswell drivers are incomplete.
if (StringUtil::StartsWithNoCase(name, "Intel")) if (StringUtil::StartsWithNoCase(name, "Intel"))
{ {
Log_InfoPrintf("Not using Vulkan for Intel GPU."); Log_InfoPrint("Not using Vulkan for Intel GPU.");
return false; return false;
} }
Log_InfoPrintf("Allowing Vulkan as default renderer."); Log_InfoPrint("Allowing Vulkan as default renderer.");
return true; return true;
#endif #endif
} }
@ -1640,7 +1640,7 @@ bool VulkanDevice::CreateDevice(const std::string_view& adapter, bool threaded_p
u32 gpu_index = 0; u32 gpu_index = 0;
for (; gpu_index < static_cast<u32>(gpus.size()); gpu_index++) for (; gpu_index < static_cast<u32>(gpus.size()); gpu_index++)
{ {
Log_InfoPrint(fmt::format("GPU {}: {}", gpu_index, gpus[gpu_index].second).c_str()); Log_InfoFmt("GPU {}: {}", gpu_index, gpus[gpu_index].second);
if (gpus[gpu_index].second == adapter) if (gpus[gpu_index].second == adapter)
{ {
m_physical_device = gpus[gpu_index].first; m_physical_device = gpus[gpu_index].first;
@ -1650,13 +1650,13 @@ bool VulkanDevice::CreateDevice(const std::string_view& adapter, bool threaded_p
if (gpu_index == static_cast<u32>(gpus.size())) if (gpu_index == static_cast<u32>(gpus.size()))
{ {
Log_WarningPrint(fmt::format("Requested GPU '{}' not found, using first ({})", adapter, gpus[0].second).c_str()); Log_WarningFmt("Requested GPU '{}' not found, using first ({})", adapter, gpus[0].second);
m_physical_device = gpus[0].first; m_physical_device = gpus[0].first;
} }
} }
else else
{ {
Log_InfoPrint(fmt::format("No GPU requested, using first ({})", gpus[0].second).c_str()); Log_InfoFmt("No GPU requested, using first ({})", gpus[0].second);
m_physical_device = gpus[0].first; m_physical_device = gpus[0].first;
} }