Cogs.Core
CommonD3D11.cpp
1#include "CommonD3D11.h"
2
3#include "Foundation/Logging/Logger.h"
4
5namespace {
6 Cogs::Logging::Log logger = Cogs::Logging::getLogger("CommonD3D11");
7}
8
9const char* Cogs::direct3D11ReturnCodeAsString(HRESULT hr)
10{
11 thread_local static char err[1024];
12 err[0] = '\0';
13 if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
14 NULL,
15 hr,
16 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
17 err,
18 sizeof(err),
19 NULL) != 0)
20 {
21 // Kill newlines.
22 for (size_t i = 0; i < std::size(err); i++) {
23 if (err[i] == '\r' || err[i] == '\n') err[i] = ' ';
24 }
25 return err;
26 }
27
28 switch (hr)
29 {
30 case D3D11_ERROR_FILE_NOT_FOUND: return "D3D11_ERROR_FILE_NOT_FOUND"; break;
31 case D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS: return "D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS"; break;
32 case D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS: return "D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS"; break;
33 case D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD: return "D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD"; break;
34 case DXGI_ERROR_INVALID_CALL: return "DXGI_ERROR_INVALID_CALL"; break;
35 case DXGI_ERROR_WAS_STILL_DRAWING: return "DXGI_ERROR_WAS_STILL_DRAWING"; break;
36 case E_FAIL: return "E_FAIL"; break;
37 case E_INVALIDARG: return "E_INVALIDARG"; break;
38 case E_OUTOFMEMORY: return "E_OUTOFMEMORY"; break;
39 case E_NOTIMPL: return "E_NOTIMPL"; break;
40 case S_FALSE: return "S_FALSE"; break;
41 case S_OK: return "S_OK"; break;
42 default:
43 return "unknown";
44 break;
45 }
46}
47
48const char * Cogs::getUsageString(Usage::EUsage usage)
49{
50 switch (usage)
51 {
52 case Cogs::Usage::Default: return "Default"; break;
53 case Cogs::Usage::Static: return "Static"; break;
54 case Cogs::Usage::Dynamic: return "Dynamic"; break;
55 case Cogs::Usage::Staging: return "Staging"; break;
56 default: return "<invalid>"; break;
57 }
58}
59
60const char* Cogs::getAccessModeString(uint32_t accessMode)
61{
62 switch (accessMode) {
63 case Cogs::AccessMode::None: return "None"; break;
64 case Cogs::AccessMode::Read: return "Read"; break;
65 case Cogs::AccessMode::Write: return "Write"; break;
66 case Cogs::AccessMode::ReadWrite: return "ReadWrite"; break;
67 default: return "<invalid>"; break;
68 }
69}
70
71const char* Cogs::getBindFlagsString(uint32_t bindFlags)
72{
73 if (bindFlags == 0) return "None";
74 if (0x100 <= bindFlags) return "<invalid>";
75
76 const char * strings[] = {
77 "VertexBuffer", // 0x01L,
78 "IndexBuffer", // 0x02L,
79 "ConstantBuffer", // 0x04L,
80 "StreamOutBuffer", // 0x08L,
81 "ShaderResource", // 0x10L,
82 "RawBuffer", // 0x20L,
83 "StructuredBuffer", // 0x40L,
84 "StructuredBufferWithCounter" // 0x80L,
85 };
86
87 static thread_local char buf[29 * 8];
88 auto * p = &buf[0];
89 for (unsigned i = 0; i < 8u; i++) {
90 if (((1u << i) & bindFlags) != 0) {
91 for (auto * s = &strings[i][0]; *s != '\0'; ) { *p++ = *s++; }
92 if ((1u << i) < bindFlags) {
93 *p++ = '|';
94 }
95 }
96 }
97 *p++ = '\0';
98 return &buf[0];
99}
100
101const char* Cogs::getString(DXGI_FORMAT format)
102{
103 switch (format)
104 {
105 case DXGI_FORMAT_UNKNOWN: return "UNKNOWN"; break;
106 case DXGI_FORMAT_R32G32B32A32_TYPELESS: return "R32G32B32A32_TYPELESS"; break;
107 case DXGI_FORMAT_R32G32B32A32_FLOAT: return "R32G32B32A32_FLOAT"; break;
108 case DXGI_FORMAT_R32G32B32A32_UINT: return "R32G32B32A32_UINT"; break;
109 case DXGI_FORMAT_R32G32B32A32_SINT: return "R32G32B32A32_SINT"; break;
110 case DXGI_FORMAT_R32G32B32_TYPELESS: return "R32G32B32_TYPELESS"; break;
111 case DXGI_FORMAT_R32G32B32_FLOAT: return "R32G32B32_FLOAT"; break;
112 case DXGI_FORMAT_R32G32B32_UINT: return "R32G32B32_UINT"; break;
113 case DXGI_FORMAT_R32G32B32_SINT: return "R32G32B32_SINT"; break;
114 case DXGI_FORMAT_R16G16B16A16_TYPELESS: return "R16G16B16A16_TYPELESS"; break;
115 case DXGI_FORMAT_R16G16B16A16_FLOAT: return "R16G16B16A16_FLOAT"; break;
116 case DXGI_FORMAT_R16G16B16A16_UNORM: return "R16G16B16A16_UNORM"; break;
117 case DXGI_FORMAT_R16G16B16A16_UINT: return "R16G16B16A16_UINT"; break;
118 case DXGI_FORMAT_R16G16B16A16_SNORM: return "R16G16B16A16_SNORM"; break;
119 case DXGI_FORMAT_R16G16B16A16_SINT: return "R16G16B16A16_SINT"; break;
120 case DXGI_FORMAT_R32G32_TYPELESS: return "R32G32_TYPELESS"; break;
121 case DXGI_FORMAT_R32G32_FLOAT: return "R32G32_FLOAT"; break;
122 case DXGI_FORMAT_R32G32_UINT: return "R32G32_UINT"; break;
123 case DXGI_FORMAT_R32G32_SINT: return "R32G32_SINT"; break;
124 case DXGI_FORMAT_R32G8X24_TYPELESS: return "R32G8X24_TYPELESS"; break;
125 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return "D32_FLOAT_S8X24_UINT"; break;
126 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return "R32_FLOAT_X8X24_TYPELESS"; break;
127 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return "X32_TYPELESS_G8X24_UINT"; break;
128 case DXGI_FORMAT_R10G10B10A2_TYPELESS: return "R10G10B10A2_TYPELESS"; break;
129 case DXGI_FORMAT_R10G10B10A2_UNORM: return "R10G10B10A2_UNORM"; break;
130 case DXGI_FORMAT_R10G10B10A2_UINT: return "R10G10B10A2_UINT"; break;
131 case DXGI_FORMAT_R11G11B10_FLOAT: return "R11G11B10_FLOAT"; break;
132 case DXGI_FORMAT_R8G8B8A8_TYPELESS: return "R8G8B8A8_TYPELESS"; break;
133 case DXGI_FORMAT_R8G8B8A8_UNORM: return "R8G8B8A8_UNORM"; break;
134 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return "R8G8B8A8_UNORM_SRGB"; break;
135 case DXGI_FORMAT_R8G8B8A8_UINT: return "R8G8B8A8_UINT"; break;
136 case DXGI_FORMAT_R8G8B8A8_SNORM: return "R8G8B8A8_SNORM"; break;
137 case DXGI_FORMAT_R8G8B8A8_SINT: return "R8G8B8A8_SINT"; break;
138 case DXGI_FORMAT_R16G16_TYPELESS: return "R16G16_TYPELESS"; break;
139 case DXGI_FORMAT_R16G16_FLOAT: return "R16G16_FLOAT"; break;
140 case DXGI_FORMAT_R16G16_UNORM: return "R16G16_UNORM"; break;
141 case DXGI_FORMAT_R16G16_UINT: return "R16G16_UINT"; break;
142 case DXGI_FORMAT_R16G16_SNORM: return "R16G16_SNORM"; break;
143 case DXGI_FORMAT_R16G16_SINT: return "R16G16_SINT"; break;
144 case DXGI_FORMAT_R32_TYPELESS: return "R32_TYPELESS"; break;
145 case DXGI_FORMAT_D32_FLOAT: return "D32_FLOAT"; break;
146 case DXGI_FORMAT_R32_FLOAT: return "R32_FLOAT"; break;
147 case DXGI_FORMAT_R32_UINT: return "R32_UINT"; break;
148 case DXGI_FORMAT_R32_SINT: return "R32_SINT"; break;
149 case DXGI_FORMAT_R24G8_TYPELESS: return "R24G8_TYPELESS"; break;
150 case DXGI_FORMAT_D24_UNORM_S8_UINT: return "D24_UNORM_S8_UINT"; break;
151 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return "R24_UNORM_X8_TYPELESS"; break;
152 case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return "X24_TYPELESS_G8_UINT"; break;
153 case DXGI_FORMAT_R8G8_TYPELESS: return "R8G8_TYPELESS"; break;
154 case DXGI_FORMAT_R8G8_UNORM: return "R8G8_UNORM"; break;
155 case DXGI_FORMAT_R8G8_UINT: return "R8G8_UINT"; break;
156 case DXGI_FORMAT_R8G8_SNORM: return "R8G8_SNORM"; break;
157 case DXGI_FORMAT_R8G8_SINT: return "R8G8_SINT"; break;
158 case DXGI_FORMAT_R16_TYPELESS: return "R16_TYPELESS"; break;
159 case DXGI_FORMAT_R16_FLOAT: return "R16_FLOAT"; break;
160 case DXGI_FORMAT_D16_UNORM: return "D16_UNORM"; break;
161 case DXGI_FORMAT_R16_UNORM: return "R16_UNORM"; break;
162 case DXGI_FORMAT_R16_UINT: return "R16_UINT"; break;
163 case DXGI_FORMAT_R16_SNORM: return "R16_SNORM"; break;
164 case DXGI_FORMAT_R16_SINT: return "R16_SINT"; break;
165 case DXGI_FORMAT_R8_TYPELESS: return "R8_TYPELESS"; break;
166 case DXGI_FORMAT_R8_UNORM: return "R8_UNORM"; break;
167 case DXGI_FORMAT_R8_UINT: return "R8_UINT"; break;
168 case DXGI_FORMAT_R8_SNORM: return "R8_SNORM"; break;
169 case DXGI_FORMAT_R8_SINT: return "R8_SINT"; break;
170 case DXGI_FORMAT_A8_UNORM: return "A8_UNORM"; break;
171 case DXGI_FORMAT_R1_UNORM: return "R1_UNORM"; break;
172 case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return "R9G9B9E5_SHAREDEXP"; break;
173 case DXGI_FORMAT_R8G8_B8G8_UNORM: return "R8G8_B8G8_UNORM"; break;
174 case DXGI_FORMAT_G8R8_G8B8_UNORM: return "G8R8_G8B8_UNORM"; break;
175 case DXGI_FORMAT_BC1_TYPELESS: return "BC1_TYPELESS"; break;
176 case DXGI_FORMAT_BC1_UNORM: return "BC1_UNORM"; break;
177 case DXGI_FORMAT_BC1_UNORM_SRGB: return "BC1_UNORM_SRGB"; break;
178 case DXGI_FORMAT_BC2_TYPELESS: return "BC2_TYPELESS"; break;
179 case DXGI_FORMAT_BC2_UNORM: return "BC2_UNORM"; break;
180 case DXGI_FORMAT_BC2_UNORM_SRGB: return "BC2_UNORM_SRGB"; break;
181 case DXGI_FORMAT_BC3_TYPELESS: return "BC3_TYPELESS"; break;
182 case DXGI_FORMAT_BC3_UNORM: return "BC3_UNORM"; break;
183 case DXGI_FORMAT_BC3_UNORM_SRGB: return "BC3_UNORM_SRGB"; break;
184 case DXGI_FORMAT_BC4_TYPELESS: return "BC4_TYPELESS"; break;
185 case DXGI_FORMAT_BC4_UNORM: return "BC4_UNORM"; break;
186 case DXGI_FORMAT_BC4_SNORM: return "BC4_SNORM"; break;
187 case DXGI_FORMAT_BC5_TYPELESS: return "BC5_TYPELESS"; break;
188 case DXGI_FORMAT_BC5_UNORM: return "BC5_UNORM"; break;
189 case DXGI_FORMAT_BC5_SNORM: return "BC5_SNORM"; break;
190 case DXGI_FORMAT_B5G6R5_UNORM: return "B5G6R5_UNORM"; break;
191 case DXGI_FORMAT_B5G5R5A1_UNORM: return "B5G5R5A1_UNORM"; break;
192 case DXGI_FORMAT_B8G8R8A8_UNORM: return "B8G8R8A8_UNORM"; break;
193 case DXGI_FORMAT_B8G8R8X8_UNORM: return "B8G8R8X8_UNORM"; break;
194 case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: return "R10G10B10_XR_BIAS_A2_UNORM"; break;
195 case DXGI_FORMAT_B8G8R8A8_TYPELESS: return "B8G8R8A8_TYPELESS"; break;
196 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return "B8G8R8A8_UNORM_SRGB"; break;
197 case DXGI_FORMAT_B8G8R8X8_TYPELESS: return "B8G8R8X8_TYPELESS"; break;
198 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return "B8G8R8X8_UNORM_SRGB"; break;
199 case DXGI_FORMAT_BC6H_TYPELESS: return "BC6H_TYPELESS"; break;
200 case DXGI_FORMAT_BC6H_UF16: return "BC6H_UF16"; break;
201 case DXGI_FORMAT_BC6H_SF16: return "BC6H_SF16"; break;
202 case DXGI_FORMAT_BC7_TYPELESS: return "BC7_TYPELESS"; break;
203 case DXGI_FORMAT_BC7_UNORM: return "BC7_UNORM"; break;
204 case DXGI_FORMAT_BC7_UNORM_SRGB: return "BC7_UNORM_SRGB"; break;
205 case DXGI_FORMAT_AYUV: return "AYUV"; break;
206 case DXGI_FORMAT_Y410: return "Y410"; break;
207 case DXGI_FORMAT_Y416: return "Y416"; break;
208 case DXGI_FORMAT_NV12: return "NV12"; break;
209 case DXGI_FORMAT_P010: return "P010"; break;
210 case DXGI_FORMAT_P016: return "P016"; break;
211 case DXGI_FORMAT_420_OPAQUE: return "420_OPAQUE"; break;
212 case DXGI_FORMAT_YUY2: return "YUY2"; break;
213 case DXGI_FORMAT_Y210: return "Y210"; break;
214 case DXGI_FORMAT_Y216: return "Y216"; break;
215 case DXGI_FORMAT_NV11: return "NV11"; break;
216 case DXGI_FORMAT_AI44: return "AI44"; break;
217 case DXGI_FORMAT_IA44: return "IA44"; break;
218 case DXGI_FORMAT_P8: return "P8"; break;
219 case DXGI_FORMAT_A8P8: return "A8P8"; break;
220 case DXGI_FORMAT_B4G4R4A4_UNORM: return "B4G4R4A4_UNORM"; break;
221 case DXGI_FORMAT_FORCE_UINT: return "FORCE_UINT"; break;
222 default: return "<invalid>"; break;
223 }
224}
225
226const char* Cogs::getString(D3D11_USAGE usage)
227{
228 switch (usage)
229 {
230 case D3D11_USAGE_DEFAULT: return "default"; break;
231 case D3D11_USAGE_IMMUTABLE: return "immutable"; break;
232 case D3D11_USAGE_DYNAMIC: return "dynamic"; break;
233 case D3D11_USAGE_STAGING: return "staging"; break;
234 default: return "<invalid>"; break;
235 }
236}
237
238const char* Cogs::getString(D3D11_CPU_ACCESS_FLAG flags)
239{
240 switch (flags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE))
241 {
242 case D3D11_CPU_ACCESS_WRITE: return "write"; break;
243 case D3D11_CPU_ACCESS_READ: return "read"; break;
244 case D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE: return "read-write"; break;
245 default: return "none";
246 }
247}
248
249const char* Cogs::getString(D3D11_BIND_FLAG flags_)
250{
251 unsigned flags = (unsigned)flags_ & 0x6ffL;
252 if (flags == 0) return "None";
253 if (0x800 <= flags) return "<invalid>";
254
255 const char * strings[] = {
256 "VERTEX_BUFFER", // 0x1L,
257 "INDEX_BUFFER", // 0x2L,
258 "CONSTANT_BUFFER", // 0x4L,
259 "SHADER_RESOURCE", // 0x8L,
260 "STREAM_OUTPUT", // 0x10L,
261 "RENDER_TARGET", // 0x20L,
262 "DEPTH_STENCIL", //0x40L,
263 "UNORDERED_ACCESS", //0x80L,
264 "",
265 "DECODER", // 0x200L,
266 "VIDEO_ENCODER", // 0x400L
267 };
268
269 static thread_local char buf[17 * 11];
270 auto * p = &buf[0];
271 for (unsigned i = 0; i < 11u; i++) {
272 if (((1u << i) & flags) != 0u) {
273 for (auto * s = &strings[i][0]; *s != '\0'; ) { *p++ = *s++; }
274 if ((1u << i) < flags) {
275 *p++ = '|';
276 }
277 }
278 }
279 *p++ = '\0';
280 return &buf[0];
281
282}
283
284const char* Cogs::getString(D3D11_TEXTURE2D_DESC desc)
285{
286 thread_local static char buf[1024];
287
288 snprintf(buf, sizeof(buf), "Tex2D, width=%u, height=%u, mips=%u, length=%u, format=%s, usage=%s, bind=%s, CPU access=%s",
289 desc.Width,
290 desc.Height,
291 desc.MipLevels,
292 desc.ArraySize,
293 getString(desc.Format),
294 getString(desc.Usage),
295 getString((D3D11_BIND_FLAG)desc.BindFlags),
296 getString((D3D11_CPU_ACCESS_FLAG)desc.CPUAccessFlags));
297 return buf;
298}
299
300const char* Cogs::getString(D3D11_TEXTURE3D_DESC desc)
301{
302 thread_local static char buf[1024];
303
304 snprintf(buf, sizeof(buf), "Tex3D, width=%u, height=%u, depth=%u, mips=%u, format=%s, usage=%s, bind=%s, CPU=%s",
305 desc.Width,
306 desc.Height,
307 desc.Depth,
308 desc.MipLevels,
309 getString(desc.Format),
310 getString(desc.Usage),
311 getString((D3D11_BIND_FLAG)desc.BindFlags),
312 getString((D3D11_CPU_ACCESS_FLAG)desc.CPUAccessFlags));
313 return buf;
314}
315
316
318public:
319 using pointer = HDC;
320
321 HdcDeleter(HWND hWnd) : handle(hWnd) {}
322 void operator()(HDC hdc) const { ReleaseDC(handle, hdc); }
323
324private:
325 HWND handle;
326};
327
328template<typename HandleT> struct HandleDeleter {
329 using pointer = HandleT;
330
331 void operator()(HandleT handle) const { DeleteObject(handle); }
332};
Log implementation class.
Definition: LogManager.h:139
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
@ Read
The buffer can be mapped and read from by the CPU after creation.
Definition: Flags.h:48
@ Write
The buffer can be mapped and written to by the CPU after creation.
Definition: Flags.h:50
@ None
The buffer can not be either read from or written to by the CPU after creation.
Definition: Flags.h:46
@ Static
Buffer will be loaded once and used to render many subsequent frames without any updates.
Definition: Flags.h:28
@ Default
Default usage.
Definition: Flags.h:26
@ Dynamic
Buffer will be loaded and modified with some frequency.
Definition: Flags.h:30
@ Staging
Definition: Flags.h:33