2828#include < string>
2929#include < vector>
3030#include < iostream>
31+ #include < sstream>
32+
33+ #ifdef _WIN32
34+ #include < Windows.h>
35+ #endif
3136
3237// Anonymous namespace to keep these types private
3338namespace {
39+ void OutputMessageToStream (std::ostream& os, XrLoaderLogMessageSeverityFlagBits message_severity,
40+ XrLoaderLogMessageTypeFlags message_type, const XrLoaderLogMessengerCallbackData* callback_data) {
41+ if (XR_LOADER_LOG_MESSAGE_SEVERITY_INFO_BIT > message_severity) {
42+ os << " Verbose [" ;
43+ } else if (XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT > message_severity) {
44+ os << " Info [" ;
45+ } else if (XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT > message_severity) {
46+ os << " Warning [" ;
47+ } else {
48+ os << " Error [" ;
49+ }
50+ switch (message_type) {
51+ case XR_LOADER_LOG_MESSAGE_TYPE_GENERAL_BIT:
52+ os << " GENERAL" ;
53+ break ;
54+ case XR_LOADER_LOG_MESSAGE_TYPE_SPECIFICATION_BIT:
55+ os << " SPEC" ;
56+ break ;
57+ case XR_LOADER_LOG_MESSAGE_TYPE_PERFORMANCE_BIT:
58+ os << " PERF" ;
59+ break ;
60+ default :
61+ os << " UNKNOWN" ;
62+ break ;
63+ }
64+ os << " | " << callback_data->command_name << " | " << callback_data->message_id << " ] : " << callback_data->message
65+ << std::endl;
66+
67+ for (uint32_t obj = 0 ; obj < callback_data->object_count ; ++obj) {
68+ os << " Object[" << obj << " ] = " << callback_data->objects [obj].ToString ();
69+ os << std::endl;
70+ }
71+ for (uint32_t label = 0 ; label < callback_data->session_labels_count ; ++label) {
72+ os << " SessionLabel[" << std::to_string (label) << " ] = " << callback_data->session_labels [label].labelName ;
73+ os << std::endl;
74+ }
75+ }
76+
3477// With std::cerr: Standard Error logger, always on for now
3578// With std::cout: Standard Output logger used with XR_LOADER_DEBUG
3679class OstreamLoaderLogRecorder : public LoaderLogRecorder {
@@ -60,6 +103,17 @@ class DebugUtilsLogRecorder : public LoaderLogRecorder {
60103 PFN_xrDebugUtilsMessengerCallbackEXT _user_callback;
61104};
62105
106+ #ifdef _WIN32
107+ // Output to debugger
108+ class DebuggerLoaderLogRecorder : public LoaderLogRecorder {
109+ public:
110+ DebuggerLoaderLogRecorder (void * user_data, XrLoaderLogMessageSeverityFlags flags);
111+
112+ bool LogMessage (XrLoaderLogMessageSeverityFlagBits message_severity, XrLoaderLogMessageTypeFlags message_type,
113+ const XrLoaderLogMessengerCallbackData* callback_data) override ;
114+ };
115+ #endif
116+
63117// Unified stdout/stderr logger
64118OstreamLoaderLogRecorder::OstreamLoaderLogRecorder (std::ostream& os, void * user_data, XrLoaderLogMessageSeverityFlags flags)
65119 : LoaderLogRecorder(XR_LOADER_LOG_STDOUT, user_data, flags, 0xFFFFFFFFUL ), os_(os) {
@@ -71,40 +125,7 @@ bool OstreamLoaderLogRecorder::LogMessage(XrLoaderLogMessageSeverityFlagBits mes
71125 XrLoaderLogMessageTypeFlags message_type,
72126 const XrLoaderLogMessengerCallbackData* callback_data) {
73127 if (_active && 0 != (_message_severities & message_severity) && 0 != (_message_types & message_type)) {
74- if (XR_LOADER_LOG_MESSAGE_SEVERITY_INFO_BIT > message_severity) {
75- os_ << " Verbose [" ;
76- } else if (XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT > message_severity) {
77- os_ << " Info [" ;
78- } else if (XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT > message_severity) {
79- os_ << " Warning [" ;
80- } else {
81- os_ << " Error [" ;
82- }
83- switch (message_type) {
84- case XR_LOADER_LOG_MESSAGE_TYPE_GENERAL_BIT:
85- os_ << " GENERAL" ;
86- break ;
87- case XR_LOADER_LOG_MESSAGE_TYPE_SPECIFICATION_BIT:
88- os_ << " SPEC" ;
89- break ;
90- case XR_LOADER_LOG_MESSAGE_TYPE_PERFORMANCE_BIT:
91- os_ << " PERF" ;
92- break ;
93- default :
94- os_ << " UNKNOWN" ;
95- break ;
96- }
97- os_ << " | " << callback_data->command_name << " | " << callback_data->message_id << " ] : " << callback_data->message
98- << std::endl;
99-
100- for (uint32_t obj = 0 ; obj < callback_data->object_count ; ++obj) {
101- os_ << " Object[" << obj << " ] = " << callback_data->objects [obj].ToString ();
102- os_ << std::endl;
103- }
104- for (uint32_t label = 0 ; label < callback_data->session_labels_count ; ++label) {
105- os_ << " SessionLabel[" << std::to_string (label) << " ] = " << callback_data->session_labels [label].labelName ;
106- os_ << std::endl;
107- }
128+ OutputMessageToStream (os_, message_severity, message_type, callback_data);
108129 }
109130
110131 // Return of "true" means that we should exit the application after the logged message. We
@@ -170,19 +191,51 @@ bool DebugUtilsLogRecorder::LogDebugUtilsMessage(XrDebugUtilsMessageSeverityFlag
170191 return (_user_callback (message_severity, message_type, callback_data, _user_data) == XR_TRUE);
171192}
172193
194+ #ifdef _WIN32
195+ // Unified stdout/stderr logger
196+ DebuggerLoaderLogRecorder::DebuggerLoaderLogRecorder (void * user_data, XrLoaderLogMessageSeverityFlags flags)
197+ : LoaderLogRecorder(XR_LOADER_LOG_DEBUGGER, user_data, flags, 0xFFFFFFFFUL ) {
198+ // Automatically start
199+ Start ();
200+ }
201+
202+ bool DebuggerLoaderLogRecorder::LogMessage (XrLoaderLogMessageSeverityFlagBits message_severity,
203+ XrLoaderLogMessageTypeFlags message_type,
204+ const XrLoaderLogMessengerCallbackData* callback_data) {
205+ if (_active && 0 != (_message_severities & message_severity) && 0 != (_message_types & message_type)) {
206+ std::stringstream ss;
207+ OutputMessageToStream (ss, message_severity, message_type, callback_data);
208+
209+ OutputDebugStringA (ss.str ().c_str ());
210+ }
211+
212+ // Return of "true" means that we should exit the application after the logged message. We
213+ // don't want to do that for our internal logging. Only let a user return true.
214+ return false ;
215+ }
216+ #endif
173217} // namespace
174218
175219std::unique_ptr<LoaderLogRecorder> MakeStdOutLoaderLogRecorder (void * user_data, XrLoaderLogMessageSeverityFlags flags) {
176220 std::unique_ptr<LoaderLogRecorder> recorder (new OstreamLoaderLogRecorder (std::cout, user_data, flags));
177221 return recorder;
178222}
223+
179224std::unique_ptr<LoaderLogRecorder> MakeStdErrLoaderLogRecorder (void * user_data) {
180225 std::unique_ptr<LoaderLogRecorder> recorder (
181226 new OstreamLoaderLogRecorder (std::cerr, user_data, XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT));
182227 return recorder;
183228}
229+
184230std::unique_ptr<LoaderLogRecorder> MakeDebugUtilsLoaderLogRecorder (const XrDebugUtilsMessengerCreateInfoEXT* create_info,
185231 XrDebugUtilsMessengerEXT debug_messenger) {
186232 std::unique_ptr<LoaderLogRecorder> recorder (new DebugUtilsLogRecorder (create_info, debug_messenger));
187233 return recorder;
188234}
235+
236+ #ifdef _WIN32
237+ std::unique_ptr<LoaderLogRecorder> MakeDebuggerLoaderLogRecorder (void * user_data) {
238+ std::unique_ptr<LoaderLogRecorder> recorder (new DebuggerLoaderLogRecorder (user_data, XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT));
239+ return recorder;
240+ }
241+ #endif
0 commit comments