VirtualBox

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

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

Fix switch statement fall-through warnings with gcc 7.2.
bugref:8192: gcc warnings

gcc 7.1 and later add a switch statement fall-through warning level, which
-Wall sets to level 3. At this level, fall-throughs have to have at least
a comment following particular requirements (see gcc manual). This change
fixes a few places in the code to meet these requirements. Currently this
warning prevents building with kObjCache enabled, as the compiler checks
the comments in the source, which are stripped out by the object cache.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 89.2 KB
Line 
1/* $Id: DevVGA-SVGA3d-info.cpp 68994 2017-10-05 14:20:22Z vboxsync $ */
2/** @file
3 * DevSVGA3d - VMWare SVGA device, 3D parts - Introspection and debugging.
4 */
5
6/*
7 * Copyright (C) 2013-2016 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 <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
649#elif defined(RT_OS_DARWIN)
650 int rc = ExplicitlyLoadVBoxSVGA3DObjC(false /*fResolveAllImports*/, NULL /*pErrInfo*/);
651 if (RT_SUCCESS(rc))
652 vmsvga3dCocoaViewInfo(pHlp, (NativeNSViewRef)(uintptr_t)idHostWindow);
653 else
654 pHlp->pfnPrintf(pHlp, " Windows info: vmsvga3dCocoaViewInfo failed to load (%Rrc)\n", rc);
655
656#else
657 RT_NOREF(idHostWindow);
658 pHlp->pfnPrintf(pHlp, " Windows info: Not implemented on this platform\n");
659#endif
660}
661
662
663/**
664 * Looks up an enum value in a translation table.
665 *
666 * @returns The value name.
667 * @param iValue The value to name.
668 * @param pEnumMap Enum value to string mapping.
669 */
670const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)
671{
672 PCVMSVGAINFOENUM paValues = pEnumMap->paValues;
673
674#ifdef VBOX_STRICT
675 /*
676 * Check that it's really sorted, or the binary lookup won't work right.
677 */
678 if (!*pEnumMap->pfAsserted)
679 {
680 *pEnumMap->pfAsserted = true;
681 for (uint32_t i = 1; i < pEnumMap->cValues; i++)
682 Assert(paValues[i - 1].iValue <= paValues[i].iValue);
683 }
684#endif
685
686 /*
687 * Binary search
688 */
689 uint32_t iStart = 0;
690 uint32_t iEnd = (uint32_t)pEnumMap->cValues;
691 for (;;)
692 {
693 uint32_t i = iStart + (iEnd - iStart) / 2;
694 if (iValue < paValues[i].iValue)
695 {
696 if (i > iStart)
697 iEnd = i;
698 else
699 break;
700 }
701 else if (iValue > paValues[i].iValue)
702 {
703 i++;
704 if (i < iEnd)
705 iStart = i;
706 else
707 break;
708 }
709 else
710 return paValues[i].pszName;
711 }
712 return NULL;
713}
714
715
716/**
717 * Formats an enum value as a string, sparse mapping table.
718 *
719 * @returns pszBuffer.
720 * @param pszBuffer The output buffer.
721 * @param cbBuffer The size of the output buffer.
722 * @param pszName The variable name, optional.
723 * @param iValue The enum value.
724 * @param fPrefix Whether to prepend the prefix or not.
725 * @param pEnumMap Enum value to string mapping.
726 */
727char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,
728 bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)
729{
730 const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);
731 const char *pszPrefix = fPrefix ? pEnumMap->pszPrefix : "";
732 if (pszValueName)
733 {
734 if (pszName)
735 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);
736 else
737 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);
738 return pszBuffer;
739 }
740
741 if (pszName)
742 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);
743 else
744 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);
745 return pszBuffer;
746}
747
748
749/**
750 * Formats an enum value as a string.
751 *
752 * @returns pszBuffer.
753 * @param pszBuffer The output buffer.
754 * @param cbBuffer The size of the output buffer.
755 * @param pszName The variable name, optional.
756 * @param uValue The enum value.
757 * @param pszPrefix The prefix of the enum values. Empty string if
758 * none. This helps reduce the memory footprint
759 * as well as the source code size.
760 * @param papszValues One to one string mapping of the enum values.
761 * @param cValues The number of values in the mapping.
762 */
763char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,
764 const char *pszPrefix, const char * const *papszValues, size_t cValues)
765{
766 if (uValue < cValues)
767 {
768 if (pszName)
769 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);
770 else
771 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);
772 }
773 else
774 {
775 if (pszName)
776 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);
777 else
778 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);
779 }
780 return pszBuffer;
781}
782
783
784/**
785 * DBGF info printer for vmsvga3dAsciiPrint.
786 *
787 * @param pszLine The line to print.
788 * @param pvUser The debug info helpers.
789 */
790DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)
791{
792 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
793 pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);
794}
795
796
797/**
798 * Log printer for vmsvga3dAsciiPrint.
799 *
800 * @param pszLine The line to print.
801 * @param pvUser Ignored.
802 */
803DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)
804{
805 size_t cch = strlen(pszLine);
806 while (cch > 0 && pszLine[cch - 1] == ' ')
807 cch--;
808 RTLogPrintf("%.*s\n", cch, pszLine);
809 NOREF(pvUser);
810}
811
812
813void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,
814 uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,
815 uint32_t cchMaxX, uint32_t cchMaxY)
816{
817 RT_NOREF(cbImage);
818
819 /*
820 * Skip stuff we can't or won't need to handle.
821 */
822 if (!cx || !cy)
823 return;
824 switch (enmFormat)
825 {
826 /* Compressed. */
827 case SVGA3D_DXT1:
828 case SVGA3D_DXT2:
829 case SVGA3D_DXT3:
830 case SVGA3D_DXT4:
831 case SVGA3D_DXT5:
832 return;
833 /* Generic. */
834 case SVGA3D_BUFFER:
835 return;
836 default:
837 break; /* ok */
838 }
839
840 /*
841 * Figure the pixel conversion factors.
842 */
843 uint32_t cxPerChar = cx / cchMaxX + 1;
844 uint32_t cyPerChar = cy / cchMaxY + 1;
845 /** @todo try keep aspect... */
846 uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;
847 uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);
848
849 /*
850 * The very simple conversion we're doing in this function is based on
851 * mapping a block of converted pixels to an ASCII character of similar
852 * weigth. We do that by summing up all the 8-bit gray scale pixels in
853 * that block, applying a conversion factor and getting an index into an
854 * array of increasingly weighty characters.
855 */
856 static const char s_szPalette[] = " ..`',:;icodxkO08XNWM";
857 static const uint32_t s_cchPalette = sizeof(s_szPalette) - 1;
858 uint32_t const cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;
859
860 /*
861 * Do the work
862 */
863 uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);
864 if (!pauScanline)
865 return;
866 char *pszLine = (char *)&pauScanline[cchLine];
867 RTCPTRUNION uSrc;
868 uSrc.pv = pvImage;
869 if (fInvY)
870 uSrc.pu8 += (cy - 1) * cbScanline;
871 uint32_t cyLeft = cy;
872 uint32_t cyLeftInScanline = cyPerChar;
873 bool fHitFormatAssert = false;
874 for (;;)
875 {
876 /*
877 * Process the scanline. This is tedious because of all the
878 * different formats. We generally ignore alpha, unless it's
879 * all we've got to work with.
880 * Color to 8-bit grayscale conversion is done by averaging.
881 */
882#define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \
883 do { \
884 for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \
885 { \
886 a_RdExpr; \
887 pauScanline[xDst] += (a_AddExpr) & 0xff; \
888 Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \
889 if (--cxLeftInChar == 0) \
890 { \
891 xDst++; \
892 cxLeftInChar = cxPerChar; \
893 } \
894 } \
895 } while (0)
896
897 switch (enmFormat)
898 {
899 /* Unsigned RGB and super/subsets. */
900 case SVGA3D_X8R8G8B8:
901 case SVGA3D_A8R8G8B8:
902 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
903 ( ( u32Tmp & 0xff) /* B */
904 + ((u32Tmp >> 8) & 0xff) /* G */
905 + ((u32Tmp >> 16) & 0xff) /* R */) / 3);
906 break;
907 case SVGA3D_R5G6B5:
908 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
909 ( ( u16Tmp & 0x1f) * 8
910 + ((u16Tmp >> 5) & 0x3f) * 4
911 + ( u16Tmp >> 11) * 8 ) / 3 );
912 break;
913 case SVGA3D_X1R5G5B5:
914 case SVGA3D_A1R5G5B5:
915 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
916 ( ( u16Tmp & 0x1f) * 8
917 + ((u16Tmp >> 5) & 0x1f) * 8
918 + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );
919 break;
920 case SVGA3D_A4R4G4B4:
921 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
922 ( ( u16Tmp & 0xf) * 16
923 + ((u16Tmp >> 4) & 0xf) * 16
924 + ((u16Tmp >> 8) & 0xf) * 16) / 3 );
925 break;
926 case SVGA3D_A16B16G16R16:
927 CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],
928 ( ((u64Tmp >> 8) & 0xff) /* R */
929 + ((u64Tmp >> 24) & 0xff) /* G */
930 + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);
931 break;
932 case SVGA3D_A2R10G10B10:
933 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
934 ( ( u32Tmp & 0x3ff) /* B */
935 + ((u32Tmp >> 10) & 0x3ff) /* G */
936 + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));
937 break;
938 case SVGA3D_G16R16:
939 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
940 ( (u32Tmp & 0xffff) /* R */
941 + (u32Tmp >> 16 ) /* G */) / 0x200);
942 break;
943
944 /* Depth. */
945 case SVGA3D_Z_D32:
946 CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),
947 (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))
948 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))
949 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))
950 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))
951 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))
952 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))
953 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))
954 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );
955 break;
956 case SVGA3D_Z_D16:
957 CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],
958 ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))
959 | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))
960 | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))
961 | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))
962 | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))
963 | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))
964 | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))
965 | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );
966 break;
967 case SVGA3D_Z_D24S8:
968 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
969 ( u32Tmp & 0xff) /* stencile */
970 | ((~u32Tmp >> 18) & 0x3f));
971 break;
972 case SVGA3D_Z_D15S1:
973 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
974 ( (u16Tmp & 0x01) << 7) /* stencile */
975 | ((~u16Tmp >> 8) & 0x7f));
976 break;
977
978 /* Pure alpha. */
979 case SVGA3D_ALPHA8:
980 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
981 break;
982
983 /* Luminance */
984 case SVGA3D_LUMINANCE8:
985 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
986 break;
987 case SVGA3D_LUMINANCE4_ALPHA4:
988 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);
989 break;
990 case SVGA3D_LUMINANCE16:
991 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
992 break;
993 case SVGA3D_LUMINANCE8_ALPHA8:
994 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);
995 break;
996
997 /* Not supported. */
998 case SVGA3D_DXT1:
999 case SVGA3D_DXT2:
1000 case SVGA3D_DXT3:
1001 case SVGA3D_DXT4:
1002 case SVGA3D_DXT5:
1003 case SVGA3D_BUFFER:
1004 AssertFailedBreak();
1005
1006 /* Not considered for implementation yet. */
1007 case SVGA3D_BUMPU8V8:
1008 case SVGA3D_BUMPL6V5U5:
1009 case SVGA3D_BUMPX8L8V8U8:
1010 case SVGA3D_BUMPL8V8U8:
1011 case SVGA3D_ARGB_S10E5:
1012 case SVGA3D_ARGB_S23E8:
1013 case SVGA3D_V8U8:
1014 case SVGA3D_Q8W8V8U8:
1015 case SVGA3D_CxV8U8:
1016 case SVGA3D_X8L8V8U8:
1017 case SVGA3D_A2W10V10U10:
1018 case SVGA3D_R_S10E5:
1019 case SVGA3D_R_S23E8:
1020 case SVGA3D_RG_S10E5:
1021 case SVGA3D_RG_S23E8:
1022 case SVGA3D_Z_D24X8:
1023 case SVGA3D_V16U16:
1024 case SVGA3D_UYVY:
1025 case SVGA3D_YUY2:
1026 case SVGA3D_NV12:
1027 case SVGA3D_AYUV:
1028 case SVGA3D_BC4_UNORM:
1029 case SVGA3D_BC5_UNORM:
1030 case SVGA3D_Z_DF16:
1031 case SVGA3D_Z_DF24:
1032 case SVGA3D_Z_D24S8_INT:
1033 if (!fHitFormatAssert)
1034 {
1035 AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));
1036 fHitFormatAssert = true;
1037 }
1038 /* fall thru */
1039 default:
1040 /* Lazy programmer fallbacks. */
1041 if (cbSrcPixel == 4)
1042 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],
1043 ( ( u32Tmp & 0xff)
1044 + ((u32Tmp >> 8) & 0xff)
1045 + ((u32Tmp >> 16) & 0xff)
1046 + ((u32Tmp >> 24) & 0xff) ) / 4);
1047 else if (cbSrcPixel == 3)
1048 CONVERT_SCANLINE(RT_NOTHING,
1049 ( (uint32_t)uSrc.pu8[xSrc * 4]
1050 + (uint32_t)uSrc.pu8[xSrc * 4 + 1]
1051 + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);
1052 else if (cbSrcPixel == 2)
1053 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],
1054 ( ( u16Tmp & 0xf)
1055 + ((u16Tmp >> 4) & 0xf)
1056 + ((u16Tmp >> 8) & 0xf)
1057 + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );
1058 else if (cbSrcPixel == 1)
1059 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);
1060 else
1061 AssertFailed();
1062 break;
1063
1064 }
1065
1066 /*
1067 * Print we've reached the end of a block in y direction or if we're at
1068 * the end of the image.
1069 */
1070 cyLeft--;
1071 if (--cyLeftInScanline == 0 || cyLeft == 0)
1072 {
1073 for (uint32_t i = 0; i < cchLine; i++)
1074 {
1075 uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);
1076 pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];
1077 }
1078 pszLine[cchLine] = '\0';
1079 pfnPrintLine(pszLine, pvUser);
1080
1081 if (!cyLeft)
1082 break;
1083 cyLeftInScanline = cyPerChar;
1084 RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);
1085 }
1086
1087 /*
1088 * Advance.
1089 */
1090 if (!fInvY)
1091 uSrc.pu8 += cbScanline;
1092 else
1093 uSrc.pu8 -= cbScanline;
1094 }
1095}
1096
1097
1098
1099/**
1100 * Formats a SVGA3dRenderState structure as a string.
1101 *
1102 * @returns pszBuffer.
1103 * @param pszBuffer Output string buffer.
1104 * @param cbBuffer Size of output buffer.
1105 * @param pRenderState The SVGA3d render state to format.
1106 */
1107char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)
1108{
1109 /*
1110 * List of render state names with type prefix.
1111 *
1112 * First char in the name is a type indicator:
1113 * - '*' = requires special handling.
1114 * - 'f' = SVGA3dbool
1115 * - 'd' = uint32_t
1116 * - 'r' = float
1117 * - 'b' = SVGA3dBlendOp
1118 * - 'c' = SVGA3dColor, SVGA3dColorMask
1119 * - 'e' = SVGA3dBlendEquation
1120 * - 'm' = SVGA3dColorMask
1121 * - 'p' = SVGA3dCmpFunc
1122 * - 's' = SVGA3dStencilOp
1123 * - 'v' = SVGA3dVertexMaterial
1124 * - 'w' = SVGA3dWrapFlags
1125 */
1126 static const char * const s_apszRenderStateNamesAndType[] =
1127 {
1128 "*" "INVALID", /* invalid */
1129 "f" "ZENABLE", /* SVGA3dBool */
1130 "f" "ZWRITEENABLE", /* SVGA3dBool */
1131 "f" "ALPHATESTENABLE", /* SVGA3dBool */
1132 "f" "DITHERENABLE", /* SVGA3dBool */
1133 "f" "BLENDENABLE", /* SVGA3dBool */
1134 "f" "FOGENABLE", /* SVGA3dBool */
1135 "f" "SPECULARENABLE", /* SVGA3dBool */
1136 "f" "STENCILENABLE", /* SVGA3dBool */
1137 "f" "LIGHTINGENABLE", /* SVGA3dBool */
1138 "f" "NORMALIZENORMALS", /* SVGA3dBool */
1139 "f" "POINTSPRITEENABLE", /* SVGA3dBool */
1140 "f" "POINTSCALEENABLE", /* SVGA3dBool */
1141 "x" "STENCILREF", /* uint32_t */
1142 "x" "STENCILMASK", /* uint32_t */
1143 "x" "STENCILWRITEMASK", /* uint32_t */
1144 "r" "FOGSTART", /* float */
1145 "r" "FOGEND", /* float */
1146 "r" "FOGDENSITY", /* float */
1147 "r" "POINTSIZE", /* float */
1148 "r" "POINTSIZEMIN", /* float */
1149 "r" "POINTSIZEMAX", /* float */
1150 "r" "POINTSCALE_A", /* float */
1151 "r" "POINTSCALE_B", /* float */
1152 "r" "POINTSCALE_C", /* float */
1153 "c" "FOGCOLOR", /* SVGA3dColor */
1154 "c" "AMBIENT", /* SVGA3dColor */
1155 "*" "CLIPPLANEENABLE", /* SVGA3dClipPlanes */
1156 "*" "FOGMODE", /* SVGA3dFogMode */
1157 "*" "FILLMODE", /* SVGA3dFillMode */
1158 "*" "SHADEMODE", /* SVGA3dShadeMode */
1159 "*" "LINEPATTERN", /* SVGA3dLinePattern */
1160 "b" "SRCBLEND", /* SVGA3dBlendOp */
1161 "b" "DSTBLEND", /* SVGA3dBlendOp */
1162 "e" "BLENDEQUATION", /* SVGA3dBlendEquation */
1163 "*" "CULLMODE", /* SVGA3dFace */
1164 "p" "ZFUNC", /* SVGA3dCmpFunc */
1165 "p" "ALPHAFUNC", /* SVGA3dCmpFunc */
1166 "p" "STENCILFUNC", /* SVGA3dCmpFunc */
1167 "s" "STENCILFAIL", /* SVGA3dStencilOp */
1168 "s" "STENCILZFAIL", /* SVGA3dStencilOp */
1169 "s" "STENCILPASS", /* SVGA3dStencilOp */
1170 "r" "ALPHAREF", /* float */
1171 "*" "FRONTWINDING", /* SVGA3dFrontWinding */
1172 "*" "COORDINATETYPE", /* SVGA3dCoordinateType */
1173 "r" "ZBIAS", /* float */
1174 "f" "RANGEFOGENABLE", /* SVGA3dBool */
1175 "c" "COLORWRITEENABLE", /* SVGA3dColorMask */
1176 "f" "VERTEXMATERIALENABLE", /* SVGA3dBool */
1177 "v" "DIFFUSEMATERIALSOURCE", /* SVGA3dVertexMaterial */
1178 "v" "SPECULARMATERIALSOURCE", /* SVGA3dVertexMaterial */
1179 "v" "AMBIENTMATERIALSOURCE", /* SVGA3dVertexMaterial */
1180 "v" "EMISSIVEMATERIALSOURCE", /* SVGA3dVertexMaterial */
1181 "c" "TEXTUREFACTOR", /* SVGA3dColor */
1182 "f" "LOCALVIEWER", /* SVGA3dBool */
1183 "f" "SCISSORTESTENABLE", /* SVGA3dBool */
1184 "c" "BLENDCOLOR", /* SVGA3dColor */
1185 "f" "STENCILENABLE2SIDED", /* SVGA3dBool */
1186 "p" "CCWSTENCILFUNC", /* SVGA3dCmpFunc */
1187 "s" "CCWSTENCILFAIL", /* SVGA3dStencilOp */
1188 "s" "CCWSTENCILZFAIL", /* SVGA3dStencilOp */
1189 "s" "CCWSTENCILPASS", /* SVGA3dStencilOp */
1190 "*" "VERTEXBLEND", /* SVGA3dVertexBlendFlags */
1191 "r" "SLOPESCALEDEPTHBIAS", /* float */
1192 "r" "DEPTHBIAS", /* float */
1193 "r" "OUTPUTGAMMA", /* float */
1194 "f" "ZVISIBLE", /* SVGA3dBool */
1195 "f" "LASTPIXEL", /* SVGA3dBool */
1196 "f" "CLIPPING", /* SVGA3dBool */
1197 "w" "WRAP0", /* SVGA3dWrapFlags */
1198 "w" "WRAP1", /* SVGA3dWrapFlags */
1199 "w" "WRAP2", /* SVGA3dWrapFlags */
1200 "w" "WRAP3", /* SVGA3dWrapFlags */
1201 "w" "WRAP4", /* SVGA3dWrapFlags */
1202 "w" "WRAP5", /* SVGA3dWrapFlags */
1203 "w" "WRAP6", /* SVGA3dWrapFlags */
1204 "w" "WRAP7", /* SVGA3dWrapFlags */
1205 "w" "WRAP8", /* SVGA3dWrapFlags */
1206 "w" "WRAP9", /* SVGA3dWrapFlags */
1207 "w" "WRAP10", /* SVGA3dWrapFlags */
1208 "w" "WRAP11", /* SVGA3dWrapFlags */
1209 "w" "WRAP12", /* SVGA3dWrapFlags */
1210 "w" "WRAP13", /* SVGA3dWrapFlags */
1211 "w" "WRAP14", /* SVGA3dWrapFlags */
1212 "w" "WRAP15", /* SVGA3dWrapFlags */
1213 "f" "MULTISAMPLEANTIALIAS", /* SVGA3dBool */
1214 "x" "MULTISAMPLEMASK", /* uint32_t */
1215 "f" "INDEXEDVERTEXBLENDENABLE", /* SVGA3dBool */
1216 "r" "TWEENFACTOR", /* float */
1217 "f" "ANTIALIASEDLINEENABLE", /* SVGA3dBool */
1218 "c" "COLORWRITEENABLE1", /* SVGA3dColorMask */
1219 "c" "COLORWRITEENABLE2", /* SVGA3dColorMask */
1220 "c" "COLORWRITEENABLE3", /* SVGA3dColorMask */
1221 "f" "SEPARATEALPHABLENDENABLE", /* SVGA3dBool */
1222 "b" "SRCBLENDALPHA", /* SVGA3dBlendOp */
1223 "b" "DSTBLENDALPHA", /* SVGA3dBlendOp */
1224 "e" "BLENDEQUATIONALPHA", /* SVGA3dBlendEquation */
1225 "*" "TRANSPARENCYANTIALIAS", /* SVGA3dTransparencyAntialiasType */
1226 "f" "LINEAA", /* SVGA3dBool */
1227 "r" "LINEWIDTH", /* float */
1228 };
1229
1230 uint32_t iState = pRenderState->state;
1231 if (iState != SVGA3D_RS_INVALID)
1232 {
1233 if (iState < RT_ELEMENTS(s_apszRenderStateNamesAndType))
1234 {
1235 const char *pszName = s_apszRenderStateNamesAndType[iState];
1236 char const chType = *pszName++;
1237
1238 union
1239 {
1240 uint32_t u;
1241 float r;
1242 SVGA3dColorMask Color;
1243 } uValue;
1244 uValue.u = pRenderState->uintValue;
1245
1246 switch (chType)
1247 {
1248 case 'f':
1249 if (uValue.u == 0)
1250 RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);
1251 else if (uValue.u == 1)
1252 RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);
1253 else
1254 RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);
1255 break;
1256 case 'x':
1257 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
1258 break;
1259 case 'r':
1260 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
1261 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
1262 break;
1263 case 'c': //SVGA3dColor, SVGA3dColorMask
1264 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
1265 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
1266 break;
1267 case 'w': //SVGA3dWrapFlags
1268 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,
1269 uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");
1270 break;
1271 default:
1272 AssertFailed(); /* Fall through */
1273 case 'b': //SVGA3dBlendOp
1274 case 'e': //SVGA3dBlendEquation
1275 case 'p': //SVGA3dCmpFunc
1276 case 's': //SVGA3dStencilOp
1277 case 'v': //SVGA3dVertexMaterial
1278 case '*':
1279 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);
1280 break;
1281 }
1282 }
1283 else
1284 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);
1285 }
1286 else
1287 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
1288 return pszBuffer;
1289}
1290
1291
1292/**
1293 * Formats a SVGA3dTextureState structure as a string.
1294 *
1295 * @returns pszBuffer.
1296 * @param pszBuffer Output string buffer.
1297 * @param cbBuffer Size of output buffer.
1298 * @param pTextureState The SVGA3d texture state to format.
1299 */
1300char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)
1301{
1302 static const char * const s_apszTextureStateNamesAndType[] =
1303 {
1304 "*" "INVALID", /* invalid */
1305 "x" "BIND_TEXTURE", /* SVGA3dSurfaceId */
1306 "m" "COLOROP", /* SVGA3dTextureCombiner */
1307 "a" "COLORARG1", /* SVGA3dTextureArgData */
1308 "a" "COLORARG2", /* SVGA3dTextureArgData */
1309 "m" "ALPHAOP", /* SVGA3dTextureCombiner */
1310 "a" "ALPHAARG1", /* SVGA3dTextureArgData */
1311 "a" "ALPHAARG2", /* SVGA3dTextureArgData */
1312 "e" "ADDRESSU", /* SVGA3dTextureAddress */
1313 "e" "ADDRESSV", /* SVGA3dTextureAddress */
1314 "l" "MIPFILTER", /* SVGA3dTextureFilter */
1315 "l" "MAGFILTER", /* SVGA3dTextureFilter */
1316 "m" "MINFILTER", /* SVGA3dTextureFilter */
1317 "c" "BORDERCOLOR", /* SVGA3dColor */
1318 "r" "TEXCOORDINDEX", /* uint32_t */
1319 "t" "TEXTURETRANSFORMFLAGS", /* SVGA3dTexTransformFlags */
1320 "g" "TEXCOORDGEN", /* SVGA3dTextureCoordGen */
1321 "r" "BUMPENVMAT00", /* float */
1322 "r" "BUMPENVMAT01", /* float */
1323 "r" "BUMPENVMAT10", /* float */
1324 "r" "BUMPENVMAT11", /* float */
1325 "x" "TEXTURE_MIPMAP_LEVEL", /* uint32_t */
1326 "r" "TEXTURE_LOD_BIAS", /* float */
1327 "x" "TEXTURE_ANISOTROPIC_LEVEL", /* uint32_t */
1328 "e" "ADDRESSW", /* SVGA3dTextureAddress */
1329 "r" "GAMMA", /* float */
1330 "r" "BUMPENVLSCALE", /* float */
1331 "r" "BUMPENVLOFFSET", /* float */
1332 "a" "COLORARG0", /* SVGA3dTextureArgData */
1333 "a" "ALPHAARG0" /* SVGA3dTextureArgData */
1334 };
1335
1336 /*
1337 * Format the stage first.
1338 */
1339 char *pszRet = pszBuffer;
1340 size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);
1341 if (cchPrefix < cbBuffer)
1342 {
1343 cbBuffer -= cchPrefix;
1344 pszBuffer += cchPrefix;
1345 }
1346 else
1347 cbBuffer = 0;
1348
1349 /*
1350 * Format the name and value.
1351 */
1352 uint32_t iName = pTextureState->name;
1353 if (iName != SVGA3D_TS_INVALID)
1354 {
1355 if (iName < RT_ELEMENTS(s_apszTextureStateNamesAndType))
1356 {
1357 const char *pszName = s_apszTextureStateNamesAndType[iName];
1358 char chType = *pszName++;
1359
1360 union
1361 {
1362 uint32_t u;
1363 float r;
1364 SVGA3dColorMask Color;
1365 } uValue;
1366 uValue.u = pTextureState->value;
1367
1368 switch (chType)
1369 {
1370 case 'x':
1371 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);
1372 break;
1373
1374 case 'r':
1375 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",
1376 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);
1377 break;
1378
1379 case 'a': //SVGA3dTextureArgData
1380 {
1381 static const char * const s_apszValues[] =
1382 {
1383 "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"
1384 };
1385 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1386 "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));
1387 break;
1388 }
1389
1390 case 'c': //SVGA3dColor, SVGA3dColorMask
1391 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,
1392 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);
1393 break;
1394
1395 case 'e': //SVGA3dTextureAddress
1396 {
1397 static const char * const s_apszValues[] =
1398 {
1399 "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",
1400 };
1401 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1402 "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));
1403 break;
1404 }
1405
1406 case 'l': //SVGA3dTextureFilter
1407 {
1408 static const char * const s_apszValues[] =
1409 {
1410 "NONE", "NEAREST", "LINEAR", "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",
1411 };
1412 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1413 "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));
1414 break;
1415 }
1416
1417 case 'g': //SVGA3dTextureCoordGen
1418 {
1419 static const char * const s_apszValues[] =
1420 {
1421 "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",
1422 };
1423 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1424 "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));
1425 break;
1426 }
1427
1428 case 'm': //SVGA3dTextureCombiner
1429 {
1430 static const char * const s_apszValues[] =
1431 {
1432 "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",
1433 "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",
1434 "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",
1435 "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",
1436 "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",
1437 };
1438 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,
1439 "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));
1440 break;
1441 }
1442
1443 default:
1444 AssertFailed();
1445 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);
1446 break;
1447 }
1448 }
1449 else
1450 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);
1451 }
1452 else
1453 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");
1454 return pszRet;
1455}
1456
1457
1458
1459static const char * const g_apszTransformTypes[] =
1460{
1461 "SVGA3D_TRANSFORM_INVALID",
1462 "SVGA3D_TRANSFORM_WORLD",
1463 "SVGA3D_TRANSFORM_VIEW",
1464 "SVGA3D_TRANSFORM_PROJECTION",
1465 "SVGA3D_TRANSFORM_TEXTURE0",
1466 "SVGA3D_TRANSFORM_TEXTURE1",
1467 "SVGA3D_TRANSFORM_TEXTURE2",
1468 "SVGA3D_TRANSFORM_TEXTURE3",
1469 "SVGA3D_TRANSFORM_TEXTURE4",
1470 "SVGA3D_TRANSFORM_TEXTURE5",
1471 "SVGA3D_TRANSFORM_TEXTURE6",
1472 "SVGA3D_TRANSFORM_TEXTURE7",
1473 "SVGA3D_TRANSFORM_WORLD1",
1474 "SVGA3D_TRANSFORM_WORLD2",
1475 "SVGA3D_TRANSFORM_WORLD3",
1476};
1477
1478static const char * const g_apszFaces[] =
1479{
1480 "SVGA3D_FACE_INVALID",
1481 "SVGA3D_FACE_NONE",
1482 "SVGA3D_FACE_FRONT",
1483 "SVGA3D_FACE_BACK",
1484 "SVGA3D_FACE_FRONT_BACK",
1485};
1486
1487static const char * const g_apszLightTypes[] =
1488{
1489 "SVGA3D_LIGHTTYPE_INVALID",
1490 "SVGA3D_LIGHTTYPE_POINT",
1491 "SVGA3D_LIGHTTYPE_SPOT1",
1492 "SVGA3D_LIGHTTYPE_SPOT2",
1493 "SVGA3D_LIGHTTYPE_DIRECTIONAL",
1494};
1495
1496static const char * const g_apszRenderTargets[] =
1497{
1498 "SVGA3D_RT_DEPTH",
1499 "SVGA3D_RT_STENCIL",
1500 "SVGA3D_RT_COLOR0",
1501 "SVGA3D_RT_COLOR1",
1502 "SVGA3D_RT_COLOR2",
1503 "SVGA3D_RT_COLOR3",
1504 "SVGA3D_RT_COLOR4",
1505 "SVGA3D_RT_COLOR5",
1506 "SVGA3D_RT_COLOR6",
1507 "SVGA3D_RT_COLOR7",
1508};
1509
1510static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
1511{
1512 RT_NOREF(fVerbose);
1513 char szTmp[128];
1514
1515 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
1516#ifdef RT_OS_WINDOWS
1517 pHlp->pfnPrintf(pHlp, "hwnd: %p\n", pContext->hwnd);
1518 if (fVerbose)
1519 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
1520# ifdef VMSVGA3D_DIRECT3D
1521 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice);
1522# else
1523 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc);
1524 pHlp->pfnPrintf(pHlp, "hglrc: %p\n", pContext->hglrc);
1525# endif
1526
1527#elif defined(RT_OS_DARWIN)
1528 pHlp->pfnPrintf(pHlp, "cocoaView: %p\n", pContext->cocoaView);
1529 if (pContext->cocoaView)
1530 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->cocoaView);
1531 pHlp->pfnPrintf(pHlp, "cocoaContext: %p\n", pContext->cocoaContext);
1532 if (pContext->fOtherProfile)
1533 pHlp->pfnPrintf(pHlp, "fOtherProfile: true\n");
1534
1535#else
1536 pHlp->pfnPrintf(pHlp, "window: %p\n", pContext->window);
1537 pHlp->pfnPrintf(pHlp, "fMapped: %RTbool\n", pContext->fMapped);
1538 if (pContext->window)
1539 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->window);
1540 pHlp->pfnPrintf(pHlp, "glxContext: %p\n", pContext->glxContext);
1541
1542#endif
1543 pHlp->pfnPrintf(pHlp, "sidRenderTarget: %#x\n", pContext->sidRenderTarget);
1544
1545 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
1546 if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
1547 pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]: %#x\n", i, pContext->aSidActiveTexture[i]);
1548
1549 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);
1550
1551 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
1552 if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
1553 pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
1554 vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
1555
1556 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
1557 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
1558 if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
1559 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
1560 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
1561
1562 AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
1563 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
1564 if (pContext->state.aTransformState[i].fValid)
1565 {
1566 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
1567 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
1568 pHlp->pfnPrintf(pHlp,
1569 (j % 4) == 0 ? " [ " FLOAT_FMT_STR : (j % 4) < 3 ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
1570 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
1571 }
1572
1573 AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
1574 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
1575 if (pContext->state.aMaterial[i].fValid)
1576 {
1577 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
1578 g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
1579 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1580 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
1581 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
1582 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
1583 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
1584 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1585 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
1586 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
1587 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
1588 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
1589 pHlp->pfnPrintf(pHlp, " specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1590 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
1591 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
1592 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
1593 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
1594 pHlp->pfnPrintf(pHlp, " emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1595 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
1596 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
1597 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
1598 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
1599 }
1600
1601 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
1602 if (pContext->state.aClipPlane[i].fValid)
1603 pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1604 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
1605 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
1606 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
1607 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
1608
1609 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
1610 if (pContext->state.aLightData[i].fValidData)
1611 {
1612 pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
1613 i,
1614 pContext->state.aLightData[i].fEnabled,
1615 pContext->state.aLightData[i].data.inWorldSpace,
1616 (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
1617 ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
1618 pContext->state.aLightData[i].data.type);
1619 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1620 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
1621 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
1622 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
1623 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
1624 pHlp->pfnPrintf(pHlp, " specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1625 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
1626 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
1627 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
1628 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
1629 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1630 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
1631 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
1632 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
1633 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
1634 pHlp->pfnPrintf(pHlp, " position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1635 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
1636 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
1637 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
1638 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
1639 pHlp->pfnPrintf(pHlp, " direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1640 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
1641 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
1642 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
1643 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
1644 pHlp->pfnPrintf(pHlp, " range=" FLOAT_FMT_STR " falloff=" FLOAT_FMT_STR "\n",
1645 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
1646 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
1647 pHlp->pfnPrintf(pHlp, " attenuation0=" FLOAT_FMT_STR " attenuation1=" FLOAT_FMT_STR " attenuation2=" FLOAT_FMT_STR "\n",
1648 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
1649 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
1650 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
1651 pHlp->pfnPrintf(pHlp, " theta=" FLOAT_FMT_STR " phi=" FLOAT_FMT_STR "\n",
1652 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
1653 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
1654 }
1655
1656 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
1657 if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
1658 pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
1659 i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
1660 pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
1661
1662 pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
1663 pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
1664 pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
1665 pHlp->pfnPrintf(pHlp, "zRange: (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
1666 FLOAT_FMT_ARGS(pContext->state.zRange.min),
1667 FLOAT_FMT_ARGS(pContext->state.zRange.max));
1668 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);
1669 pHlp->pfnPrintf(pHlp, "shidPixel: %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
1670 pHlp->pfnPrintf(pHlp, "shidVertex: %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
1671
1672 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
1673 {
1674 uint32_t cConsts = iWhich == 0 ? pContext->state.cPixelShaderConst : pContext->state.cVertexShaderConst;
1675 PVMSVGASHADERCONST paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst : pContext->state.paVertexShaderConst;
1676 const char *pszName = iWhich ? "paPixelShaderConst" : "paVertexShaderConst";
1677
1678 for (uint32_t i = 0; i < cConsts; i++)
1679 if (paConsts[i].fValid)
1680 {
1681 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
1682 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
1683 pszName, i, i,
1684 FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
1685 FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
1686 else
1687 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
1688 pszName, i, i,
1689 paConsts[i].value[0], paConsts[i].value[1],
1690 paConsts[i].value[2], paConsts[i].value[3],
1691 paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
1692 : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
1693 }
1694 }
1695
1696 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
1697 {
1698 uint32_t cShaders = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
1699 PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
1700 const char *pszName = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
1701 for (uint32_t i = 0; i < cShaders; i++)
1702 if (paShaders[i].id == i)
1703 {
1704 pHlp->pfnPrintf(pHlp, "%s[%u]: id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
1705 pszName, i,
1706 paShaders[i].id,
1707 paShaders[i].cid,
1708 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
1709 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
1710 paShaders[i].type,
1711 paShaders[i].cbData,
1712 paShaders[i].pShaderProgram);
1713 }
1714 }
1715}
1716
1717
1718void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
1719{
1720 /* Warning! This code is currently racing papContexts reallocation! */
1721 /* Warning! This code is currently racing papContexts reallocation! */
1722 /* Warning! This code is currently racing papContexts reallocation! */
1723 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
1724 if (pState)
1725 {
1726 /*
1727 * Deal with a specific request first.
1728 */
1729 if (cid != UINT32_MAX)
1730 {
1731 if (cid < pState->cContexts)
1732 {
1733 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
1734 if (pContext && pContext->id == cid)
1735 {
1736 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
1737 return;
1738 }
1739 }
1740#ifdef VMSVGA3D_OPENGL
1741 else if ( cid == VMSVGA3D_SHARED_CTX_ID
1742 && pState->SharedCtx.id == cid)
1743 {
1744 vmsvga3dInfoContextWorkerOne(pHlp, &((PVMSVGA3DSTATE)pState)->SharedCtx, fVerbose);
1745 return;
1746 }
1747#endif
1748 pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
1749 }
1750 else
1751 {
1752#ifdef VMSVGA3D_OPENGL
1753 /*
1754 * Dump the shared context.
1755 */
1756 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
1757 {
1758 pHlp->pfnPrintf(pHlp, "Shared context:\n");
1759 vmsvga3dInfoContextWorkerOne(pHlp, &((PVMSVGA3DSTATE)pState)->SharedCtx, fVerbose);
1760 }
1761#endif
1762
1763 /*
1764 * Dump the per-screen contexts.
1765 */
1766 /** @todo multi screen */
1767
1768 /*
1769 * Dump all.
1770 */
1771 uint32_t cContexts = pState->cContexts;
1772 pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
1773 for (cid = 0; cid < cContexts; cid++)
1774 {
1775 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
1776 if (pContext && pContext->id == cid)
1777 {
1778 pHlp->pfnPrintf(pHlp, "\n");
1779 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
1780 }
1781 }
1782 }
1783 }
1784}
1785
1786
1787#ifdef VMSVGA3D_DIRECT3D
1788/**
1789 * Release all shared surface objects.
1790 */
1791static DECLCALLBACK(int) vmsvga3dInfoSharedObjectCallback(PAVLU32NODECORE pNode, void *pvUser)
1792{
1793 PVMSVGA3DSHAREDSURFACE pSharedSurface = (PVMSVGA3DSHAREDSURFACE)pNode;
1794 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
1795
1796 pHlp->pfnPrintf(pHlp, "Shared surface: %#x pv=%p\n", pSharedSurface->Core.Key, pSharedSurface->u.pCubeTexture);
1797
1798 return 0;
1799}
1800#endif /* VMSVGA3D_DIRECT3D */
1801
1802
1803static void vmsvga3dInfoSurfaceWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
1804 bool fVerbose, uint32_t cxAscii, bool fInvY)
1805{
1806 char szTmp[128];
1807
1808 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : "");
1809#ifdef VMSVGA3D_OPENGL
1810 pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation);
1811#else
1812 pHlp->pfnPrintf(pHlp, "idAssociatedContext: %#x\n", pSurface->idAssociatedContext);
1813#endif
1814 pHlp->pfnPrintf(pHlp, "Format: %s\n",
1815 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, (int)pSurface->format, false, &g_SVGA3dSurfaceFormat2String));
1816 pHlp->pfnPrintf(pHlp, "Flags: %#x", pSurface->flags);
1817 vmsvga3dInfoU32Flags(pHlp, pSurface->flags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags));
1818 pHlp->pfnPrintf(pHlp, "\n");
1819 if (pSurface->cFaces == 0)
1820 pHlp->pfnPrintf(pHlp, "Faces: %u\n", pSurface->cFaces);
1821 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
1822 {
1823 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
1824 if (pSurface->faces[iFace].numMipLevels == 0)
1825 pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels: %u\n", iFace, pSurface->faces[iFace].numMipLevels);
1826
1827 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
1828 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
1829 {
1830 pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x",
1831 iFace, iLevel, iMipmap, iMipmap < 10 ? " " : "",
1832 pSurface->pMipmapLevels[iMipmap].size.width,
1833 pSurface->pMipmapLevels[iMipmap].size.height,
1834 pSurface->pMipmapLevels[iMipmap].size.depth,
1835 pSurface->pMipmapLevels[iMipmap].cbSurface,
1836 pSurface->pMipmapLevels[iMipmap].cbSurfacePitch);
1837 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
1838 pHlp->pfnPrintf(pHlp, " pvData=%p", pSurface->pMipmapLevels[iMipmap].pSurfaceData);
1839 if (pSurface->pMipmapLevels[iMipmap].fDirty)
1840 pHlp->pfnPrintf(pHlp, " dirty");
1841 pHlp->pfnPrintf(pHlp, "\n");
1842 }
1843 }
1844
1845 pHlp->pfnPrintf(pHlp, "cbBlock: %u (%#x)\n", pSurface->cbBlock, pSurface->cbBlock);
1846 pHlp->pfnPrintf(pHlp, "Multi-sample count: %u\n", pSurface->multiSampleCount);
1847 pHlp->pfnPrintf(pHlp, "Autogen filter: %s\n",
1848 vmsvgaFormatEnumValue(szTmp, sizeof(szTmp), NULL, pSurface->autogenFilter,
1849 "SVGA3D_TEX_FILTER_", g_apszTexureFilters, RT_ELEMENTS(g_apszTexureFilters)));
1850
1851#ifdef VMSVGA3D_DIRECT3D
1852 pHlp->pfnPrintf(pHlp, "formatD3D: %s\n",
1853 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->formatD3D, true, &g_D3DFormat2String));
1854 pHlp->pfnPrintf(pHlp, "fUsageD3D: %#x", pSurface->fUsageD3D);
1855 vmsvga3dInfoU32Flags(pHlp, pSurface->fUsageD3D, "D3DUSAGE_", g_aD3DUsageFlags, RT_ELEMENTS(g_aD3DUsageFlags));
1856 pHlp->pfnPrintf(pHlp, "\n");
1857 pHlp->pfnPrintf(pHlp, "multiSampleTypeD3D: %s\n",
1858 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->multiSampleTypeD3D,
1859 true, &g_D3DMultiSampleType2String));
1860 if (pSurface->hSharedObject != NULL)
1861 pHlp->pfnPrintf(pHlp, "hSharedObject: %p\n", pSurface->hSharedObject);
1862 if (pSurface->pQuery)
1863 pHlp->pfnPrintf(pHlp, "pQuery: %p\n", pSurface->pQuery);
1864 if (pSurface->u.pSurface)
1865 pHlp->pfnPrintf(pHlp, "u.pXxxx: %p\n", pSurface->u.pSurface);
1866 if (pSurface->bounce.pTexture)
1867 pHlp->pfnPrintf(pHlp, "bounce.pXxxx: %p\n", pSurface->bounce.pTexture);
1868 RTAvlU32DoWithAll(&pSurface->pSharedObjectTree, true /*fFromLeft*/, vmsvga3dInfoSharedObjectCallback, (void *)pHlp);
1869 pHlp->pfnPrintf(pHlp, "fStencilAsTexture: %RTbool\n", pSurface->fStencilAsTexture);
1870
1871#elif defined(VMSVGA3D_OPENGL)
1872 /** @todo */
1873#else
1874# error "Build config error."
1875#endif
1876
1877 if (fVerbose)
1878 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
1879 {
1880 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
1881 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
1882 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
1883 {
1884 if (ASMMemIsZero(pSurface->pMipmapLevels[iMipmap].pSurfaceData,
1885 pSurface->pMipmapLevels[iMipmap].cbSurface))
1886 pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: all zeros ---\n", iFace, iLevel, iMipmap);
1887 else
1888 {
1889 pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: cx=%u, cy=%u, cz=%u ---\n",
1890 iFace, iLevel, iMipmap,
1891 pSurface->pMipmapLevels[iMipmap].size.width,
1892 pSurface->pMipmapLevels[iMipmap].size.height,
1893 pSurface->pMipmapLevels[iMipmap].size.depth);
1894 vmsvga3dAsciiPrint(vmsvga3dAsciiPrintlnInfo, (void *)pHlp,
1895 pSurface->pMipmapLevels[iMipmap].pSurfaceData,
1896 pSurface->pMipmapLevels[iMipmap].cbSurface,
1897 pSurface->pMipmapLevels[iMipmap].size.width,
1898 pSurface->pMipmapLevels[iMipmap].size.height,
1899 pSurface->pMipmapLevels[iMipmap].cbSurfacePitch,
1900 pSurface->format,
1901 fInvY,
1902 cxAscii, cxAscii * 3 / 4);
1903 }
1904 }
1905 }
1906}
1907
1908
1909void vmsvga3dInfoSurfaceWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t sid, bool fVerbose, uint32_t cxAscii, bool fInvY)
1910{
1911 /* Warning! This code is currently racing papSurfaces reallocation! */
1912 /* Warning! This code is currently racing papSurfaces reallocation! */
1913 /* Warning! This code is currently racing papSurfaces reallocation! */
1914 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
1915 if (pState)
1916 {
1917 /*
1918 * Deal with a specific request first.
1919 */
1920 if (sid != UINT32_MAX)
1921 {
1922 if (sid < pState->cSurfaces)
1923 {
1924 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1925 if (pSurface && pSurface->id == sid)
1926 {
1927 if (fVerbose)
1928 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, sid);
1929 vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
1930 return;
1931 }
1932 }
1933 pHlp->pfnPrintf(pHlp, "Surface ID %#x not found.\n", sid);
1934 }
1935 else
1936 {
1937 /*
1938 * Dump all.
1939 */
1940 if (fVerbose)
1941 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, UINT32_MAX);
1942 uint32_t cSurfaces = pState->cSurfaces;
1943 pHlp->pfnPrintf(pHlp, "cSurfaces=%d\n", cSurfaces);
1944 for (sid = 0; sid < cSurfaces; sid++)
1945 {
1946 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1947 if (pSurface && pSurface->id == sid)
1948 {
1949 pHlp->pfnPrintf(pHlp, "\n");
1950 vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
1951 }
1952 }
1953 }
1954 }
1955
1956}
1957
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