VirtualBox

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

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

vmsvga3d: Removed non-VMSVGA3D_OGL_WITH_SHARED_CTX OpenGL code.

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