VirtualBox

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

Last change on this file since 64186 was 63033, checked in by vboxsync, 8 years ago

GA/NT/Graphics: warnings

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