VirtualBox

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

Last change on this file since 86156 was 86024, checked in by vboxsync, 4 years ago

Devices/Graphics: use current VMSVGA headers

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

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