VirtualBox

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

Last change on this file since 39160 was 39160, checked in by vboxsync, 13 years ago

wddm: better logging

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.7 KB
Line 
1/* $Id: VBoxDispDbg.cpp 39160 2011-11-01 14:35:23Z 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
52#define VBOXWDDMDISP_DEBUG_DUMP_DEFAULT 0
53DWORD g_VBoxVDbgFDumpSetTexture = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
54DWORD g_VBoxVDbgFDumpDrawPrim = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
55DWORD g_VBoxVDbgFDumpTexBlt = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
56DWORD g_VBoxVDbgFDumpBlt = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
57DWORD g_VBoxVDbgFDumpRtSynch = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
58DWORD g_VBoxVDbgFDumpFlush = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
59DWORD g_VBoxVDbgFDumpShared = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
60DWORD g_VBoxVDbgFDumpLock = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
61DWORD g_VBoxVDbgFDumpUnlock = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
62
63DWORD g_VBoxVDbgFBreakShared = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
64DWORD g_VBoxVDbgFBreakDdi = 0;
65
66DWORD g_VBoxVDbgFCheckSysMemSync = 0;
67DWORD g_VBoxVDbgFCheckBlt = 0;
68DWORD g_VBoxVDbgFCheckTexBlt = 0;
69
70DWORD g_VBoxVDbgFSkipCheckTexBltDwmWndUpdate = 1;
71
72DWORD g_VBoxVDbgFLogRel = 1;
73DWORD g_VBoxVDbgFLog = 1;
74DWORD g_VBoxVDbgFLogFlow = 0;
75
76DWORD g_VBoxVDbgFIsModuleNameInited = 0;
77char g_VBoxVDbgModuleName[MAX_PATH];
78
79LONG g_VBoxVDbgFIsDwm = -1;
80
81DWORD g_VBoxVDbgPid = 0;
82
83void vboxDispLogDbgPrintF(char * szString, ...)
84{
85 char szBuffer[4096] = {0};
86 va_list pArgList;
87 va_start(pArgList, szString);
88 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
89 va_end(pArgList);
90
91 OutputDebugStringA(szBuffer);
92}
93
94VOID vboxVDbgDoDumpSurfRectByAlloc(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
95{
96 vboxVDbgDoDumpSurfRectByRc(pPrefix, pAlloc->pRc, pAlloc->iAlloc, pRect, pSuffix);
97}
98
99VOID vboxVDbgDoPrintDmlCmd(const char* pszDesc, const char* pszCmd)
100{
101 vboxVDbgPrint(("<?dml?><exec cmd=\"%s\">%s</exec>, ( %s )\n", pszCmd, pszDesc, pszCmd));
102}
103
104VOID vboxVDbgDoPrintDumpCmd(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
105{
106 char Cmd[1024];
107 sprintf(Cmd, "!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d", pvData, width, height, bpp, pitch);
108 vboxVDbgDoPrintDmlCmd(pszDesc, Cmd);
109}
110
111VOID vboxVDbgDoPrintLopLastCmd(const char* pszDesc)
112{
113 vboxVDbgDoPrintDmlCmd(pszDesc, "ed @@(&vboxVDbgLoop) 0");
114}
115
116VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, const RECT *pRect, const char* pSuffix)
117{
118 if (pPrefix)
119 {
120 vboxVDbgPrint(("%s", pPrefix));
121 }
122
123 Assert(pAlloc->hAllocation);
124
125 HANDLE hSharedHandle = pAlloc->hSharedHandle;
126
127 vboxVDbgPrint(("SharedHandle: (0x%p)\n", hSharedHandle));
128
129 D3DDDICB_LOCK LockData;
130 LockData.hAllocation = pAlloc->hAllocation;
131 LockData.PrivateDriverData = 0;
132 LockData.NumPages = 0;
133 LockData.pPages = NULL;
134 LockData.pData = NULL; /* out */
135 LockData.Flags.Value = 0;
136 LockData.Flags.LockEntire =1;
137 LockData.Flags.ReadOnly = 1;
138
139 PVBOXWDDMDISP_DEVICE pDevice = pAlloc->pRc->pDevice;
140
141 HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
142 Assert(hr == S_OK);
143 if (hr == S_OK)
144 {
145 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
146 vboxVDbgDoPrintDumpCmd("Surf Info", LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch);
147 if (pRect)
148 {
149 Assert(pRect->right > pRect->left);
150 Assert(pRect->bottom > pRect->top);
151 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
152 vboxVDbgDoPrintDumpCmd("Rect Info", ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
153 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch);
154 }
155 Assert(0);
156
157 D3DDDICB_UNLOCK DdiUnlock;
158
159 DdiUnlock.NumAllocations = 1;
160 DdiUnlock.phAllocations = &pAlloc->hAllocation;
161
162 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
163 Assert(hr == S_OK);
164 }
165 if (pSuffix)
166 {
167 vboxVDbgPrint(("%s\n", pSuffix));
168 }
169}
170
171
172VOID vboxVDbgDoDumpSurfRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const RECT *pRect, const char* pSuffix)
173{
174 Assert(pRc->cAllocations > iAlloc);
175 BOOL bReleaseSurf = false;
176 IDirect3DSurface9 *pSurf;
177 HRESULT hr = vboxWddmSurfGet(pRc, iAlloc, &pSurf);
178 Assert(hr == S_OK);
179 if (hr == S_OK)
180 {
181 vboxVDbgDoDumpSurfRect(pPrefix, pSurf, pRect, pSuffix, true);
182 pSurf->Release();
183 }
184}
185
186VOID vboxVDbgDoDumpSurfRect(const char * pPrefix, IDirect3DSurface9 *pSurf, const RECT *pRect, const char * pSuffix, bool bBreak)
187{
188 if (pPrefix)
189 {
190 vboxVDbgPrint(("%s", pPrefix));
191 }
192
193 D3DSURFACE_DESC Desc;
194 HRESULT hr = pSurf->GetDesc(&Desc);
195 Assert(hr == S_OK);
196 if (hr == S_OK)
197 {
198 D3DLOCKED_RECT Lr;
199 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
200 Assert(hr == S_OK);
201 if (hr == S_OK)
202 {
203 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
204 vboxVDbgDoPrintDumpCmd("Surf Info", Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch);
205 if (pRect)
206 {
207 Assert(pRect->right > pRect->left);
208 Assert(pRect->bottom > pRect->top);
209 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
210 vboxVDbgDoPrintDumpCmd("Rect Info", ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
211 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch);
212 }
213
214 if (bBreak)
215 {
216 Assert(0);
217
218 hr = pSurf->UnlockRect();
219 Assert(hr == S_OK);
220 }
221 }
222 }
223
224 if (pSuffix)
225 {
226 vboxVDbgPrint(("%s", pSuffix));
227 }
228}
229
230VOID vboxVDbgDoDumpSurf(const char * pPrefix, IDirect3DSurface9 *pSurf, const char * pSuffix)
231{
232 vboxVDbgDoDumpSurfRect(pPrefix, pSurf, NULL, pSuffix, true);
233}
234
235#define VBOXVDBG_STRCASE(_t) \
236 case _t: return #_t;
237#define VBOXVDBG_STRCASE_UNKNOWN() \
238 default: Assert(0); return "Unknown";
239
240const char* vboxVDbgStrCubeFaceType(D3DCUBEMAP_FACES enmFace)
241{
242 switch (enmFace)
243 {
244 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_X);
245 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_X);
246 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Y);
247 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Y);
248 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Z);
249 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Z);
250 VBOXVDBG_STRCASE_UNKNOWN();
251 }
252}
253
254VOID vboxVDbgDoDumpRcRect(const char * pPrefix, IDirect3DResource9 *pRc, const RECT *pRect, const char * pSuffix)
255{
256 if (pPrefix)
257 {
258 vboxVDbgPrint(("%s", pPrefix));
259 }
260
261 switch (pRc->GetType())
262 {
263 case D3DRTYPE_TEXTURE:
264 {
265 vboxVDbgPrint(("this is a texture\n"));
266
267 IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pRc;
268 IDirect3DSurface9 *pSurf;
269 HRESULT hr = pTex->GetSurfaceLevel(0, &pSurf);
270 Assert(hr == S_OK);
271 if (hr == S_OK)
272 {
273 vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
274 pSurf->Release();
275 }
276 break;
277 }
278 case D3DRTYPE_CUBETEXTURE:
279 {
280 vboxVDbgPrint(("this is a cube texture\n"));
281
282 IDirect3DCubeTexture9 *pCubeTex = (IDirect3DCubeTexture9*)pRc;
283 IDirect3DSurface9 *apSurf[6] = {0};
284 for (UINT i = D3DCUBEMAP_FACE_POSITIVE_X; i < D3DCUBEMAP_FACE_POSITIVE_X + 6; ++i)
285 {
286 vboxVDbgPrint(("face %s: ", vboxVDbgStrCubeFaceType((D3DCUBEMAP_FACES)i)));
287
288 HRESULT hr = pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0, &apSurf[i]);
289 Assert(hr == S_OK);
290 if (hr == S_OK)
291 {
292 vboxVDbgDoDumpSurfRect("", apSurf[i], pRect, "\n", false);
293 }
294 else
295 {
296 Assert(0);
297 }
298 }
299
300 Assert(0);
301
302 for (UINT i = D3DCUBEMAP_FACE_POSITIVE_X; i < D3DCUBEMAP_FACE_POSITIVE_X + 6; ++i)
303 {
304 apSurf[i]->UnlockRect();
305 apSurf[i]->Release();
306 }
307
308 break;
309 }
310 case D3DRTYPE_SURFACE:
311 {
312 vboxVDbgPrint(("this is a surface\n"));
313 IDirect3DSurface9 *pSurf = (IDirect3DSurface9 *)pRc;
314 vboxVDbgDoDumpSurfRect("", pSurf, pRect, "\n", true);
315 break;
316 }
317 default:
318 vboxVDbgPrint(("unsupported rc type\n"));
319 Assert(0);
320 }
321
322 if (pSuffix)
323 {
324 vboxVDbgPrint(("%s", pSuffix));
325 }
326}
327
328VOID vboxVDbgDoDumpRcRectByAlloc(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DResource9 *pD3DIf, const RECT *pRect, const char* pSuffix)
329{
330 if (pPrefix)
331 vboxVDbgPrint(("%s", pPrefix));
332
333 if (!pD3DIf)
334 {
335 pD3DIf = (IDirect3DResource9*)pAlloc->pD3DIf;
336 }
337
338 vboxVDbgPrint(("Rc(0x%p), pAlloc(0x%x), pD3DIf(0x%p), SharedHandle(0x%p)\n", pAlloc->pRc, pAlloc, pD3DIf, pAlloc->pRc->aAllocations[0].hSharedHandle));
339
340 vboxVDbgDoDumpRcRect("", pD3DIf, pRect, pSuffix);
341}
342
343VOID vboxVDbgDoDumpRcRectByRc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, const RECT *pRect, const char* pSuffix)
344{
345 vboxVDbgDoDumpRcRectByAlloc(pPrefix, &pRc->aAllocations[0], NULL, pRect, pSuffix);
346}
347
348VOID vboxVDbgDoDumpTex(const char * pPrefix, IDirect3DBaseTexture9 *pTexBase, const char * pSuffix)
349{
350 vboxVDbgDoDumpRcRect(pPrefix, pTexBase, NULL, pSuffix);
351}
352
353VOID vboxVDbgDoDumpRt(const char * pPrefix, PVBOXWDDMDISP_DEVICE pDevice, const char * pSuffix)
354{
355 for (UINT i = 0; i < pDevice->cRTs; ++i)
356 {
357 IDirect3DSurface9 *pRt;
358 PVBOXWDDMDISP_ALLOCATION pAlloc = pDevice->apRTs[i];
359 IDirect3DDevice9 *pDeviceIf = pDevice->pDevice9If;
360 HRESULT hr = pDeviceIf->GetRenderTarget(i, &pRt);
361 Assert(hr == S_OK);
362 if (hr == S_OK)
363 {
364// Assert(pAlloc->pD3DIf == pRt);
365 vboxVDbgDoDumpRcRectByAlloc(pPrefix, pAlloc, NULL, NULL, "\n");
366 pRt->Release();
367 }
368 else
369 {
370 vboxVDbgPrint((__FUNCTION__": ERROR getting rt: 0x%x", hr));
371 }
372 }
373}
374
375VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, const char * pSuffix, bool fBreak)
376{
377 if (pPrefix)
378 {
379 vboxVDbgPrint(("%s", pPrefix));
380 }
381
382 Assert(!pAlloc->hSharedHandle);
383
384 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
385 uint32_t width, height, pitch;
386 RECT Rect, *pRect;
387 void *pvData;
388 Assert(!pAlloc->LockInfo.fFlags.RangeValid);
389 Assert(!pAlloc->LockInfo.fFlags.BoxValid);
390 if (pAlloc->LockInfo.fFlags.AreaValid)
391 {
392 pRect = &pAlloc->LockInfo.Area;
393 width = pAlloc->LockInfo.Area.left - pAlloc->LockInfo.Area.right;
394 height = pAlloc->LockInfo.Area.bottom - pAlloc->LockInfo.Area.top;
395 }
396 else
397 {
398 width = pAlloc->SurfDesc.width;
399 height = pAlloc->SurfDesc.height;
400 Rect.top = 0;
401 Rect.bottom = height;
402 Rect.left = 0;
403 Rect.right = width;
404 pRect = &Rect;
405 }
406
407 if (pAlloc->LockInfo.fFlags.NotifyOnly)
408 {
409 pitch = pAlloc->SurfDesc.pitch;
410 pvData = ((uint8_t*)pAlloc->pvMem) + pitch*pRect->top + ((bpp*pRect->left) >> 3);
411 }
412 else
413 {
414 pvData = pAlloc->LockInfo.pvData;
415 }
416
417 vboxVDbgPrint(("pRc(0x%p) iAlloc(%d), type(%d), cLocks(%d)\n", pAlloc->pRc, pAlloc->iAlloc, pAlloc->enmD3DIfType, pAlloc->LockInfo.cLocks));
418
419 vboxVDbgDoPrintDumpCmd("Surf Info", pvData, width, height, bpp, pitch);
420
421 if (fBreak)
422 {
423 Assert(0);
424 }
425
426 if (pSuffix)
427 {
428 vboxVDbgPrint(("%s", pSuffix));
429 }
430
431}
432
433VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, bool fBreak)
434{
435 const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource;
436 const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
437 pAlloc->LockInfo.pvData = pData->pSurfData;
438 vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fBreak);
439}
440
441VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, bool fBreak)
442{
443 const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource;
444 const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
445 vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fBreak);
446}
447
448BOOL vboxVDbgDoCheckLRects(D3DLOCKED_RECT *pDstLRect, const RECT *pDstRect, D3DLOCKED_RECT *pSrcLRect, const RECT *pSrcRect, DWORD bpp, BOOL fBreakOnMismatch)
449{
450 LONG DstH, DstW, SrcH, SrcW, DstWBytes;
451 BOOL fMatch = FALSE;
452 DstH = pDstRect->bottom - pDstRect->top;
453 DstW = pDstRect->right - pDstRect->left;
454 SrcH = pSrcRect->bottom - pSrcRect->top;
455 SrcW = pSrcRect->right - pSrcRect->left;
456
457 DstWBytes = ((DstW * bpp + 7) >> 3);
458
459 if(DstW != SrcW && DstH != SrcH)
460 {
461 WARN(("stretched comparison not supported!!"));
462 return FALSE;
463 }
464
465 uint8_t *pDst = (uint8_t*)pDstLRect->pBits;
466 uint8_t *pSrc = (uint8_t*)pSrcLRect->pBits;
467 for (LONG i = 0; i < DstH; ++i)
468 {
469 if (!(fMatch = !memcmp(pDst, pSrc, DstWBytes)))
470 {
471 vboxVDbgPrint(("not match!\n"));
472 if (fBreakOnMismatch)
473 Assert(0);
474 break;
475 }
476 pDst += pDstLRect->Pitch;
477 pSrc += pSrcLRect->Pitch;
478 }
479 return fMatch;
480}
481
482#ifndef IN_VBOXCRHGSMI
483BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDstAlloc,
484 const PVBOXWDDMDISP_RESOURCE pSrcRc, uint32_t iSrcAlloc,
485 const RECT *pDstRect,
486 const RECT *pSrcRect,
487 BOOL fBreakOnMismatch)
488{
489 BOOL fMatch = FALSE;
490 RECT DstRect = {0}, SrcRect = {0};
491 if (!pDstRect)
492 {
493 DstRect.left = 0;
494 DstRect.right = pDstRc->aAllocations[iDstAlloc].SurfDesc.width;
495 DstRect.top = 0;
496 DstRect.bottom = pDstRc->aAllocations[iDstAlloc].SurfDesc.height;
497 pDstRect = &DstRect;
498 }
499
500 if (!pSrcRect)
501 {
502 SrcRect.left = 0;
503 SrcRect.right = pSrcRc->aAllocations[iSrcAlloc].SurfDesc.width;
504 SrcRect.top = 0;
505 SrcRect.bottom = pSrcRc->aAllocations[iSrcAlloc].SurfDesc.height;
506 pSrcRect = &SrcRect;
507 }
508
509 if (pDstRc == pSrcRc
510 && iDstAlloc == iSrcAlloc)
511 {
512 if (!memcmp(pDstRect, pSrcRect, sizeof (*pDstRect)))
513 {
514 vboxVDbgPrint(("matching same rect of one allocation, skipping..\n"));
515 return TRUE;
516 }
517 WARN(("matching different rects of the same allocation, unsupported!"));
518 return FALSE;
519 }
520
521 if (pDstRc->RcDesc.enmFormat != pSrcRc->RcDesc.enmFormat)
522 {
523 WARN(("matching different formats, unsupported!"));
524 return FALSE;
525 }
526
527 DWORD bpp = pDstRc->aAllocations[iDstAlloc].SurfDesc.bpp;
528 if (!bpp)
529 {
530 WARN(("uninited bpp! unsupported!"));
531 return FALSE;
532 }
533
534 LONG DstH, DstW, SrcH, SrcW;
535 DstH = pDstRect->bottom - pDstRect->top;
536 DstW = pDstRect->right - pDstRect->left;
537 SrcH = pSrcRect->bottom - pSrcRect->top;
538 SrcW = pSrcRect->right - pSrcRect->left;
539
540 if(DstW != SrcW && DstH != SrcH)
541 {
542 WARN(("stretched comparison not supported!!"));
543 return FALSE;
544 }
545
546 D3DLOCKED_RECT SrcLRect, DstLRect;
547 HRESULT hr = vboxWddmLockRect(pDstRc, iDstAlloc, &DstLRect, pDstRect, D3DLOCK_READONLY);
548 if (FAILED(hr))
549 {
550 WARN(("vboxWddmLockRect failed, hr(0x%x)", hr));
551 return FALSE;
552 }
553
554 hr = vboxWddmLockRect(pSrcRc, iSrcAlloc, &SrcLRect, pSrcRect, D3DLOCK_READONLY);
555 if (FAILED(hr))
556 {
557 WARN(("vboxWddmLockRect failed, hr(0x%x)", hr));
558 hr = vboxWddmUnlockRect(pDstRc, iDstAlloc);
559 return FALSE;
560 }
561
562 fMatch = vboxVDbgDoCheckLRects(&DstLRect, pDstRect, &SrcLRect, pSrcRect, bpp, fBreakOnMismatch);
563
564 hr = vboxWddmUnlockRect(pDstRc, iDstAlloc);
565 Assert(hr == S_OK);
566
567 hr = vboxWddmUnlockRect(pSrcRc, iSrcAlloc);
568 Assert(hr == S_OK);
569
570 return fMatch;
571}
572#endif
573
574void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
575{
576 Assert(pRc->cAllocations > iAlloc);
577 const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
578 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
579 BOOL bFrontBuf = FALSE;
580 if (bPrimary)
581 {
582 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
583 Assert(pSwapchain);
584 bFrontBuf = (vboxWddmSwapchainGetFb(pSwapchain)->pAlloc == pAlloc);
585 }
586 vboxVDbgPrint(("%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
587 pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
588 bPrimary ?
589 (bFrontBuf ? "Front Buffer" : "Back Buffer")
590 : "?Everage? Alloc",
591 pSuffix));
592}
593
594void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix)
595{
596 vboxVDbgPrint(("%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix));
597}
598
599char *vboxVDbgDoGetModuleName()
600{
601 if (!g_VBoxVDbgFIsModuleNameInited)
602 {
603 DWORD cName = GetModuleFileNameA(NULL, g_VBoxVDbgModuleName, RT_ELEMENTS(g_VBoxVDbgModuleName));
604 if (!cName)
605 {
606 DWORD winEr = GetLastError();
607 WARN(("GetModuleFileNameA failed, winEr %d", winEr));
608 return NULL;
609 }
610 g_VBoxVDbgFIsModuleNameInited = TRUE;
611 }
612 return g_VBoxVDbgModuleName;
613}
614
615BOOL vboxVDbgDoCheckExe(const char * pszName)
616{
617 char *pszModule = vboxVDbgDoGetModuleName();
618 if (!pszModule)
619 return FALSE;
620 DWORD cbModule, cbName;
621 cbModule = strlen(pszModule);
622 cbName = strlen(pszName);
623 if (cbName > cbModule)
624 return FALSE;
625 if (_stricmp(pszName, pszModule + (cbModule - cbName)))
626 return FALSE;
627 return TRUE;
628}
629#endif
630
631#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
632
633static PVOID g_VBoxWDbgVEHandler = NULL;
634LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
635{
636 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
637 PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
638 switch (pExceptionRecord->ExceptionCode)
639 {
640 case EXCEPTION_BREAKPOINT:
641 case EXCEPTION_ACCESS_VIOLATION:
642 case EXCEPTION_STACK_OVERFLOW:
643 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
644 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
645 case EXCEPTION_FLT_INVALID_OPERATION:
646 case EXCEPTION_INT_DIVIDE_BY_ZERO:
647 case EXCEPTION_ILLEGAL_INSTRUCTION:
648 AssertRelease(0);
649 break;
650 default:
651 break;
652 }
653 return EXCEPTION_CONTINUE_SEARCH;
654}
655
656void vboxVDbgVEHandlerRegister()
657{
658 Assert(!g_VBoxWDbgVEHandler);
659 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
660 Assert(g_VBoxWDbgVEHandler);
661}
662
663void vboxVDbgVEHandlerUnregister()
664{
665 Assert(g_VBoxWDbgVEHandler);
666 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
667 Assert(uResult);
668 g_VBoxWDbgVEHandler = NULL;
669}
670
671#endif
672
673#if defined(VBOXWDDMDISP_DEBUG) || defined(LOG_TO_BACKDOOR_DRV)
674typedef enum
675{
676 VBOXDISPDBG_STATE_UNINITIALIZED = 0,
677 VBOXDISPDBG_STATE_INITIALIZING,
678 VBOXDISPDBG_STATE_INITIALIZED,
679} VBOXDISPDBG_STATE;
680
681typedef struct VBOXDISPDBG
682{
683 VBOXDISPKMT_CALLBACKS KmtCallbacks;
684 VBOXDISPDBG_STATE enmState;
685} VBOXDISPDBG, *PVBOXDISPDBG;
686
687static VBOXDISPDBG g_VBoxDispDbg = {0};
688
689PVBOXDISPDBG vboxDispDbgGet()
690{
691 if (ASMAtomicCmpXchgU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_INITIALIZING, VBOXDISPDBG_STATE_UNINITIALIZED))
692 {
693 HRESULT hr = vboxDispKmtCallbacksInit(&g_VBoxDispDbg.KmtCallbacks);
694 Assert(hr == S_OK);
695 if (hr == S_OK)
696 {
697 ASMAtomicWriteU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_INITIALIZED);
698 return &g_VBoxDispDbg;
699 }
700 else
701 {
702 ASMAtomicWriteU32((volatile uint32_t *)&g_VBoxDispDbg.enmState, VBOXDISPDBG_STATE_UNINITIALIZED);
703 }
704 }
705 else if (ASMAtomicReadU32((volatile uint32_t *)&g_VBoxDispDbg.enmState) == VBOXDISPDBG_STATE_INITIALIZED)
706 {
707 return &g_VBoxDispDbg;
708 }
709 Assert(0);
710 return NULL;
711}
712
713void vboxDispLogDrv(char * szString)
714{
715 PVBOXDISPDBG pDbg = vboxDispDbgGet();
716 if (!pDbg)
717 {
718 /* do not use WARN her esince this would lead to a recursion */
719 BP_WARN();
720 return;
721 }
722
723 VBOXDISPKMT_ADAPTER Adapter;
724 HRESULT hr = vboxDispKmtOpenAdapter(&pDbg->KmtCallbacks, &Adapter);
725 if (hr == S_OK)
726 {
727 uint32_t cbString = (uint32_t)strlen(szString) + 1;
728 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
729 PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)RTMemAllocZ(cbCmd);
730 if (pCmd)
731 {
732 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
733 memcpy(pCmd->aStringBuf, szString, cbString);
734
735 D3DKMT_ESCAPE EscapeData = {0};
736 EscapeData.hAdapter = Adapter.hAdapter;
737 //EscapeData.hDevice = NULL;
738 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
739 // EscapeData.Flags.HardwareAccess = 1;
740 EscapeData.pPrivateDriverData = pCmd;
741 EscapeData.PrivateDriverDataSize = cbCmd;
742 //EscapeData.hContext = NULL;
743
744 int Status = pDbg->KmtCallbacks.pfnD3DKMTEscape(&EscapeData);
745 if (Status)
746 {
747 BP_WARN();
748 }
749
750 RTMemFree(pCmd);
751 }
752 else
753 {
754 BP_WARN();
755 }
756 hr = vboxDispKmtCloseAdapter(&Adapter);
757 if(hr != S_OK)
758 {
759 BP_WARN();
760 }
761 }
762}
763
764void vboxDispLogDrvF(char * szString, ...)
765{
766 char szBuffer[4096] = {0};
767 va_list pArgList;
768 va_start(pArgList, szString);
769 _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
770 va_end(pArgList);
771
772 vboxDispLogDrv(szBuffer);
773}
774
775static void vboxDispDumpBufDrv(void *pvBuf, uint32_t cbBuf, VBOXDISPIFESCAPE_DBGDUMPBUF_TYPE enmBuf)
776{
777 PVBOXDISPDBG pDbg = vboxDispDbgGet();
778 if (!pDbg)
779 {
780 /* do not use WARN her esince this would lead to a recursion */
781 BP_WARN();
782 return;
783 }
784
785 VBOXDISPKMT_ADAPTER Adapter;
786 HRESULT hr = vboxDispKmtOpenAdapter(&pDbg->KmtCallbacks, &Adapter);
787 if (hr == S_OK)
788 {
789 uint32_t cbCmd = RT_OFFSETOF(VBOXDISPIFESCAPE_DBGDUMPBUF, aBuf[cbBuf]);
790 PVBOXDISPIFESCAPE_DBGDUMPBUF pCmd = (PVBOXDISPIFESCAPE_DBGDUMPBUF)RTMemAllocZ(cbCmd);
791 if (pCmd)
792 {
793 pCmd->EscapeHdr.escapeCode = VBOXESC_DBGDUMPBUF;
794 pCmd->enmType = enmBuf;
795#ifdef VBOX_WDDM_WOW64
796 pCmd->Flags.WoW64 = 1;
797#endif
798 memcpy(pCmd->aBuf, pvBuf, cbBuf);
799
800 D3DKMT_ESCAPE EscapeData = {0};
801 EscapeData.hAdapter = Adapter.hAdapter;
802 //EscapeData.hDevice = NULL;
803 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
804 // EscapeData.Flags.HardwareAccess = 1;
805 EscapeData.pPrivateDriverData = pCmd;
806 EscapeData.PrivateDriverDataSize = cbCmd;
807 //EscapeData.hContext = NULL;
808
809 int Status = pDbg->KmtCallbacks.pfnD3DKMTEscape(&EscapeData);
810 if (Status)
811 {
812 BP_WARN();
813 }
814
815 RTMemFree(pCmd);
816 }
817 else
818 {
819 BP_WARN();
820 }
821 hr = vboxDispKmtCloseAdapter(&Adapter);
822 if(hr != S_OK)
823 {
824 BP_WARN();
825 }
826 }
827}
828
829void vboxDispDumpD3DCAPS9Drv(D3DCAPS9 *pCaps)
830{
831 vboxDispDumpBufDrv(pCaps, sizeof (*pCaps), VBOXDISPIFESCAPE_DBGDUMPBUF_TYPE_D3DCAPS9);
832}
833#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