VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp@ 57151

Last change on this file since 57151 was 57151, checked in by vboxsync, 10 years ago

VMSVGA3d: Started reworking 3d command handling code to avoid duplicating code and ending up with slightly different versions. E.g. the input validation is the same regardless of the backend.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 87.4 KB
Line 
1/* $Id: DevVGA-SVGA3d-info.cpp 57151 2015-08-02 19:46:25Z vboxsync $ */
2/** @file
3 * DevSVGA3d - VMWare SVGA device, 3D parts - Introspection and debugging.
4 */
5
6/*
7 * Copyright (C) 2013-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
23#include <VBox/vmm/pdmdev.h>
24#include <VBox/err.h>
25#include <VBox/log.h>
26
27#include <iprt/assert.h>
28#include <iprt/mem.h>
29
30#include <VBox/vmm/pgm.h> /* required by DevVGA.h */
31#include <VBox/VBoxVideo.h> /* required by DevVGA.h */
32
33/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
34#include "DevVGA.h"
35
36#include "DevVGA-SVGA.h"
37#include "DevVGA-SVGA3d.h"
38#define VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
39#include "DevVGA-SVGA3d-internal.h"
40
41
42/*********************************************************************************************************************************
43* Global Variables *
44*********************************************************************************************************************************/
45/** Enum value to string mappings for SVGA3dSurfaceFormat, prefix "SVGA3D_". */
46static const VMSVGAINFOENUM g_aSVGA3dSurfaceFormats[] =
47{
48 { SVGA3D_FORMAT_INVALID , "FORMAT_INVALID" },
49 { SVGA3D_X8R8G8B8 , "X8R8G8B8" },
50 { SVGA3D_A8R8G8B8 , "A8R8G8B8" },
51 { SVGA3D_R5G6B5 , "R5G6B5" },
52 { SVGA3D_X1R5G5B5 , "X1R5G5B5" },
53 { SVGA3D_A1R5G5B5 , "A1R5G5B5" },
54 { SVGA3D_A4R4G4B4 , "A4R4G4B4" },
55 { SVGA3D_Z_D32 , "Z_D32" },
56 { SVGA3D_Z_D16 , "Z_D16" },
57 { SVGA3D_Z_D24S8 , "Z_D24S8" },
58 { SVGA3D_Z_D15S1 , "Z_D15S1" },
59 { SVGA3D_LUMINANCE8 , "LUMINANCE8" },
60 { SVGA3D_LUMINANCE4_ALPHA4 , "LUMINANCE4_ALPHA4" },
61 { SVGA3D_LUMINANCE16 , "LUMINANCE16" },
62 { SVGA3D_LUMINANCE8_ALPHA8 , "LUMINANCE8_ALPHA8" },
63 { SVGA3D_DXT1 , "DXT1" },
64 { SVGA3D_DXT2 , "DXT2" },
65 { SVGA3D_DXT3 , "DXT3" },
66 { SVGA3D_DXT4 , "DXT4" },
67 { SVGA3D_DXT5 , "DXT5" },
68 { SVGA3D_BUMPU8V8 , "BUMPU8V8" },
69 { SVGA3D_BUMPL6V5U5 , "BUMPL6V5U5" },
70 { SVGA3D_BUMPX8L8V8U8 , "BUMPX8L8V8U8" },
71 { SVGA3D_BUMPL8V8U8 , "BUMPL8V8U8" },
72 { SVGA3D_ARGB_S10E5 , "ARGB_S10E5" },
73 { SVGA3D_ARGB_S23E8 , "ARGB_S23E8" },
74 { SVGA3D_A2R10G10B10 , "A2R10G10B10" },
75 { SVGA3D_V8U8 , "V8U8" },
76 { SVGA3D_Q8W8V8U8 , "Q8W8V8U8" },
77 { SVGA3D_CxV8U8 , "CxV8U8" },
78 { SVGA3D_X8L8V8U8 , "X8L8V8U8" },
79 { SVGA3D_A2W10V10U10 , "A2W10V10U10" },
80 { SVGA3D_ALPHA8 , "ALPHA8" },
81 { SVGA3D_R_S10E5 , "R_S10E5" },
82 { SVGA3D_R_S23E8 , "R_S23E8" },
83 { SVGA3D_RG_S10E5 , "RG_S10E5" },
84 { SVGA3D_RG_S23E8 , "RG_S23E8" },
85 { SVGA3D_BUFFER , "BUFFER" },
86 { SVGA3D_Z_D24X8 , "Z_D24X8" },
87 { SVGA3D_V16U16 , "V16U16" },
88 { SVGA3D_G16R16 , "G16R16" },
89 { SVGA3D_A16B16G16R16 , "A16B16G16R16" },
90 { SVGA3D_UYVY , "UYVY" },
91 { SVGA3D_YUY2 , "YUY2" },
92 { SVGA3D_NV12 , "NV12" },
93 { SVGA3D_AYUV , "AYUV" },
94 { SVGA3D_BC4_UNORM , "BC4_UNORM" },
95 { SVGA3D_BC5_UNORM , "BC5_UNORM" },
96 { SVGA3D_Z_DF16 , "Z_DF16" },
97 { SVGA3D_Z_DF24 , "Z_DF24" },
98 { SVGA3D_Z_D24S8_INT , "Z_D24S8_INT" },
99};
100VMSVGAINFOENUMMAP_MAKE(RT_NOTHING, g_SVGA3dSurfaceFormat2String, g_aSVGA3dSurfaceFormats, "SVGA3D_");
101
102
103/**
104 * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.
105 *
106 * This will allocate heap buffers if necessary, thus increasing the memory
107 * usage of the process.
108 *
109 * @todo Would be interesting to share this code with the saved state code.
110 *
111 * @returns VBox status code.
112 * @param pState The 3D state structure.
113 * @param pSurface The surface to refresh the heap buffers for.
114 */
115static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
116{
117 /*
118 * Currently we've got trouble retreving bit for DEPTHSTENCIL
119 * surfaces both for OpenGL and D3D, so skip these here (don't
120 * wast memory on them).
121 */
122 uint32_t const fSwitchFlags = pSurface->flags
123 & ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER
124 | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET
125 | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);
126 if ( fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL
127 && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))
128 {
129
130#ifdef VMSVGA3D_OPENGL
131 /*
132 * Change OpenGL context to the one the surface is associated with.
133 */
134# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
135 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
136 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
137# else
138 /** @todo stricter checks for associated context */
139 uint32_t cid = pSurface->idAssociatedContext;
140 if ( cid >= pState->cContexts
141 || pState->papContexts[cid]->id != cid)
142 {
143 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
144 AssertFailedReturn(VERR_INVALID_PARAMETER);
145 }
146 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
147 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
148# endif
149#endif
150
151 /*
152 * Work thru each mipmap level for each face.
153 */
154 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
155 {
156 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
157 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
158 for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
159 {
160#ifdef VMSVGA3D_DIRECT3D
161 if (pSurface->u.pSurface)
162#else
163 if (pSurface->oglId.texture != OPENGL_INVALID_ID)
164#endif
165 {
166 Assert(pMipmapLevel->cbSurface);
167 Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */
168
169 /*
170 * Make sure we've got surface memory buffer.
171 */
172 uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;
173 if (!pbDst)
174 {
175 pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);
176 AssertReturn(pbDst, VERR_NO_MEMORY);
177 }
178
179#ifdef VMSVGA3D_DIRECT3D
180 /*
181 * D3D specifics.
182 */
183 HRESULT hr;
184 switch (fSwitchFlags)
185 {
186 case SVGA3D_SURFACE_HINT_TEXTURE:
187 case SVGA3D_SURFACE_HINT_RENDERTARGET:
188 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
189 {
190 /*
191 * Lock the buffer and make it accessible to memcpy.
192 */
193 D3DLOCKED_RECT LockedRect;
194 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
195 {
196 if (pSurface->bounce.pTexture)
197 {
198 if ( !pSurface->fDirty
199 && fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)
200 && i == 0 /* only the first time */)
201 {
202 /** @todo stricter checks for associated context */
203 uint32_t cid = pSurface->idAssociatedContext;
204 if ( cid >= pState->cContexts
205 || pState->papContexts[cid]->id != cid)
206 {
207 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
208 AssertFailedReturn(VERR_INVALID_PARAMETER);
209 }
210 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
211
212 IDirect3DSurface9 *pDst = NULL;
213 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);
214 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
215
216 IDirect3DSurface9 *pSrc = NULL;
217 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
218 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
219
220 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);
221 AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);
222
223 pSrc->Release();
224 pDst->Release();
225 }
226
227 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
228 &LockedRect,
229 NULL,
230 D3DLOCK_READONLY);
231 }
232 else
233 hr = pSurface->u.pTexture->LockRect(i, /* texture level */
234 &LockedRect,
235 NULL,
236 D3DLOCK_READONLY);
237 }
238 else
239 hr = pSurface->u.pSurface->LockRect(&LockedRect,
240 NULL,
241 D3DLOCK_READONLY);
242 AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
243
244 /*
245 * Copy the data. Take care in case the pitch differs.
246 */
247 if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)
248 memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);
249 else
250 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
251 memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,
252 (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,
253 pMipmapLevel->cbSurfacePitch);
254
255 /*
256 * Release the buffer.
257 */
258 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
259 {
260 if (pSurface->bounce.pTexture)
261 {
262 hr = pSurface->bounce.pTexture->UnlockRect(i);
263 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
264 }
265 else
266 hr = pSurface->u.pTexture->UnlockRect(i);
267 }
268 else
269 hr = pSurface->u.pSurface->UnlockRect();
270 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
271 break;
272 }
273
274 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
275 {
276 void *pvD3DData = NULL;
277 hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
278 AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);
279
280 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
281
282 hr = pSurface->u.pVertexBuffer->Unlock();
283 AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));
284 break;
285 }
286
287 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
288 {
289 void *pvD3DData = NULL;
290 hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
291 AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);
292
293 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
294
295 hr = pSurface->u.pIndexBuffer->Unlock();
296 AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));
297 break;
298 }
299
300 default:
301 AssertMsgFailed(("%#x\n", fSwitchFlags));
302 }
303
304#elif defined(VMSVGA3D_OPENGL)
305 /*
306 * OpenGL specifics.
307 */
308 switch (fSwitchFlags)
309 {
310 case SVGA3D_SURFACE_HINT_TEXTURE:
311 case SVGA3D_SURFACE_HINT_RENDERTARGET:
312 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
313 {
314 GLint activeTexture;
315 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
316 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
317
318 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
319 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
320
321 /* Set row length and alignment of the output data. */
322 VMSVGAPACKPARAMS SavedParams;
323 vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);
324
325 glGetTexImage(GL_TEXTURE_2D,
326 i,
327 pSurface->formatGL,
328 pSurface->typeGL,
329 pbDst);
330 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
331
332 vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);
333
334 /* Restore the old active texture. */
335 glBindTexture(GL_TEXTURE_2D, activeTexture);
336 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
337 break;
338 }
339
340 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
341 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
342 {
343 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
344 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
345
346 void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
347 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
348 if (RT_VALID_PTR(pvSrc))
349 memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);
350 else
351 AssertPtr(pvSrc);
352
353 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
354 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
355
356 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
357 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
358 break;
359 }
360
361 default:
362 AssertMsgFailed(("%#x\n", fSwitchFlags));
363 }
364#else
365# error "misconfigured"
366#endif
367 }
368 /* else: There is no data in hardware yet, so whatever we got is already current. */
369 }
370 }
371 }
372
373 return VINF_SUCCESS;
374}
375
376
377/**
378 * Updates the heap buffers for all surfaces or one specific one.
379 *
380 * @param pThis The VGA device instance data.
381 * @param sid The surface ID, UINT32_MAX if all.
382 * @thread VMSVGAFIFO
383 */
384void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)
385{
386 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
387 AssertReturnVoid(pState);
388
389 if (sid == UINT32_MAX)
390 {
391 uint32_t cSurfaces = pState->cSurfaces;
392 for (sid = 0; sid < cSurfaces; sid++)
393 {
394 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
395 if (pSurface && pSurface->id == sid)
396 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
397 }
398 }
399 else if (sid < pState->cSurfaces)
400 {
401 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
402 if (pSurface && pSurface->id == sid)
403 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
404 }
405}
406
407
408
409
410void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)
411{
412 for (uint32_t i = 0; i < cFlags; i++)
413 if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)
414 {
415 Assert(paFlags[i].fFlags);
416 pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);
417 fFlags &= ~paFlags[i].fFlags;
418 if (!fFlags)
419 return;
420 }
421 if (fFlags)
422 pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);
423}
424
425
426/**
427 * Worker for vmsvgaR3Info that display details of a host window.
428 *
429 * @param pHlp The output methods.
430 * @param idHostWindow The host window handle/id/whatever.
431 */
432void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)
433{
434#ifdef RT_OS_WINDOWS
435 HWND hwnd = (HWND)(uintptr_t)idHostWindow;
436 Assert((uintptr_t)hwnd == idHostWindow);
437 if (hwnd != NULL)
438 {
439 WINDOWINFO Info;
440 RT_ZERO(Info);
441 Info.cbSize = sizeof(Info);
442 if (GetWindowInfo(hwnd, &Info))
443 {
444 pHlp->pfnPrintf(pHlp, " Window rect: xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
445 Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,
446 Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);
447 pHlp->pfnPrintf(pHlp, " Client rect: xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",
448 Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,
449 Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);
450 pHlp->pfnPrintf(pHlp, " Style: %#x", Info.dwStyle);
451 static const VMSVGAINFOFLAGS32 g_aStyles[] =
452 {
453 { WS_POPUP , "POPUP" },
454 { WS_CHILD , "CHILD" },
455 { WS_MINIMIZE , "MINIMIZE" },
456 { WS_VISIBLE , "VISIBLE" },
457 { WS_DISABLED , "DISABLED" },
458 { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },
459 { WS_CLIPCHILDREN , "CLIPCHILDREN" },
460 { WS_MAXIMIZE , "MAXIMIZE" },
461 { WS_BORDER , "BORDER" },
462 { WS_DLGFRAME , "DLGFRAME" },
463 { WS_VSCROLL , "VSCROLL" },
464 { WS_HSCROLL , "HSCROLL" },
465 { WS_SYSMENU , "SYSMENU" },
466 { WS_THICKFRAME , "THICKFRAME" },
467 { WS_GROUP , "GROUP" },
468 { WS_TABSTOP , "TABSTOP" },
469 };
470 vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));
471 pHlp->pfnPrintf(pHlp, "\n");
472
473 pHlp->pfnPrintf(pHlp, " ExStyle: %#x", Info.dwExStyle);
474 static const VMSVGAINFOFLAGS32 g_aExStyles[] =
475 {
476 { WS_EX_DLGMODALFRAME, "DLGMODALFRAME" },
477 { 0x00000002, "DRAGDETECT" },
478 { WS_EX_NOPARENTNOTIFY, "NOPARENTNOTIFY" },
479 { WS_EX_TOPMOST, "TOPMOST" },
480 { WS_EX_ACCEPTFILES, "ACCEPTFILES" },
481 { WS_EX_TRANSPARENT, "TRANSPARENT" },
482 { WS_EX_MDICHILD, "MDICHILD" },
483 { WS_EX_TOOLWINDOW, "TOOLWINDOW" },
484 { WS_EX_WINDOWEDGE, "WINDOWEDGE" },
485 { WS_EX_CLIENTEDGE, "CLIENTEDGE" },
486 { WS_EX_CONTEXTHELP, "CONTEXTHELP" },
487 { WS_EX_RIGHT, "RIGHT" },
488 /*{ WS_EX_LEFT, "LEFT" }, = 0 */
489 { WS_EX_RTLREADING, "RTLREADING" },
490 /*{ WS_EX_LTRREADING, "LTRREADING" }, = 0 */
491 { WS_EX_LEFTSCROLLBAR, "LEFTSCROLLBAR" },
492 /*{ WS_EX_RIGHTSCROLLBAR, "RIGHTSCROLLBAR" }, = 0 */
493 { WS_EX_CONTROLPARENT, "CONTROLPARENT" },
494 { WS_EX_STATICEDGE, "STATICEDGE" },
495 { WS_EX_APPWINDOW, "APPWINDOW" },
496 { WS_EX_LAYERED, "LAYERED" },
497 { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },
498 { WS_EX_LAYOUTRTL, "LAYOUTRTL" },
499 { WS_EX_COMPOSITED, "COMPOSITED" },
500 { WS_EX_NOACTIVATE, "NOACTIVATE" },
501 };
502 vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));
503 pHlp->pfnPrintf(pHlp, "\n");
504
505 pHlp->pfnPrintf(pHlp, " Window Status: %#x\n", Info.dwWindowStatus);
506 if (Info.cxWindowBorders || Info.cyWindowBorders)
507 pHlp->pfnPrintf(pHlp, " Borders: cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);
508 pHlp->pfnPrintf(pHlp, " Window Type: %#x\n", Info.atomWindowType);
509 pHlp->pfnPrintf(pHlp, " Creator Ver: %#x\n", Info.wCreatorVersion);
510 }
511 else
512 pHlp->pfnPrintf(pHlp, " GetWindowInfo: last error %d\n", GetLastError());
513 }
514#else
515 pHlp->pfnPrintf(pHlp, " Windows info: Not implemented on this platform\n");
516#endif
517
518}
519
520
521/**
522 * Looks up an enum value in a translation table.
523 *
524 * @returns The value name.
525 * @param iValue The value to name.
526 * @param pEnumMap Enum value to string mapping.
527 */
528const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)
529{
530 PCVMSVGAINFOENUM paValues = pEnumMap->paValues;
531
532#ifdef VBOX_STRICT
533 /*
534 * Check that it's really sorted, or the binary lookup won't work right.
535 */
536 if (!*pEnumMap->pfAsserted)
537 {
538 *pEnumMap->pfAsserted = true;
539 for (uint32_t i = 1; i < pEnumMap->cValues; i++)
540 Assert(paValues[i - 1].iValue <= paValues[i].iValue);
541 }
542#endif
543
544 /*
545 * Binary search
546 */
547 uint32_t iStart = 0;
548 uint32_t iEnd = (uint32_t)pEnumMap->cValues;
549 for (;;)
550 {
551 uint32_t i = iStart + (iEnd - iStart) / 2;
552 if (iValue < paValues[i].iValue)
553 {
554 if (i > iStart)
555 iEnd = i;
556 else
557 break;
558 }
559 else if (iValue > paValues[i].iValue)
560 {
561 i++;
562 if (i < iEnd)
563 iStart = i;
564 else
565 break;
566 }
567 else
568 return paValues[i].pszName;
569 }
570 return NULL;
571}
572
573
574/**
575 * Formats an enum value as a string, sparse mapping table.
576 *
577 * @returns pszBuffer.
578 * @param pszBuffer The output buffer.
579 * @param cbBuffer The size of the output buffer.
580 * @param pszName The variable name, optional.
581 * @param iValue The enum value.
582 * @param fPrefix Whether to prepend the prefix or not.
583 * @param pEnumMap Enum value to string mapping.
584 */
585char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
586 bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)
587{
588 const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);
589 const char *pszPrefix = fPrefix ? pEnumMap->pszPrefix : "";
590 if (pszValueName)
591 {
592 if (pszName)
593 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);
594 else
595 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);
596 return pszBuffer;
597 }
598
599 if (pszName)
600 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
601 else
602 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
603 return pszBuffer;
604}
605
606
607/**
608 * Formats an enum value as a string.
609 *
610 * @returns pszBuffer.
611 * @param pszBuffer The output buffer.
612 * @param cbBuffer The size of the output buffer.
613 * @param pszName The variable name, optional.
614 * @param uValue The enum value.
615 * @param pszPrefix The prefix of the enum values. Empty string if
616 * none. This helps reduce the memory footprint
617 * as well as the source code size.
618 * @param papszValues One to one string mapping of the enum values.
619 * @param cValues The number of values in the mapping.
620 */
621char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
622 const char *pszPrefix, const char * const *papszValues, size_t cValues)
623{
624 if (uValue < cValues)
625 {
626 if (pszName)
627 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
628 else
629 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
630 }
631 else
632 {
633 if (pszName)
634 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
635 else
636 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
637 }
638 return pszBuffer;
639}
640
641
642/**
643 * DBGF info printer for vmsvga3dAsciiPrint.
644 *
645 * @param pszLine The line to print.
646 * @param pvUser The debug info helpers.
647 */
648DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
649{
650 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
651 pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
652}
653
654
655/**
656 * Log printer for vmsvga3dAsciiPrint.
657 *
658 * @param pszLine The line to print.
659 * @param pvUser Ignored.
660 */
661DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
662{
663 size_t cch = strlen(pszLine);
664 while (cch > 0 && pszLine[cch - 1] == ' ')
665 cch--;
666 RTLogPrintf("%.*s\n", cch, pszLine);
667 NOREF(pvUser);
668}
669
670
671void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
672 uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
673 uint32_t cchMaxX, uint32_t cchMaxY)
674{
675 /*
676 * Skip stuff we can't or won't need to handle.
677 */
678 if (!cx || !cy)
679 return;
680 switch (enmFormat)
681 {
682 /* Compressed. */
683 case SVGA3D_DXT1:
684 case SVGA3D_DXT2:
685 case SVGA3D_DXT3:
686 case SVGA3D_DXT4:
687 case SVGA3D_DXT5:
688 return;
689 /* Generic. */
690 case SVGA3D_BUFFER:
691 return;
692 default:
693 break; /* ok */
694 }
695
696 /*
697 * Figure the pixel conversion factors.
698 */
699 uint32_t cxPerChar = cx / cchMaxX + 1;
700 uint32_t cyPerChar = cy / cchMaxY + 1;
701 /** @todo try keep aspect... */
702 uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
703 uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
704
705 /*
706 * The very simple conversion we're doing in this function is based on
707 * mapping a block of converted pixels to an ASCII character of similar
708 * weigth. We do that by summing up all the 8-bit gray scale pixels in
709 * that block, applying a conversion factor and getting an index into an
710 * array of increasingly weighty characters.
711 */
712 static const char s_szPalette[] = " ..`',:;icodxkO08XNWM";
713 static const uint32_t s_cchPalette = sizeof(s_szPalette) - 1;
714 uint32_t const cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
715
716 /*
717 * Do the work
718 */
719 uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
720 if (!pauScanline)
721 return;
722 char *pszLine = (char *)&pauScanline[cchLine];
723 RTCPTRUNION uSrc;
724 uSrc.pv = pvImage;
725 if (fInvY)
726 uSrc.pu8 += (cy - 1) * cbScanline;
727 uint32_t cyLeft = cy;
728 uint32_t cyLeftInScanline = cyPerChar;
729 bool fHitFormatAssert = false;
730 for (;;)
731 {
732 /*
733 * Process the scanline. This is tedious because of all the
734 * different formats. We generally ignore alpha, unless it's
735 * all we've got to work with.
736 * Color to 8-bit grayscale conversion is done by averaging.
737 */
738#define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \
739 do { \
740 for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
741 { \
742 a_RdExpr; \
743 pauScanline[xDst] += (a_AddExpr) & 0xff; \
744 Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
745 if (--cxLeftInChar == 0) \
746 { \
747 xDst++; \
748 cxLeftInChar = cxPerChar; \
749 } \
750 } \
751 } while (0)
752
753 switch (enmFormat)
754 {
755 /* Unsigned RGB and super/subsets. */
756 case SVGA3D_X8R8G8B8:
757 case SVGA3D_A8R8G8B8:
758 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
759 ( ( u32Tmp & 0xff) /* B */
760 + ((u32Tmp >> 8) & 0xff) /* G */
761 + ((u32Tmp >> 16) & 0xff) /* R */) / 3);
762 break;
763 case SVGA3D_R5G6B5:
764 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
765 ( ( u16Tmp & 0x1f) * 8
766 + ((u16Tmp >> 5) & 0x3f) * 4
767 + ( u16Tmp >> 11) * 8 ) / 3 );
768 break;
769 case SVGA3D_X1R5G5B5:
770 case SVGA3D_A1R5G5B5:
771 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
772 ( ( u16Tmp & 0x1f) * 8
773 + ((u16Tmp >> 5) & 0x1f) * 8
774 + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );
775 break;
776 case SVGA3D_A4R4G4B4:
777 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
778 ( ( u16Tmp & 0xf) * 16
779 + ((u16Tmp >> 4) & 0xf) * 16
780 + ((u16Tmp >> 8) & 0xf) * 16) / 3 );
781 break;
782 case SVGA3D_A16B16G16R16:
783 CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],
784 ( ((u64Tmp >> 8) & 0xff) /* R */
785 + ((u64Tmp >> 24) & 0xff) /* G */
786 + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);
787 break;
788 case SVGA3D_A2R10G10B10:
789 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
790 ( ( u32Tmp & 0x3ff) /* B */
791 + ((u32Tmp >> 10) & 0x3ff) /* G */
792 + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));
793 break;
794 case SVGA3D_G16R16:
795 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
796 ( (u32Tmp & 0xffff) /* R */
797 + (u32Tmp >> 16 ) /* G */) / 0x200);
798 break;
799
800 /* Depth. */
801 case SVGA3D_Z_D32:
802 CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),
803 (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))
804 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
805 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
806 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
807 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
808 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
809 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
810 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
811 break;
812 case SVGA3D_Z_D16:
813 CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],
814 ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))
815 | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))
816 | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))
817 | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))
818 | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))
819 | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))
820 | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))
821 | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );
822 break;
823 case SVGA3D_Z_D24S8:
824 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
825 ( u32Tmp & 0xff) /* stencile */
826 | ((~u32Tmp >> 18) & 0x3f));
827 break;
828 case SVGA3D_Z_D15S1:
829 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
830 ( (u16Tmp & 0x01) << 7) /* stencile */
831 | ((~u16Tmp >> 8) & 0x7f));
832 break;
833
834 /* Pure alpha. */
835 case SVGA3D_ALPHA8:
836 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
837 break;
838
839 /* Luminance */
840 case SVGA3D_LUMINANCE8:
841 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
842 break;
843 case SVGA3D_LUMINANCE4_ALPHA4:
844 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);
845 break;
846 case SVGA3D_LUMINANCE16:
847 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
848 break;
849 case SVGA3D_LUMINANCE8_ALPHA8:
850 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
851 break;
852
853 /* Not supported. */
854 case SVGA3D_DXT1:
855 case SVGA3D_DXT2:
856 case SVGA3D_DXT3:
857 case SVGA3D_DXT4:
858 case SVGA3D_DXT5:
859 case SVGA3D_BUFFER:
860 AssertFailedBreak();
861
862 /* Not considered for implementation yet. */
863 case SVGA3D_BUMPU8V8:
864 case SVGA3D_BUMPL6V5U5:
865 case SVGA3D_BUMPX8L8V8U8:
866 case SVGA3D_BUMPL8V8U8:
867 case SVGA3D_ARGB_S10E5:
868 case SVGA3D_ARGB_S23E8:
869 case SVGA3D_V8U8:
870 case SVGA3D_Q8W8V8U8:
871 case SVGA3D_CxV8U8:
872 case SVGA3D_X8L8V8U8:
873 case SVGA3D_A2W10V10U10:
874 case SVGA3D_R_S10E5:
875 case SVGA3D_R_S23E8:
876 case SVGA3D_RG_S10E5:
877 case SVGA3D_RG_S23E8:
878 case SVGA3D_Z_D24X8:
879 case SVGA3D_V16U16:
880 case SVGA3D_UYVY:
881 case SVGA3D_YUY2:
882 case SVGA3D_NV12:
883 case SVGA3D_AYUV:
884 case SVGA3D_BC4_UNORM:
885 case SVGA3D_BC5_UNORM:
886 case SVGA3D_Z_DF16:
887 case SVGA3D_Z_DF24:
888 case SVGA3D_Z_D24S8_INT:
889 if (!fHitFormatAssert)
890 {
891 AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));
892 fHitFormatAssert = true;
893 }
894 /* fall thru */
895 default:
896 /* Lazy programmer fallbacks. */
897 if (cbSrcPixel == 4)
898 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
899 ( ( u32Tmp & 0xff)
900 + ((u32Tmp >> 8) & 0xff)
901 + ((u32Tmp >> 16) & 0xff)
902 + ((u32Tmp >> 24) & 0xff) ) / 4);
903 else if (cbSrcPixel == 3)
904 CONVERT_SCANLINE(RT_NOTHING,
905 ( (uint32_t)uSrc.pu8[xSrc * 4]
906 + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
907 + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
908 else if (cbSrcPixel == 2)
909 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
910 ( ( u16Tmp & 0xf)
911 + ((u16Tmp >> 4) & 0xf)
912 + ((u16Tmp >> 8) & 0xf)
913 + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );
914 else if (cbSrcPixel == 1)
915 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
916 else
917 AssertFailed();
918 break;
919
920 }
921
922 /*
923 * Print we've reached the end of a block in y direction or if we're at
924 * the end of the image.
925 */
926 cyLeft--;
927 if (--cyLeftInScanline == 0 || cyLeft == 0)
928 {
929 for (uint32_t i = 0; i < cchLine; i++)
930 {
931 uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
932 pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
933 }
934 pszLine[cchLine] = '\0';
935 pfnPrintLine(pszLine, pvUser);
936
937 if (!cyLeft)
938 break;
939 cyLeftInScanline = cyPerChar;
940 RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
941 }
942
943 /*
944 * Advance.
945 */
946 if (!fInvY)
947 uSrc.pu8 += cbScanline;
948 else
949 uSrc.pu8 -= cbScanline;
950 }
951}
952
953
954/**
955 * List of render state names with type prefix.
956 *
957 * First char in the name is a type indicator:
958 * - '*' = requires special handling.
959 * - 'f' = SVGA3dbool
960 * - 'd' = uint32_t
961 * - 'r' = float
962 * - 'b' = SVGA3dBlendOp
963 * - 'c' = SVGA3dColor, SVGA3dColorMask
964 * - 'e' = SVGA3dBlendEquation
965 * - 'm' = SVGA3dColorMask
966 * - 'p' = SVGA3dCmpFunc
967 * - 's' = SVGA3dStencilOp
968 * - 'v' = SVGA3dVertexMaterial
969 * - 'w' = SVGA3dWrapFlags
970 */
971static const char * const g_apszRenderStateNamesAndType[] =
972{
973 "*" "INVALID", /* invalid */
974 "f" "ZENABLE", /* SVGA3dBool */
975 "f" "ZWRITEENABLE", /* SVGA3dBool */
976 "f" "ALPHATESTENABLE", /* SVGA3dBool */
977 "f" "DITHERENABLE", /* SVGA3dBool */
978 "f" "BLENDENABLE", /* SVGA3dBool */
979 "f" "FOGENABLE", /* SVGA3dBool */
980 "f" "SPECULARENABLE", /* SVGA3dBool */
981 "f" "STENCILENABLE", /* SVGA3dBool */
982 "f" "LIGHTINGENABLE", /* SVGA3dBool */
983 "f" "NORMALIZENORMALS", /* SVGA3dBool */
984 "f" "POINTSPRITEENABLE", /* SVGA3dBool */
985 "f" "POINTSCALEENABLE", /* SVGA3dBool */
986 "x" "STENCILREF", /* uint32_t */
987 "x" "STENCILMASK", /* uint32_t */
988 "x" "STENCILWRITEMASK", /* uint32_t */
989 "r" "FOGSTART", /* float */
990 "r" "FOGEND", /* float */
991 "r" "FOGDENSITY", /* float */
992 "r" "POINTSIZE", /* float */
993 "r" "POINTSIZEMIN", /* float */
994 "r" "POINTSIZEMAX", /* float */
995 "r" "POINTSCALE_A", /* float */
996 "r" "POINTSCALE_B", /* float */
997 "r" "POINTSCALE_C", /* float */
998 "c" "FOGCOLOR", /* SVGA3dColor */
999 "c" "AMBIENT", /* SVGA3dColor */
1000 "*" "CLIPPLANEENABLE", /* SVGA3dClipPlanes */
1001 "*" "FOGMODE", /* SVGA3dFogMode */
1002 "*" "FILLMODE", /* SVGA3dFillMode */
1003 "*" "SHADEMODE", /* SVGA3dShadeMode */
1004 "*" "LINEPATTERN", /* SVGA3dLinePattern */
1005 "b" "SRCBLEND", /* SVGA3dBlendOp */
1006 "b" "DSTBLEND", /* SVGA3dBlendOp */
1007 "e" "BLENDEQUATION", /* SVGA3dBlendEquation */
1008 "*" "CULLMODE", /* SVGA3dFace */
1009 "p" "ZFUNC", /* SVGA3dCmpFunc */
1010 "p" "ALPHAFUNC", /* SVGA3dCmpFunc */
1011 "p" "STENCILFUNC", /* SVGA3dCmpFunc */
1012 "s" "STENCILFAIL", /* SVGA3dStencilOp */
1013 "s" "STENCILZFAIL", /* SVGA3dStencilOp */
1014 "s" "STENCILPASS", /* SVGA3dStencilOp */
1015 "r" "ALPHAREF", /* float */
1016 "*" "FRONTWINDING", /* SVGA3dFrontWinding */
1017 "*" "COORDINATETYPE", /* SVGA3dCoordinateType */
1018 "r" "ZBIAS", /* float */
1019 "f" "RANGEFOGENABLE", /* SVGA3dBool */
1020 "c" "COLORWRITEENABLE", /* SVGA3dColorMask */
1021 "f" "VERTEXMATERIALENABLE", /* SVGA3dBool */
1022 "v" "DIFFUSEMATERIALSOURCE", /* SVGA3dVertexMaterial */
1023 "v" "SPECULARMATERIALSOURCE", /* SVGA3dVertexMaterial */
1024 "v" "AMBIENTMATERIALSOURCE", /* SVGA3dVertexMaterial */
1025 "v" "EMISSIVEMATERIALSOURCE", /* SVGA3dVertexMaterial */
1026 "c" "TEXTUREFACTOR", /* SVGA3dColor */
1027 "f" "LOCALVIEWER", /* SVGA3dBool */
1028 "f" "SCISSORTESTENABLE", /* SVGA3dBool */
1029 "c" "BLENDCOLOR", /* SVGA3dColor */
1030 "f" "STENCILENABLE2SIDED", /* SVGA3dBool */
1031 "p" "CCWSTENCILFUNC", /* SVGA3dCmpFunc */
1032 "s" "CCWSTENCILFAIL", /* SVGA3dStencilOp */
1033 "s" "CCWSTENCILZFAIL", /* SVGA3dStencilOp */
1034 "s" "CCWSTENCILPASS", /* SVGA3dStencilOp */
1035 "*" "VERTEXBLEND", /* SVGA3dVertexBlendFlags */
1036 "r" "SLOPESCALEDEPTHBIAS", /* float */
1037 "r" "DEPTHBIAS", /* float */
1038 "r" "OUTPUTGAMMA", /* float */
1039 "f" "ZVISIBLE", /* SVGA3dBool */
1040 "f" "LASTPIXEL", /* SVGA3dBool */
1041 "f" "CLIPPING", /* SVGA3dBool */
1042 "w" "WRAP0", /* SVGA3dWrapFlags */
1043 "w" "WRAP1", /* SVGA3dWrapFlags */
1044 "w" "WRAP2", /* SVGA3dWrapFlags */
1045 "w" "WRAP3", /* SVGA3dWrapFlags */
1046 "w" "WRAP4", /* SVGA3dWrapFlags */
1047 "w" "WRAP5", /* SVGA3dWrapFlags */
1048 "w" "WRAP6", /* SVGA3dWrapFlags */
1049 "w" "WRAP7", /* SVGA3dWrapFlags */
1050 "w" "WRAP8", /* SVGA3dWrapFlags */
1051 "w" "WRAP9", /* SVGA3dWrapFlags */
1052 "w" "WRAP10", /* SVGA3dWrapFlags */
1053 "w" "WRAP11", /* SVGA3dWrapFlags */
1054 "w" "WRAP12", /* SVGA3dWrapFlags */
1055 "w" "WRAP13", /* SVGA3dWrapFlags */
1056 "w" "WRAP14", /* SVGA3dWrapFlags */
1057 "w" "WRAP15", /* SVGA3dWrapFlags */
1058 "f" "MULTISAMPLEANTIALIAS", /* SVGA3dBool */
1059 "x" "MULTISAMPLEMASK", /* uint32_t */
1060 "f" "INDEXEDVERTEXBLENDENABLE", /* SVGA3dBool */
1061 "r" "TWEENFACTOR", /* float */
1062 "f" "ANTIALIASEDLINEENABLE", /* SVGA3dBool */
1063 "c" "COLORWRITEENABLE1", /* SVGA3dColorMask */
1064 "c" "COLORWRITEENABLE2", /* SVGA3dColorMask */
1065 "c" "COLORWRITEENABLE3", /* SVGA3dColorMask */
1066 "f" "SEPARATEALPHABLENDENABLE", /* SVGA3dBool */
1067 "b" "SRCBLENDALPHA", /* SVGA3dBlendOp */
1068 "b" "DSTBLENDALPHA", /* SVGA3dBlendOp */
1069 "e" "BLENDEQUATIONALPHA", /* SVGA3dBlendEquation */
1070 "*" "TRANSPARENCYANTIALIAS", /* SVGA3dTransparencyAntialiasType */
1071 "f" "LINEAA", /* SVGA3dBool */
1072 "r" "LINEWIDTH", /* float */
1073};
1074
1075
1076/**
1077 * Formats a SVGA3dRenderState structure as a string.
1078 *
1079 * @returns pszBuffer.
1080 * @param pszBuffer Output string buffer.
1081 * @param cbBuffer Size of output buffer.
1082 * @param pRenderState The SVGA3d render state to format.
1083 */
1084char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
1085{
1086 uint32_t iState = pRenderState->state;
1087 if (iState != SVGA3D_RS_INVALID)
1088 {
1089 if (iState < RT_ELEMENTS(g_apszRenderStateNamesAndType))
1090 {
1091 const char *pszName = g_apszRenderStateNamesAndType[iState];
1092 char const chType = *pszName++;
1093
1094 union
1095 {
1096 uint32_t u;
1097 float r;
1098 SVGA3dColorMask Color;
1099 } uValue;
1100 uValue.u = pRenderState->uintValue;
1101
1102 switch (chType)
1103 {
1104 case 'f':
1105 if (uValue.u == 0)
1106 RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
1107 else if (uValue.u == 1)
1108 RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
1109 else
1110 RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
1111 break;
1112 case 'x':
1113 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
1114 break;
1115 case 'r':
1116 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
1117 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
1118 break;
1119 case 'c': //SVGA3dColor, SVGA3dColorMask
1120 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
1121 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
1122 break;
1123 case 'w': //SVGA3dWrapFlags
1124 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
1125 uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
1126 break;
1127 default:
1128 AssertFailed();
1129 case 'b': //SVGA3dBlendOp
1130 case 'e': //SVGA3dBlendEquation
1131 case 'p': //SVGA3dCmpFunc
1132 case 's': //SVGA3dStencilOp
1133 case 'v': //SVGA3dVertexMaterial
1134 case '*':
1135 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
1136 break;
1137 }
1138 }
1139 else
1140 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
1141 }
1142 else
1143 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
1144 return pszBuffer;
1145}
1146
1147/**
1148 * Texture state names with type prefix.
1149 */
1150static const char * const g_apszTextureStateNamesAndType[] =
1151{
1152 "*" "INVALID", /* invalid */
1153 "x" "BIND_TEXTURE", /* SVGA3dSurfaceId */
1154 "m" "COLOROP", /* SVGA3dTextureCombiner */
1155 "a" "COLORARG1", /* SVGA3dTextureArgData */
1156 "a" "COLORARG2", /* SVGA3dTextureArgData */
1157 "m" "ALPHAOP", /* SVGA3dTextureCombiner */
1158 "a" "ALPHAARG1", /* SVGA3dTextureArgData */
1159 "a" "ALPHAARG2", /* SVGA3dTextureArgData */
1160 "e" "ADDRESSU", /* SVGA3dTextureAddress */
1161 "e" "ADDRESSV", /* SVGA3dTextureAddress */
1162 "l" "MIPFILTER", /* SVGA3dTextureFilter */
1163 "l" "MAGFILTER", /* SVGA3dTextureFilter */
1164 "m" "MINFILTER", /* SVGA3dTextureFilter */
1165 "c" "BORDERCOLOR", /* SVGA3dColor */
1166 "r" "TEXCOORDINDEX", /* uint32_t */
1167 "t" "TEXTURETRANSFORMFLAGS", /* SVGA3dTexTransformFlags */
1168 "g" "TEXCOORDGEN", /* SVGA3dTextureCoordGen */
1169 "r" "BUMPENVMAT00", /* float */
1170 "r" "BUMPENVMAT01", /* float */
1171 "r" "BUMPENVMAT10", /* float */
1172 "r" "BUMPENVMAT11", /* float */
1173 "x" "TEXTURE_MIPMAP_LEVEL", /* uint32_t */
1174 "r" "TEXTURE_LOD_BIAS", /* float */
1175 "x" "TEXTURE_ANISOTROPIC_LEVEL", /* uint32_t */
1176 "e" "ADDRESSW", /* SVGA3dTextureAddress */
1177 "r" "GAMMA", /* float */
1178 "r" "BUMPENVLSCALE", /* float */
1179 "r" "BUMPENVLOFFSET", /* float */
1180 "a" "COLORARG0", /* SVGA3dTextureArgData */
1181 "a" "ALPHAARG0" /* SVGA3dTextureArgData */
1182};
1183
1184/**
1185 * Formats a SVGA3dTextureState structure as a string.
1186 *
1187 * @returns pszBuffer.
1188 * @param pszBuffer Output string buffer.
1189 * @param cbBuffer Size of output buffer.
1190 * @param pTextureState The SVGA3d texture state to format.
1191 */
1192char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
1193{
1194 /*
1195 * Format the stage first.
1196 */
1197 char *pszRet = pszBuffer;
1198 size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
1199 if (cchPrefix < cbBuffer)
1200 {
1201 cbBuffer -= cchPrefix;
1202 pszBuffer += cchPrefix;
1203 }
1204 else
1205 cbBuffer = 0;
1206
1207 /*
1208 * Format the name and value.
1209 */
1210 uint32_t iName = pTextureState->name;
1211 if (iName != SVGA3D_TS_INVALID)
1212 {
1213 if (iName < RT_ELEMENTS(g_apszTextureStateNamesAndType))
1214 {
1215 const char *pszName = g_apszTextureStateNamesAndType[iName];
1216 char chType = *pszName++;
1217
1218 union
1219 {
1220 uint32_t u;
1221 float r;
1222 SVGA3dColorMask Color;
1223 } uValue;
1224 uValue.u = pTextureState->value;
1225
1226 switch (chType)
1227 {
1228 case 'x':
1229 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
1230 break;
1231
1232 case 'r':
1233 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
1234 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
1235 break;
1236
1237 case 'a': //SVGA3dTextureArgData
1238 {
1239 static const char * const s_apszValues[] =
1240 {
1241 "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
1242 };
1243 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1244 "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
1245 break;
1246 }
1247
1248 case 'c': //SVGA3dColor, SVGA3dColorMask
1249 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
1250 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
1251 break;
1252
1253 case 'e': //SVGA3dTextureAddress
1254 {
1255 static const char * const s_apszValues[] =
1256 {
1257 "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
1258 };
1259 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1260 "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
1261 break;
1262 }
1263
1264 case 'l': //SVGA3dTextureFilter
1265 {
1266 static const char * const s_apszValues[] =
1267 {
1268 "NONE", "NEAREST", "LINEAR", "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
1269 };
1270 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1271 "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
1272 break;
1273 }
1274
1275 case 'g': //SVGA3dTextureCoordGen
1276 {
1277 static const char * const s_apszValues[] =
1278 {
1279 "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
1280 };
1281 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1282 "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
1283 break;
1284 }
1285
1286 case 'm': //SVGA3dTextureCombiner
1287 {
1288 static const char * const s_apszValues[] =
1289 {
1290 "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
1291 "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
1292 "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
1293 "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
1294 "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
1295 };
1296 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1297 "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
1298 break;
1299 }
1300
1301 default:
1302 AssertFailed();
1303 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
1304 break;
1305 }
1306 }
1307 else
1308 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
1309 }
1310 else
1311 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
1312 return pszRet;
1313}
1314
1315
1316
1317static const char * const g_apszTransformTypes[] =
1318{
1319 "SVGA3D_TRANSFORM_INVALID",
1320 "SVGA3D_TRANSFORM_WORLD",
1321 "SVGA3D_TRANSFORM_VIEW",
1322 "SVGA3D_TRANSFORM_PROJECTION",
1323 "SVGA3D_TRANSFORM_TEXTURE0",
1324 "SVGA3D_TRANSFORM_TEXTURE1",
1325 "SVGA3D_TRANSFORM_TEXTURE2",
1326 "SVGA3D_TRANSFORM_TEXTURE3",
1327 "SVGA3D_TRANSFORM_TEXTURE4",
1328 "SVGA3D_TRANSFORM_TEXTURE5",
1329 "SVGA3D_TRANSFORM_TEXTURE6",
1330 "SVGA3D_TRANSFORM_TEXTURE7",
1331 "SVGA3D_TRANSFORM_WORLD1",
1332 "SVGA3D_TRANSFORM_WORLD2",
1333 "SVGA3D_TRANSFORM_WORLD3",
1334};
1335
1336static const char * const g_apszFaces[] =
1337{
1338 "SVGA3D_FACE_INVALID",
1339 "SVGA3D_FACE_NONE",
1340 "SVGA3D_FACE_FRONT",
1341 "SVGA3D_FACE_BACK",
1342 "SVGA3D_FACE_FRONT_BACK",
1343};
1344
1345static const char * const g_apszLightTypes[] =
1346{
1347 "SVGA3D_LIGHTTYPE_INVALID",
1348 "SVGA3D_LIGHTTYPE_POINT",
1349 "SVGA3D_LIGHTTYPE_SPOT1",
1350 "SVGA3D_LIGHTTYPE_SPOT2",
1351 "SVGA3D_LIGHTTYPE_DIRECTIONAL",
1352};
1353
1354static const char * const g_apszRenderTargets[] =
1355{
1356 "SVGA3D_RT_DEPTH",
1357 "SVGA3D_RT_STENCIL",
1358 "SVGA3D_RT_COLOR0",
1359 "SVGA3D_RT_COLOR1",
1360 "SVGA3D_RT_COLOR2",
1361 "SVGA3D_RT_COLOR3",
1362 "SVGA3D_RT_COLOR4",
1363 "SVGA3D_RT_COLOR5",
1364 "SVGA3D_RT_COLOR6",
1365 "SVGA3D_RT_COLOR7",
1366};
1367
1368static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
1369{
1370 char szTmp[128];
1371
1372 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
1373#ifdef RT_OS_WINDOWS
1374 pHlp->pfnPrintf(pHlp, "hwnd: %p\n", pContext->hwnd);
1375 if (fVerbose)
1376 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
1377# ifdef VMSVGA3D_DIRECT3D
1378 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice);
1379# else
1380 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc);
1381 pHlp->pfnPrintf(pHlp, "hglrc: %p\n", pContext->hglrc);
1382# endif
1383#else
1384/** @todo Other hosts... */
1385#endif
1386 pHlp->pfnPrintf(pHlp, "sidRenderTarget: %#x\n", pContext->sidRenderTarget);
1387
1388 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
1389 if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
1390 pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]: %#x\n", i, pContext->aSidActiveTexture[i]);
1391
1392 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);
1393
1394 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
1395 if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
1396 pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
1397 vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
1398
1399 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
1400 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
1401 if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
1402 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
1403 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
1404
1405 AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
1406 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
1407 if (pContext->state.aTransformState[i].fValid)
1408 {
1409 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
1410 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
1411 pHlp->pfnPrintf(pHlp,
1412 (j % 4) == 0 ? " [ " FLOAT_FMT_STR : (j % 4) < 3 ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
1413 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
1414 }
1415
1416 AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
1417 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
1418 if (pContext->state.aMaterial[i].fValid)
1419 {
1420 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
1421 g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
1422 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1423 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
1424 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
1425 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
1426 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
1427 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1428 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
1429 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
1430 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
1431 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
1432 pHlp->pfnPrintf(pHlp, " specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1433 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
1434 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
1435 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
1436 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
1437 pHlp->pfnPrintf(pHlp, " emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1438 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
1439 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
1440 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
1441 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
1442 }
1443
1444 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
1445 if (pContext->state.aClipPlane[i].fValid)
1446 pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1447 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
1448 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
1449 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
1450 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
1451
1452 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
1453 if (pContext->state.aLightData[i].fValidData)
1454 {
1455 pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
1456 i,
1457 pContext->state.aLightData[i].fEnabled,
1458 pContext->state.aLightData[i].data.inWorldSpace,
1459 (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
1460 ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
1461 pContext->state.aLightData[i].data.type);
1462 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1463 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
1464 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
1465 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
1466 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
1467 pHlp->pfnPrintf(pHlp, " specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1468 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
1469 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
1470 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
1471 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
1472 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1473 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
1474 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
1475 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
1476 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
1477 pHlp->pfnPrintf(pHlp, " position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1478 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
1479 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
1480 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
1481 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
1482 pHlp->pfnPrintf(pHlp, " direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1483 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
1484 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
1485 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
1486 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
1487 pHlp->pfnPrintf(pHlp, " range=" FLOAT_FMT_STR " falloff=" FLOAT_FMT_STR "\n",
1488 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
1489 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
1490 pHlp->pfnPrintf(pHlp, " attenuation0=" FLOAT_FMT_STR " attenuation1=" FLOAT_FMT_STR " attenuation2=" FLOAT_FMT_STR "\n",
1491 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
1492 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
1493 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
1494 pHlp->pfnPrintf(pHlp, " theta=" FLOAT_FMT_STR " phi=" FLOAT_FMT_STR "\n",
1495 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
1496 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
1497 }
1498
1499 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
1500 if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
1501 pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
1502 i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
1503 pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
1504
1505 pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
1506 pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
1507 pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
1508 pHlp->pfnPrintf(pHlp, "zRange: (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
1509 FLOAT_FMT_ARGS(pContext->state.zRange.min),
1510 FLOAT_FMT_ARGS(pContext->state.zRange.max));
1511 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);
1512 pHlp->pfnPrintf(pHlp, "shidPixel: %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
1513 pHlp->pfnPrintf(pHlp, "shidVertex: %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
1514
1515 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
1516 {
1517 uint32_t cConsts = iWhich == 0 ? pContext->state.cPixelShaderConst : pContext->state.cVertexShaderConst;
1518 PVMSVGASHADERCONST paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst : pContext->state.paVertexShaderConst;
1519 const char *pszName = iWhich ? "paPixelShaderConst" : "paVertexShaderConst";
1520
1521 for (uint32_t i = 0; i < cConsts; i++)
1522 if (paConsts[i].fValid)
1523 {
1524 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
1525 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
1526 pszName, i, i,
1527 FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
1528 FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
1529 else
1530 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
1531 pszName, i, i,
1532 paConsts[i].value[0], paConsts[i].value[1],
1533 paConsts[i].value[2], paConsts[i].value[3],
1534 paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
1535 : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
1536 }
1537 }
1538
1539 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
1540 {
1541 uint32_t cShaders = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
1542 PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
1543 const char *pszName = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
1544 for (uint32_t i = 0; i < cShaders; i++)
1545 if (paShaders[i].id == i)
1546 {
1547 pHlp->pfnPrintf(pHlp, "%s[%u]: id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
1548 pszName, i,
1549 paShaders[i].id,
1550 paShaders[i].cid,
1551 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
1552 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
1553 paShaders[i].type,
1554 paShaders[i].cbData,
1555 paShaders[i].pShaderProgram);
1556 }
1557 }
1558}
1559
1560
1561void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
1562{
1563 /* Warning! This code is currently racing papContexts reallocation! */
1564 /* Warning! This code is currently racing papContexts reallocation! */
1565 /* Warning! This code is currently racing papContexts reallocation! */
1566 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
1567 if (pState)
1568 {
1569 /*
1570 * Deal with a specific request first.
1571 */
1572 if (cid != UINT32_MAX)
1573 {
1574 if (cid < pState->cContexts)
1575 {
1576 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
1577 if (pContext && pContext->id == cid)
1578 {
1579 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
1580 return;
1581 }
1582 }
1583 pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
1584 }
1585 else
1586 {
1587 /*
1588 * Dump all.
1589 */
1590 uint32_t cContexts = pState->cContexts;
1591 pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
1592 for (cid = 0; cid < cContexts; cid++)
1593 {
1594 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
1595 if (pContext && pContext->id == cid)
1596 {
1597 pHlp->pfnPrintf(pHlp, "\n");
1598 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
1599 }
1600 }
1601 }
1602 }
1603}
1604
1605/** Values for SVGA3dTextureFilter, prefix SVGA3D_TEX_FILTER_. */
1606static const char * const g_apszTexureFilters[] =
1607{
1608 "NONE",
1609 "NEAREST",
1610 "LINEAR",
1611 "ANISOTROPIC",
1612 "FLATCUBIC",
1613 "GAUSSIANCUBIC",
1614 "PYRAMIDALQUAD",
1615 "GAUSSIANQUAD",
1616};
1617
1618/** SVGA3dSurfaceFlags values, prefix SVGA3D_SURFACE_. */
1619static VMSVGAINFOFLAGS32 const g_aSvga3DSurfaceFlags[] =
1620{
1621 { SVGA3D_SURFACE_CUBEMAP , "CUBEMAP" },
1622 { SVGA3D_SURFACE_HINT_STATIC , "HINT_STATIC" },
1623 { SVGA3D_SURFACE_HINT_DYNAMIC , "HINT_DYNAMIC" },
1624 { SVGA3D_SURFACE_HINT_INDEXBUFFER , "HINT_INDEXBUFFER" },
1625 { SVGA3D_SURFACE_HINT_VERTEXBUFFER , "HINT_VERTEXBUFFER" },
1626 { SVGA3D_SURFACE_HINT_TEXTURE , "HINT_TEXTURE" },
1627 { SVGA3D_SURFACE_HINT_RENDERTARGET , "HINT_RENDERTARGET" },
1628 { SVGA3D_SURFACE_HINT_DEPTHSTENCIL , "HINT_DEPTHSTENCIL" },
1629 { SVGA3D_SURFACE_HINT_WRITEONLY , "HINT_WRITEONLY" },
1630 { SVGA3D_SURFACE_MASKABLE_ANTIALIAS , "MASKABLE_ANTIALIAS" },
1631 { SVGA3D_SURFACE_AUTOGENMIPMAPS , "AUTOGENMIPMAPS" },
1632};
1633
1634
1635#ifdef VMSVGA3D_DIRECT3D
1636
1637/** Values for D3DFORMAT, prefix D3DFMT_. */
1638static VMSVGAINFOENUM const g_aD3DFormats[] =
1639{
1640 { D3DFMT_UNKNOWN , "UNKNOWN" },
1641 { D3DFMT_R8G8B8 , "R8G8B8" },
1642 { D3DFMT_A8R8G8B8 , "A8R8G8B8" },
1643 { D3DFMT_X8R8G8B8 , "X8R8G8B8" },
1644 { D3DFMT_R5G6B5 , "R5G6B5" },
1645 { D3DFMT_X1R5G5B5 , "X1R5G5B5" },
1646 { D3DFMT_A1R5G5B5 , "A1R5G5B5" },
1647 { D3DFMT_A4R4G4B4 , "A4R4G4B4" },
1648 { D3DFMT_R3G3B2 , "R3G3B2" },
1649 { D3DFMT_A8 , "A8" },
1650 { D3DFMT_A8R3G3B2 , "A8R3G3B2" },
1651 { D3DFMT_X4R4G4B4 , "X4R4G4B4" },
1652 { D3DFMT_A2B10G10R10 , "A2B10G10R10" },
1653 { D3DFMT_A8B8G8R8 , "A8B8G8R8" },
1654 { D3DFMT_X8B8G8R8 , "X8B8G8R8" },
1655 { D3DFMT_G16R16 , "G16R16" },
1656 { D3DFMT_A2R10G10B10 , "A2R10G10B10" },
1657 { D3DFMT_A16B16G16R16 , "A16B16G16R16" },
1658 { D3DFMT_A8P8 , "A8P8" },
1659 { D3DFMT_P8 , "P8" },
1660 { D3DFMT_L8 , "L8" },
1661 { D3DFMT_A8L8 , "A8L8" },
1662 { D3DFMT_A4L4 , "A4L4" },
1663 { D3DFMT_V8U8 , "V8U8" },
1664 { D3DFMT_L6V5U5 , "L6V5U5" },
1665 { D3DFMT_X8L8V8U8 , "X8L8V8U8" },
1666 { D3DFMT_Q8W8V8U8 , "Q8W8V8U8" },
1667 { D3DFMT_V16U16 , "V16U16" },
1668 { D3DFMT_A2W10V10U10 , "A2W10V10U10" },
1669 { D3DFMT_D16_LOCKABLE , "D16_LOCKABLE" },
1670 { D3DFMT_D32 , "D32" },
1671 { D3DFMT_D15S1 , "D15S1" },
1672 { D3DFMT_D24S8 , "D24S8" },
1673 { D3DFMT_D24X8 , "D24X8" },
1674 { D3DFMT_D24X4S4 , "D24X4S4" },
1675 { D3DFMT_D16 , "D16" },
1676 { D3DFMT_L16 , "L16" },
1677 { D3DFMT_D32F_LOCKABLE , "D32F_LOCKABLE" },
1678 { D3DFMT_D24FS8 , "D24FS8" },
1679 { D3DFMT_VERTEXDATA , "VERTEXDATA" },
1680 { D3DFMT_INDEX16 , "INDEX16" },
1681 { D3DFMT_INDEX32 , "INDEX32" },
1682 { D3DFMT_Q16W16V16U16 , "Q16W16V16U16" },
1683 { D3DFMT_R16F , "R16F" },
1684 { D3DFMT_G16R16F , "G16R16F" },
1685 { D3DFMT_A16B16G16R16F , "A16B16G16R16F" },
1686 { D3DFMT_R32F , "R32F" },
1687 { D3DFMT_G32R32F , "G32R32F" },
1688 { D3DFMT_A32B32G32R32F , "A32B32G32R32F" },
1689 { D3DFMT_CxV8U8 , "CxV8U8" },
1690 /* Fourcc values, MSB is in the right most char: */
1691 { D3DFMT_MULTI2_ARGB8 , "MULTI2_ARGB8" },
1692 { D3DFMT_DXT1 , "DXT1" },
1693 { D3DFMT_DXT2 , "DXT2" },
1694 { D3DFMT_YUY2 , "YUY2" },
1695 { D3DFMT_DXT3 , "DXT3" },
1696 { D3DFMT_DXT4 , "DXT4" },
1697 { D3DFMT_DXT5 , "DXT5" },
1698 { D3DFMT_G8R8_G8B8 , "G8R8_G8B8" },
1699 { D3DFMT_R8G8_B8G8 , "R8G8_B8G8" },
1700 { D3DFMT_UYVY , "UYVY" },
1701 { D3DFMT_FORCE_DWORD , "FORCE_DWORD" }, /* UINT32_MAX */
1702};
1703VMSVGAINFOENUMMAP_MAKE(static, g_D3DFormat2String, g_aD3DFormats, "D3DFMT_");
1704
1705/** Values for D3DMULTISAMPLE_TYPE, prefix D3DMULTISAMPLE_. */
1706static VMSVGAINFOENUM const g_aD3DMultiSampleTypes[] =
1707{
1708 { D3DMULTISAMPLE_NONE , "NONE" },
1709 { D3DMULTISAMPLE_NONMASKABLE , "NONMASKABLE" },
1710 { D3DMULTISAMPLE_2_SAMPLES , "2_SAMPLES" },
1711 { D3DMULTISAMPLE_3_SAMPLES , "3_SAMPLES" },
1712 { D3DMULTISAMPLE_4_SAMPLES , "4_SAMPLES" },
1713 { D3DMULTISAMPLE_5_SAMPLES , "5_SAMPLES" },
1714 { D3DMULTISAMPLE_6_SAMPLES , "6_SAMPLES" },
1715 { D3DMULTISAMPLE_7_SAMPLES , "7_SAMPLES" },
1716 { D3DMULTISAMPLE_8_SAMPLES , "8_SAMPLES" },
1717 { D3DMULTISAMPLE_9_SAMPLES , "9_SAMPLES" },
1718 { D3DMULTISAMPLE_10_SAMPLES , "10_SAMPLES" },
1719 { D3DMULTISAMPLE_11_SAMPLES , "11_SAMPLES" },
1720 { D3DMULTISAMPLE_12_SAMPLES , "12_SAMPLES" },
1721 { D3DMULTISAMPLE_13_SAMPLES , "13_SAMPLES" },
1722 { D3DMULTISAMPLE_14_SAMPLES , "14_SAMPLES" },
1723 { D3DMULTISAMPLE_15_SAMPLES , "15_SAMPLES" },
1724 { D3DMULTISAMPLE_16_SAMPLES , "16_SAMPLES" },
1725 { D3DMULTISAMPLE_FORCE_DWORD , "FORCE_DWORD" },
1726};
1727VMSVGAINFOENUMMAP_MAKE(static, g_D3DMultiSampleType2String, g_aD3DMultiSampleTypes, "D3DMULTISAMPLE_");
1728
1729/** D3DUSAGE_XXX flag value, prefix D3DUSAGE_. */
1730static VMSVGAINFOFLAGS32 const g_aD3DUsageFlags[] =
1731{
1732 { D3DUSAGE_RENDERTARGET , "RENDERTARGET" },
1733 { D3DUSAGE_DEPTHSTENCIL , "DEPTHSTENCIL" },
1734 { D3DUSAGE_WRITEONLY , "WRITEONLY" },
1735 { D3DUSAGE_SOFTWAREPROCESSING , "SOFTWAREPROCESSING" },
1736 { D3DUSAGE_DONOTCLIP , "DONOTCLIP" },
1737 { D3DUSAGE_POINTS , "POINTS" },
1738 { D3DUSAGE_RTPATCHES , "RTPATCHES" },
1739 { D3DUSAGE_NPATCHES , "NPATCHES" },
1740 { D3DUSAGE_DYNAMIC , "DYNAMIC" },
1741 { D3DUSAGE_AUTOGENMIPMAP , "AUTOGENMIPMAP" },
1742 { D3DUSAGE_RESTRICTED_CONTENT , "RESTRICTED_CONTENT" },
1743 { D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER , "RESTRICT_SHARED_RESOURCE_DRIVER" },
1744 { D3DUSAGE_RESTRICT_SHARED_RESOURCE , "RESTRICT_SHARED_RESOURCE" },
1745 { D3DUSAGE_DMAP , "DMAP" },
1746 { D3DUSAGE_NONSECURE , "NONSECURE" },
1747 { D3DUSAGE_TEXTAPI , "TEXTAPI" },
1748};
1749
1750
1751/**
1752 * Release all shared surface objects.
1753 */
1754static DECLCALLBACK(int) vmsvga3dInfoSharedObjectCallback(PAVLU32NODECORE pNode, void *pvUser)
1755{
1756 PVMSVGA3DSHAREDSURFACE pSharedSurface = (PVMSVGA3DSHAREDSURFACE)pNode;
1757 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
1758
1759 pHlp->pfnPrintf(pHlp, "Shared surface: %#x pv=%p\n", pSharedSurface->Core.Key, pSharedSurface->u.pCubeTexture);
1760
1761 return 0;
1762}
1763
1764#elif defined(VMSVGA3D_OPENGL)
1765 /** @todo */
1766
1767#else
1768# error "Build config error."
1769#endif
1770
1771
1772static void vmsvga3dInfoSurfaceWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
1773 bool fVerbose, uint32_t cxAscii, bool fInvY)
1774{
1775 char szTmp[128];
1776
1777 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : "");
1778#if defined(VMSVGA3D_OPENGL) && defined(VMSVGA3D_OGL_WITH_SHARED_CTX)
1779 pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation);
1780#else
1781 pHlp->pfnPrintf(pHlp, "idAssociatedContext: %#x\n", pSurface->idAssociatedContext);
1782#endif
1783 pHlp->pfnPrintf(pHlp, "Format: %s\n",
1784 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, (int)pSurface->format, false, &g_SVGA3dSurfaceFormat2String));
1785 pHlp->pfnPrintf(pHlp, "Flags: %#x", pSurface->flags);
1786 vmsvga3dInfoU32Flags(pHlp, pSurface->flags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags));
1787 pHlp->pfnPrintf(pHlp, "\n");
1788 if (pSurface->cFaces == 0)
1789 pHlp->pfnPrintf(pHlp, "Faces: %u\n", pSurface->cFaces);
1790 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
1791 {
1792 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
1793 if (pSurface->faces[iFace].numMipLevels == 0)
1794 pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels: %u\n", iFace, pSurface->faces[iFace].numMipLevels);
1795
1796 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
1797 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
1798 {
1799 pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x",
1800 iFace, iLevel, iMipmap, iMipmap < 10 ? " " : "",
1801 pSurface->pMipmapLevels[iMipmap].size.width,
1802 pSurface->pMipmapLevels[iMipmap].size.height,
1803 pSurface->pMipmapLevels[iMipmap].size.depth,
1804 pSurface->pMipmapLevels[iMipmap].cbSurface,
1805 pSurface->pMipmapLevels[iMipmap].cbSurfacePitch);
1806 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
1807 pHlp->pfnPrintf(pHlp, " pvData=%p", pSurface->pMipmapLevels[iMipmap].pSurfaceData);
1808 if (pSurface->pMipmapLevels[iMipmap].fDirty)
1809 pHlp->pfnPrintf(pHlp, " dirty");
1810 pHlp->pfnPrintf(pHlp, "\n");
1811 }
1812 }
1813
1814 pHlp->pfnPrintf(pHlp, "cbBlock: %u (%#x)\n", pSurface->cbBlock, pSurface->cbBlock);
1815 pHlp->pfnPrintf(pHlp, "Multi-sample count: %u\n", pSurface->multiSampleCount);
1816 pHlp->pfnPrintf(pHlp, "Autogen filter: %s\n",
1817 vmsvgaFormatEnumValue(szTmp, sizeof(szTmp), NULL, pSurface->autogenFilter,
1818 "SVGA3D_TEX_FILTER_", g_apszTexureFilters, RT_ELEMENTS(g_apszTexureFilters)));
1819
1820#ifdef VMSVGA3D_DIRECT3D
1821 pHlp->pfnPrintf(pHlp, "formatD3D: %s\n",
1822 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->formatD3D, true, &g_D3DFormat2String));
1823 pHlp->pfnPrintf(pHlp, "fUsageD3D: %#x", pSurface->fUsageD3D);
1824 vmsvga3dInfoU32Flags(pHlp, pSurface->fUsageD3D, "D3DUSAGE_", g_aD3DUsageFlags, RT_ELEMENTS(g_aD3DUsageFlags));
1825 pHlp->pfnPrintf(pHlp, "\n");
1826 pHlp->pfnPrintf(pHlp, "multiSampleTypeD3D: %s\n",
1827 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->multiSampleTypeD3D,
1828 true, &g_D3DMultiSampleType2String));
1829 if (pSurface->hSharedObject != NULL)
1830 pHlp->pfnPrintf(pHlp, "hSharedObject: %p\n", pSurface->hSharedObject);
1831 if (pSurface->pQuery)
1832 pHlp->pfnPrintf(pHlp, "pQuery: %p\n", pSurface->pQuery);
1833 if (pSurface->u.pSurface)
1834 pHlp->pfnPrintf(pHlp, "u.pXxxx: %p\n", pSurface->u.pSurface);
1835 if (pSurface->bounce.pTexture)
1836 pHlp->pfnPrintf(pHlp, "bounce.pXxxx: %p\n", pSurface->bounce.pTexture);
1837 RTAvlU32DoWithAll(&pSurface->pSharedObjectTree, true /*fFromLeft*/, vmsvga3dInfoSharedObjectCallback, (void *)pHlp);
1838 pHlp->pfnPrintf(pHlp, "fStencilAsTexture: %RTbool\n", pSurface->fStencilAsTexture);
1839
1840#elif defined(VMSVGA3D_OPENGL)
1841 /** @todo */
1842#else
1843# error "Build config error."
1844#endif
1845
1846 if (fVerbose)
1847 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
1848 {
1849 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
1850 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
1851 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
1852 {
1853 if ( ASMMemIsAll8(pSurface->pMipmapLevels[iMipmap].pSurfaceData,
1854 pSurface->pMipmapLevels[iMipmap].cbSurface, 0) == NULL)
1855 pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: all zeros ---\n", iFace, iLevel, iMipmap);
1856 else
1857 {
1858 pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: cx=%u, cy=%u, cz=%u ---\n",
1859 iFace, iLevel, iMipmap,
1860 pSurface->pMipmapLevels[iMipmap].size.width,
1861 pSurface->pMipmapLevels[iMipmap].size.height,
1862 pSurface->pMipmapLevels[iMipmap].size.depth);
1863 vmsvga3dAsciiPrint(vmsvga3dAsciiPrintlnInfo, (void *)pHlp,
1864 pSurface->pMipmapLevels[iMipmap].pSurfaceData,
1865 pSurface->pMipmapLevels[iMipmap].cbSurface,
1866 pSurface->pMipmapLevels[iMipmap].size.width,
1867 pSurface->pMipmapLevels[iMipmap].size.height,
1868 pSurface->pMipmapLevels[iMipmap].cbSurfacePitch,
1869 pSurface->format,
1870 fInvY,
1871 cxAscii, cxAscii * 3 / 4);
1872 }
1873 }
1874 }
1875}
1876
1877
1878void vmsvga3dInfoSurfaceWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t sid, bool fVerbose, uint32_t cxAscii, bool fInvY)
1879{
1880 /* Warning! This code is currently racing papSurfaces reallocation! */
1881 /* Warning! This code is currently racing papSurfaces reallocation! */
1882 /* Warning! This code is currently racing papSurfaces reallocation! */
1883 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
1884 if (pState)
1885 {
1886 /*
1887 * Deal with a specific request first.
1888 */
1889 if (sid != UINT32_MAX)
1890 {
1891 if (sid < pState->cSurfaces)
1892 {
1893 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1894 if (pSurface && pSurface->id == sid)
1895 {
1896 if (fVerbose)
1897 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, sid);
1898 vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
1899 return;
1900 }
1901 }
1902 pHlp->pfnPrintf(pHlp, "Surface ID %#x not found.\n", sid);
1903 }
1904 else
1905 {
1906 /*
1907 * Dump all.
1908 */
1909 if (fVerbose)
1910 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, UINT32_MAX);
1911 uint32_t cSurfaces = pState->cSurfaces;
1912 pHlp->pfnPrintf(pHlp, "cSurfaces=%d\n", cSurfaces);
1913 for (sid = 0; sid < cSurfaces; sid++)
1914 {
1915 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1916 if (pSurface && pSurface->id == sid)
1917 {
1918 pHlp->pfnPrintf(pHlp, "\n");
1919 vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
1920 }
1921 }
1922 }
1923 }
1924
1925}
1926
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette