VirtualBox

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

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

wddm/3d: 1.fix ie9 under Aero (still some problems w/o Aero), 2.Fix the driver crash

  • 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 37734 2011-07-01 16:36:39Z 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
52DWORD g_VBoxVDbgFDumpSetTexture = 0;
53DWORD g_VBoxVDbgFDumpDrawPrim = 0;
54DWORD g_VBoxVDbgFDumpTexBlt = 0;
55DWORD g_VBoxVDbgFDumpBlt = 0;
56DWORD g_VBoxVDbgFDumpRtSynch = 0;
57
58typedef enum
59{
60 VBOXDISPDBG_STATE_UNINITIALIZED = 0,
61 VBOXDISPDBG_STATE_INITIALIZING,
62 VBOXDISPDBG_STATE_INITIALIZED,
63} VBOXDISPDBG_STATE;
64
65typedef struct VBOXDISPDBG
66{
67 VBOXDISPKMT_CALLBACKS KmtCallbacks;
68 VBOXDISPDBG_STATE enmState;
69} VBOXDISPDBG, *PVBOXDISPDBG;
70
71static VBOXDISPDBG g_VBoxDispDbg = {0};
72
73PVBOXDISPDBG vboxDispDbgGet()
74{
75 if (ASMAtomicCmpXchgU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_INITIALIZING, VBOXDISPDBG_STATE_UNINITIALIZED))
76 {
77 HRESULT hr = vboxDispKmtCallbacksInit(&g_VBoxDispDbg.KmtCallbacks);
78 Assert(hr == S_OK);
79 if (hr == S_OK)
80 {
81 ASMAtomicWriteU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_INITIALIZED);
82 return &g_VBoxDispDbg;
83 }
84 else
85 {
86 ASMAtomicWriteU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_UNINITIALIZED);
87 }
88 }
89 else if (ASMAtomicReadU32((volatile uint32_t *)&g_VBoxDispDbg.enmState) == VBOXDISPDBG_STATE_INITIALIZED)
90 {
91 return &g_VBoxDispDbg;
92 }
93 Assert(0);
94 return NULL;
95}
96
97void vboxDispLogDrv(char * szString)
98{
99 PVBOXDISPDBG pDbg = vboxDispDbgGet();
100 if (!pDbg)
101 {
102 /* do not use WARN her esince this would lead to a recursion */
103 WARN_BREAK();
104 return;
105 }
106
107 VBOXDISPKMT_ADAPTER Adapter;
108 HRESULT hr = vboxDispKmtOpenAdapter(&pDbg->KmtCallbacks, &Adapter);
109 if (hr == S_OK)
110 {
111 uint32_t cbString = (uint32_t)strlen(szString) + 1;
112 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
113 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
114 if (pCmd)
115 {
116 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
117 memcpy(pCmd->aStringBuf, szString, cbString);
118
119 D3DKMT_ESCAPE EscapeData = {0};
120 EscapeData.hAdapter = Adapter.hAdapter;
121 //EscapeData.hDevice = NULL;
122 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
123 // EscapeData.Flags.HardwareAccess = 1;
124 EscapeData.pPrivateDriverData = pCmd;
125 EscapeData.PrivateDriverDataSize = cbCmd;
126 //EscapeData.hContext = NULL;
127
128 int Status = pDbg->KmtCallbacks.pfnD3DKMTEscape(&EscapeData);
129 if (Status)
130 {
131 WARN_BREAK();
132 }
133
134 RTMemFree(pCmd);
135 }
136 else
137 {
138 WARN_BREAK();
139 }
140 hr = vboxDispKmtCloseAdapter(&Adapter);
141 if(hr != S_OK)
142 {
143 WARN_BREAK();
144 }
145 }
146}
147
148void vboxDispLogDrvF(char * szString, ...)
149{
150 char szBuffer[4096] = {0};
151 va_list pArgList;
152 va_start(pArgList, szString);
153 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
154 va_end(pArgList);
155
156 vboxDispLogDrv(szBuffer);
157}
158
159void vboxDispLogDbgPrintF(char * szString, ...)
160{
161 char szBuffer[4096] = {0};
162 va_list pArgList;
163 va_start(pArgList, szString);
164 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
165 va_end(pArgList);
166
167 OutputDebugStringA(szBuffer);
168}
169
170
171VOID vboxVDbgDoDumpSurfRectByAlloc(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
172{
173 vboxVDbgDoDumpSurfRectByRc(pPrefix, pAlloc->pRc, pAlloc->iAlloc, pRect, pSuffix);
174}
175
176VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
177{
178 if (pPrefix)
179 {
180 vboxVDbgPrint(("%s", pPrefix));
181 }
182
183 Assert(pAlloc->hAllocation);
184
185 D3DDDICB_LOCK LockData;
186 LockData.hAllocation = pAlloc->hAllocation;
187 LockData.PrivateDriverData = 0;
188 LockData.NumPages = 0;
189 LockData.pPages = NULL;
190 LockData.pData = NULL; /* out */
191 LockData.Flags.Value = 0;
192 LockData.Flags.LockEntire =1;
193 LockData.Flags.ReadOnly = 1;
194
195 PVBOXWDDMDISP_DEVICE pDevice = pAlloc->pRc->pDevice;
196
197 HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
198 Assert(hr == S_OK);
199 if (hr == S_OK)
200 {
201 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
202 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
203 LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch));
204 if (pRect)
205 {
206 Assert(pRect->right > pRect->left);
207 Assert(pRect->bottom > pRect->top);
208 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
209 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
210 ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
211 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch));
212 }
213 Assert(0);
214
215 D3DDDICB_UNLOCK DdiUnlock;
216
217 DdiUnlock.NumAllocations = 1;
218 DdiUnlock.phAllocations = &pAlloc->hAllocation;
219
220 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
221 Assert(hr == S_OK);
222 }
223 if (pSuffix)
224 {
225 vboxVDbgPrint(("%s\n", pSuffix));
226 }
227}
228
229
230VOID vboxVDbgDoDumpSurfRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, const char* pSuffix)
231{
232 Assert(pRc->cAllocations > iAlloc);
233 BOOL bReleaseSurf = false;
234 IDirect3DSurface9 *pSurf;
235 HRESULT hr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
236 Assert(hr == S_OK);
237 if (hr == S_OK)
238 {
239 vboxVDbgDoDumpSurfRect(pPrefix, pSurf, pRect, pSuffix, true);
240 pSurf->Release();
241 }
242}
243
244VOID vboxVDbgDoDumpSurfRect(const char * pPrefix, IDirect3DSurface9 *pSurf, const RECT *pRect, const char * pSuffix, bool bBreak)
245{
246 if (pPrefix)
247 {
248 vboxVDbgPrint(("%s", pPrefix));
249 }
250
251 D3DSURFACE_DESC Desc;
252 HRESULT hr = pSurf->GetDesc(&Desc);
253 Assert(hr == S_OK);
254 if (hr == S_OK)
255 {
256 D3DLOCKED_RECT Lr;
257 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
258 Assert(hr == S_OK);
259 if (hr == S_OK)
260 {
261 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
262 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">surface info</exec>\n",
263 Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch));
264 if (pRect)
265 {
266 Assert(pRect->right > pRect->left);
267 Assert(pRect->bottom > pRect->top);
268 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
269 vboxVDbgPrint(("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">rect info</exec>\n",
270 ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
271 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch));
272 }
273
274 if (bBreak)
275 {
276 Assert(0);
277
278 hr = pSurf->UnlockRect();
279 Assert(hr == S_OK);
280 }
281 }
282 }
283
284 if (pSuffix)
285 {
286 vboxVDbgPrint(("%s", pSuffix));
287 }
288}
289
290VOID vboxVDbgDoDumpSurf(const char * pPrefix, IDirect3DSurface9 *pSurf, const char * pSuffix)
291{
292 vboxVDbgDoDumpSurfRect(pPrefix, pSurf, NULL, pSuffix, true);
293}
294
295#define VBOXVDBG_STRCASE(_t) \
296 case _t: return #_t;
297#define VBOXVDBG_STRCASE_UNKNOWN() \
298 default: Assert(0); return "Unknown";
299
300const char* vboxVDbgStrCubeFaceType(D3DCUBEMAP_FACES enmFace)
301{
302 switch (enmFace)
303 {
304 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_X);
305 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_X);
306 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Y);
307 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Y);
308 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Z);
309 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Z);
310 VBOXVDBG_STRCASE_UNKNOWN();
311 }
312}
313
314VOID vboxVDbgDoDumpRcRect(const char * pPrefix, IDirect3DResource9 *pRc, const RECT *pRect, const char * pSuffix)
315{
316 if (pPrefix)
317 {
318 vboxVDbgPrint(("%s", pPrefix));
319 }
320
321 switch (pRc->GetType())
322 {
323 case D3DRTYPE_TEXTURE:
324 {
325 vboxVDbgPrint(("this is a texture\n"));
326
327 IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pRc;
328 IDirect3DSurface9 *pSurf;
329 HRESULT hr = pTex->GetSurfaceLevel(0, &pSurf);
330 Assert(hr == S_OK);
331 if (hr == S_OK)
332 {
333 vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
334 pSurf->Release();
335 }
336 break;
337 }
338 case D3DRTYPE_CUBETEXTURE:
339 {
340 vboxVDbgPrint(("this is a cube texture\n"));
341
342 IDirect3DCubeTexture9 *pCubeTex = (IDirect3DCubeTexture9*)pRc;
343 IDirect3DSurface9 *apSurf[6] = {0};
344 for (UINT i = D3DCUBEMAP_FACE_POSITIVE_X; i < D3DCUBEMAP_FACE_POSITIVE_X + 6; ++i)
345 {
346 vboxVDbgPrint(("face %s: ", vboxVDbgStrCubeFaceType((D3DCUBEMAP_FACES)i)));
347
348 HRESULT hr = pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0, &apSurf[i]);
349 Assert(hr == S_OK);
350 if (hr == S_OK)
351 {
352 vboxVDbgDoDumpSurfRect("", apSurf[i], pRect, "\n", false);
353 }
354 else
355 {
356 Assert(0);
357 }
358 }
359
360 Assert(0);
361
362 for (UINT i = D3DCUBEMAP_FACE_POSITIVE_X; i < D3DCUBEMAP_FACE_POSITIVE_X + 6; ++i)
363 {
364 apSurf[i]->UnlockRect();
365 apSurf[i]->Release();
366 }
367
368 break;
369 }
370 case D3DRTYPE_SURFACE:
371 {
372 vboxVDbgPrint(("this is a surface\n"));
373 IDirect3DSurface9 *pSurf = (IDirect3DSurface9 *)pRc;
374 vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
375 }
376 default:
377 vboxVDbgPrint(("unsupported rc type\n"));
378 Assert(0);
379 }
380
381 if (pSuffix)
382 {
383 vboxVDbgPrint(("%s", pSuffix));
384 }
385}
386
387VOID vboxVDbgDoDumpRcRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, const RECT *pRect, const char* pSuffix)
388{
389 vboxVDbgDoDumpRcRect(pPrefix, (IDirect3DResource9*)pRc->aAllocations[0].pD3DIf, pRect, pSuffix);
390}
391
392VOID vboxVDbgDoDumpTex(const char * pPrefix, IDirect3DBaseTexture9 *pTexBase, const char * pSuffix)
393{
394 vboxVDbgDoDumpRcRect(pPrefix, pTexBase, NULL, pSuffix);
395}
396
397VOID vboxVDbgDoDumpRt(const char * pPrefix, IDirect3DDevice9 *pDevice, const char * pSuffix)
398{
399 IDirect3DSurface9 *pRt;
400 HRESULT hr = pDevice->GetRenderTarget(0, &pRt);
401 Assert(hr == S_OK);
402 if (hr == S_OK)
403 {
404 vboxVDbgDoDumpSurf(pPrefix, pRt, pSuffix);
405 }
406 else
407 {
408 vboxVDbgPrint((__FUNCTION__": ERROR getting rt: 0x%x", hr));
409 }
410}
411
412void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
413{
414 Assert(pRc->cAllocations > iAlloc);
415 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
416 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
417 BOOL bFrontBuf = FALSE;
418 if (bPrimary)
419 {
420 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
421 Assert(pSwapchain);
422 bFrontBuf = (vboxWddmSwapchainGetFb(pSwapchain)->pAlloc == pAlloc);
423 }
424 vboxVDbgPrint(("%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
425 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
426 bPrimary ?
427 (bFrontBuf ? "Front Buffer" : "Back Buffer")
428 : "?Everage? Alloc",
429 pSuffix));
430}
431
432void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix)
433{
434 vboxVDbgPrint(("%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix));
435}
436#endif
437
438#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
439
440static PVOID g_VBoxWDbgVEHandler = NULL;
441LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
442{
443 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
444 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
445 switch (pExceptionRecord->ExceptionCode)
446 {
447 case 0x40010006: /* <- OutputDebugString exception, ignore */
448 case 0xe06d7363: /* <- ms compiler - generated exception related to C++ exception */
449 case 0x000006d9: /* <- RPC exception, ignore */
450 case 0x406d1388: /* <- VS/WinDbg thread naming exception, ignore */
451 case 0xe0434f4d: /* <- CLR exception */
452 break;
453 default:
454 AssertRelease(0);
455 break;
456 }
457 return EXCEPTION_CONTINUE_SEARCH;
458}
459
460void vboxVDbgVEHandlerRegister()
461{
462 Assert(!g_VBoxWDbgVEHandler);
463 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
464 Assert(g_VBoxWDbgVEHandler);
465}
466
467void vboxVDbgVEHandlerUnregister()
468{
469 Assert(g_VBoxWDbgVEHandler);
470 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
471 Assert(uResult);
472 g_VBoxWDbgVEHandler = NULL;
473}
474
475#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