• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Razakhel / RaZ / 18064138724

27 Sep 2025 04:20PM UTC coverage: 74.093% (+0.04%) from 74.05%
18064138724

push

github

Razakhel
[Utils/Logger] Added formatted logging overloads

- Formatted calls to logging functions and made use of std::format() in several other places

100 of 170 new or added lines in 36 files covered. (58.82%)

4 existing lines in 2 files now uncovered.

8334 of 11248 relevant lines covered (74.09%)

1757.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/RaZ/XR/XrContext.cpp
1
#include "RaZ/Utils/Logger.hpp"
2
#include "RaZ/XR/XrContext.hpp"
3

4
#if defined(XR_OS_WINDOWS)
5
#define WIN32_LEAN_AND_MEAN
6
#include <Windows.h>
7
#include <Unknwn.h>
8
#elif defined(XR_OS_LINUX)
9
#include "GL/glx.h"
10
#endif
11

12
#include "openxr/openxr.h"
13
#include "openxr/openxr_platform.h"
14

15
#include "tracy/Tracy.hpp"
16

17
#include <algorithm>
18
#include <array>
19
#include <stdexcept>
20
#include <string>
21

22
namespace Raz {
23

24
namespace {
25

26
const char* getResultStr(XrInstance instance, XrResult result) {
×
27
  static std::array<char, XR_MAX_RESULT_STRING_SIZE> errorStr {};
28
  xrResultToString(instance, result, errorStr.data());
×
29
  return errorStr.data();
×
30
}
31

32
std::string getErrorStr(const std::string& errorMsg, XrResult result, XrInstance instance) {
×
NEW
33
  return std::format("[XrContext] {}: {} ({})", errorMsg, getResultStr(instance, result), static_cast<int>(result));
×
34
}
35

36
void checkLog(XrResult result, const std::string& errorMsg, XrInstance instance) {
×
37
  if (XR_SUCCEEDED(result))
×
38
    return;
×
39

40
  Logger::error(getErrorStr(errorMsg, result, instance));
×
41
}
42

43
void checkThrow(XrResult result, const std::string& errorMsg, XrInstance instance) {
×
44
  if (XR_SUCCEEDED(result))
×
45
    return;
×
46

47
  throw std::runtime_error(getErrorStr(errorMsg, result, instance));
×
48
}
49

50
XrBool32 logCallback(XrDebugUtilsMessageSeverityFlagsEXT severity,
×
51
                     XrDebugUtilsMessageTypeFlagsEXT type,
52
                     const XrDebugUtilsMessengerCallbackDataEXT* callbackData,
53
                     void* /* userData */) {
54
  std::string severityStr;
×
55
  LoggingLevel logLevel = LoggingLevel::INFO;
×
56

57
  if (severity & XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
×
58
    severityStr += "INFO";
×
59

60
  if (severity & XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
×
61
    if (!severityStr.empty())
×
62
      severityStr += ',';
×
63
    severityStr += "WARN";
×
64

65
    logLevel = LoggingLevel::WARNING;
×
66
  }
67

68
  if (severity & XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
×
69
    if (!severityStr.empty())
×
70
      severityStr += ',';
×
71
    severityStr += "ERROR";
×
72

73
    logLevel = LoggingLevel::ERROR;
×
74
  }
75

76
  constexpr auto getTypeStr = [] (XrDebugUtilsMessageTypeFlagsEXT messageType) {
×
77
    std::string msgFlags;
×
78

79
    if (messageType & XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
×
80
      msgFlags += "GEN";
×
81

82
    if (messageType & XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) {
×
83
      if (!msgFlags.empty())
×
84
        msgFlags += ',';
×
85
      msgFlags += "SPEC";
×
86
    }
87

88
    if (messageType & XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
×
89
      if (!msgFlags.empty())
×
90
        msgFlags += ',';
×
91
      msgFlags += "PERF";
×
92
    }
93

94
    return msgFlags;
×
95
  };
×
96

97
  std::string logMsg = "[OpenXR] ";
×
98

99
  if (callbackData->functionName)
×
100
    logMsg += callbackData->functionName;
×
101

NEW
102
  logMsg += std::format("({}/{}): ", severityStr, getTypeStr(type));
×
103

104
  if (callbackData->messageId)
×
105
    logMsg += "ID: " + std::string(callbackData->messageId);
×
106

107
  if (callbackData->message)
×
108
    logMsg += " - " + std::string(callbackData->message);
×
109

110
  switch (logLevel) {
×
111
    case LoggingLevel::INFO:
×
112
      Logger::info(logMsg);
×
113
      break;
×
114

115
    case LoggingLevel::WARNING:
×
116
      Logger::warn(logMsg);
×
117
      break;
×
118

119
    case LoggingLevel::ERROR:
×
120
      Logger::error(logMsg);
×
121
      break;
×
122

123
    default:
×
124
      break;
×
125
  }
126

127
  // Returning false to indicate that the call shouldn't be aborted
128
  // See: https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#PFN_xrDebugUtilsMessengerCallbackEXT
129
  return false;
×
130
}
×
131

132
} // namespace
133

134
XrContext::XrContext(const std::string& appName) {
×
135
  ZoneScopedN("XrContext::XrContext");
136

137
  Logger::debug("[XrContext] Creating context...");
×
138

139
  recoverApiLayers();
×
140
  recoverExtensions();
×
141
  createInstance(appName);
×
142

143
  XrInstanceProperties instanceProperties {};
×
144
  instanceProperties.type = XR_TYPE_INSTANCE_PROPERTIES;
×
145
  checkLog(xrGetInstanceProperties(m_instance, &instanceProperties), "Failed to get instance properties", m_instance);
×
146

NEW
147
  Logger::info("[XrContext] OpenXR runtime: {} - {}.{}.{}",
×
NEW
148
               instanceProperties.runtimeName, XR_VERSION_MAJOR(instanceProperties.runtimeVersion),
×
NEW
149
               XR_VERSION_MINOR(instanceProperties.runtimeVersion), XR_VERSION_PATCH(instanceProperties.runtimeVersion));
×
150

151
  createDebugMessenger();
×
152

153
  XrSystemGetInfo systemGetInfo {};
×
154
  systemGetInfo.type       = XR_TYPE_SYSTEM_GET_INFO;
×
155
  systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; // Always search for a VR headset for now
×
156
  checkThrow(xrGetSystem(m_instance, &systemGetInfo, &m_systemId), "Failed to get system ID", m_instance);
×
157

158
  XrSystemProperties m_systemProperties {};
×
159
  m_systemProperties.type = XR_TYPE_SYSTEM_PROPERTIES;
×
160
  checkLog(xrGetSystemProperties(m_instance, m_systemId, &m_systemProperties), "Failed to get system properties", m_instance);
×
161

162
  Logger::debug("[XrContext] System properties:"
×
163
                "\n    - System ID:             " + std::to_string(m_systemProperties.systemId)
×
164
              + "\n    - Vendor ID:             " + std::to_string(m_systemProperties.vendorId)
×
165
              + "\n    - Name:                  " + m_systemProperties.systemName
×
166
              + "\n    - Max. swapchain height: " + std::to_string(m_systemProperties.graphicsProperties.maxSwapchainImageHeight)
×
167
              + "\n    - Max. swapchain width:  " + std::to_string(m_systemProperties.graphicsProperties.maxSwapchainImageWidth)
×
168
              + "\n    - Max. layer count:      " + std::to_string(m_systemProperties.graphicsProperties.maxLayerCount)
×
169
              + "\n    - Orientation tracking:  " + (m_systemProperties.trackingProperties.orientationTracking == XR_TRUE ? "true" : "false")
×
170
              + "\n    - Position tracking:     " + (m_systemProperties.trackingProperties.positionTracking == XR_TRUE ? "true" : "false"));
×
171

172
  Logger::debug("[XrContext] Created context");
×
173
}
×
174

175
XrContext::~XrContext() {
×
176
  ZoneScopedN("XrContext::~XrContext");
177

178
  Logger::debug("[XrContext] Destroying context...");
×
179
  destroyDebugMessenger();
×
180
  destroyInstance();
×
181
  Logger::debug("[XrContext] Destroyed context");
×
182
}
×
183

184
void XrContext::recoverApiLayers() {
×
185
  ZoneScopedN("XrContext::recoverApiLayers");
186

187
  Logger::debug("[XrContext] Recovering API layers...");
×
188

189
  uint32_t apiLayerCount {};
×
190
  std::vector<XrApiLayerProperties> apiLayerProperties;
×
191
  checkLog(xrEnumerateApiLayerProperties(0, &apiLayerCount, nullptr), "Failed to get API layer property count", m_instance);
×
192
  apiLayerProperties.resize(apiLayerCount, { XR_TYPE_API_LAYER_PROPERTIES });
×
193
  checkLog(xrEnumerateApiLayerProperties(apiLayerCount, &apiLayerCount, apiLayerProperties.data()), "Failed to enumerate API layer properties", m_instance);
×
194

195
#if !defined(NDEBUG) || defined(RAZ_FORCE_DEBUG_LOG)
196
  {
197
    std::string availableLayersMsg = "[XrContext] Available layers:";
×
198
    for (const XrApiLayerProperties& layerProp : apiLayerProperties) {
×
199
      availableLayersMsg += "\n    " + std::string(layerProp.layerName) +
×
200
                            "\n     -> " + std::string(layerProp.description);
×
201
    }
202
    Logger::debug(availableLayersMsg);
×
203
  }
×
204
#endif
205

206
  for (const std::string& requestedLayer : m_apiLayers) {
×
NEW
207
    const auto layerPropIter = std::ranges::find_if(apiLayerProperties, [&requestedLayer] (const XrApiLayerProperties& layerProp) {
×
NEW
208
      return requestedLayer == layerProp.layerName;
×
209
    });
210

211
    if (layerPropIter != apiLayerProperties.cend())
×
212
      m_activeApiLayers.emplace_back(requestedLayer.c_str());
×
213
    else
NEW
214
      Logger::error("[XrContext] Failed to find OpenXR API layer: {}", requestedLayer);
×
215
  }
216

217
#if !defined(NDEBUG) || defined(RAZ_FORCE_DEBUG_LOG)
218
  if (!m_activeApiLayers.empty()) {
×
219
    std::string activeLayersMsg = "[XrContext] Active layers:";
×
220
    for (const char* activeLayer : m_activeApiLayers)
×
NEW
221
      activeLayersMsg += std::format("\n    {}", activeLayer);
×
222
    Logger::debug(activeLayersMsg);
×
223
  }
×
224
#endif
225

226
  Logger::debug("[XrContext] Recovered API layers");
×
227
}
×
228

229
void XrContext::recoverExtensions() {
×
230
  ZoneScopedN("XrContext::recoverExtensions");
231

232
  Logger::debug("[XrContext] Recovering extensions...");
×
233

234
  m_extensions.emplace_back(XR_EXT_DEBUG_UTILS_EXTENSION_NAME);
×
235
  m_extensions.emplace_back(XR_KHR_OPENGL_ENABLE_EXTENSION_NAME);
×
236

237
  uint32_t extensionCount {};
×
238
  std::vector<XrExtensionProperties> extensionProperties;
×
239
  checkLog(xrEnumerateInstanceExtensionProperties(nullptr, 0, &extensionCount, nullptr), "Failed to get instance extension property count", m_instance);
×
240
  extensionProperties.resize(extensionCount, { XR_TYPE_EXTENSION_PROPERTIES });
×
241
  checkLog(xrEnumerateInstanceExtensionProperties(nullptr, extensionCount, &extensionCount, extensionProperties.data()),
×
242
           "Failed to enumerate instance extension properties",
243
           m_instance);
244

245
#if !defined(NDEBUG) || defined(RAZ_FORCE_DEBUG_LOG)
246
  {
247
    std::string availableExtensionsMsg = "[XrContext] Available extensions:";
×
248
    for (const XrExtensionProperties& extProp : extensionProperties) {
×
NEW
249
      const std::string extVersionStr = std::format("{}.{}.{}", XR_VERSION_MAJOR(extProp.extensionVersion),
×
NEW
250
                                                                XR_VERSION_MINOR(extProp.extensionVersion),
×
NEW
251
                                                                XR_VERSION_PATCH(extProp.extensionVersion));
×
NEW
252
      availableExtensionsMsg += std::format("\n    {} - {}", extProp.extensionName, extVersionStr);
×
253
    }
×
254
    Logger::debug(availableExtensionsMsg);
×
255
  }
×
256
#endif
257

258
  for (const std::string& requestedExtension : m_extensions) {
×
NEW
259
    const auto extIter = std::ranges::find_if(extensionProperties, [&requestedExtension] (const XrExtensionProperties& extProp) {
×
260
      return requestedExtension == extProp.extensionName;
×
261
    });
262

263
    if (extIter != extensionProperties.cend())
×
264
      m_activeExtensions.emplace_back(requestedExtension.c_str());
×
265
    else
NEW
266
      Logger::error("[XrContext] Failed to find OpenXR instance extension: {}", requestedExtension);
×
267
  }
268

269
#if !defined(NDEBUG) || defined(RAZ_FORCE_DEBUG_LOG)
270
  if (!m_activeExtensions.empty()) {
×
271
    std::string activeExtensionsMsg = "[XrContext] Active extensions:";
×
272
    for (const char* activeExt : m_activeExtensions)
×
NEW
273
      activeExtensionsMsg += std::format("\n    {}", activeExt);
×
274
    Logger::debug(activeExtensionsMsg);
×
275
  }
×
276
#endif
277

278
  Logger::debug("[XrContext] Recovered extensions");
×
279
}
×
280

281
void XrContext::createInstance(const std::string& appName) {
×
282
  ZoneScopedN("XrContext::createInstance");
283

284
  Logger::debug("[XrContext] Creating instance...");
×
285

286
  XrApplicationInfo appInfo {};
×
287
  appName.copy(appInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE - 1);
×
288
  appInfo.applicationVersion = 1;
×
289
  std::string("RaZ").copy(appInfo.engineName, XR_MAX_ENGINE_NAME_SIZE - 1);
×
290
  appInfo.engineVersion      = 1;
×
291
  appInfo.apiVersion         = XR_MAKE_VERSION(1, 0, 34); // XR_CURRENT_API_VERSION is too recent for the tested runtime
×
292

293
  XrInstanceCreateInfo instanceCreateInfo {};
×
294
  instanceCreateInfo.type                  = XR_TYPE_INSTANCE_CREATE_INFO;
×
295
  instanceCreateInfo.createFlags           = 0;
×
296
  instanceCreateInfo.applicationInfo       = appInfo;
×
297
  instanceCreateInfo.enabledApiLayerCount  = static_cast<uint32_t>(m_activeApiLayers.size());
×
298
  instanceCreateInfo.enabledApiLayerNames  = m_activeApiLayers.data();
×
299
  instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(m_activeExtensions.size());
×
300
  instanceCreateInfo.enabledExtensionNames = m_activeExtensions.data();
×
301
  checkThrow(xrCreateInstance(&instanceCreateInfo, &m_instance), "Failed to create instance", m_instance);
×
302

303
  Logger::debug("[XrContext] Created instance");
×
304
}
×
305

306
void XrContext::destroyInstance() {
×
307
  ZoneScopedN("XrContext::destroyInstance");
308

309
  Logger::debug("[XrContext] Destroying instance...");
×
310
  checkLog(xrDestroyInstance(m_instance), "Failed to destroy instance", m_instance);
×
311
  Logger::debug("[XrContext] Destroyed instance");
×
312
}
×
313

314
void XrContext::createDebugMessenger() {
×
315
  ZoneScopedN("XrContext::createDebugMessenger");
316

NEW
317
  if (std::ranges::find(m_activeExtensions, std::string_view(XR_EXT_DEBUG_UTILS_EXTENSION_NAME)) == m_activeExtensions.cend())
×
318
    return; // Extension not found
×
319

320
  Logger::debug("[XrContext] Creating debug messenger...");
×
321

322
  XrDebugUtilsMessengerCreateInfoEXT debugMsgrCreateInfo {};
×
323
  debugMsgrCreateInfo.type = XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
×
324
  debugMsgrCreateInfo.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
×
325
                                        | XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
326
                                        | XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; // Ignoring verbose severity
327
  debugMsgrCreateInfo.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
×
328
                                   | XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
329
                                   | XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
330
                                   | XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT;
331
  debugMsgrCreateInfo.userCallback = logCallback;
×
332
  debugMsgrCreateInfo.userData     = nullptr;
×
333

334
  PFN_xrCreateDebugUtilsMessengerEXT xrCreateDebugUtilsMessengerEXT {};
×
335
  checkLog(xrGetInstanceProcAddr(m_instance,
×
336
                                 "xrCreateDebugUtilsMessengerEXT",
337
                                 reinterpret_cast<PFN_xrVoidFunction*>(&xrCreateDebugUtilsMessengerEXT)),
338
           "Failed to get debug messenger create function",
339
           m_instance);
340

341
  checkLog(xrCreateDebugUtilsMessengerEXT(m_instance, &debugMsgrCreateInfo, &m_debugMsgr), "Failed to create debug messenger", m_instance);
×
342

343
  Logger::debug("[XrContext] Created debug messenger");
×
344
}
345

346
void XrContext::destroyDebugMessenger() {
×
347
  ZoneScopedN("XrContext::destroyDebugMessenger");
348

349
  if (m_debugMsgr == XR_NULL_HANDLE)
×
350
    return;
×
351

NEW
352
  if (std::ranges::find(m_activeExtensions, std::string_view(XR_EXT_DEBUG_UTILS_EXTENSION_NAME)) == m_activeExtensions.cend())
×
353
    return; // Extension not found
×
354

355
  Logger::debug("[XrContext] Destroying debug messenger...");
×
356

357
  PFN_xrDestroyDebugUtilsMessengerEXT xrDestroyDebugUtilsMessengerEXT {};
×
358
  checkLog(xrGetInstanceProcAddr(m_instance,
×
359
                                 "xrDestroyDebugUtilsMessengerEXT",
360
                                 reinterpret_cast<PFN_xrVoidFunction*>(&xrDestroyDebugUtilsMessengerEXT)),
361
           "Failed to get debug messenger destroy function",
362
           m_instance);
363

364
  checkLog(xrDestroyDebugUtilsMessengerEXT(m_debugMsgr), "Failed to destroy debug messenger", m_instance);
×
365

366
  Logger::debug("[XrContext] Destroyed debug messenger");
×
367
}
368

369
} // namespace Raz
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc