VirtualBox

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

Last change on this file since 83222 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.5 KB
Line 
1/* $Id: VBoxDispDbg.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * VBoxVideo Display D3D User mode dll
4 */
5
6/*
7 * Copyright (C) 2011-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "VBoxDispD3DCmn.h"
19
20#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
21#include <Psapi.h>
22#endif
23
24#include <stdio.h>
25#include <stdarg.h>
26
27#include <iprt/asm.h>
28#include <iprt/assert.h>
29
30static DWORD g_VBoxVDbgFIsModuleNameInited = 0;
31static char g_VBoxVDbgModuleName[MAX_PATH];
32
33char *vboxVDbgDoGetModuleName()
34{
35 if (!g_VBoxVDbgFIsModuleNameInited)
36 {
37 DWORD cName = GetModuleFileNameA(NULL, g_VBoxVDbgModuleName, RT_ELEMENTS(g_VBoxVDbgModuleName));
38 if (!cName)
39 {
40#ifdef LOG_ENABLED
41 DWORD winEr = GetLastError();
42#endif
43 WARN(("GetModuleFileNameA failed, winEr %d", winEr));
44 return NULL;
45 }
46 g_VBoxVDbgFIsModuleNameInited = TRUE;
47 }
48 return g_VBoxVDbgModuleName;
49}
50
51static void vboxDispLogDbgFormatStringV(char * szBuffer, uint32_t cbBuffer, const char * szString, va_list pArgList)
52{
53 uint32_t cbWritten = sprintf(szBuffer, "['%s' 0x%x.0x%x] Disp: ", vboxVDbgDoGetModuleName(), GetCurrentProcessId(), GetCurrentThreadId());
54 if (cbWritten > cbBuffer)
55 {
56 AssertReleaseFailed();
57 return;
58 }
59
60 _vsnprintf(szBuffer + cbWritten, cbBuffer - cbWritten, szString, pArgList);
61}
62
63#if defined(VBOXWDDMDISP_DEBUG)
64LONG g_VBoxVDbgFIsDwm = -1;
65
66DWORD g_VBoxVDbgPid = 0;
67
68DWORD g_VBoxVDbgFLogRel = 1;
69# if !defined(VBOXWDDMDISP_DEBUG)
70DWORD g_VBoxVDbgFLog = 0;
71# else
72DWORD g_VBoxVDbgFLog = 1;
73# endif
74DWORD g_VBoxVDbgFLogFlow = 0;
75
76#endif
77
78#ifdef VBOXWDDMDISP_DEBUG
79
80#define VBOXWDDMDISP_DEBUG_DUMP_DEFAULT 0
81DWORD g_VBoxVDbgFDumpSetTexture = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
82DWORD g_VBoxVDbgFDumpDrawPrim = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
83DWORD g_VBoxVDbgFDumpTexBlt = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
84DWORD g_VBoxVDbgFDumpBlt = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
85DWORD g_VBoxVDbgFDumpRtSynch = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
86DWORD g_VBoxVDbgFDumpFlush = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
87DWORD g_VBoxVDbgFDumpShared = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
88DWORD g_VBoxVDbgFDumpLock = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
89DWORD g_VBoxVDbgFDumpUnlock = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
90DWORD g_VBoxVDbgFDumpPresentEnter = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
91DWORD g_VBoxVDbgFDumpPresentLeave = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
92DWORD g_VBoxVDbgFDumpScSync = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
93
94DWORD g_VBoxVDbgFBreakShared = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
95DWORD g_VBoxVDbgFBreakDdi = 0;
96
97DWORD g_VBoxVDbgFCheckSysMemSync = 0;
98DWORD g_VBoxVDbgFCheckBlt = 0;
99DWORD g_VBoxVDbgFCheckTexBlt = 0;
100DWORD g_VBoxVDbgFCheckScSync = 0;
101
102DWORD g_VBoxVDbgFSkipCheckTexBltDwmWndUpdate = 1;
103
104DWORD g_VBoxVDbgCfgMaxDirectRts = 3;
105DWORD g_VBoxVDbgCfgForceDummyDevCreate = 0;
106
107PVBOXWDDMDISP_DEVICE g_VBoxVDbgInternalDevice = NULL;
108PVBOXWDDMDISP_RESOURCE g_VBoxVDbgInternalRc = NULL;
109
110VOID vboxVDbgDoPrintDmlCmd(const char* pszDesc, const char* pszCmd)
111{
112 vboxVDbgPrint(("<?dml?><exec cmd=\"%s\">%s</exec>, ( %s )\n", pszCmd, pszDesc, pszCmd));
113}
114
115VOID vboxVDbgDoPrintDumpCmd(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
116{
117 char Cmd[1024];
118 sprintf(Cmd, "!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d", pvData, width, height, bpp, pitch);
119 vboxVDbgDoPrintDmlCmd(pszDesc, Cmd);
120}
121
122VOID vboxVDbgDoPrintLopLastCmd(const char* pszDesc)
123{
124 vboxVDbgDoPrintDmlCmd(pszDesc, "ed @@(&vboxVDbgLoop) 0");
125}
126
127typedef struct VBOXVDBG_DUMP_INFO
128{
129 DWORD fFlags;
130 const VBOXWDDMDISP_ALLOCATION *pAlloc;
131 IDirect3DResource9 *pD3DRc;
132 const RECT *pRect;
133} VBOXVDBG_DUMP_INFO, *PVBOXVDBG_DUMP_INFO;
134
135typedef DECLCALLBACK(void) FNVBOXVDBG_CONTENTS_DUMPER(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper);
136typedef FNVBOXVDBG_CONTENTS_DUMPER *PFNVBOXVDBG_CONTENTS_DUMPER;
137
138static VOID vboxVDbgDoDumpSummary(const char * pPrefix, PVBOXVDBG_DUMP_INFO pInfo, const char * pSuffix)
139{
140 const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
141 IDirect3DResource9 *pD3DRc = pInfo->pD3DRc;
142 char rectBuf[24];
143 if (pInfo->pRect)
144 _snprintf(rectBuf, sizeof(rectBuf) / sizeof(rectBuf[0]), "(%d:%d);(%d:%d)",
145 pInfo->pRect->left, pInfo->pRect->top,
146 pInfo->pRect->right, pInfo->pRect->bottom);
147 else
148 strcpy(rectBuf, "n/a");
149
150 vboxVDbgPrint(("%s Sh(0x%p), Rc(0x%p), pAlloc(0x%x), pD3DIf(0x%p), Type(%s), Rect(%s), Locks(%d) %s",
151 pPrefix ? pPrefix : "",
152 pAlloc ? pAlloc->pRc->aAllocations[0].hSharedHandle : NULL,
153 pAlloc ? pAlloc->pRc : NULL,
154 pAlloc,
155 pD3DRc,
156 pD3DRc ? vboxDispLogD3DRcType(pD3DRc->GetType()) : "n/a",
157 rectBuf,
158 pAlloc ? pAlloc->LockInfo.cLocks : 0,
159 pSuffix ? pSuffix : ""));
160}
161
162VOID vboxVDbgDoDumpPerform(const char * pPrefix, PVBOXVDBG_DUMP_INFO pInfo, const char * pSuffix,
163 PFNVBOXVDBG_CONTENTS_DUMPER pfnCd, void *pvCd)
164{
165 DWORD fFlags = pInfo->fFlags;
166
167 if (!VBOXVDBG_DUMP_TYPE_ENABLED_FOR_INFO(pInfo, fFlags))
168 return;
169
170 if (!pInfo->pD3DRc && pInfo->pAlloc)
171 pInfo->pD3DRc = (IDirect3DResource9*)pInfo->pAlloc->pD3DIf;
172
173 BOOLEAN bLogOnly = VBOXVDBG_DUMP_TYPE_FLOW_ONLY(fFlags);
174 if (bLogOnly || !pfnCd)
175 {
176 vboxVDbgDoDumpSummary(pPrefix, pInfo, pSuffix);
177 if (VBOXVDBG_DUMP_FLAGS_IS_SET(fFlags, VBOXVDBG_DUMP_TYPEF_BREAK_ON_FLOW)
178 || (!bLogOnly && VBOXVDBG_DUMP_FLAGS_IS_CLEARED(fFlags, VBOXVDBG_DUMP_TYPEF_DONT_BREAK_ON_CONTENTS)))
179 Assert(0);
180 return;
181 }
182
183 vboxVDbgDoDumpSummary(pPrefix, pInfo, NULL);
184
185 pfnCd(pInfo, VBOXVDBG_DUMP_FLAGS_IS_CLEARED(fFlags, VBOXVDBG_DUMP_TYPEF_DONT_BREAK_ON_CONTENTS), pvCd);
186
187 if (pSuffix && pSuffix[0] != '\0')
188 vboxVDbgPrint(("%s", pSuffix));
189}
190
191static DECLCALLBACK(void) vboxVDbgAllocRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper)
192{
193 RT_NOREF(fBreak, pvDumper);
194 const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
195 const RECT *pRect = pInfo->pRect;
196
197 Assert(pAlloc->hAllocation);
198
199 D3DDDICB_LOCK LockData;
200 LockData.hAllocation = pAlloc->hAllocation;
201 LockData.PrivateDriverData = 0;
202 LockData.NumPages = 0;
203 LockData.pPages = NULL;
204 LockData.pData = NULL; /* out */
205 LockData.Flags.Value = 0;
206 LockData.Flags.LockEntire =1;
207 LockData.Flags.ReadOnly = 1;
208
209 PVBOXWDDMDISP_DEVICE pDevice = pAlloc->pRc->pDevice;
210
211 HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
212 Assert(hr == S_OK);
213 if (hr == S_OK)
214 {
215 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
216 vboxVDbgDoPrintDumpCmd("Surf Info", LockData.pData, pAlloc->SurfDesc.d3dWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch);
217 if (pRect)
218 {
219 Assert(pRect->right > pRect->left);
220 Assert(pRect->bottom > pRect->top);
221 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
222 vboxVDbgDoPrintDumpCmd("Rect Info", ((uint8_t*)LockData.pData) + (pRect->top * pAlloc->SurfDesc.pitch) + ((pRect->left * bpp) >> 3),
223 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, pAlloc->SurfDesc.pitch);
224 }
225 Assert(0);
226
227 D3DDDICB_UNLOCK DdiUnlock;
228
229 DdiUnlock.NumAllocations = 1;
230 DdiUnlock.phAllocations = &pAlloc->hAllocation;
231
232 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
233 Assert(hr == S_OK);
234 }
235}
236
237VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, RECT *pRect, const char* pSuffix, DWORD fFlags)
238{
239 VBOXVDBG_DUMP_INFO Info;
240 Info.fFlags = fFlags;
241 Info.pAlloc = pAlloc;
242 Info.pD3DRc = NULL;
243 Info.pRect = pRect;
244 vboxVDbgDoDumpPerform(pPrefix, &Info, pSuffix, vboxVDbgAllocRectContentsDumperCb, NULL);
245}
246
247static DECLCALLBACK(void) vboxVDbgRcRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper)
248{
249 RT_NOREF(pvDumper);
250 const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
251 const RECT *pRect = pInfo->pRect;
252 IDirect3DSurface9 *pSurf;
253 HRESULT hr = VBoxD3DIfSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pSurf);
254 if (hr != S_OK)
255 {
256 WARN(("VBoxD3DIfSurfGet failed, hr 0x%x", hr));
257 return;
258 }
259
260 D3DSURFACE_DESC Desc;
261 hr = pSurf->GetDesc(&Desc);
262 Assert(hr == S_OK);
263 if (hr == S_OK)
264 {
265 D3DLOCKED_RECT Lr;
266 hr = pSurf->LockRect(&Lr, NULL, D3DLOCK_READONLY);
267 Assert(hr == S_OK);
268 if (hr == S_OK)
269 {
270 UINT bpp = vboxWddmCalcBitsPerPixel((D3DDDIFORMAT)Desc.Format);
271 vboxVDbgDoPrintDumpCmd("Surf Info", Lr.pBits, Desc.Width, Desc.Height, bpp, Lr.Pitch);
272 if (pRect)
273 {
274 Assert(pRect->right > pRect->left);
275 Assert(pRect->bottom > pRect->top);
276 vboxVDbgDoPrintRect("rect: ", pRect, "\n");
277 vboxVDbgDoPrintDumpCmd("Rect Info", ((uint8_t*)Lr.pBits) + (pRect->top * Lr.Pitch) + ((pRect->left * bpp) >> 3),
278 pRect->right - pRect->left, pRect->bottom - pRect->top, bpp, Lr.Pitch);
279 }
280
281 if (fBreak)
282 {
283 Assert(0);
284 }
285 hr = pSurf->UnlockRect();
286 Assert(hr == S_OK);
287 }
288 }
289
290 pSurf->Release();
291}
292
293VOID vboxVDbgDoDumpRcRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc,
294 IDirect3DResource9 *pD3DRc, RECT *pRect, const char * pSuffix, DWORD fFlags)
295{
296 VBOXVDBG_DUMP_INFO Info;
297 Info.fFlags = fFlags;
298 Info.pAlloc = pAlloc;
299 Info.pD3DRc = pD3DRc;
300 Info.pRect = pRect;
301 vboxVDbgDoDumpPerform(pPrefix, &Info, pSuffix, vboxVDbgRcRectContentsDumperCb, NULL);
302}
303
304
305#define VBOXVDBG_STRCASE(_t) \
306 case _t: return #_t;
307#define VBOXVDBG_STRCASE_UNKNOWN() \
308 default: Assert(0); return "Unknown";
309
310const char* vboxVDbgStrCubeFaceType(D3DCUBEMAP_FACES enmFace)
311{
312 switch (enmFace)
313 {
314 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_X);
315 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_X);
316 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Y);
317 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Y);
318 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_POSITIVE_Z);
319 VBOXVDBG_STRCASE(D3DCUBEMAP_FACE_NEGATIVE_Z);
320 VBOXVDBG_STRCASE_UNKNOWN();
321 }
322}
323
324VOID vboxVDbgDoDumpRt(const char * pPrefix, PVBOXWDDMDISP_DEVICE pDevice, const char * pSuffix, DWORD fFlags)
325{
326 for (UINT i = 0; i < pDevice->cRTs; ++i)
327 {
328 IDirect3DSurface9 *pRt;
329 PVBOXWDDMDISP_ALLOCATION pAlloc = pDevice->apRTs[i];
330 if (!pAlloc) continue;
331 IDirect3DDevice9 *pDeviceIf = pDevice->pDevice9If;
332 HRESULT hr = pDeviceIf->GetRenderTarget(i, &pRt);
333 Assert(hr == S_OK);
334 if (hr == S_OK)
335 {
336// Assert(pAlloc->pD3DIf == pRt);
337 vboxVDbgDoDumpRcRect(pPrefix, pAlloc, NULL, NULL, pSuffix, fFlags);
338 pRt->Release();
339 }
340 else
341 {
342 vboxVDbgPrint((__FUNCTION__": ERROR getting rt: 0x%x", hr));
343 }
344 }
345}
346
347VOID vboxVDbgDoDumpSamplers(const char * pPrefix, PVBOXWDDMDISP_DEVICE pDevice, const char * pSuffix, DWORD fFlags)
348{
349 for (UINT i = 0, iSampler = 0; iSampler < pDevice->cSamplerTextures; ++i)
350 {
351 Assert(i < RT_ELEMENTS(pDevice->aSamplerTextures));
352 if (!pDevice->aSamplerTextures[i]) continue;
353 PVBOXWDDMDISP_RESOURCE pRc = pDevice->aSamplerTextures[i];
354 for (UINT j = 0; j < pRc->cAllocations; ++j)
355 {
356 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j];
357 vboxVDbgDoDumpRcRect(pPrefix, pAlloc, NULL, NULL, pSuffix, fFlags);
358 }
359 ++iSampler;
360 }
361}
362
363static DECLCALLBACK(void) vboxVDbgLockUnlockSurfTexContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper)
364{
365 RT_NOREF(pvDumper);
366 const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
367 const RECT *pRect = pInfo->pRect;
368 UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
369 uint32_t width, height, pitch = 0;
370 void *pvData;
371 if (pAlloc->LockInfo.fFlags.AreaValid)
372 {
373 width = pAlloc->LockInfo.Area.left - pAlloc->LockInfo.Area.right;
374 height = pAlloc->LockInfo.Area.bottom - pAlloc->LockInfo.Area.top;
375 }
376 else
377 {
378 width = pAlloc->SurfDesc.width;
379 height = pAlloc->SurfDesc.height;
380 }
381
382 if (pAlloc->LockInfo.fFlags.NotifyOnly)
383 {
384 pitch = pAlloc->SurfDesc.pitch;
385 pvData = ((uint8_t*)pAlloc->pvMem) + pitch*pRect->top + ((bpp*pRect->left) >> 3);
386 }
387 else
388 {
389 pvData = pAlloc->LockInfo.pvData;
390 }
391
392 vboxVDbgDoPrintDumpCmd("Surf Info", pvData, width, height, bpp, pitch);
393
394 if (fBreak)
395 {
396 Assert(0);
397 }
398}
399
400VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const VBOXWDDMDISP_ALLOCATION *pAlloc, const char * pSuffix, DWORD fFlags)
401{
402 Assert(!pAlloc->hSharedHandle);
403
404 RECT Rect;
405 const RECT *pRect;
406 Assert(!pAlloc->LockInfo.fFlags.RangeValid);
407 Assert(!pAlloc->LockInfo.fFlags.BoxValid);
408 if (pAlloc->LockInfo.fFlags.AreaValid)
409 {
410 pRect = &pAlloc->LockInfo.Area;
411 }
412 else
413 {
414 Rect.top = 0;
415 Rect.bottom = pAlloc->SurfDesc.height;
416 Rect.left = 0;
417 Rect.right = pAlloc->SurfDesc.width;
418 pRect = &Rect;
419 }
420
421 VBOXVDBG_DUMP_INFO Info;
422 Info.fFlags = fFlags;
423 Info.pAlloc = pAlloc;
424 Info.pD3DRc = NULL;
425 Info.pRect = pRect;
426 vboxVDbgDoDumpPerform(pPrefix, &Info, pSuffix, vboxVDbgLockUnlockSurfTexContentsDumperCb, NULL);
427}
428
429VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, DWORD fFlags)
430{
431 const VBOXWDDMDISP_RESOURCE *pRc = (const VBOXWDDMDISP_RESOURCE*)pData->hResource;
432 const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
433#ifdef VBOXWDDMDISP_DEBUG
434 VBOXWDDMDISP_ALLOCATION *pUnconstpAlloc = (VBOXWDDMDISP_ALLOCATION *)pAlloc;
435 pUnconstpAlloc->LockInfo.pvData = pData->pSurfData;
436#endif
437 vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fFlags);
438}
439
440VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, DWORD fFlags)
441{
442 const VBOXWDDMDISP_RESOURCE *pRc = (const VBOXWDDMDISP_RESOURCE*)pData->hResource;
443 const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
444 vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fFlags);
445}
446
447BOOL vboxVDbgDoCheckLRects(D3DLOCKED_RECT *pDstLRect, const RECT *pDstRect, D3DLOCKED_RECT *pSrcLRect, const RECT *pSrcRect, DWORD bpp, BOOL fBreakOnMismatch)
448{
449 LONG DstH, DstW, SrcH, SrcW, DstWBytes;
450 BOOL fMatch = FALSE;
451 DstH = pDstRect->bottom - pDstRect->top;
452 DstW = pDstRect->right - pDstRect->left;
453 SrcH = pSrcRect->bottom - pSrcRect->top;
454 SrcW = pSrcRect->right - pSrcRect->left;
455
456 DstWBytes = ((DstW * bpp + 7) >> 3);
457
458 if(DstW != SrcW && DstH != SrcH)
459 {
460 WARN(("stretched comparison not supported!!"));
461 return FALSE;
462 }
463
464 uint8_t *pDst = (uint8_t*)pDstLRect->pBits;
465 uint8_t *pSrc = (uint8_t*)pSrcLRect->pBits;
466 for (LONG i = 0; i < DstH; ++i)
467 {
468 if (!(fMatch = !memcmp(pDst, pSrc, DstWBytes)))
469 {
470 vboxVDbgPrint(("not match!\n"));
471 if (fBreakOnMismatch)
472 Assert(0);
473 break;
474 }
475 pDst += pDstLRect->Pitch;
476 pSrc += pSrcLRect->Pitch;
477 }
478 return fMatch;
479}
480
481BOOL vboxVDbgDoCheckRectsMatch(const VBOXWDDMDISP_RESOURCE *pDstRc, uint32_t iDstAlloc,
482 const VBOXWDDMDISP_RESOURCE *pSrcRc, uint32_t iSrcAlloc,
483 const RECT *pDstRect,
484 const RECT *pSrcRect,
485 BOOL fBreakOnMismatch)
486{
487 BOOL fMatch = FALSE;
488 RECT DstRect = {0}, SrcRect = {0};
489 if (!pDstRect)
490 {
491 DstRect.left = 0;
492 DstRect.right = pDstRc->aAllocations[iDstAlloc].SurfDesc.width;
493 DstRect.top = 0;
494 DstRect.bottom = pDstRc->aAllocations[iDstAlloc].SurfDesc.height;
495 pDstRect = &DstRect;
496 }
497
498 if (!pSrcRect)
499 {
500 SrcRect.left = 0;
501 SrcRect.right = pSrcRc->aAllocations[iSrcAlloc].SurfDesc.width;
502 SrcRect.top = 0;
503 SrcRect.bottom = pSrcRc->aAllocations[iSrcAlloc].SurfDesc.height;
504 pSrcRect = &SrcRect;
505 }
506
507 if (pDstRc == pSrcRc
508 && iDstAlloc == iSrcAlloc)
509 {
510 if (!memcmp(pDstRect, pSrcRect, sizeof (*pDstRect)))
511 {
512 vboxVDbgPrint(("matching same rect of one allocation, skipping..\n"));
513 return TRUE;
514 }
515 WARN(("matching different rects of the same allocation, unsupported!"));
516 return FALSE;
517 }
518
519 if (pDstRc->RcDesc.enmFormat != pSrcRc->RcDesc.enmFormat)
520 {
521 WARN(("matching different formats, unsupported!"));
522 return FALSE;
523 }
524
525 DWORD bpp = pDstRc->aAllocations[iDstAlloc].SurfDesc.bpp;
526 if (!bpp)
527 {
528 WARN(("uninited bpp! unsupported!"));
529 return FALSE;
530 }
531
532 LONG DstH, DstW, SrcH, SrcW;
533 DstH = pDstRect->bottom - pDstRect->top;
534 DstW = pDstRect->right - pDstRect->left;
535 SrcH = pSrcRect->bottom - pSrcRect->top;
536 SrcW = pSrcRect->right - pSrcRect->left;
537
538 if(DstW != SrcW && DstH != SrcH)
539 {
540 WARN(("stretched comparison not supported!!"));
541 return FALSE;
542 }
543
544 D3DLOCKED_RECT SrcLRect, DstLRect;
545 HRESULT hr = VBoxD3DIfLockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc, &DstLRect, pDstRect, D3DLOCK_READONLY);
546 if (FAILED(hr))
547 {
548 WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr));
549 return FALSE;
550 }
551
552 hr = VBoxD3DIfLockRect((VBOXWDDMDISP_RESOURCE *)pSrcRc, iSrcAlloc, &SrcLRect, pSrcRect, D3DLOCK_READONLY);
553 if (FAILED(hr))
554 {
555 WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr));
556 hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc);
557 return FALSE;
558 }
559
560 fMatch = vboxVDbgDoCheckLRects(&DstLRect, pDstRect, &SrcLRect, pSrcRect, bpp, fBreakOnMismatch);
561
562 hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc);
563 Assert(hr == S_OK);
564
565 hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pSrcRc, iSrcAlloc);
566 Assert(hr == S_OK);
567
568 return fMatch;
569}
570
571void vboxVDbgDoPrintAlloc(const char * pPrefix, const VBOXWDDMDISP_RESOURCE *pRc, uint32_t iAlloc, const char * pSuffix)
572{
573 Assert(pRc->cAllocations > iAlloc);
574 const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[iAlloc];
575 BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
576 BOOL bFrontBuf = FALSE;
577 vboxVDbgPrint(("%s d3dWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
578 pAlloc->SurfDesc.d3dWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
579 bPrimary ?
580 (bFrontBuf ? "Front Buffer" : "Back Buffer")
581 : "?Everage? Alloc",
582 pSuffix));
583}
584
585void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix)
586{
587 vboxVDbgPrint(("%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix));
588}
589
590static VOID CALLBACK vboxVDbgTimerCb(__in PVOID lpParameter, __in BOOLEAN TimerOrWaitFired)
591{
592 RT_NOREF(lpParameter, TimerOrWaitFired);
593 Assert(0);
594}
595
596HRESULT vboxVDbgTimerStart(HANDLE hTimerQueue, HANDLE *phTimer, DWORD msTimeout)
597{
598 if (!CreateTimerQueueTimer(phTimer, hTimerQueue,
599 vboxVDbgTimerCb,
600 NULL,
601 msTimeout, /* ms*/
602 0,
603 WT_EXECUTEONLYONCE))
604 {
605 DWORD winEr = GetLastError();
606 AssertMsgFailed(("CreateTimerQueueTimer failed, winEr (%d)\n", winEr));
607 return E_FAIL;
608 }
609 return S_OK;
610}
611
612HRESULT vboxVDbgTimerStop(HANDLE hTimerQueue, HANDLE hTimer)
613{
614 if (!DeleteTimerQueueTimer(hTimerQueue, hTimer, NULL))
615 {
616 DWORD winEr = GetLastError();
617 AssertMsg(winEr == ERROR_IO_PENDING, ("DeleteTimerQueueTimer failed, winEr (%d)\n", winEr));
618 }
619 return S_OK;
620}
621#endif
622
623#if defined(VBOXWDDMDISP_DEBUG)
624BOOL vboxVDbgDoCheckExe(const char * pszName)
625{
626 char *pszModule = vboxVDbgDoGetModuleName();
627 if (!pszModule)
628 return FALSE;
629 size_t cbModule, cbName;
630 cbModule = strlen(pszModule);
631 cbName = strlen(pszName);
632 if (cbName > cbModule)
633 return FALSE;
634 if (_stricmp(pszName, pszModule + (cbModule - cbName)))
635 return FALSE;
636 return TRUE;
637}
638#endif
639
640#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
641
642typedef BOOL WINAPI FNGetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb);
643typedef FNGetModuleInformation *PFNGetModuleInformation;
644
645static PFNGetModuleInformation g_pfnGetModuleInformation = NULL;
646static HMODULE g_hModPsapi = NULL;
647static PVOID g_VBoxWDbgVEHandler = NULL;
648
649static bool vboxVDbgIsAddressInModule(PVOID pv, const char *pszModuleName)
650{
651 HMODULE hMod = GetModuleHandleA(pszModuleName);
652 if (!hMod)
653 return false;
654
655 HANDLE hProcess = GetCurrentProcess();
656
657 if (!g_pfnGetModuleInformation)
658 return false;
659
660 MODULEINFO ModuleInfo = {0};
661 if (!g_pfnGetModuleInformation(hProcess, hMod, &ModuleInfo, sizeof(ModuleInfo)))
662 return false;
663
664 return (uintptr_t)ModuleInfo.lpBaseOfDll <= (uintptr_t)pv
665 && (uintptr_t)pv < (uintptr_t)ModuleInfo.lpBaseOfDll + ModuleInfo.SizeOfImage;
666}
667
668static bool vboxVDbgIsExceptionIgnored(PEXCEPTION_RECORD pExceptionRecord)
669{
670 /* Module (dll) names for GetModuleHandle.
671 * Exceptions originated from these modules will be ignored.
672 */
673 static const char *apszIgnoredModuleNames[] =
674 {
675 NULL
676 };
677
678 int i = 0;
679 while (apszIgnoredModuleNames[i])
680 {
681 if (vboxVDbgIsAddressInModule(pExceptionRecord->ExceptionAddress, apszIgnoredModuleNames[i]))
682 return true;
683
684 ++i;
685 }
686
687 return false;
688}
689
690LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
691{
692 static volatile bool g_fAllowIgnore = true; /* Might be changed in kernel debugger. */
693
694 PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
695 /* PCONTEXT pContextRecord = pExceptionInfo->ContextRecord; */
696
697 switch (pExceptionRecord->ExceptionCode)
698 {
699 default:
700 break;
701 case EXCEPTION_BREAKPOINT:
702 case EXCEPTION_ACCESS_VIOLATION:
703 case EXCEPTION_STACK_OVERFLOW:
704 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
705 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
706 case EXCEPTION_FLT_INVALID_OPERATION:
707 case EXCEPTION_INT_DIVIDE_BY_ZERO:
708 case EXCEPTION_ILLEGAL_INSTRUCTION:
709 if (g_fAllowIgnore && vboxVDbgIsExceptionIgnored(pExceptionRecord))
710 break;
711 ASMBreakpoint();
712 break;
713 case 0x40010006: /* OutputDebugStringA? */
714 case 0x4001000a: /* OutputDebugStringW? */
715 break;
716 }
717 return EXCEPTION_CONTINUE_SEARCH;
718}
719
720void vboxVDbgVEHandlerRegister()
721{
722 Assert(!g_VBoxWDbgVEHandler);
723 g_VBoxWDbgVEHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
724 Assert(g_VBoxWDbgVEHandler);
725
726 g_hModPsapi = GetModuleHandleA("Psapi.dll"); /* Usually already loaded. */
727 if (g_hModPsapi)
728 g_pfnGetModuleInformation = (PFNGetModuleInformation)GetProcAddress(g_hModPsapi, "GetModuleInformation");
729}
730
731void vboxVDbgVEHandlerUnregister()
732{
733 Assert(g_VBoxWDbgVEHandler);
734 ULONG uResult = RemoveVectoredExceptionHandler(g_VBoxWDbgVEHandler);
735 Assert(uResult); RT_NOREF(uResult);
736 g_VBoxWDbgVEHandler = NULL;
737
738 g_hModPsapi = NULL;
739 g_pfnGetModuleInformation = NULL;
740}
741
742#endif /* VBOXWDDMDISP_DEBUG_VEHANDLER */
743
744#if defined(VBOXWDDMDISP_DEBUG) || defined(LOG_TO_BACKDOOR_DRV)
745void vboxDispLogDrvF(char * szString, ...)
746{
747 char szBuffer[4096] = {0};
748 va_list pArgList;
749 va_start(pArgList, szString);
750 vboxDispLogDbgFormatStringV(szBuffer, sizeof (szBuffer), szString, pArgList);
751 va_end(pArgList);
752
753 VBoxDispMpLoggerLog(szBuffer);
754}
755
756void vboxDispLogDbgPrintF(char * szString, ...)
757{
758 char szBuffer[4096] = { 0 };
759 va_list pArgList;
760 va_start(pArgList, szString);
761 vboxDispLogDbgFormatStringV(szBuffer, sizeof(szBuffer), szString, pArgList);
762 va_end(pArgList);
763
764 OutputDebugStringA(szBuffer);
765}
766#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