VirtualBox

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

Last change on this file since 88798 was 88787, checked in by vboxsync, 4 years ago

Devices/Graphics: a few DX commands. bugref:9830

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