VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp@ 37300

Last change on this file since 37300 was 37300, checked in by vboxsync, 14 years ago

wddm: memory leaks fixes, some cleanup

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.1 KB
Line 
1/* $Id: VBoxDispDbg.cpp 37300 2011-06-01 19:45:51Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/* @todo: move this to VBoxDispD3DCmn.h ? */
20# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
21# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
22# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
23# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
24# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
25# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
26# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
27# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
28# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
29# pragma warning(disable : 4163)
30# include <windows.h>
31# pragma warning(default : 4163)
32# undef _InterlockedExchange
33# undef _InterlockedExchangeAdd
34# undef _InterlockedCompareExchange
35# undef _InterlockedAddLargeStatistic
36# undef _interlockedbittestandset
37# undef _interlockedbittestandreset
38# undef _interlockedbittestandset64
39# undef _interlockedbittestandreset64
40# else
41# include <windows.h>
42# endif
43
44#include "VBoxDispD3DCmn.h"
45
46#include <stdio.h>
47#include <stdarg.h>
48
49#include <iprt/asm.h>
50
51#ifdef VBOXWDDMDISP_DEBUG
52bool g_bVBoxVDbgFDumpSetTexture = false;
53bool g_bVBoxVDbgFDumpDrawPrim = false;
54bool g_bVBoxVDbgFDumpTexBlt = false;
55bool g_bVBoxVDbgFDumpBlt = false;
56
57typedef enum
58{
59 VBOXDISPDBG_STATE_UNINITIALIZED = 0,
60 VBOXDISPDBG_STATE_INITIALIZING,
61 VBOXDISPDBG_STATE_INITIALIZED,
62} VBOXDISPDBG_STATE;
63
64typedef struct VBOXDISPDBG
65{
66 VBOXDISPKMT_CALLBACKS KmtCallbacks;
67 VBOXDISPDBG_STATE enmState;
68} VBOXDISPDBG, *PVBOXDISPDBG;
69
70static VBOXDISPDBG g_VBoxDispDbg = {0};
71
72PVBOXDISPDBG vboxDispDbgGet()
73{
74 if (ASMAtomicCmpXchgU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_INITIALIZING, VBOXDISPDBG_STATE_UNINITIALIZED))
75 {
76 HRESULT hr = vboxDispKmtCallbacksInit(&g_VBoxDispDbg.KmtCallbacks);
77 Assert(hr == S_OK);
78 if (hr == S_OK)
79 {
80 ASMAtomicWriteU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_INITIALIZED);
81 return &g_VBoxDispDbg;
82 }
83 else
84 {
85 ASMAtomicWriteU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_UNINITIALIZED);
86 }
87 }
88 else if (ASMAtomicReadU32((volatile uint32_t *)&g_VBoxDispDbg.enmState) == VBOXDISPDBG_STATE_INITIALIZED)
89 {
90 return &g_VBoxDispDbg;
91 }
92 Assert(0);
93 return NULL;
94}
95
96void vboxDispLogDrv(char * szString)
97{
98 PVBOXDISPDBG pDbg = vboxDispDbgGet();
99 if (!pDbg)
100 {
101 /* do not use WARN her esince this would lead to a recursion */
102 WARN_BREAK();
103 return;
104 }
105
106 VBOXDISPKMT_ADAPTER Adapter;
107 HRESULT hr = vboxDispKmtOpenAdapter(&pDbg->KmtCallbacks, &Adapter);
108 if (hr == S_OK)
109 {
110 uint32_t cbString = (uint32_t)strlen(szString) + 1;
111 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
112 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
113 if (pCmd)
114 {
115 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
116 memcpy(pCmd->aStringBuf, szString, cbString);
117
118 D3DKMT_ESCAPE EscapeData = {0};
119 EscapeData.hAdapter = Adapter.hAdapter;
120 //EscapeData.hDevice = NULL;
121 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
122 // EscapeData.Flags.HardwareAccess = 1;
123 EscapeData.pPrivateDriverData = pCmd;
124 EscapeData.PrivateDriverDataSize = cbCmd;
125 //EscapeData.hContext = NULL;
126
127 int Status = pDbg->KmtCallbacks.pfnD3DKMTEscape(&EscapeData);
128 if (Status)
129 {
130 WARN_BREAK();
131 }
132
133 RTMemFree(pCmd);
134 }
135 else
136 {
137 WARN_BREAK();
138 }
139 hr = vboxDispKmtCloseAdapter(&Adapter);
140 if(hr != S_OK)
141 {
142 WARN_BREAK();
143 }
144 }
145}
146
147void vboxDispLogDrvF(char * szString, ...)
148{
149 char szBuffer[4096] = {0};
150 va_list pArgList;
151 va_start(pArgList, szString);
152 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
153 va_end(pArgList);
154
155 vboxDispLogDrv(szBuffer);
156}
157
158void vboxDispLogDbgPrintF(char * szString, ...)
159{
160 char szBuffer[4096] = {0};
161 va_list pArgList;
162 va_start(pArgList, szString);
163 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
164 va_end(pArgList);
165
166 OutputDebugStringA(szBuffer);
167}
168
169
170VOID vboxVDbgDoDumpSurfRectByAlloc(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
171{
172 vboxVDbgDoDumpSurfRectByRc(pPrefix, pAlloc->pRc, pAlloc->iAlloc, pRect, pSuffix);
173}
174
175VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
176{
177 if (pPrefix)
178 {
179 vboxVDbgPrint(("%s", pPrefix));
180 }
181
182 Assert(pAlloc->hAllocation);
183
184 D3DDDICB_LOCK LockData;
185 LockData.hAllocation = pAlloc->hAllocation;
186 LockData.PrivateDriverData = 0;
187 LockData.NumPages = 0;
188 LockData.pPages = NULL;
189 LockData.pData = NULL; /* out */
190 LockData.Flags.Value = 0;
191 LockData.Flags.LockEntire =1;
192 LockData.Flags.ReadOnly = 1;
193
194 PVBOXWDDMDISP_DEVICE pDevice = pAlloc->pRc->pDevice;
195
196 HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
197 Assert(hr == S_OK);
198 if (hr == S_OK)
199 {
200 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
201 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
202 LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch));
203 if (pRect)
204 {
205 Assert(pRect->right > pRect->left);
206 Assert(pRect->bottom > pRect->top);
207 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
208 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
209 ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
210 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch));
211 }
212 Assert(0);
213
214 D3DDDICB_UNLOCK DdiUnlock;
215
216 DdiUnlock.NumAllocations = 1;
217 DdiUnlock.phAllocations = &pAlloc->hAllocation;
218
219 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
220 Assert(hr == S_OK);
221 }
222 if (pSuffix)
223 {
224 vboxVDbgPrint(("%s\n", pSuffix));
225 }
226}
227
228
229VOID vboxVDbgDoDumpSurfRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, const char* pSuffix)
230{
231 Assert(pRc->cAllocations > iAlloc);
232 BOOL bReleaseSurf = false;
233 IDirect3DSurface9 *pSurf;
234 HRESULT hr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
235 Assert(hr == S_OK);
236 if (hr == S_OK)
237 {
238 vboxVDbgDoDumpSurfRect(pPrefix, pSurf, pRect, pSuffix, true);
239 pSurf->Release();
240 }
241}
242
243VOID vboxVDbgDoDumpSurfRect(const char * pPrefix, IDirect3DSurface9 *pSurf, const RECT *pRect, const char * pSuffix, bool bBreak)
244{
245 if (pPrefix)
246 {
247 vboxVDbgPrint(("%s", pPrefix));
248 }
249
250 D3DSURFACE_DESC Desc;
251 HRESULT hr = pSurf->GetDesc(&Desc);
252 Assert(hr == S_OK);
253 if (hr == S_OK)
254 {
255 D3DLOCKED_RECT Lr;
256 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
257 Assert(hr == S_OK);
258 if (hr == S_OK)
259 {
260 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
261 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
262 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
263 if (pRect)
264 {
265 Assert(pRect->right > pRect->left);
266 Assert(pRect->bottom > pRect->top);
267 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
268 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
269 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
270 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
271 }
272
273 if (bBreak)
274 {
275 Assert(0);
276
277 hr = pSurf->UnlockRect();
278 Assert(hr == S_OK);
279 }
280 }
281 }
282
283 if (pSuffix)
284 {
285 vboxVDbgPrint(("%s", pSuffix));
286 }
287}
288
289VOID vboxVDbgDoDumpSurf(const char * pPrefix, IDirect3DSurface9 *pSurf, const char * pSuffix)
290{
291 vboxVDbgDoDumpSurfRect(pPrefix, pSurf, NULL, pSuffix, true);
292}
293
294#define VBOXVDBG_STRCASE(_t) \
295 case _t: return #_t;
296#define VBOXVDBG_STRCASE_UNKNOWN() \
297 default: Assert(0); return "Unknown";
298
299const char* vboxVDbgStrCubeFaceType(D3DCUBEMAP_FACES enmFace)
300{
301 switch (enmFace)
302 {
303 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_X);
304 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_X);
305 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Y);
306 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Y);
307 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Z);
308 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Z);
309 VBOXVDBG_STRCASE_UNKNOWN();
310 }
311}
312
313VOID vboxVDbgDoDumpRcRect(const char * pPrefix, IDirect3DResource9 *pRc, const RECT *pRect, const char * pSuffix)
314{
315 if (pPrefix)
316 {
317 vboxVDbgPrint(("%s", pPrefix));
318 }
319
320 switch (pRc->GetType())
321 {
322 case D3DRTYPE_TEXTURE:
323 {
324 vboxVDbgPrint(("this is a texture\n"));
325
326 IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pRc;
327 IDirect3DSurface9 *pSurf;
328 HRESULT hr = pTex->GetSurfaceLevel(0, &pSurf);
329 Assert(hr == S_OK);
330 if (hr == S_OK)
331 {
332 vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
333 pSurf->Release();
334 }
335 break;
336 }
337 case D3DRTYPE_CUBETEXTURE:
338 {
339 vboxVDbgPrint(("this is a cube texture\n"));
340
341 IDirect3DCubeTexture9 *pCubeTex = (IDirect3DCubeTexture9*)pRc;
342 IDirect3DSurface9 *apSurf[6] = {0};
343 for (UINT i = D3DCUBEMAP_FACE_POSITIVE_X; i < D3DCUBEMAP_FACE_POSITIVE_X + 6; ++i)
344 {
345 vboxVDbgPrint(("face %s: ", vboxVDbgStrCubeFaceType((D3DCUBEMAP_FACES)i)));
346
347 HRESULT hr = pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0, &apSurf[i]);
348 Assert(hr == S_OK);
349 if (hr == S_OK)
350 {
351 vboxVDbgDoDumpSurfRect("", apSurf[i], pRect, "\n", false);
352 }
353 else
354 {
355 Assert(0);
356 }
357 }
358
359 Assert(0);
360
361 for (UINT i = D3DCUBEMAP_FACE_POSITIVE_X; i < D3DCUBEMAP_FACE_POSITIVE_X + 6; ++i)
362 {
363 apSurf[i]->UnlockRect();
364 apSurf[i]->Release();
365 }
366
367 break;
368 }
369 case D3DRTYPE_SURFACE:
370 {
371 vboxVDbgPrint(("this is a surface\n"));
372 IDirect3DSurface9 *pSurf = (IDirect3DSurface9 *)pRc;
373 vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
374 }
375 default:
376 vboxVDbgPrint(("unsupported rc type\n"));
377 Assert(0);
378 }
379
380 if (pSuffix)
381 {
382 vboxVDbgPrint(("%s", pSuffix));
383 }
384}
385
386VOID vboxVDbgDoDumpRcRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, const RECT *pRect, const char* pSuffix)
387{
388 vboxVDbgDoDumpRcRect(pPrefix, (IDirect3DResource9*)pRc->aAllocations[0].pD3DIf, pRect, pSuffix);
389}
390
391VOID vboxVDbgDoDumpTex(const char * pPrefix, IDirect3DBaseTexture9 *pTexBase, const char * pSuffix)
392{
393 vboxVDbgDoDumpRcRect(pPrefix, pTexBase, NULL, pSuffix);
394}
395
396VOID vboxVDbgDoDumpRt(const char * pPrefix, IDirect3DDevice9 *pDevice, const char * pSuffix)
397{
398 IDirect3DSurface9 *pRt;
399 HRESULT hr = pDevice->GetRenderTarget(0, &pRt);
400 Assert(hr == S_OK);
401 if (hr == S_OK)
402 {
403 vboxVDbgDoDumpSurf(pPrefix, pRt, pSuffix);
404 }
405 else
406 {
407 vboxVDbgPrint((__FUNCTION__": ERROR getting rt: 0x%x", hr));
408 }
409}
410
411void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
412{
413 Assert(pRc->cAllocations > iAlloc);
414 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
415 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
416 BOOL bFrontBuf = FALSE;
417 if (bPrimary)
418 {
419 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
420 Assert(pSwapchain);
421 bFrontBuf = (vboxWddmSwapchainGetFb(pSwapchain)->pAlloc == pAlloc);
422 }
423 vboxVDbgPrint(("%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
424 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
425 bPrimary ?
426 (bFrontBuf ? "Front Buffer" : "Back Buffer")
427 : "?Everage? Alloc",
428 pSuffix));
429}
430
431void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix)
432{
433 vboxVDbgPrint(("%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix));
434}
435#endif
436
437#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
438
439static PVOID g_VBoxWDbgVEHandler = NULL;
440LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
441{
442 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
443 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
444 switch (pExceptionRecord->ExceptionCode)
445 {
446 case 0x40010006: /* <- OutputDebugString exception, ignore */
447 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
448 case 0x000006d9: /* <- RPC exception, ignore */
449 case 0x406d1388: /* <- VS/WinDbg thread naming exception, ignore */
450 break;
451 default:
452 AssertRelease(0);
453 break;
454 }
455 return EXCEPTION_CONTINUE_SEARCH;
456}
457
458void vboxVDbgVEHandlerRegister()
459{
460 Assert(!g_VBoxWDbgVEHandler);
461 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
462 Assert(g_VBoxWDbgVEHandler);
463}
464
465void vboxVDbgVEHandlerUnregister()
466{
467 Assert(g_VBoxWDbgVEHandler);
468 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
469 Assert(uResult);
470 g_VBoxWDbgVEHandler = NULL;
471}
472
473#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette