1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DebugAnnotator11.cpp: D3D11 helpers for adding trace annotations.
7 //
8
9 #include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
10
11 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
12 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
13 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
14 #include "libANGLE/renderer/driver_utils.h"
15
16 #include "common/system_utils.h"
17
18 namespace rx
19 {
20
21 // DebugAnnotator11 implementation
DebugAnnotator11()22 DebugAnnotator11::DebugAnnotator11() {}
23
~DebugAnnotator11()24 DebugAnnotator11::~DebugAnnotator11() {}
25
beginEvent(gl::Context * context,angle::EntryPoint entryPoint,const char * eventName,const char * eventMessage)26 void DebugAnnotator11::beginEvent(gl::Context *context,
27 angle::EntryPoint entryPoint,
28 const char *eventName,
29 const char *eventMessage)
30 {
31 angle::LoggingAnnotator::beginEvent(context, entryPoint, eventName, eventMessage);
32 if (!context)
33 {
34 return;
35 }
36 Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
37 renderer11->getDebugAnnotatorContext()->beginEvent(entryPoint, eventName, eventMessage);
38 }
39
endEvent(gl::Context * context,const char * eventName,angle::EntryPoint entryPoint)40 void DebugAnnotator11::endEvent(gl::Context *context,
41 const char *eventName,
42 angle::EntryPoint entryPoint)
43 {
44 angle::LoggingAnnotator::endEvent(context, eventName, entryPoint);
45 if (!context)
46 {
47 return;
48 }
49 Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
50 renderer11->getDebugAnnotatorContext()->endEvent(eventName, entryPoint);
51 }
52
setMarker(gl::Context * context,const char * markerName)53 void DebugAnnotator11::setMarker(gl::Context *context, const char *markerName)
54 {
55 angle::LoggingAnnotator::setMarker(context, markerName);
56 if (!context)
57 {
58 return;
59 }
60 Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
61 renderer11->getDebugAnnotatorContext()->setMarker(markerName);
62 }
63
getStatus(const gl::Context * context)64 bool DebugAnnotator11::getStatus(const gl::Context *context)
65 {
66 if (!context)
67 {
68 return false;
69 }
70 Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
71 return renderer11->getDebugAnnotatorContext()->getStatus();
72 }
73
74 // DebugAnnotatorContext11 implemenetation
75 DebugAnnotatorContext11::DebugAnnotatorContext11() = default;
76
77 DebugAnnotatorContext11::~DebugAnnotatorContext11() = default;
78
beginEvent(angle::EntryPoint entryPoint,const char * eventName,const char * eventMessage)79 void DebugAnnotatorContext11::beginEvent(angle::EntryPoint entryPoint,
80 const char *eventName,
81 const char *eventMessage)
82 {
83 if (loggingEnabledForThisThread())
84 {
85 std::mbstate_t state = std::mbstate_t();
86 std::mbsrtowcs(mWCharMessage, &eventMessage, kMaxMessageLength, &state);
87 mUserDefinedAnnotation->BeginEvent(mWCharMessage);
88 }
89 }
90
endEvent(const char * eventName,angle::EntryPoint entryPoint)91 void DebugAnnotatorContext11::endEvent(const char *eventName, angle::EntryPoint entryPoint)
92 {
93 if (loggingEnabledForThisThread())
94 {
95 mUserDefinedAnnotation->EndEvent();
96 }
97 }
98
setMarker(const char * markerName)99 void DebugAnnotatorContext11::setMarker(const char *markerName)
100 {
101 if (loggingEnabledForThisThread())
102 {
103 std::mbstate_t state = std::mbstate_t();
104 std::mbsrtowcs(mWCharMessage, &markerName, kMaxMessageLength, &state);
105 mUserDefinedAnnotation->SetMarker(mWCharMessage);
106 }
107 }
108
getStatus() const109 bool DebugAnnotatorContext11::getStatus() const
110 {
111 if (loggingEnabledForThisThread())
112 {
113 return !!(mUserDefinedAnnotation->GetStatus());
114 }
115
116 return false;
117 }
118
loggingEnabledForThisThread() const119 bool DebugAnnotatorContext11::loggingEnabledForThisThread() const
120 {
121 return mUserDefinedAnnotation != nullptr &&
122 angle::GetCurrentThreadUniqueId() == mAnnotationThread;
123 }
124
initialize(ID3D11DeviceContext * context)125 void DebugAnnotatorContext11::initialize(ID3D11DeviceContext *context)
126 {
127 // ID3DUserDefinedAnnotation.GetStatus only works on Windows10 or greater.
128 // Returning true unconditionally from DebugAnnotatorContext11::getStatus() means
129 // writing out all compiled shaders to temporary files even if debugging
130 // tools are not attached. See rx::ShaderD3D::prepareSourceAndReturnOptions.
131 // If you want debug annotations, you must use Windows 10.
132 if (IsWindows10OrLater())
133 {
134 mAnnotationThread = angle::GetCurrentThreadUniqueId();
135 mUserDefinedAnnotation.Attach(
136 d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context));
137 }
138 }
139
release()140 void DebugAnnotatorContext11::release()
141 {
142 mUserDefinedAnnotation.Reset();
143 }
144
145 } // namespace rx
146