VirtualBox

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

Last change on this file since 106061 was 106061, checked in by vboxsync, 8 weeks ago

Copyright year updates by scm.

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