VirtualBox

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

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

WDDM: remove old chromium based 3D code from the user mode driver. bugref:9529

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