VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp@ 86888

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

Devices/Graphics: logging. bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 199.3 KB
Line 
1/* $Id: DevVGA-SVGA-cmd.cpp 86888 2020-11-16 13:22:42Z vboxsync $ */
2/** @file
3 * VMware SVGA device - implementation of VMSVGA commands.
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#ifndef IN_RING3
19# error "DevVGA-SVGA-cmd.cpp is only for ring-3 code"
20#endif
21
22
23#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
24#include <iprt/mem.h>
25#include <VBox/AssertGuest.h>
26#include <VBox/log.h>
27#include <VBox/vmm/pdmdev.h>
28#include <VBoxVideo.h>
29
30/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
31#include "DevVGA.h"
32
33/* Should be included after DevVGA.h/DevVGA-SVGA.h to pick all defines. */
34#ifdef VBOX_WITH_VMSVGA3D
35# include "DevVGA-SVGA3d.h"
36#endif
37#include "DevVGA-SVGA-internal.h"
38
39#ifdef DUMP_BITMAPS
40# include <iprt/formats/bmp.h>
41# include <stdio.h>
42#endif
43
44#if defined(LOG_ENABLED) || defined(VBOX_STRICT)
45# define SVGA_CASE_ID2STR(idx) case idx: return #idx
46/**
47 * FIFO command name lookup
48 *
49 * @returns FIFO command string or "UNKNOWN"
50 * @param u32Cmd FIFO command
51 */
52const char *vmsvgaR3FifoCmdToString(uint32_t u32Cmd)
53{
54 switch (u32Cmd)
55 {
56 SVGA_CASE_ID2STR(SVGA_CMD_INVALID_CMD);
57 SVGA_CASE_ID2STR(SVGA_CMD_UPDATE);
58 SVGA_CASE_ID2STR(SVGA_CMD_RECT_FILL);
59 SVGA_CASE_ID2STR(SVGA_CMD_RECT_COPY);
60 SVGA_CASE_ID2STR(SVGA_CMD_RECT_ROP_COPY);
61 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_CURSOR);
62 SVGA_CASE_ID2STR(SVGA_CMD_DISPLAY_CURSOR);
63 SVGA_CASE_ID2STR(SVGA_CMD_MOVE_CURSOR);
64 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_ALPHA_CURSOR);
65 SVGA_CASE_ID2STR(SVGA_CMD_UPDATE_VERBOSE);
66 SVGA_CASE_ID2STR(SVGA_CMD_FRONT_ROP_FILL);
67 SVGA_CASE_ID2STR(SVGA_CMD_FENCE);
68 SVGA_CASE_ID2STR(SVGA_CMD_ESCAPE);
69 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_SCREEN);
70 SVGA_CASE_ID2STR(SVGA_CMD_DESTROY_SCREEN);
71 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_GMRFB);
72 SVGA_CASE_ID2STR(SVGA_CMD_BLIT_GMRFB_TO_SCREEN);
73 SVGA_CASE_ID2STR(SVGA_CMD_BLIT_SCREEN_TO_GMRFB);
74 SVGA_CASE_ID2STR(SVGA_CMD_ANNOTATION_FILL);
75 SVGA_CASE_ID2STR(SVGA_CMD_ANNOTATION_COPY);
76 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_GMR2);
77 SVGA_CASE_ID2STR(SVGA_CMD_REMAP_GMR2);
78 SVGA_CASE_ID2STR(SVGA_CMD_DEAD);
79 SVGA_CASE_ID2STR(SVGA_CMD_DEAD_2);
80 SVGA_CASE_ID2STR(SVGA_CMD_NOP);
81 SVGA_CASE_ID2STR(SVGA_CMD_NOP_ERROR);
82 SVGA_CASE_ID2STR(SVGA_CMD_MAX);
83 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DEFINE);
84 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DESTROY);
85 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_COPY);
86 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_STRETCHBLT);
87 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DMA);
88 SVGA_CASE_ID2STR(SVGA_3D_CMD_CONTEXT_DEFINE);
89 SVGA_CASE_ID2STR(SVGA_3D_CMD_CONTEXT_DESTROY);
90 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETTRANSFORM);
91 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETZRANGE);
92 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETRENDERSTATE);
93 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETRENDERTARGET);
94 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETTEXTURESTATE);
95 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETMATERIAL);
96 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETLIGHTDATA);
97 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETLIGHTENABLED);
98 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETVIEWPORT);
99 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETCLIPPLANE);
100 SVGA_CASE_ID2STR(SVGA_3D_CMD_CLEAR);
101 SVGA_CASE_ID2STR(SVGA_3D_CMD_PRESENT);
102 SVGA_CASE_ID2STR(SVGA_3D_CMD_SHADER_DEFINE);
103 SVGA_CASE_ID2STR(SVGA_3D_CMD_SHADER_DESTROY);
104 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_SHADER);
105 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_SHADER_CONST);
106 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW_PRIMITIVES);
107 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETSCISSORRECT);
108 SVGA_CASE_ID2STR(SVGA_3D_CMD_BEGIN_QUERY);
109 SVGA_CASE_ID2STR(SVGA_3D_CMD_END_QUERY);
110 SVGA_CASE_ID2STR(SVGA_3D_CMD_WAIT_FOR_QUERY);
111 SVGA_CASE_ID2STR(SVGA_3D_CMD_PRESENT_READBACK);
112 SVGA_CASE_ID2STR(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
113 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DEFINE_V2);
114 SVGA_CASE_ID2STR(SVGA_3D_CMD_GENERATE_MIPMAPS);
115 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_CREATE_DECODER);
116 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DESTROY_DECODER);
117 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_CREATE_PROCESSOR);
118 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DESTROY_PROCESSOR);
119 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_START_FRAME);
120 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_RENDER);
121 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_END_FRAME);
122 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_PROCESS_FRAME);
123 SVGA_CASE_ID2STR(SVGA_3D_CMD_ACTIVATE_SURFACE);
124 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEACTIVATE_SURFACE);
125 SVGA_CASE_ID2STR(SVGA_3D_CMD_SCREEN_DMA);
126 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD1);
127 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD2);
128 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_BITBLT);
129 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_TRANSBLT);
130 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_STRETCHBLT);
131 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_COLORFILL);
132 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_ALPHABLEND);
133 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND);
134 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_OTABLE_BASE);
135 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_OTABLE);
136 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_MOB);
137 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_MOB);
138 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD3);
139 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING);
140 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SURFACE);
141 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SURFACE);
142 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SURFACE);
143 SVGA_CASE_ID2STR(SVGA_3D_CMD_COND_BIND_GB_SURFACE);
144 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_IMAGE);
145 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_SURFACE);
146 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_IMAGE);
147 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_SURFACE);
148 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_IMAGE);
149 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_SURFACE);
150 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_CONTEXT);
151 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_CONTEXT);
152 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_CONTEXT);
153 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_CONTEXT);
154 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_CONTEXT);
155 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SHADER);
156 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SHADER);
157 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SHADER);
158 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_OTABLE_BASE64);
159 SVGA_CASE_ID2STR(SVGA_3D_CMD_BEGIN_GB_QUERY);
160 SVGA_CASE_ID2STR(SVGA_3D_CMD_END_GB_QUERY);
161 SVGA_CASE_ID2STR(SVGA_3D_CMD_WAIT_FOR_GB_QUERY);
162 SVGA_CASE_ID2STR(SVGA_3D_CMD_NOP);
163 SVGA_CASE_ID2STR(SVGA_3D_CMD_ENABLE_GART);
164 SVGA_CASE_ID2STR(SVGA_3D_CMD_DISABLE_GART);
165 SVGA_CASE_ID2STR(SVGA_3D_CMD_MAP_MOB_INTO_GART);
166 SVGA_CASE_ID2STR(SVGA_3D_CMD_UNMAP_GART_RANGE);
167 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SCREENTARGET);
168 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SCREENTARGET);
169 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SCREENTARGET);
170 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_SCREENTARGET);
171 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL);
172 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL);
173 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE);
174 SVGA_CASE_ID2STR(SVGA_3D_CMD_GB_SCREEN_DMA);
175 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH);
176 SVGA_CASE_ID2STR(SVGA_3D_CMD_GB_MOB_FENCE);
177 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SURFACE_V2);
178 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_MOB64);
179 SVGA_CASE_ID2STR(SVGA_3D_CMD_REDEFINE_GB_MOB64);
180 SVGA_CASE_ID2STR(SVGA_3D_CMD_NOP_ERROR);
181 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_STREAMS);
182 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_DECLS);
183 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_DIVISORS);
184 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW);
185 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW_INDEXED);
186 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_CONTEXT);
187 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_CONTEXT);
188 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_CONTEXT);
189 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_CONTEXT);
190 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_INVALIDATE_CONTEXT);
191 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER);
192 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SHADER_RESOURCES);
193 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SHADER);
194 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SAMPLERS);
195 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW);
196 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INDEXED);
197 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INSTANCED);
198 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED);
199 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_AUTO);
200 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT);
201 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS);
202 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_INDEX_BUFFER);
203 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_TOPOLOGY);
204 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_RENDERTARGETS);
205 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_BLEND_STATE);
206 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE);
207 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_RASTERIZER_STATE);
208 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_QUERY);
209 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_QUERY);
210 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_QUERY);
211 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_QUERY_OFFSET);
212 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BEGIN_QUERY);
213 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_END_QUERY);
214 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_QUERY);
215 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_PREDICATION);
216 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SOTARGETS);
217 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VIEWPORTS);
218 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SCISSORRECTS);
219 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW);
220 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW);
221 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_COPY_REGION);
222 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_COPY);
223 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_STRETCHBLT);
224 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_GENMIPS);
225 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE);
226 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_SUBRESOURCE);
227 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE);
228 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW);
229 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW);
230 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW);
231 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW);
232 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW);
233 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW);
234 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT);
235 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT);
236 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_BLEND_STATE);
237 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_BLEND_STATE);
238 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE);
239 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE);
240 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE);
241 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE);
242 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE);
243 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE);
244 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SHADER);
245 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SHADER);
246 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_SHADER);
247 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT);
248 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT);
249 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_STREAMOUTPUT);
250 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_COTABLE);
251 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_COTABLE);
252 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BUFFER_COPY);
253 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER);
254 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK);
255 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MOVE_QUERY);
256 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_ALL_QUERY);
257 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_ALL_QUERY);
258 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER);
259 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MOB_FENCE_64);
260 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_ALL_SHADER);
261 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_HINT);
262 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BUFFER_UPDATE);
263 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET);
264 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET);
265 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET);
266 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED1);
267 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED2);
268 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED3);
269 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER);
270 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MAX);
271 default: return "UNKNOWN";
272 }
273}
274# undef SVGA_CASE_ID2STR
275#endif /* LOG_ENABLED || VBOX_STRICT */
276
277
278#if !defined(VMSVGA3D_DX)
279# ifdef VBOX_WITH_VMSVGA3D
280/*
281 * Stub for old backends.
282 */
283int vmsvga3dQueryInterface(PVGASTATECC pThisCC, char const *pszInterfaceName, void *pvInterfaceFuncs, size_t cbInterfaceFuncs)
284{
285 RT_NOREF(pThisCC, pszInterfaceName, pvInterfaceFuncs, cbInterfaceFuncs);
286 return VERR_NOT_IMPLEMENTED;
287}
288# endif
289#endif
290
291
292/*
293 *
294 * Guest-Backed Objects (GBO).
295 *
296 */
297
298/**
299 * HC access handler for GBOs which require write protection, i.e. OTables, etc.
300 *
301 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
302 * @param pVM VM Handle.
303 * @param pVCpu The cross context CPU structure for the calling EMT.
304 * @param GCPhys The physical address the guest is writing to.
305 * @param pvPhys The HC mapping of that address.
306 * @param pvBuf What the guest is reading/writing.
307 * @param cbBuf How much it's reading/writing.
308 * @param enmAccessType The access type.
309 * @param enmOrigin Who is making the access.
310 * @param pvUser User argument.
311 */
312DECLCALLBACK(VBOXSTRICTRC)
313vmsvgaR3GboAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
314 PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
315{
316 RT_NOREF(pVM, pVCpu, pvPhys, enmAccessType);
317
318 if (RT_LIKELY(enmOrigin == PGMACCESSORIGIN_DEVICE || enmOrigin == PGMACCESSORIGIN_DEBUGGER))
319 return VINF_PGM_HANDLER_DO_DEFAULT;
320
321 PPDMDEVINS pDevIns = (PPDMDEVINS)pvUser;
322 PVGASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PVGASTATE);
323 PVGASTATECC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVGASTATECC);
324 PVMSVGAR3STATE pSvgaR3State = pThisCC->svga.pSvgaR3State;
325
326 /*
327 * The guest is not allowed to access the memory.
328 * Set the error condition.
329 */
330 ASMAtomicWriteBool(&pThis->svga.fBadGuest, true);
331
332 /* Try to find the GBO which the guest is accessing. */
333 char const *pszTarget = NULL;
334 for (uint32_t i = 0; i < RT_ELEMENTS(pSvgaR3State->aGboOTables) && !pszTarget; ++i)
335 {
336 PVMSVGAGBO pGbo = &pSvgaR3State->aGboOTables[i];
337 if (pGbo->cDescriptors)
338 {
339 for (uint32_t j = 0; j < pGbo->cDescriptors; ++j)
340 {
341 if ( GCPhys >= pGbo->paDescriptors[j].GCPhys
342 && GCPhys < pGbo->paDescriptors[j].GCPhys + pGbo->paDescriptors[j].cPages * PAGE_SIZE)
343 {
344 switch (i)
345 {
346 case SVGA_OTABLE_MOB: pszTarget = "SVGA_OTABLE_MOB"; break;
347 case SVGA_OTABLE_SURFACE: pszTarget = "SVGA_OTABLE_SURFACE"; break;
348 case SVGA_OTABLE_CONTEXT: pszTarget = "SVGA_OTABLE_CONTEXT"; break;
349 case SVGA_OTABLE_SHADER: pszTarget = "SVGA_OTABLE_SHADER"; break;
350 case SVGA_OTABLE_SCREENTARGET: pszTarget = "SVGA_OTABLE_SCREENTARGET"; break;
351 case SVGA_OTABLE_DXCONTEXT: pszTarget = "SVGA_OTABLE_DXCONTEXT"; break;
352 default: pszTarget = "Unknown OTABLE"; break;
353 }
354 break;
355 }
356 }
357 }
358 }
359
360 LogRelMax(8, ("VMSVGA: invalid guest access to page %RGp, target %s:\n"
361 "%.*Rhxd\n",
362 GCPhys, pszTarget ? pszTarget : "unknown", RT_MIN(cbBuf, 256), pvBuf));
363
364 return VINF_PGM_HANDLER_DO_DEFAULT;
365}
366
367
368static int vmsvgaR3GboCreate(PVMSVGAR3STATE pSvgaR3State, SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, bool fGCPhys64, bool fWriteProtected, PVMSVGAGBO pGbo)
369{
370 ASSERT_GUEST_RETURN(sizeInBytes <= _128M, VERR_INVALID_PARAMETER); /** @todo Less than SVGA_REG_MOB_MAX_SIZE */
371
372 /*
373 * The 'baseAddress' is a page number and points to the 'root page' of the GBO.
374 * Content of the root page depends on the ptDepth value:
375 * SVGA3D_MOBFMT_PTDEPTH[64]_0 - the only data page;
376 * SVGA3D_MOBFMT_PTDEPTH[64]_1 - array of page numbers for data pages;
377 * SVGA3D_MOBFMT_PTDEPTH[64]_2 - array of page numbers for SVGA3D_MOBFMT_PTDEPTH[64]_1 pages.
378 * The code below extracts the page addresses of the GBO.
379 */
380
381 /* Verify and normalize the ptDepth value. */
382 if (RT_LIKELY( ptDepth == SVGA3D_MOBFMT_PTDEPTH64_0
383 || ptDepth == SVGA3D_MOBFMT_PTDEPTH64_1
384 || ptDepth == SVGA3D_MOBFMT_PTDEPTH64_2))
385 ASSERT_GUEST_RETURN(fGCPhys64, VERR_INVALID_PARAMETER);
386 else if ( ptDepth == SVGA3D_MOBFMT_PTDEPTH_0
387 || ptDepth == SVGA3D_MOBFMT_PTDEPTH_1
388 || ptDepth == SVGA3D_MOBFMT_PTDEPTH_2)
389 {
390 ASSERT_GUEST_RETURN(!fGCPhys64, VERR_INVALID_PARAMETER);
391 /* Shift ptDepth to the SVGA3D_MOBFMT_PTDEPTH64_x range. */
392 ptDepth = (SVGAMobFormat)(ptDepth + SVGA3D_MOBFMT_PTDEPTH64_0 - SVGA3D_MOBFMT_PTDEPTH_0);
393 }
394 else if (ptDepth == SVGA3D_MOBFMT_RANGE)
395 { }
396 else
397 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER);
398
399 uint32_t const cPPNsPerPage = X86_PAGE_SIZE / (fGCPhys64 ? sizeof(PPN64) : sizeof(PPN));
400
401 pGbo->cbTotal = sizeInBytes;
402 pGbo->cTotalPages = (sizeInBytes + X86_PAGE_SIZE - 1) >> X86_PAGE_SHIFT;
403
404 /* Allocate the maximum amount possible (everything non-continuous) */
405 PVMSVGAGBODESCRIPTOR paDescriptors = (PVMSVGAGBODESCRIPTOR)RTMemAlloc(pGbo->cTotalPages * sizeof(VMSVGAGBODESCRIPTOR));
406 AssertReturn(paDescriptors, VERR_NO_MEMORY);
407
408 int rc = VINF_SUCCESS;
409 if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_0)
410 {
411 ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages == 1,
412 RTMemFree(paDescriptors),
413 VERR_INVALID_PARAMETER);
414
415 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
416 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
417 paDescriptors[0].GCPhys = GCPhys;
418 paDescriptors[0].cPages = 1;
419 }
420 else if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_1)
421 {
422 ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages <= cPPNsPerPage,
423 RTMemFree(paDescriptors),
424 VERR_INVALID_PARAMETER);
425
426 /* Read the root page. */
427 uint8_t au8RootPage[X86_PAGE_SIZE];
428 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
429 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, &au8RootPage, sizeof(au8RootPage));
430 if (RT_SUCCESS(rc))
431 {
432 PPN64 *paPPN64 = (PPN64 *)&au8RootPage[0];
433 PPN *paPPN32 = (PPN *)&au8RootPage[0];
434 for (uint32_t iPPN = 0; iPPN < pGbo->cTotalPages; ++iPPN)
435 {
436 GCPhys = (RTGCPHYS)(fGCPhys64 ? paPPN64[iPPN] : paPPN32[iPPN]) << X86_PAGE_SHIFT;
437 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
438 paDescriptors[iPPN].GCPhys = GCPhys;
439 paDescriptors[iPPN].cPages = 1;
440 }
441 }
442 }
443 else if (ptDepth == SVGA3D_MOBFMT_PTDEPTH64_2)
444 {
445 ASSERT_GUEST_STMT_RETURN(pGbo->cTotalPages <= cPPNsPerPage * cPPNsPerPage,
446 RTMemFree(paDescriptors),
447 VERR_INVALID_PARAMETER);
448
449 /* Read the Level2 root page. */
450 uint8_t au8RootPageLevel2[X86_PAGE_SIZE];
451 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
452 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, &au8RootPageLevel2, sizeof(au8RootPageLevel2));
453 if (RT_SUCCESS(rc))
454 {
455 uint32_t cPagesLeft = pGbo->cTotalPages;
456
457 PPN64 *paPPN64Level2 = (PPN64 *)&au8RootPageLevel2[0];
458 PPN *paPPN32Level2 = (PPN *)&au8RootPageLevel2[0];
459
460 uint32_t const cPPNsLevel2 = (pGbo->cTotalPages + cPPNsPerPage - 1) / cPPNsPerPage;
461 for (uint32_t iPPNLevel2 = 0; iPPNLevel2 < cPPNsLevel2; ++iPPNLevel2)
462 {
463 /* Read the Level1 root page. */
464 uint8_t au8RootPage[X86_PAGE_SIZE];
465 RTGCPHYS GCPhysLevel1 = (RTGCPHYS)(fGCPhys64 ? paPPN64Level2[iPPNLevel2] : paPPN32Level2[iPPNLevel2]) << X86_PAGE_SHIFT;
466 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
467 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhysLevel1, &au8RootPage, sizeof(au8RootPage));
468 if (RT_SUCCESS(rc))
469 {
470 PPN64 *paPPN64 = (PPN64 *)&au8RootPage[0];
471 PPN *paPPN32 = (PPN *)&au8RootPage[0];
472
473 uint32_t const cPPNs = RT_MIN(cPagesLeft, cPPNsPerPage);
474 for (uint32_t iPPN = 0; iPPN < cPPNs; ++iPPN)
475 {
476 GCPhys = (RTGCPHYS)(fGCPhys64 ? paPPN64[iPPN] : paPPN32[iPPN]) << X86_PAGE_SHIFT;
477 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
478 paDescriptors[iPPN + iPPNLevel2 * cPPNsPerPage].GCPhys = GCPhys;
479 paDescriptors[iPPN + iPPNLevel2 * cPPNsPerPage].cPages = 1;
480 }
481 cPagesLeft -= cPPNs;
482 }
483 }
484 }
485 }
486 else if (ptDepth == SVGA3D_MOBFMT_RANGE)
487 {
488 RTGCPHYS GCPhys = (RTGCPHYS)baseAddress << X86_PAGE_SHIFT;
489 GCPhys &= UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
490 paDescriptors[0].GCPhys = GCPhys;
491 paDescriptors[0].cPages = pGbo->cTotalPages;
492 }
493 else
494 {
495 AssertFailed();
496 return VERR_INTERNAL_ERROR; /* ptDepth should be already verified. */
497 }
498
499 /* Compress the descriptors. */
500 if (ptDepth != SVGA3D_MOBFMT_RANGE)
501 {
502 uint32_t iDescriptor = 0;
503 for (uint32_t i = 1; i < pGbo->cTotalPages; ++i)
504 {
505 /* Continuous physical memory? */
506 if (paDescriptors[i].GCPhys == paDescriptors[iDescriptor].GCPhys + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE)
507 {
508 Assert(paDescriptors[iDescriptor].cPages);
509 paDescriptors[iDescriptor].cPages++;
510 Log5Func(("Page %x GCPhys=%RGp successor\n", i, paDescriptors[i].GCPhys));
511 }
512 else
513 {
514 iDescriptor++;
515 paDescriptors[iDescriptor].GCPhys = paDescriptors[i].GCPhys;
516 paDescriptors[iDescriptor].cPages = 1;
517 Log5Func(("Page %x GCPhys=%RGp\n", i, paDescriptors[iDescriptor].GCPhys));
518 }
519 }
520
521 pGbo->cDescriptors = iDescriptor + 1;
522 Log5Func(("Nr of descriptors %d\n", pGbo->cDescriptors));
523 }
524 else
525 pGbo->cDescriptors = 1;
526
527 if (RT_LIKELY(pGbo->cDescriptors < pGbo->cTotalPages))
528 {
529 pGbo->paDescriptors = (PVMSVGAGBODESCRIPTOR)RTMemRealloc(paDescriptors, pGbo->cDescriptors * sizeof(VMSVGAGBODESCRIPTOR));
530 AssertReturn(pGbo->paDescriptors, VERR_NO_MEMORY);
531 }
532 else
533 pGbo->paDescriptors = paDescriptors;
534
535 if (fWriteProtected)
536 {
537 pGbo->fGboFlags |= VMSVGAGBO_F_WRITE_PROTECTED;
538 for (uint32_t i = 0; i < pGbo->cDescriptors; ++i)
539 {
540 rc = PGMHandlerPhysicalRegister(PDMDevHlpGetVM(pSvgaR3State->pDevIns),
541 pGbo->paDescriptors[i].GCPhys, pGbo->paDescriptors[i].GCPhys + pGbo->paDescriptors[i].cPages * PAGE_SIZE - 1,
542 pSvgaR3State->hGboAccessHandlerType, pSvgaR3State->pDevIns, NIL_RTR0PTR, NIL_RTRCPTR, "VMSVGA GBO");
543 AssertRC(rc);
544 }
545 }
546
547 return VINF_SUCCESS;
548}
549
550
551static void vmsvgaR3GboDestroy(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo)
552{
553 if (RT_LIKELY(VMSVGA_IS_GBO_CREATED(pGbo)))
554 {
555 if (pGbo->fGboFlags & VMSVGAGBO_F_WRITE_PROTECTED)
556 {
557 for (uint32_t i = 0; i < pGbo->cDescriptors; ++i)
558 {
559 int rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pSvgaR3State->pDevIns), pGbo->paDescriptors[i].GCPhys);
560 AssertRC(rc);
561 }
562 }
563 RTMemFree(pGbo->paDescriptors);
564 RT_ZERO(pGbo);
565 }
566}
567
568
569typedef enum VMSVGAGboTransferDirection
570{
571 VMSVGAGboTransferDirection_Read,
572 VMSVGAGboTransferDirection_Write,
573} VMSVGAGboTransferDirection;
574
575static int vmsvgaR3GboTransfer(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo,
576 uint32_t off, void *pvData, uint32_t cbData,
577 VMSVGAGboTransferDirection enmDirection)
578{
579// ASMBreakpoint();
580 int rc = VINF_SUCCESS;
581 uint8_t *pu8CurrentHost = (uint8_t *)pvData;
582
583 /* Find the right descriptor */
584 PCVMSVGAGBODESCRIPTOR const paDescriptors = pGbo->paDescriptors;
585 uint32_t iDescriptor = 0; /* Index in the descriptor array. */
586 uint32_t offDescriptor = 0; /* GMR offset of the current descriptor. */
587 while (offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE <= off)
588 {
589 offDescriptor += paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE;
590 AssertReturn(offDescriptor < pGbo->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
591 ++iDescriptor;
592 AssertReturn(iDescriptor < pGbo->cDescriptors, VERR_INTERNAL_ERROR);
593 }
594
595 while (cbData)
596 {
597 uint32_t cbToCopy;
598 if (off + cbData <= offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE)
599 cbToCopy = cbData;
600 else
601 {
602 cbToCopy = (offDescriptor + paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE - off);
603 AssertReturn(cbToCopy <= cbData, VERR_INVALID_PARAMETER);
604 }
605
606 RTGCPHYS const GCPhys = paDescriptors[iDescriptor].GCPhys + off - offDescriptor;
607 Log5Func(("%s phys=%RGp\n", (enmDirection == VMSVGAGboTransferDirection_Read) ? "READ" : "WRITE", GCPhys));
608
609 if (enmDirection == VMSVGAGboTransferDirection_Read)
610 rc = PDMDevHlpPCIPhysRead(pSvgaR3State->pDevIns, GCPhys, pu8CurrentHost, cbToCopy);
611 else
612 rc = PDMDevHlpPCIPhysWrite(pSvgaR3State->pDevIns, GCPhys, pu8CurrentHost, cbToCopy);
613 AssertRCBreak(rc);
614
615 cbData -= cbToCopy;
616 off += cbToCopy;
617 pu8CurrentHost += cbToCopy;
618
619 /* Go to the next descriptor if there's anything left. */
620 if (cbData)
621 {
622 offDescriptor += paDescriptors[iDescriptor].cPages * X86_PAGE_SIZE;
623 AssertReturn(offDescriptor < pGbo->cbTotal, VERR_INTERNAL_ERROR);
624 ++iDescriptor;
625 AssertReturn(iDescriptor < pGbo->cDescriptors, VERR_INTERNAL_ERROR);
626 }
627 }
628 return rc;
629}
630
631
632static int vmsvgaR3GboWrite(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo,
633 uint32_t off, void const *pvData, uint32_t cbData)
634{
635 return vmsvgaR3GboTransfer(pSvgaR3State, pGbo,
636 off, (void *)pvData, cbData,
637 VMSVGAGboTransferDirection_Write);
638}
639
640
641static int vmsvgaR3GboRead(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGbo,
642 uint32_t off, void *pvData, uint32_t cbData)
643{
644 return vmsvgaR3GboTransfer(pSvgaR3State, pGbo,
645 off, pvData, cbData,
646 VMSVGAGboTransferDirection_Read);
647}
648
649
650/*
651 *
652 * Object Tables.
653 *
654 */
655
656static int vmsvgaR3OTableVerifyIndex(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable,
657 uint32_t idx, uint32_t cbEntry)
658{
659 RT_NOREF(pSvgaR3State);
660
661 /* The table must exist and the index must be within the table. */
662 ASSERT_GUEST_RETURN(VMSVGA_IS_GBO_CREATED(pGboOTable), VERR_INVALID_PARAMETER);
663 ASSERT_GUEST_RETURN(idx < pGboOTable->cbTotal / cbEntry, VERR_INVALID_PARAMETER);
664 RT_UNTRUSTED_VALIDATED_FENCE();
665 return VINF_SUCCESS;
666}
667
668
669static int vmsvgaR3OTableRead(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable,
670 uint32_t idx, uint32_t cbEntry,
671 void *pvData, uint32_t cbData)
672{
673 AssertReturn(cbData <= cbEntry, VERR_INVALID_PARAMETER);
674
675 int rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, pGboOTable, idx, cbEntry);
676 if (RT_SUCCESS(rc))
677 {
678 uint32_t const off = idx * cbEntry;
679 rc = vmsvgaR3GboRead(pSvgaR3State, pGboOTable, off, pvData, cbData);
680 }
681 return rc;
682}
683
684static int vmsvgaR3OTableWrite(PVMSVGAR3STATE pSvgaR3State, PVMSVGAGBO pGboOTable,
685 uint32_t idx, uint32_t cbEntry,
686 void const *pvData, uint32_t cbData)
687{
688 AssertReturn(cbData <= cbEntry, VERR_INVALID_PARAMETER);
689
690 int rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, pGboOTable, idx, cbEntry);
691 if (RT_SUCCESS(rc))
692 {
693 uint32_t const off = idx * cbEntry;
694 rc = vmsvgaR3GboWrite(pSvgaR3State, pGboOTable, off, pvData, cbData);
695 }
696 return rc;
697}
698
699
700/*
701 *
702 * The guest's Memory OBjects (MOB).
703 *
704 */
705
706static int vmsvgaR3MobCreate(PVMSVGAR3STATE pSvgaR3State,
707 SVGAMobFormat ptDepth, PPN64 baseAddress, uint32_t sizeInBytes, SVGAMobId mobid,
708 bool fGCPhys64, PVMSVGAMOB pMob)
709{
710 RT_ZERO(*pMob);
711
712 /* Update the entry in the pSvgaR3State->pGboOTableMob. */
713 SVGAOTableMobEntry entry;
714 entry.ptDepth = ptDepth;
715 entry.sizeInBytes = sizeInBytes;
716 entry.base = baseAddress;
717 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_MOB],
718 mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry));
719 if (RT_SUCCESS(rc))
720 {
721 /* Create the corresponding GBO. */
722 rc = vmsvgaR3GboCreate(pSvgaR3State, ptDepth, baseAddress, sizeInBytes, fGCPhys64, /* fWriteProtected = */ false, &pMob->Gbo);
723 if (RT_SUCCESS(rc))
724 {
725 /* Add to the tree of known GBOs and the LRU list. */
726 pMob->Core.Key = mobid;
727 if (RTAvlU32Insert(&pSvgaR3State->MOBTree, &pMob->Core))
728 {
729 RTListPrepend(&pSvgaR3State->MOBLRUList, &pMob->nodeLRU);
730 return VINF_SUCCESS;
731 }
732
733 vmsvgaR3GboDestroy(pSvgaR3State, &pMob->Gbo);
734 }
735 }
736
737 return rc;
738}
739
740
741static int vmsvgaR3MobDestroy(PVMSVGAR3STATE pSvgaR3State, SVGAMobId mobid)
742{
743 /* Update the entry in the pSvgaR3State->pGboOTableMob. */
744 SVGAOTableMobEntry entry;
745 RT_ZERO(entry);
746 vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_MOB],
747 mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE, &entry, sizeof(entry));
748
749 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Remove(&pSvgaR3State->MOBTree, mobid);
750 if (pMob)
751 {
752 RTListNodeRemove(&pMob->nodeLRU);
753 vmsvgaR3GboDestroy(pSvgaR3State, &pMob->Gbo);
754 RTMemFree(pMob);
755 return VINF_SUCCESS;
756 }
757
758 return VERR_INVALID_PARAMETER;
759}
760
761
762static PVMSVGAMOB vmsvgaR3MobGet(PVMSVGAR3STATE pSvgaR3State, SVGAMobId mobid)
763{
764 PVMSVGAMOB pMob = (PVMSVGAMOB)RTAvlU32Get(&pSvgaR3State->MOBTree, mobid);
765 if (pMob)
766 {
767 /* Move to the head of the LRU list. */
768 RTListNodeRemove(&pMob->nodeLRU);
769 RTListPrepend(&pSvgaR3State->MOBLRUList, &pMob->nodeLRU);
770 }
771
772 return pMob;
773}
774
775/*
776 * Screen objects.
777 */
778VMSVGASCREENOBJECT *vmsvgaR3GetScreenObject(PVGASTATECC pThisCC, uint32_t idScreen)
779{
780 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
781 if ( idScreen < (uint32_t)RT_ELEMENTS(pSVGAState->aScreens)
782 && pSVGAState
783 && pSVGAState->aScreens[idScreen].fDefined)
784 {
785 return &pSVGAState->aScreens[idScreen];
786 }
787 return NULL;
788}
789
790void vmsvgaR3ResetScreens(PVGASTATE pThis, PVGASTATECC pThisCC)
791{
792#ifdef VBOX_WITH_VMSVGA3D
793 if (pThis->svga.f3DEnabled)
794 {
795 for (uint32_t idScreen = 0; idScreen < (uint32_t)RT_ELEMENTS(pThisCC->svga.pSvgaR3State->aScreens); ++idScreen)
796 {
797 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, idScreen);
798 if (pScreen)
799 vmsvga3dDestroyScreen(pThisCC, pScreen);
800 }
801 }
802#else
803 RT_NOREF(pThis, pThisCC);
804#endif
805}
806
807
808/**
809 * Copy a rectangle of pixels within guest VRAM.
810 */
811static void vmsvgaR3RectCopy(PVGASTATECC pThisCC, VMSVGASCREENOBJECT const *pScreen, uint32_t srcX, uint32_t srcY,
812 uint32_t dstX, uint32_t dstY, uint32_t width, uint32_t height, unsigned cbFrameBuffer)
813{
814 if (!width || !height)
815 return; /* Nothing to do, don't even bother. */
816
817 /*
818 * The guest VRAM (aka GFB) is considered to be a bitmap in the format
819 * corresponding to the current display mode.
820 */
821 uint32_t const cbPixel = RT_ALIGN(pScreen->cBpp, 8) / 8;
822 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch : width * cbPixel;
823 uint8_t const *pSrc;
824 uint8_t *pDst;
825 unsigned const cbRectWidth = width * cbPixel;
826 unsigned uMaxOffset;
827
828 uMaxOffset = (RT_MAX(srcY, dstY) + height) * cbScanline + (RT_MAX(srcX, dstX) + width) * cbPixel;
829 if (uMaxOffset >= cbFrameBuffer)
830 {
831 Log(("Max offset (%u) too big for framebuffer (%u bytes), ignoring!\n", uMaxOffset, cbFrameBuffer));
832 return; /* Just don't listen to a bad guest. */
833 }
834
835 pSrc = pDst = pThisCC->pbVRam;
836 pSrc += srcY * cbScanline + srcX * cbPixel;
837 pDst += dstY * cbScanline + dstX * cbPixel;
838
839 if (srcY >= dstY)
840 {
841 /* Source below destination, copy top to bottom. */
842 for (; height > 0; height--)
843 {
844 memmove(pDst, pSrc, cbRectWidth);
845 pSrc += cbScanline;
846 pDst += cbScanline;
847 }
848 }
849 else
850 {
851 /* Source above destination, copy bottom to top. */
852 pSrc += cbScanline * (height - 1);
853 pDst += cbScanline * (height - 1);
854 for (; height > 0; height--)
855 {
856 memmove(pDst, pSrc, cbRectWidth);
857 pSrc -= cbScanline;
858 pDst -= cbScanline;
859 }
860 }
861}
862
863
864/**
865 * Common worker for changing the pointer shape.
866 *
867 * @param pThisCC The VGA/VMSVGA state for ring-3.
868 * @param pSVGAState The VMSVGA ring-3 instance data.
869 * @param fAlpha Whether there is alpha or not.
870 * @param xHot Hotspot x coordinate.
871 * @param yHot Hotspot y coordinate.
872 * @param cx Width.
873 * @param cy Height.
874 * @param pbData Heap copy of the cursor data. Consumed.
875 * @param cbData The size of the data.
876 */
877static void vmsvgaR3InstallNewCursor(PVGASTATECC pThisCC, PVMSVGAR3STATE pSVGAState, bool fAlpha,
878 uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy, uint8_t *pbData, uint32_t cbData)
879{
880 LogRel2(("vmsvgaR3InstallNewCursor: cx=%d cy=%d xHot=%d yHot=%d fAlpha=%d cbData=%#x\n", cx, cy, xHot, yHot, fAlpha, cbData));
881#ifdef LOG_ENABLED
882 if (LogIs2Enabled())
883 {
884 uint32_t cbAndLine = RT_ALIGN(cx, 8) / 8;
885 if (!fAlpha)
886 {
887 Log2(("VMSVGA Cursor AND mask (%d,%d):\n", cx, cy));
888 for (uint32_t y = 0; y < cy; y++)
889 {
890 Log2(("%3u:", y));
891 uint8_t const *pbLine = &pbData[y * cbAndLine];
892 for (uint32_t x = 0; x < cx; x += 8)
893 {
894 uint8_t b = pbLine[x / 8];
895 char szByte[12];
896 szByte[0] = b & 0x80 ? '*' : ' '; /* most significant bit first */
897 szByte[1] = b & 0x40 ? '*' : ' ';
898 szByte[2] = b & 0x20 ? '*' : ' ';
899 szByte[3] = b & 0x10 ? '*' : ' ';
900 szByte[4] = b & 0x08 ? '*' : ' ';
901 szByte[5] = b & 0x04 ? '*' : ' ';
902 szByte[6] = b & 0x02 ? '*' : ' ';
903 szByte[7] = b & 0x01 ? '*' : ' ';
904 szByte[8] = '\0';
905 Log2(("%s", szByte));
906 }
907 Log2(("\n"));
908 }
909 }
910
911 Log2(("VMSVGA Cursor XOR mask (%d,%d):\n", cx, cy));
912 uint32_t const *pu32Xor = (uint32_t const *)&pbData[RT_ALIGN_32(cbAndLine * cy, 4)];
913 for (uint32_t y = 0; y < cy; y++)
914 {
915 Log2(("%3u:", y));
916 uint32_t const *pu32Line = &pu32Xor[y * cx];
917 for (uint32_t x = 0; x < cx; x++)
918 Log2((" %08x", pu32Line[x]));
919 Log2(("\n"));
920 }
921 }
922#endif
923
924 int rc = pThisCC->pDrv->pfnVBVAMousePointerShape(pThisCC->pDrv, true /*fVisible*/, fAlpha, xHot, yHot, cx, cy, pbData);
925 AssertRC(rc);
926
927 if (pSVGAState->Cursor.fActive)
928 RTMemFreeZ(pSVGAState->Cursor.pData, pSVGAState->Cursor.cbData);
929
930 pSVGAState->Cursor.fActive = true;
931 pSVGAState->Cursor.xHotspot = xHot;
932 pSVGAState->Cursor.yHotspot = yHot;
933 pSVGAState->Cursor.width = cx;
934 pSVGAState->Cursor.height = cy;
935 pSVGAState->Cursor.cbData = cbData;
936 pSVGAState->Cursor.pData = pbData;
937}
938
939
940#ifdef VBOX_WITH_VMSVGA3D
941
942/*
943 * SVGA_3D_CMD_* handlers.
944 */
945
946
947/** SVGA_3D_CMD_SURFACE_DEFINE 1040, SVGA_3D_CMD_SURFACE_DEFINE_V2 1070
948 *
949 * @param pThisCC The VGA/VMSVGA state for the current context.
950 * @param pCmd The VMSVGA command.
951 * @param cMipLevelSizes Number of elements in the paMipLevelSizes array.
952 * @param paMipLevelSizes Arrays of surface sizes for each face and miplevel.
953 */
954static void vmsvga3dCmdDefineSurface(PVGASTATECC pThisCC, SVGA3dCmdDefineSurface_v2 const *pCmd,
955 uint32_t cMipLevelSizes, SVGA3dSize *paMipLevelSizes)
956{
957 ASSERT_GUEST_RETURN_VOID(pCmd->sid < SVGA3D_MAX_SURFACE_IDS);
958 ASSERT_GUEST_RETURN_VOID(cMipLevelSizes >= 1);
959 RT_UNTRUSTED_VALIDATED_FENCE();
960
961 /* Number of faces (cFaces) is specified as the number of the first non-zero elements in the 'face' array.
962 * Since only plain surfaces (cFaces == 1) and cubemaps (cFaces == 6) are supported
963 * (see also SVGA3dCmdDefineSurface definition in svga3d_reg.h), we ignore anything else.
964 */
965 uint32_t cRemainingMipLevels = cMipLevelSizes;
966 uint32_t cFaces = 0;
967 for (uint32_t i = 0; i < SVGA3D_MAX_SURFACE_FACES; ++i)
968 {
969 if (pCmd->face[i].numMipLevels == 0)
970 break;
971
972 /* All SVGA3dSurfaceFace structures must have the same value of numMipLevels field */
973 ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels == pCmd->face[0].numMipLevels);
974
975 /* numMipLevels value can't be greater than the number of remaining elements in the paMipLevelSizes array. */
976 ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels <= cRemainingMipLevels);
977 cRemainingMipLevels -= pCmd->face[i].numMipLevels;
978
979 ++cFaces;
980 }
981 for (uint32_t i = cFaces; i < SVGA3D_MAX_SURFACE_FACES; ++i)
982 ASSERT_GUEST_RETURN_VOID(pCmd->face[i].numMipLevels == 0);
983
984 /* cFaces must be 6 for a cubemap and 1 otherwise. */
985 ASSERT_GUEST_RETURN_VOID(cFaces == (uint32_t)((pCmd->surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1));
986
987 /* Sum of face[i].numMipLevels must be equal to cMipLevels. */
988 ASSERT_GUEST_RETURN_VOID(cRemainingMipLevels == 0);
989 RT_UNTRUSTED_VALIDATED_FENCE();
990
991 /* Verify paMipLevelSizes */
992 uint32_t cWidth = paMipLevelSizes[0].width;
993 uint32_t cHeight = paMipLevelSizes[0].height;
994 uint32_t cDepth = paMipLevelSizes[0].depth;
995 for (uint32_t i = 1; i < pCmd->face[0].numMipLevels; ++i)
996 {
997 cWidth >>= 1;
998 if (cWidth == 0) cWidth = 1;
999 cHeight >>= 1;
1000 if (cHeight == 0) cHeight = 1;
1001 cDepth >>= 1;
1002 if (cDepth == 0) cDepth = 1;
1003 for (uint32_t iFace = 0; iFace < cFaces; ++iFace)
1004 {
1005 uint32_t const iMipLevelSize = iFace * pCmd->face[0].numMipLevels + i;
1006 ASSERT_GUEST_RETURN_VOID( cWidth == paMipLevelSizes[iMipLevelSize].width
1007 && cHeight == paMipLevelSizes[iMipLevelSize].height
1008 && cDepth == paMipLevelSizes[iMipLevelSize].depth);
1009 }
1010 }
1011 RT_UNTRUSTED_VALIDATED_FENCE();
1012
1013 /* Create the surface. */
1014 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
1015 pCmd->multisampleCount, pCmd->autogenFilter,
1016 pCmd->face[0].numMipLevels, &paMipLevelSizes[0]);
1017}
1018
1019
1020/* SVGA_3D_CMD_DEFINE_GB_MOB 1093 */
1021static void vmsvga3dCmdDefineGBMob(PVGASTATECC pThisCC, SVGA3dCmdDefineGBMob const *pCmd)
1022{
1023 ASMBreakpoint();
1024 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1025
1026 ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */
1027
1028 /* Maybe just update the OTable and create Gbo when the MOB is actually accessed? */
1029 /* Allocate a structure for the MOB. */
1030 PVMSVGAMOB pMob = (PVMSVGAMOB)RTMemAllocZ(sizeof(*pMob));
1031 AssertPtrReturnVoid(pMob);
1032
1033 int rc = vmsvgaR3MobCreate(pSvgaR3State, pCmd->ptDepth, pCmd->base, pCmd->sizeInBytes, pCmd->mobid, /*fGCPhys64=*/ false, pMob);
1034 if (RT_SUCCESS(rc))
1035 {
1036 return;
1037 }
1038
1039 AssertFailed();
1040
1041 RTMemFree(pMob);
1042}
1043
1044
1045/* SVGA_3D_CMD_DESTROY_GB_MOB 1094 */
1046static void vmsvga3dCmdDestroyGBMob(PVGASTATECC pThisCC, SVGA3dCmdDestroyGBMob const *pCmd)
1047{
1048// ASMBreakpoint();
1049 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1050
1051 ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */
1052
1053 int rc = vmsvgaR3MobDestroy(pSvgaR3State, pCmd->mobid);
1054 if (RT_SUCCESS(rc))
1055 {
1056 return;
1057 }
1058
1059 AssertFailed();
1060}
1061
1062
1063/* SVGA_3D_CMD_DEFINE_GB_SURFACE 1097 */
1064static void vmsvga3dCmdDefineGBSurface(PVGASTATECC pThisCC, SVGA3dCmdDefineGBSurface const *pCmd)
1065{
1066// ASMBreakpoint();
1067 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1068
1069 /* Update the entry in the pSvgaR3State->pGboOTableSurface. */
1070 SVGAOTableSurfaceEntry entry;
1071 RT_ZERO(entry);
1072 entry.format = pCmd->format;
1073 entry.surfaceFlags = pCmd->surfaceFlags;
1074 entry.numMipLevels = pCmd->numMipLevels;
1075 entry.multisampleCount = pCmd->multisampleCount;
1076 entry.autogenFilter = pCmd->autogenFilter;
1077 entry.size = pCmd->size;
1078 entry.mobid = SVGA_ID_INVALID;
1079 // entry.arraySize = 0;
1080 // entry.mobPitch = 0;
1081 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1082 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
1083 if (RT_SUCCESS(rc))
1084 {
1085 /* Create the host surface. */
1086 /** @todo fGBO = true flag. */
1087 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format,
1088 pCmd->multisampleCount, pCmd->autogenFilter,
1089 pCmd->numMipLevels, &pCmd->size);
1090 }
1091}
1092
1093
1094/* SVGA_3D_CMD_DESTROY_GB_SURFACE 1098 */
1095static void vmsvga3dCmdDestroyGBSurface(PVGASTATECC pThisCC, SVGA3dCmdDestroyGBSurface const *pCmd)
1096{
1097// ASMBreakpoint();
1098 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1099
1100 /* Update the entry in the pSvgaR3State->pGboOTableSurface. */
1101 SVGAOTableSurfaceEntry entry;
1102 RT_ZERO(entry);
1103 entry.mobid = SVGA_ID_INVALID;
1104 vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1105 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
1106
1107 vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid);
1108}
1109
1110
1111/* SVGA_3D_CMD_BIND_GB_SURFACE 1099 */
1112static void vmsvga3dCmdBindGBSurface(PVGASTATECC pThisCC, SVGA3dCmdBindGBSurface const *pCmd)
1113{
1114// ASMBreakpoint();
1115 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1116 RT_NOREF(pCmd, pSvgaR3State);
1117
1118 /* Assign the mobid to the surface. */
1119 int rc = VINF_SUCCESS;
1120 if (pCmd->mobid != SVGA_ID_INVALID)
1121 rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_MOB],
1122 pCmd->mobid, SVGA3D_OTABLE_MOB_ENTRY_SIZE);
1123 if (RT_SUCCESS(rc))
1124 {
1125 SVGAOTableSurfaceEntry entry;
1126 rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1127 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
1128 if (RT_SUCCESS(rc))
1129 {
1130 entry.mobid = pCmd->mobid;
1131 rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1132 pCmd->sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entry, sizeof(entry));
1133 if (RT_SUCCESS(rc))
1134 {
1135 /* */
1136 }
1137 }
1138 }
1139}
1140
1141
1142#ifdef DUMP_BITMAPS
1143static int vmsvga3dBmpWrite(const char *pszFilename, VMSVGA3D_MAPPED_SURFACE const *pMap)
1144{
1145 if (pMap->cbPixel != 4)
1146 return VERR_NOT_SUPPORTED;
1147
1148 int const w = pMap->box.w;
1149 int const h = pMap->box.h;
1150
1151 const int cbBitmap = w * h * 4;
1152
1153 FILE *f = fopen(pszFilename, "wb");
1154 if (!f)
1155 return VERR_FILE_NOT_FOUND;
1156
1157 {
1158 BMPFILEHDR fileHdr;
1159 RT_ZERO(fileHdr);
1160 fileHdr.uType = BMP_HDR_MAGIC;
1161 fileHdr.cbFileSize = sizeof(BMPFILEHDR) + sizeof(BMPWIN3XINFOHDR) + cbBitmap;
1162 fileHdr.offBits = sizeof(BMPFILEHDR) + sizeof(BMPWIN3XINFOHDR);
1163
1164 BMPWIN3XINFOHDR coreHdr;
1165 RT_ZERO(coreHdr);
1166 coreHdr.cbSize = sizeof(coreHdr);
1167 coreHdr.uWidth = w;
1168 coreHdr.uHeight = -h;
1169 coreHdr.cPlanes = 1;
1170 coreHdr.cBits = 32;
1171 coreHdr.cbSizeImage = cbBitmap;
1172
1173 fwrite(&fileHdr, 1, sizeof(fileHdr), f);
1174 fwrite(&coreHdr, 1, sizeof(coreHdr), f);
1175 }
1176
1177 if (pMap->cbPixel == 4)
1178 {
1179 const uint8_t *s = (uint8_t *)pMap->pvData;
1180 for (int32_t y = 0; y < h; ++y)
1181 {
1182 fwrite(s, 1, w * pMap->cbPixel, f);
1183
1184 s += pMap->cbRowPitch;
1185 }
1186 }
1187
1188 fclose(f);
1189
1190 return VINF_SUCCESS;
1191}
1192
1193
1194void vmsvga3dMapWriteBmpFile(VMSVGA3D_MAPPED_SURFACE const *pMap, char const *pszPrefix)
1195{
1196 static int idxBitmap = 0;
1197 char *pszFilename = RTStrAPrintf2("bmp\\%s%d.bmp", pszPrefix, idxBitmap++);
1198 vmsvga3dBmpWrite(pszFilename, pMap);
1199 RTStrFree(pszFilename);
1200}
1201#endif /* DUMP_BITMAPS */
1202
1203
1204/* SVGA_3D_CMD_UPDATE_GB_IMAGE 1101 */
1205static void vmsvga3dCmdUpdateGBImage(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBImage const *pCmd)
1206{
1207// ASMBreakpoint();
1208 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1209
1210 LogFlowFunc(("sid=%u @%u,%u,%u %ux%ux%u\n",
1211 pCmd->image.sid, pCmd->box.x, pCmd->box.y, pCmd->box.z, pCmd->box.w, pCmd->box.h, pCmd->box.d));
1212
1213 /* "update a surface from its backing MOB." */
1214 SVGAOTableSurfaceEntry entrySurface;
1215 int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1216 pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface));
1217 if (RT_SUCCESS(rc))
1218 {
1219 PVMSVGAMOB pMob = vmsvgaR3MobGet(pSvgaR3State, entrySurface.mobid);
1220 if (pMob)
1221 {
1222 VMSVGA3D_MAPPED_SURFACE map;
1223 rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, &pCmd->image, &pCmd->box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
1224 if (RT_SUCCESS(rc))
1225 {
1226 /* Copy MOB -> mapped surface. */
1227 uint32_t offSrc = pCmd->box.x * map.cbPixel
1228 + pCmd->box.y * entrySurface.size.width * map.cbPixel
1229 + pCmd->box.z * entrySurface.size.height * entrySurface.size.width * map.cbPixel;
1230 uint8_t *pu8Dst = (uint8_t *)map.pvData;
1231 for (uint32_t z = 0; z < pCmd->box.d; ++z)
1232 {
1233 for (uint32_t y = 0; y < pCmd->box.h; ++y)
1234 {
1235 rc = vmsvgaR3GboRead(pSvgaR3State, &pMob->Gbo, offSrc, pu8Dst, pCmd->box.w * map.cbPixel);
1236 if (RT_FAILURE(rc))
1237 break;
1238
1239 pu8Dst += map.cbRowPitch;
1240 offSrc += entrySurface.size.width * map.cbPixel;
1241 }
1242
1243 pu8Dst += map.cbDepthPitch;
1244 offSrc += entrySurface.size.height * entrySurface.size.width * map.cbPixel;
1245 }
1246
1247 // vmsvga3dMapWriteBmpFile(&map, "Dynamic");
1248
1249 pSvgaR3State->pFuncsMap->pfnSurfaceUnmap(pThisCC, &pCmd->image, &map, /* fWritten = */true);
1250 }
1251 }
1252 }
1253}
1254
1255
1256/* SVGA_3D_CMD_INVALIDATE_GB_SURFACE 1106 */
1257static void vmsvga3dCmdInvalidateGBSurface(PVGASTATECC pThisCC, SVGA3dCmdInvalidateGBSurface const *pCmd)
1258{
1259// ASMBreakpoint();
1260 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1261 RT_NOREF(pSvgaR3State, pCmd);
1262 /** @todo Implement. */
1263}
1264
1265
1266/* SVGA_3D_CMD_SET_OTABLE_BASE64 1115 */
1267static void vmsvga3dCmdSetOTableBase64(PVGASTATECC pThisCC, SVGA3dCmdSetOTableBase64 const *pCmd)
1268{
1269 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1270
1271 /*
1272 * Create a GBO for the table.
1273 */
1274 PVMSVGAGBO pGbo;
1275 if (pCmd->type <= RT_ELEMENTS(pSvgaR3State->aGboOTables))
1276 {
1277 RT_UNTRUSTED_VALIDATED_FENCE();
1278 pGbo = &pSvgaR3State->aGboOTables[pCmd->type];
1279 }
1280 else
1281 {
1282 ASSERT_GUEST_FAILED();
1283 pGbo = NULL;
1284 }
1285
1286 if (pGbo)
1287 {
1288 /* Recreate. */
1289 vmsvgaR3GboDestroy(pSvgaR3State, pGbo);
1290 int rc = vmsvgaR3GboCreate(pSvgaR3State, pCmd->ptDepth, pCmd->baseAddress, pCmd->sizeInBytes, /*fGCPhys64=*/ true, /* fWriteProtected = */ true, pGbo);
1291 AssertRC(rc);
1292 }
1293}
1294
1295
1296/* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET 1124 */
1297static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC, SVGA3dCmdDefineGBScreenTarget const *pCmd)
1298{
1299// ASMBreakpoint();
1300 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1301
1302 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
1303 ASSERT_GUEST_RETURN_VOID(pCmd->width > 0 && pCmd->width <= pThis->svga.u32MaxWidth); /* SVGA_REG_SCREENTARGET_MAX_WIDTH */
1304 ASSERT_GUEST_RETURN_VOID(pCmd->height > 0 && pCmd->height <= pThis->svga.u32MaxHeight); /* SVGA_REG_SCREENTARGET_MAX_HEIGHT */
1305 RT_UNTRUSTED_VALIDATED_FENCE();
1306
1307 /* Update the entry in the pSvgaR3State->pGboOTableScreenTarget. */
1308 SVGAOTableScreenTargetEntry entry;
1309 RT_ZERO(entry);
1310 entry.image.sid = SVGA_ID_INVALID;
1311 // entry.image.face = 0;
1312 // entry.image.mipmap = 0;
1313 entry.width = pCmd->width;
1314 entry.height = pCmd->height;
1315 entry.xRoot = pCmd->xRoot;
1316 entry.yRoot = pCmd->yRoot;
1317 entry.flags = pCmd->flags;
1318 entry.dpi = pCmd->dpi;
1319 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
1320 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
1321 if (RT_SUCCESS(rc))
1322 {
1323 /* Screen objects and screen targets are similar, therefore we will use the same for both. */
1324 /** @todo Generic screen object/target interface. */
1325 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
1326 pScreen->fDefined = true;
1327 pScreen->fModified = true;
1328 pScreen->fuScreen = SVGA_SCREEN_MUST_BE_SET
1329 | (RT_BOOL(pCmd->flags & SVGA_STFLAG_PRIMARY) ? SVGA_SCREEN_IS_PRIMARY : 0);
1330 pScreen->idScreen = pCmd->stid;
1331
1332 pScreen->xOrigin = pCmd->xRoot;
1333 pScreen->yOrigin = pCmd->yRoot;
1334 pScreen->cWidth = pCmd->width;
1335 pScreen->cHeight = pCmd->height;
1336 pScreen->offVRAM = 0; /* Always for screen targets, they use either a separate memory buffer or a host window. */
1337 pScreen->cbPitch = pCmd->width * 4;
1338 pScreen->cBpp = 32;
1339
1340 if (RT_LIKELY(pThis->svga.f3DEnabled))
1341 vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
1342
1343 if (!pScreen->pHwScreen)
1344 {
1345 /* System memory buffer. */
1346 pScreen->pvScreenBitmap = RTMemAllocZ(pScreen->cHeight * pScreen->cbPitch);
1347 }
1348
1349 pThis->svga.fGFBRegisters = false;
1350 vmsvgaR3ChangeMode(pThis, pThisCC);
1351 }
1352}
1353
1354
1355/* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET 1125 */
1356static void vmsvga3dCmdDestroyGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC, SVGA3dCmdDestroyGBScreenTarget const *pCmd)
1357{
1358// ASMBreakpoint();
1359 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1360
1361 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
1362 RT_UNTRUSTED_VALIDATED_FENCE();
1363
1364 /* Update the entry in the pSvgaR3State->pGboOTableScreenTarget. */
1365 SVGAOTableScreenTargetEntry entry;
1366 RT_ZERO(entry);
1367 int rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
1368 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
1369 if (RT_SUCCESS(rc))
1370 {
1371 /* Screen objects and screen targets are similar, therefore we will use the same for both. */
1372 /** @todo Generic screen object/target interface. */
1373 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
1374 pScreen->fModified = true;
1375 pScreen->fDefined = false;
1376 pScreen->idScreen = pCmd->stid;
1377
1378 if (RT_LIKELY(pThis->svga.f3DEnabled))
1379 vmsvga3dDestroyScreen(pThisCC, pScreen);
1380
1381 vmsvgaR3ChangeMode(pThis, pThisCC);
1382
1383 RTMemFree(pScreen->pvScreenBitmap);
1384 pScreen->pvScreenBitmap = NULL;
1385 }
1386}
1387
1388
1389/* SVGA_3D_CMD_BIND_GB_SCREENTARGET 1126 */
1390static void vmsvga3dCmdBindGBScreenTarget(PVGASTATECC pThisCC, SVGA3dCmdBindGBScreenTarget const *pCmd)
1391{
1392// ASMBreakpoint();
1393 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1394
1395 /* "Binding a surface to a Screen Target the same as flipping" */
1396
1397 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
1398 ASSERT_GUEST_RETURN_VOID(pCmd->image.face == 0 && pCmd->image.mipmap == 0);
1399 RT_UNTRUSTED_VALIDATED_FENCE();
1400
1401 /* Assign the surface to the screen target. */
1402 int rc = VINF_SUCCESS;
1403 if (pCmd->image.sid != SVGA_ID_INVALID)
1404 rc = vmsvgaR3OTableVerifyIndex(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1405 pCmd->image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE);
1406 if (RT_SUCCESS(rc))
1407 {
1408 SVGAOTableScreenTargetEntry entry;
1409 rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
1410 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
1411 if (RT_SUCCESS(rc))
1412 {
1413 entry.image = pCmd->image;
1414 rc = vmsvgaR3OTableWrite(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
1415 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entry, sizeof(entry));
1416 if (RT_SUCCESS(rc))
1417 {
1418 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
1419 rc = pSvgaR3State->pFuncsGBO->pfnScreenTargetBind(pThisCC, pScreen, pCmd->image.sid);
1420 AssertRC(rc);
1421 }
1422 }
1423 }
1424}
1425
1426
1427/* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET 1127 */
1428static void vmsvga3dCmdUpdateGBScreenTarget(PVGASTATECC pThisCC, SVGA3dCmdUpdateGBScreenTarget const *pCmd)
1429{
1430// ASMBreakpoint();
1431 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1432
1433 /* Update the screen target from its backing surface. */
1434 ASSERT_GUEST_RETURN_VOID(pCmd->stid < RT_ELEMENTS(pSvgaR3State->aScreens));
1435 RT_UNTRUSTED_VALIDATED_FENCE();
1436
1437 /* Get the screen target info. */
1438 SVGAOTableScreenTargetEntry entryScreenTarget;
1439 int rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SCREENTARGET],
1440 pCmd->stid, SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE, &entryScreenTarget, sizeof(entryScreenTarget));
1441 if (RT_SUCCESS(rc))
1442 {
1443 ASSERT_GUEST_RETURN_VOID(entryScreenTarget.image.face == 0 && entryScreenTarget.image.mipmap == 0);
1444 RT_UNTRUSTED_VALIDATED_FENCE();
1445
1446 if (entryScreenTarget.image.sid != SVGA_ID_INVALID)
1447 {
1448 SVGAOTableSurfaceEntry entrySurface;
1449 rc = vmsvgaR3OTableRead(pSvgaR3State, &pSvgaR3State->aGboOTables[SVGA_OTABLE_SURFACE],
1450 entryScreenTarget.image.sid, SVGA3D_OTABLE_SURFACE_ENTRY_SIZE, &entrySurface, sizeof(entrySurface));
1451 if (RT_SUCCESS(rc))
1452 {
1453 /* Copy entrySurface.mobid content to the screen target. */
1454 if (entrySurface.mobid != SVGA_ID_INVALID)
1455 {
1456 RT_UNTRUSTED_VALIDATED_FENCE();
1457 SVGA3dRect targetRect = pCmd->rect;
1458
1459 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[pCmd->stid];
1460 if (pScreen->pHwScreen)
1461 {
1462 /* Copy the screen target surface to the backend's screen. */
1463 pSvgaR3State->pFuncsGBO->pfnScreenTargetUpdate(pThisCC, pScreen, &targetRect);
1464 }
1465 else if (pScreen->pvScreenBitmap)
1466 {
1467 /* Copy the screen target surface to the memory buffer. */
1468 VMSVGA3D_MAPPED_SURFACE map;
1469 rc = pSvgaR3State->pFuncsMap->pfnSurfaceMap(pThisCC, &entryScreenTarget.image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
1470 if (RT_SUCCESS(rc))
1471 {
1472 uint8_t const *pu8Src = (uint8_t *)map.pvData
1473 + targetRect.x * map.cbPixel
1474 + targetRect.y * map.cbRowPitch;
1475 uint8_t *pu8Dst = (uint8_t *)pScreen->pvScreenBitmap
1476 + targetRect.x * map.cbPixel
1477 + targetRect.y * map.box.w * map.cbPixel;
1478 for (uint32_t y = 0; y < targetRect.h; ++y)
1479 {
1480 memcpy(pu8Dst, pu8Src, targetRect.w * map.cbPixel);
1481
1482 pu8Src += map.cbRowPitch;
1483 pu8Dst += map.box.w * map.cbPixel;
1484 }
1485
1486 pSvgaR3State->pFuncsMap->pfnSurfaceUnmap(pThisCC, &entryScreenTarget.image, &map, /* fWritten = */ false);
1487
1488 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->rect.x, pCmd->rect.y, pCmd->rect.w, pCmd->rect.h);
1489 }
1490 else
1491 AssertFailed();
1492 }
1493 }
1494 }
1495 }
1496 }
1497}
1498
1499
1500/* SVGA_3D_CMD_DEFINE_GB_MOB64 1135 */
1501static void vmsvga3dCmdDefineGBMob64(PVGASTATECC pThisCC, SVGA3dCmdDefineGBMob64 const *pCmd)
1502{
1503// ASMBreakpoint();
1504 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1505
1506 ASSERT_GUEST_RETURN_VOID(pCmd->mobid != SVGA_ID_INVALID); /* The guest should not use this id. */
1507
1508 /* Maybe just update the OTable and create Gbo when the MOB is actually accessed? */
1509 /* Allocate a structure for the MOB. */
1510 PVMSVGAMOB pMob = (PVMSVGAMOB)RTMemAllocZ(sizeof(*pMob));
1511 AssertPtrReturnVoid(pMob);
1512
1513 int rc = vmsvgaR3MobCreate(pSvgaR3State, pCmd->ptDepth, pCmd->base, pCmd->sizeInBytes, pCmd->mobid, /*fGCPhys64=*/ true, pMob);
1514 if (RT_SUCCESS(rc))
1515 {
1516 return;
1517 }
1518
1519 RTMemFree(pMob);
1520}
1521
1522
1523/* SVGA_3D_CMD_DX_DEFINE_CONTEXT 1143 */
1524static void vmsvga3dCmdDXDefineContext(PVGASTATECC pThisCC, SVGA3dCmdDXDefineContext const *pCmd)
1525{
1526ASMBreakpoint();
1527 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1528 if (pSvgaR3State->pFuncsDX)
1529 {
1530 RT_NOREF(pCmd);
1531 pSvgaR3State->pFuncsDX->pfnDXDefineContext(pThisCC->svga.p3dState);
1532 }
1533}
1534
1535
1536/* SVGA_3D_CMD_DX_DESTROY_CONTEXT 1144 */
1537static void vmsvga3dCmdDXDestroyContext(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyContext const *pCmd)
1538{
1539ASMBreakpoint();
1540 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1541 if (pSvgaR3State->pFuncsDX)
1542 {
1543 RT_NOREF(pCmd);
1544 pSvgaR3State->pFuncsDX->pfnDXDestroyContext(pThisCC->svga.p3dState);
1545 }
1546}
1547
1548
1549/* SVGA_3D_CMD_DX_BIND_CONTEXT 1145 */
1550static void vmsvga3dCmdDXBindContext(PVGASTATECC pThisCC, SVGA3dCmdDXBindContext const *pCmd)
1551{
1552ASMBreakpoint();
1553 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1554 if (pSvgaR3State->pFuncsDX)
1555 {
1556 RT_NOREF(pCmd);
1557 pSvgaR3State->pFuncsDX->pfnDXBindContext(pThisCC->svga.p3dState);
1558 }
1559}
1560
1561
1562/* SVGA_3D_CMD_DX_READBACK_CONTEXT 1146 */
1563static void vmsvga3dCmdDXReadbackContext(PVGASTATECC pThisCC, SVGA3dCmdDXReadbackContext const *pCmd)
1564{
1565ASMBreakpoint();
1566 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1567 if (pSvgaR3State->pFuncsDX)
1568 {
1569 RT_NOREF(pCmd);
1570 pSvgaR3State->pFuncsDX->pfnDXReadbackContext(pThisCC->svga.p3dState);
1571 }
1572}
1573
1574
1575/* SVGA_3D_CMD_DX_INVALIDATE_CONTEXT 1147 */
1576static void vmsvga3dCmdDXInvalidateContext(PVGASTATECC pThisCC, SVGA3dCmdDXInvalidateContext const *pCmd)
1577{
1578ASMBreakpoint();
1579 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1580 if (pSvgaR3State->pFuncsDX)
1581 {
1582 RT_NOREF(pCmd);
1583 pSvgaR3State->pFuncsDX->pfnDXInvalidateContext(pThisCC->svga.p3dState);
1584 }
1585}
1586
1587
1588/* SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER 1148 */
1589static void vmsvga3dCmdDXSetSingleConstantBuffer(PVGASTATECC pThisCC, SVGA3dCmdDXSetSingleConstantBuffer const *pCmd)
1590{
1591ASMBreakpoint();
1592 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1593 if (pSvgaR3State->pFuncsDX)
1594 {
1595 RT_NOREF(pCmd);
1596 pSvgaR3State->pFuncsDX->pfnDXSetSingleConstantBuffer(pThisCC->svga.p3dState);
1597 }
1598}
1599
1600
1601/* SVGA_3D_CMD_DX_SET_SHADER_RESOURCES 1149 */
1602static void vmsvga3dCmdDXSetShaderResources(PVGASTATECC pThisCC, SVGA3dCmdDXSetShaderResources const *pCmd)
1603{
1604ASMBreakpoint();
1605 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1606 if (pSvgaR3State->pFuncsDX)
1607 {
1608 RT_NOREF(pCmd);
1609 pSvgaR3State->pFuncsDX->pfnDXSetShaderResources(pThisCC->svga.p3dState);
1610 }
1611}
1612
1613
1614/* SVGA_3D_CMD_DX_SET_SHADER 1150 */
1615static void vmsvga3dCmdDXSetShader(PVGASTATECC pThisCC, SVGA3dCmdDXSetShader const *pCmd)
1616{
1617ASMBreakpoint();
1618 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1619 if (pSvgaR3State->pFuncsDX)
1620 {
1621 RT_NOREF(pCmd);
1622 pSvgaR3State->pFuncsDX->pfnDXSetShader(pThisCC->svga.p3dState);
1623 }
1624}
1625
1626
1627/* SVGA_3D_CMD_DX_SET_SAMPLERS 1151 */
1628static void vmsvga3dCmdDXSetSamplers(PVGASTATECC pThisCC, SVGA3dCmdDXSetSamplers const *pCmd)
1629{
1630ASMBreakpoint();
1631 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1632 if (pSvgaR3State->pFuncsDX)
1633 {
1634 RT_NOREF(pCmd);
1635 pSvgaR3State->pFuncsDX->pfnDXSetSamplers(pThisCC->svga.p3dState);
1636 }
1637}
1638
1639
1640/* SVGA_3D_CMD_DX_DRAW 1152 */
1641static void vmsvga3dCmdDXDraw(PVGASTATECC pThisCC, SVGA3dCmdDXDraw const *pCmd)
1642{
1643ASMBreakpoint();
1644 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1645 if (pSvgaR3State->pFuncsDX)
1646 {
1647 RT_NOREF(pCmd);
1648 pSvgaR3State->pFuncsDX->pfnDXDraw(pThisCC->svga.p3dState);
1649 }
1650}
1651
1652
1653/* SVGA_3D_CMD_DX_DRAW_INDEXED 1153 */
1654static void vmsvga3dCmdDXDrawIndexed(PVGASTATECC pThisCC, SVGA3dCmdDXDrawIndexed const *pCmd)
1655{
1656ASMBreakpoint();
1657 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1658 if (pSvgaR3State->pFuncsDX)
1659 {
1660 RT_NOREF(pCmd);
1661 pSvgaR3State->pFuncsDX->pfnDXDrawIndexed(pThisCC->svga.p3dState);
1662 }
1663}
1664
1665
1666/* SVGA_3D_CMD_DX_DRAW_INSTANCED 1154 */
1667static void vmsvga3dCmdDXDrawInstanced(PVGASTATECC pThisCC, SVGA3dCmdDXDrawInstanced const *pCmd)
1668{
1669ASMBreakpoint();
1670 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1671 if (pSvgaR3State->pFuncsDX)
1672 {
1673 RT_NOREF(pCmd);
1674 pSvgaR3State->pFuncsDX->pfnDXDrawInstanced(pThisCC->svga.p3dState);
1675 }
1676}
1677
1678
1679/* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED 1155 */
1680static void vmsvga3dCmdDXDrawIndexedInstanced(PVGASTATECC pThisCC, SVGA3dCmdDXDrawIndexedInstanced const *pCmd)
1681{
1682ASMBreakpoint();
1683 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1684 if (pSvgaR3State->pFuncsDX)
1685 {
1686 RT_NOREF(pCmd);
1687 pSvgaR3State->pFuncsDX->pfnDXDrawIndexedInstanced(pThisCC->svga.p3dState);
1688 }
1689}
1690
1691
1692/* SVGA_3D_CMD_DX_DRAW_AUTO 1156 */
1693static void vmsvga3dCmdDXDrawAuto(PVGASTATECC pThisCC, SVGA3dCmdDXDrawAuto const *pCmd)
1694{
1695ASMBreakpoint();
1696 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1697 if (pSvgaR3State->pFuncsDX)
1698 {
1699 RT_NOREF(pCmd);
1700 pSvgaR3State->pFuncsDX->pfnDXDrawAuto(pThisCC->svga.p3dState);
1701 }
1702}
1703
1704
1705/* SVGA_3D_CMD_DX_SET_INPUT_LAYOUT 1157 */
1706static void vmsvga3dCmdDXSetInputLayout(PVGASTATECC pThisCC, SVGA3dCmdDXSetInputLayout const *pCmd)
1707{
1708ASMBreakpoint();
1709 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1710 if (pSvgaR3State->pFuncsDX)
1711 {
1712 RT_NOREF(pCmd);
1713 pSvgaR3State->pFuncsDX->pfnDXSetInputLayout(pThisCC->svga.p3dState);
1714 }
1715}
1716
1717
1718/* SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS 1158 */
1719static void vmsvga3dCmdDXSetVertexBuffers(PVGASTATECC pThisCC, SVGA3dCmdDXSetVertexBuffers const *pCmd)
1720{
1721ASMBreakpoint();
1722 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1723 if (pSvgaR3State->pFuncsDX)
1724 {
1725 RT_NOREF(pCmd);
1726 pSvgaR3State->pFuncsDX->pfnDXSetVertexBuffers(pThisCC->svga.p3dState);
1727 }
1728}
1729
1730
1731/* SVGA_3D_CMD_DX_SET_INDEX_BUFFER 1159 */
1732static void vmsvga3dCmdDXSetIndexBuffer(PVGASTATECC pThisCC, SVGA3dCmdDXSetIndexBuffer const *pCmd)
1733{
1734ASMBreakpoint();
1735 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1736 if (pSvgaR3State->pFuncsDX)
1737 {
1738 RT_NOREF(pCmd);
1739 pSvgaR3State->pFuncsDX->pfnDXSetIndexBuffer(pThisCC->svga.p3dState);
1740 }
1741}
1742
1743
1744/* SVGA_3D_CMD_DX_SET_TOPOLOGY 1160 */
1745static void vmsvga3dCmdDXSetTopology(PVGASTATECC pThisCC, SVGA3dCmdDXSetTopology const *pCmd)
1746{
1747ASMBreakpoint();
1748 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1749 if (pSvgaR3State->pFuncsDX)
1750 {
1751 RT_NOREF(pCmd);
1752 pSvgaR3State->pFuncsDX->pfnDXSetTopology(pThisCC->svga.p3dState);
1753 }
1754}
1755
1756
1757/* SVGA_3D_CMD_DX_SET_RENDERTARGETS 1161 */
1758static void vmsvga3dCmdDXSetRenderTargets(PVGASTATECC pThisCC, SVGA3dCmdDXSetRenderTargets const *pCmd)
1759{
1760ASMBreakpoint();
1761 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1762 if (pSvgaR3State->pFuncsDX)
1763 {
1764 RT_NOREF(pCmd);
1765 pSvgaR3State->pFuncsDX->pfnDXSetRenderTargets(pThisCC->svga.p3dState);
1766 }
1767}
1768
1769
1770/* SVGA_3D_CMD_DX_SET_BLEND_STATE 1162 */
1771static void vmsvga3dCmdDXSetBlendState(PVGASTATECC pThisCC, SVGA3dCmdDXSetBlendState const *pCmd)
1772{
1773ASMBreakpoint();
1774 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1775 if (pSvgaR3State->pFuncsDX)
1776 {
1777 RT_NOREF(pCmd);
1778 pSvgaR3State->pFuncsDX->pfnDXSetBlendState(pThisCC->svga.p3dState);
1779 }
1780}
1781
1782
1783/* SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE 1163 */
1784static void vmsvga3dCmdDXSetDepthStencilState(PVGASTATECC pThisCC, SVGA3dCmdDXSetDepthStencilState const *pCmd)
1785{
1786ASMBreakpoint();
1787 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1788 if (pSvgaR3State->pFuncsDX)
1789 {
1790 RT_NOREF(pCmd);
1791 pSvgaR3State->pFuncsDX->pfnDXSetDepthStencilState(pThisCC->svga.p3dState);
1792 }
1793}
1794
1795
1796/* SVGA_3D_CMD_DX_SET_RASTERIZER_STATE 1164 */
1797static void vmsvga3dCmdDXSetRasterizerState(PVGASTATECC pThisCC, SVGA3dCmdDXSetRasterizerState const *pCmd)
1798{
1799ASMBreakpoint();
1800 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1801 if (pSvgaR3State->pFuncsDX)
1802 {
1803 RT_NOREF(pCmd);
1804 pSvgaR3State->pFuncsDX->pfnDXSetRasterizerState(pThisCC->svga.p3dState);
1805 }
1806}
1807
1808
1809/* SVGA_3D_CMD_DX_DEFINE_QUERY 1165 */
1810static void vmsvga3dCmdDXDefineQuery(PVGASTATECC pThisCC, SVGA3dCmdDXDefineQuery const *pCmd)
1811{
1812ASMBreakpoint();
1813 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1814 if (pSvgaR3State->pFuncsDX)
1815 {
1816 RT_NOREF(pCmd);
1817 pSvgaR3State->pFuncsDX->pfnDXDefineQuery(pThisCC->svga.p3dState);
1818 }
1819}
1820
1821
1822/* SVGA_3D_CMD_DX_DESTROY_QUERY 1166 */
1823static void vmsvga3dCmdDXDestroyQuery(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyQuery const *pCmd)
1824{
1825ASMBreakpoint();
1826 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1827 if (pSvgaR3State->pFuncsDX)
1828 {
1829 RT_NOREF(pCmd);
1830 pSvgaR3State->pFuncsDX->pfnDXDestroyQuery(pThisCC->svga.p3dState);
1831 }
1832}
1833
1834
1835/* SVGA_3D_CMD_DX_BIND_QUERY 1167 */
1836static void vmsvga3dCmdDXBindQuery(PVGASTATECC pThisCC, SVGA3dCmdDXBindQuery const *pCmd)
1837{
1838ASMBreakpoint();
1839 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1840 if (pSvgaR3State->pFuncsDX)
1841 {
1842 RT_NOREF(pCmd);
1843 pSvgaR3State->pFuncsDX->pfnDXBindQuery(pThisCC->svga.p3dState);
1844 }
1845}
1846
1847
1848/* SVGA_3D_CMD_DX_SET_QUERY_OFFSET 1168 */
1849static void vmsvga3dCmdDXSetQueryOffset(PVGASTATECC pThisCC, SVGA3dCmdDXSetQueryOffset const *pCmd)
1850{
1851ASMBreakpoint();
1852 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1853 if (pSvgaR3State->pFuncsDX)
1854 {
1855 RT_NOREF(pCmd);
1856 pSvgaR3State->pFuncsDX->pfnDXSetQueryOffset(pThisCC->svga.p3dState);
1857 }
1858}
1859
1860
1861/* SVGA_3D_CMD_DX_BEGIN_QUERY 1169 */
1862static void vmsvga3dCmdDXBeginQuery(PVGASTATECC pThisCC, SVGA3dCmdDXBeginQuery const *pCmd)
1863{
1864ASMBreakpoint();
1865 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1866 if (pSvgaR3State->pFuncsDX)
1867 {
1868 RT_NOREF(pCmd);
1869 pSvgaR3State->pFuncsDX->pfnDXBeginQuery(pThisCC->svga.p3dState);
1870 }
1871}
1872
1873
1874/* SVGA_3D_CMD_DX_END_QUERY 1170 */
1875static void vmsvga3dCmdDXEndQuery(PVGASTATECC pThisCC, SVGA3dCmdDXEndQuery const *pCmd)
1876{
1877ASMBreakpoint();
1878 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1879 if (pSvgaR3State->pFuncsDX)
1880 {
1881 RT_NOREF(pCmd);
1882 pSvgaR3State->pFuncsDX->pfnDXEndQuery(pThisCC->svga.p3dState);
1883 }
1884}
1885
1886
1887/* SVGA_3D_CMD_DX_READBACK_QUERY 1171 */
1888static void vmsvga3dCmdDXReadbackQuery(PVGASTATECC pThisCC, SVGA3dCmdDXReadbackQuery const *pCmd)
1889{
1890ASMBreakpoint();
1891 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1892 if (pSvgaR3State->pFuncsDX)
1893 {
1894 RT_NOREF(pCmd);
1895 pSvgaR3State->pFuncsDX->pfnDXReadbackQuery(pThisCC->svga.p3dState);
1896 }
1897}
1898
1899
1900/* SVGA_3D_CMD_DX_SET_PREDICATION 1172 */
1901static void vmsvga3dCmdDXSetPredication(PVGASTATECC pThisCC, SVGA3dCmdDXSetPredication const *pCmd)
1902{
1903ASMBreakpoint();
1904 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1905 if (pSvgaR3State->pFuncsDX)
1906 {
1907 RT_NOREF(pCmd);
1908 pSvgaR3State->pFuncsDX->pfnDXSetPredication(pThisCC->svga.p3dState);
1909 }
1910}
1911
1912
1913/* SVGA_3D_CMD_DX_SET_SOTARGETS 1173 */
1914static void vmsvga3dCmdDXSetSOTargets(PVGASTATECC pThisCC, SVGA3dCmdDXSetSOTargets const *pCmd)
1915{
1916ASMBreakpoint();
1917 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1918 if (pSvgaR3State->pFuncsDX)
1919 {
1920 RT_NOREF(pCmd);
1921 pSvgaR3State->pFuncsDX->pfnDXSetSOTargets(pThisCC->svga.p3dState);
1922 }
1923}
1924
1925
1926/* SVGA_3D_CMD_DX_SET_VIEWPORTS 1174 */
1927static void vmsvga3dCmdDXSetViewports(PVGASTATECC pThisCC, SVGA3dCmdDXSetViewports const *pCmd)
1928{
1929ASMBreakpoint();
1930 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1931 if (pSvgaR3State->pFuncsDX)
1932 {
1933 RT_NOREF(pCmd);
1934 pSvgaR3State->pFuncsDX->pfnDXSetViewports(pThisCC->svga.p3dState);
1935 }
1936}
1937
1938
1939/* SVGA_3D_CMD_DX_SET_SCISSORRECTS 1175 */
1940static void vmsvga3dCmdDXSetScissorRects(PVGASTATECC pThisCC, SVGA3dCmdDXSetScissorRects const *pCmd)
1941{
1942ASMBreakpoint();
1943 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1944 if (pSvgaR3State->pFuncsDX)
1945 {
1946 RT_NOREF(pCmd);
1947 pSvgaR3State->pFuncsDX->pfnDXSetScissorRects(pThisCC->svga.p3dState);
1948 }
1949}
1950
1951
1952/* SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW 1176 */
1953static void vmsvga3dCmdDXClearRenderTargetView(PVGASTATECC pThisCC, SVGA3dCmdDXClearRenderTargetView const *pCmd)
1954{
1955ASMBreakpoint();
1956 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1957 if (pSvgaR3State->pFuncsDX)
1958 {
1959 RT_NOREF(pCmd);
1960 pSvgaR3State->pFuncsDX->pfnDXClearRenderTargetView(pThisCC->svga.p3dState);
1961 }
1962}
1963
1964
1965/* SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW 1177 */
1966static void vmsvga3dCmdDXClearDepthStencilView(PVGASTATECC pThisCC, SVGA3dCmdDXClearDepthStencilView const *pCmd)
1967{
1968ASMBreakpoint();
1969 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1970 if (pSvgaR3State->pFuncsDX)
1971 {
1972 RT_NOREF(pCmd);
1973 pSvgaR3State->pFuncsDX->pfnDXClearDepthStencilView(pThisCC->svga.p3dState);
1974 }
1975}
1976
1977
1978/* SVGA_3D_CMD_DX_PRED_COPY_REGION 1178 */
1979static void vmsvga3dCmdDXPredCopyRegion(PVGASTATECC pThisCC, SVGA3dCmdDXPredCopyRegion const *pCmd)
1980{
1981ASMBreakpoint();
1982 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1983 if (pSvgaR3State->pFuncsDX)
1984 {
1985 RT_NOREF(pCmd);
1986 pSvgaR3State->pFuncsDX->pfnDXPredCopyRegion(pThisCC->svga.p3dState);
1987 }
1988}
1989
1990
1991/* SVGA_3D_CMD_DX_PRED_COPY 1179 */
1992static void vmsvga3dCmdDXPredCopy(PVGASTATECC pThisCC, SVGA3dCmdDXPredCopy const *pCmd)
1993{
1994ASMBreakpoint();
1995 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1996 if (pSvgaR3State->pFuncsDX)
1997 {
1998 RT_NOREF(pCmd);
1999 pSvgaR3State->pFuncsDX->pfnDXPredCopy(pThisCC->svga.p3dState);
2000 }
2001}
2002
2003
2004/* SVGA_3D_CMD_DX_STRETCHBLT 1180 */
2005static void vmsvga3dCmdDXStretchBlt(PVGASTATECC pThisCC, SVGA3dCmdDXStretchBlt const *pCmd)
2006{
2007ASMBreakpoint();
2008 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2009 if (pSvgaR3State->pFuncsDX)
2010 {
2011 RT_NOREF(pCmd);
2012 pSvgaR3State->pFuncsDX->pfnDXStretchBlt(pThisCC->svga.p3dState);
2013 }
2014}
2015
2016
2017/* SVGA_3D_CMD_DX_GENMIPS 1181 */
2018static void vmsvga3dCmdDXGenMips(PVGASTATECC pThisCC, SVGA3dCmdDXGenMips const *pCmd)
2019{
2020ASMBreakpoint();
2021 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2022 if (pSvgaR3State->pFuncsDX)
2023 {
2024 RT_NOREF(pCmd);
2025 pSvgaR3State->pFuncsDX->pfnDXGenMips(pThisCC->svga.p3dState);
2026 }
2027}
2028
2029
2030/* SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE 1182 */
2031static void vmsvga3dCmdDXUpdateSubResource(PVGASTATECC pThisCC, SVGA3dCmdDXUpdateSubResource const *pCmd)
2032{
2033ASMBreakpoint();
2034 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2035 if (pSvgaR3State->pFuncsDX)
2036 {
2037 RT_NOREF(pCmd);
2038 pSvgaR3State->pFuncsDX->pfnDXUpdateSubResource(pThisCC->svga.p3dState);
2039 }
2040}
2041
2042
2043/* SVGA_3D_CMD_DX_READBACK_SUBRESOURCE 1183 */
2044static void vmsvga3dCmdDXReadbackSubResource(PVGASTATECC pThisCC, SVGA3dCmdDXReadbackSubResource const *pCmd)
2045{
2046ASMBreakpoint();
2047 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2048 if (pSvgaR3State->pFuncsDX)
2049 {
2050 RT_NOREF(pCmd);
2051 pSvgaR3State->pFuncsDX->pfnDXReadbackSubResource(pThisCC->svga.p3dState);
2052 }
2053}
2054
2055
2056/* SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE 1184 */
2057static void vmsvga3dCmdDXInvalidateSubResource(PVGASTATECC pThisCC, SVGA3dCmdDXInvalidateSubResource const *pCmd)
2058{
2059ASMBreakpoint();
2060 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2061 if (pSvgaR3State->pFuncsDX)
2062 {
2063 RT_NOREF(pCmd);
2064 pSvgaR3State->pFuncsDX->pfnDXInvalidateSubResource(pThisCC->svga.p3dState);
2065 }
2066}
2067
2068
2069/* SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW 1185 */
2070static void vmsvga3dCmdDXDefineShaderResourceView(PVGASTATECC pThisCC, SVGA3dCmdDXDefineShaderResourceView const *pCmd)
2071{
2072ASMBreakpoint();
2073 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2074 if (pSvgaR3State->pFuncsDX)
2075 {
2076 RT_NOREF(pCmd);
2077 pSvgaR3State->pFuncsDX->pfnDXDefineShaderResourceView(pThisCC->svga.p3dState);
2078 }
2079}
2080
2081
2082/* SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW 1186 */
2083static void vmsvga3dCmdDXDestroyShaderResourceView(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyShaderResourceView const *pCmd)
2084{
2085ASMBreakpoint();
2086 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2087 if (pSvgaR3State->pFuncsDX)
2088 {
2089 RT_NOREF(pCmd);
2090 pSvgaR3State->pFuncsDX->pfnDXDestroyShaderResourceView(pThisCC->svga.p3dState);
2091 }
2092}
2093
2094
2095/* SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW 1187 */
2096static void vmsvga3dCmdDXDefineRenderTargetView(PVGASTATECC pThisCC, SVGA3dCmdDXDefineRenderTargetView const *pCmd)
2097{
2098ASMBreakpoint();
2099 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2100 if (pSvgaR3State->pFuncsDX)
2101 {
2102 RT_NOREF(pCmd);
2103 pSvgaR3State->pFuncsDX->pfnDXDefineRenderTargetView(pThisCC->svga.p3dState);
2104 }
2105}
2106
2107
2108/* SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW 1188 */
2109static void vmsvga3dCmdDXDestroyRenderTargetView(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyRenderTargetView const *pCmd)
2110{
2111ASMBreakpoint();
2112 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2113 if (pSvgaR3State->pFuncsDX)
2114 {
2115 RT_NOREF(pCmd);
2116 pSvgaR3State->pFuncsDX->pfnDXDestroyRenderTargetView(pThisCC->svga.p3dState);
2117 }
2118}
2119
2120
2121/* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW 1189 */
2122static void vmsvga3dCmdDXDefineDepthStencilView(PVGASTATECC pThisCC, SVGA3dCmdDXDefineDepthStencilView const *pCmd)
2123{
2124ASMBreakpoint();
2125 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2126 if (pSvgaR3State->pFuncsDX)
2127 {
2128 RT_NOREF(pCmd);
2129 pSvgaR3State->pFuncsDX->pfnDXDefineDepthStencilView(pThisCC->svga.p3dState);
2130 }
2131}
2132
2133
2134/* SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW 1190 */
2135static void vmsvga3dCmdDXDestroyDepthStencilView(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyDepthStencilView const *pCmd)
2136{
2137ASMBreakpoint();
2138 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2139 if (pSvgaR3State->pFuncsDX)
2140 {
2141 RT_NOREF(pCmd);
2142 pSvgaR3State->pFuncsDX->pfnDXDestroyDepthStencilView(pThisCC->svga.p3dState);
2143 }
2144}
2145
2146
2147/* SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT 1191 */
2148static void vmsvga3dCmdDXDefineElementLayout(PVGASTATECC pThisCC, SVGA3dCmdDXDefineElementLayout const *pCmd)
2149{
2150ASMBreakpoint();
2151 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2152 if (pSvgaR3State->pFuncsDX)
2153 {
2154 RT_NOREF(pCmd);
2155 pSvgaR3State->pFuncsDX->pfnDXDefineElementLayout(pThisCC->svga.p3dState);
2156 }
2157}
2158
2159
2160/* SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT 1192 */
2161static void vmsvga3dCmdDXDestroyElementLayout(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyElementLayout const *pCmd)
2162{
2163ASMBreakpoint();
2164 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2165 if (pSvgaR3State->pFuncsDX)
2166 {
2167 RT_NOREF(pCmd);
2168 pSvgaR3State->pFuncsDX->pfnDXDestroyElementLayout(pThisCC->svga.p3dState);
2169 }
2170}
2171
2172
2173/* SVGA_3D_CMD_DX_DEFINE_BLEND_STATE 1193 */
2174static void vmsvga3dCmdDXDefineBlendState(PVGASTATECC pThisCC, SVGA3dCmdDXDefineBlendState const *pCmd)
2175{
2176ASMBreakpoint();
2177 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2178 if (pSvgaR3State->pFuncsDX)
2179 {
2180 RT_NOREF(pCmd);
2181 pSvgaR3State->pFuncsDX->pfnDXDefineBlendState(pThisCC->svga.p3dState);
2182 }
2183}
2184
2185
2186/* SVGA_3D_CMD_DX_DESTROY_BLEND_STATE 1194 */
2187static void vmsvga3dCmdDXDestroyBlendState(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyBlendState const *pCmd)
2188{
2189ASMBreakpoint();
2190 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2191 if (pSvgaR3State->pFuncsDX)
2192 {
2193 RT_NOREF(pCmd);
2194 pSvgaR3State->pFuncsDX->pfnDXDestroyBlendState(pThisCC->svga.p3dState);
2195 }
2196}
2197
2198
2199/* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE 1195 */
2200static void vmsvga3dCmdDXDefineDepthStencilState(PVGASTATECC pThisCC, SVGA3dCmdDXDefineDepthStencilState const *pCmd)
2201{
2202ASMBreakpoint();
2203 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2204 if (pSvgaR3State->pFuncsDX)
2205 {
2206 RT_NOREF(pCmd);
2207 pSvgaR3State->pFuncsDX->pfnDXDefineDepthStencilState(pThisCC->svga.p3dState);
2208 }
2209}
2210
2211
2212/* SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE 1196 */
2213static void vmsvga3dCmdDXDestroyDepthStencilState(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyDepthStencilState const *pCmd)
2214{
2215ASMBreakpoint();
2216 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2217 if (pSvgaR3State->pFuncsDX)
2218 {
2219 RT_NOREF(pCmd);
2220 pSvgaR3State->pFuncsDX->pfnDXDestroyDepthStencilState(pThisCC->svga.p3dState);
2221 }
2222}
2223
2224
2225/* SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE 1197 */
2226static void vmsvga3dCmdDXDefineRasterizerState(PVGASTATECC pThisCC, SVGA3dCmdDXDefineRasterizerState const *pCmd)
2227{
2228ASMBreakpoint();
2229 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2230 if (pSvgaR3State->pFuncsDX)
2231 {
2232 RT_NOREF(pCmd);
2233 pSvgaR3State->pFuncsDX->pfnDXDefineRasterizerState(pThisCC->svga.p3dState);
2234 }
2235}
2236
2237
2238/* SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE 1198 */
2239static void vmsvga3dCmdDXDestroyRasterizerState(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyRasterizerState const *pCmd)
2240{
2241ASMBreakpoint();
2242 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2243 if (pSvgaR3State->pFuncsDX)
2244 {
2245 RT_NOREF(pCmd);
2246 pSvgaR3State->pFuncsDX->pfnDXDestroyRasterizerState(pThisCC->svga.p3dState);
2247 }
2248}
2249
2250
2251/* SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE 1199 */
2252static void vmsvga3dCmdDXDefineSamplerState(PVGASTATECC pThisCC, SVGA3dCmdDXDefineSamplerState const *pCmd)
2253{
2254ASMBreakpoint();
2255 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2256 if (pSvgaR3State->pFuncsDX)
2257 {
2258 RT_NOREF(pCmd);
2259 pSvgaR3State->pFuncsDX->pfnDXDefineSamplerState(pThisCC->svga.p3dState);
2260 }
2261}
2262
2263
2264/* SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE 1200 */
2265static void vmsvga3dCmdDXDestroySamplerState(PVGASTATECC pThisCC, SVGA3dCmdDXDestroySamplerState const *pCmd)
2266{
2267ASMBreakpoint();
2268 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2269 if (pSvgaR3State->pFuncsDX)
2270 {
2271 RT_NOREF(pCmd);
2272 pSvgaR3State->pFuncsDX->pfnDXDestroySamplerState(pThisCC->svga.p3dState);
2273 }
2274}
2275
2276
2277/* SVGA_3D_CMD_DX_DEFINE_SHADER 1201 */
2278static void vmsvga3dCmdDXDefineShader(PVGASTATECC pThisCC, SVGA3dCmdDXDefineShader const *pCmd)
2279{
2280ASMBreakpoint();
2281 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2282 if (pSvgaR3State->pFuncsDX)
2283 {
2284 RT_NOREF(pCmd);
2285 pSvgaR3State->pFuncsDX->pfnDXDefineShader(pThisCC->svga.p3dState);
2286 }
2287}
2288
2289
2290/* SVGA_3D_CMD_DX_DESTROY_SHADER 1202 */
2291static void vmsvga3dCmdDXDestroyShader(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyShader const *pCmd)
2292{
2293ASMBreakpoint();
2294 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2295 if (pSvgaR3State->pFuncsDX)
2296 {
2297 RT_NOREF(pCmd);
2298 pSvgaR3State->pFuncsDX->pfnDXDestroyShader(pThisCC->svga.p3dState);
2299 }
2300}
2301
2302
2303/* SVGA_3D_CMD_DX_BIND_SHADER 1203 */
2304static void vmsvga3dCmdDXBindShader(PVGASTATECC pThisCC, SVGA3dCmdDXBindShader const *pCmd)
2305{
2306ASMBreakpoint();
2307 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2308 if (pSvgaR3State->pFuncsDX)
2309 {
2310 RT_NOREF(pCmd);
2311 pSvgaR3State->pFuncsDX->pfnDXBindShader(pThisCC->svga.p3dState);
2312 }
2313}
2314
2315
2316/* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT 1204 */
2317static void vmsvga3dCmdDXDefineStreamOutput(PVGASTATECC pThisCC, SVGA3dCmdDXDefineStreamOutput const *pCmd)
2318{
2319ASMBreakpoint();
2320 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2321 if (pSvgaR3State->pFuncsDX)
2322 {
2323 RT_NOREF(pCmd);
2324 pSvgaR3State->pFuncsDX->pfnDXDefineStreamOutput(pThisCC->svga.p3dState);
2325 }
2326}
2327
2328
2329/* SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT 1205 */
2330static void vmsvga3dCmdDXDestroyStreamOutput(PVGASTATECC pThisCC, SVGA3dCmdDXDestroyStreamOutput const *pCmd)
2331{
2332ASMBreakpoint();
2333 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2334 if (pSvgaR3State->pFuncsDX)
2335 {
2336 RT_NOREF(pCmd);
2337 pSvgaR3State->pFuncsDX->pfnDXDestroyStreamOutput(pThisCC->svga.p3dState);
2338 }
2339}
2340
2341
2342/* SVGA_3D_CMD_DX_SET_STREAMOUTPUT 1206 */
2343static void vmsvga3dCmdDXSetStreamOutput(PVGASTATECC pThisCC, SVGA3dCmdDXSetStreamOutput const *pCmd)
2344{
2345ASMBreakpoint();
2346 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2347 if (pSvgaR3State->pFuncsDX)
2348 {
2349 RT_NOREF(pCmd);
2350 pSvgaR3State->pFuncsDX->pfnDXSetStreamOutput(pThisCC->svga.p3dState);
2351 }
2352}
2353
2354
2355/* SVGA_3D_CMD_DX_SET_COTABLE 1207 */
2356static void vmsvga3dCmdDXSetCOTable(PVGASTATECC pThisCC, SVGA3dCmdDXSetCOTable const *pCmd)
2357{
2358ASMBreakpoint();
2359 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2360 if (pSvgaR3State->pFuncsDX)
2361 {
2362 RT_NOREF(pCmd);
2363 pSvgaR3State->pFuncsDX->pfnDXSetCOTable(pThisCC->svga.p3dState);
2364 }
2365}
2366
2367
2368/* SVGA_3D_CMD_DX_READBACK_COTABLE 1208 */
2369static void vmsvga3dCmdDXReadbackCOTable(PVGASTATECC pThisCC, SVGA3dCmdDXReadbackCOTable const *pCmd)
2370{
2371ASMBreakpoint();
2372 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2373 if (pSvgaR3State->pFuncsDX)
2374 {
2375 RT_NOREF(pCmd);
2376 pSvgaR3State->pFuncsDX->pfnDXReadbackCOTable(pThisCC->svga.p3dState);
2377 }
2378}
2379
2380
2381/* SVGA_3D_CMD_DX_BUFFER_COPY 1209 */
2382static void vmsvga3dCmdDXBufferCopy(PVGASTATECC pThisCC, SVGA3dCmdDXBufferCopy const *pCmd)
2383{
2384ASMBreakpoint();
2385 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2386 if (pSvgaR3State->pFuncsDX)
2387 {
2388 RT_NOREF(pCmd);
2389 pSvgaR3State->pFuncsDX->pfnDXBufferCopy(pThisCC->svga.p3dState);
2390 }
2391}
2392
2393
2394/* SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER 1210 */
2395static void vmsvga3dCmdDXTransferFromBuffer(PVGASTATECC pThisCC, SVGA3dCmdDXTransferFromBuffer const *pCmd)
2396{
2397ASMBreakpoint();
2398 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2399 if (pSvgaR3State->pFuncsDX)
2400 {
2401 RT_NOREF(pCmd);
2402 pSvgaR3State->pFuncsDX->pfnDXTransferFromBuffer(pThisCC->svga.p3dState);
2403 }
2404}
2405
2406
2407/* SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK 1211 */
2408static void vmsvga3dCmdDXSurfaceCopyAndReadback(PVGASTATECC pThisCC, SVGA3dCmdDXSurfaceCopyAndReadback const *pCmd)
2409{
2410ASMBreakpoint();
2411 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2412 if (pSvgaR3State->pFuncsDX)
2413 {
2414 RT_NOREF(pCmd);
2415 pSvgaR3State->pFuncsDX->pfnDXSurfaceCopyAndReadback(pThisCC->svga.p3dState);
2416 }
2417}
2418
2419
2420/* SVGA_3D_CMD_DX_MOVE_QUERY 1212 */
2421static void vmsvga3dCmdDXMoveQuery(PVGASTATECC pThisCC, SVGA3dCmdDXMoveQuery const *pCmd)
2422{
2423ASMBreakpoint();
2424 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2425 if (pSvgaR3State->pFuncsDX)
2426 {
2427 RT_NOREF(pCmd);
2428 pSvgaR3State->pFuncsDX->pfnDXMoveQuery(pThisCC->svga.p3dState);
2429 }
2430}
2431
2432
2433/* SVGA_3D_CMD_DX_BIND_ALL_QUERY 1213 */
2434static void vmsvga3dCmdDXBindAllQuery(PVGASTATECC pThisCC, SVGA3dCmdDXBindAllQuery const *pCmd)
2435{
2436ASMBreakpoint();
2437 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2438 if (pSvgaR3State->pFuncsDX)
2439 {
2440 RT_NOREF(pCmd);
2441 pSvgaR3State->pFuncsDX->pfnDXBindAllQuery(pThisCC->svga.p3dState);
2442 }
2443}
2444
2445
2446/* SVGA_3D_CMD_DX_READBACK_ALL_QUERY 1214 */
2447static void vmsvga3dCmdDXReadbackAllQuery(PVGASTATECC pThisCC, SVGA3dCmdDXReadbackAllQuery const *pCmd)
2448{
2449ASMBreakpoint();
2450 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2451 if (pSvgaR3State->pFuncsDX)
2452 {
2453 RT_NOREF(pCmd);
2454 pSvgaR3State->pFuncsDX->pfnDXReadbackAllQuery(pThisCC->svga.p3dState);
2455 }
2456}
2457
2458
2459/* SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER 1215 */
2460static void vmsvga3dCmdDXPredTransferFromBuffer(PVGASTATECC pThisCC, SVGA3dCmdDXPredTransferFromBuffer const *pCmd)
2461{
2462ASMBreakpoint();
2463 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2464 if (pSvgaR3State->pFuncsDX)
2465 {
2466 RT_NOREF(pCmd);
2467 pSvgaR3State->pFuncsDX->pfnDXPredTransferFromBuffer(pThisCC->svga.p3dState);
2468 }
2469}
2470
2471
2472/* SVGA_3D_CMD_DX_MOB_FENCE_64 1216 */
2473static void vmsvga3dCmdDXMobFence64(PVGASTATECC pThisCC, SVGA3dCmdDXMobFence64 const *pCmd)
2474{
2475ASMBreakpoint();
2476 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2477 if (pSvgaR3State->pFuncsDX)
2478 {
2479 RT_NOREF(pCmd);
2480 pSvgaR3State->pFuncsDX->pfnDXMobFence64(pThisCC->svga.p3dState);
2481 }
2482}
2483
2484
2485/* SVGA_3D_CMD_DX_BIND_ALL_SHADER 1217 */
2486static void vmsvga3dCmdDXBindAllShader(PVGASTATECC pThisCC, SVGA3dCmdDXBindAllShader const *pCmd)
2487{
2488ASMBreakpoint();
2489 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2490 if (pSvgaR3State->pFuncsDX)
2491 {
2492 RT_NOREF(pCmd);
2493 pSvgaR3State->pFuncsDX->pfnDXBindAllShader(pThisCC->svga.p3dState);
2494 }
2495}
2496
2497
2498/* SVGA_3D_CMD_DX_HINT 1218 */
2499static void vmsvga3dCmdDXHint(PVGASTATECC pThisCC, SVGA3dCmdDXHint const *pCmd)
2500{
2501ASMBreakpoint();
2502 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2503 if (pSvgaR3State->pFuncsDX)
2504 {
2505 RT_NOREF(pCmd);
2506 pSvgaR3State->pFuncsDX->pfnDXHint(pThisCC->svga.p3dState);
2507 }
2508}
2509
2510
2511/* SVGA_3D_CMD_DX_BUFFER_UPDATE 1219 */
2512static void vmsvga3dCmdDXBufferUpdate(PVGASTATECC pThisCC, SVGA3dCmdDXBufferUpdate const *pCmd)
2513{
2514ASMBreakpoint();
2515 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2516 if (pSvgaR3State->pFuncsDX)
2517 {
2518 RT_NOREF(pCmd);
2519 pSvgaR3State->pFuncsDX->pfnDXBufferUpdate(pThisCC->svga.p3dState);
2520 }
2521}
2522
2523
2524/* SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET 1220 */
2525static void vmsvga3dCmdDXSetVSConstantBufferOffset(PVGASTATECC pThisCC, SVGA3dCmdDXSetVSConstantBufferOffset const *pCmd)
2526{
2527ASMBreakpoint();
2528 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2529 if (pSvgaR3State->pFuncsDX)
2530 {
2531 RT_NOREF(pCmd);
2532 pSvgaR3State->pFuncsDX->pfnDXSetVSConstantBufferOffset(pThisCC->svga.p3dState);
2533 }
2534}
2535
2536
2537/* SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET 1221 */
2538static void vmsvga3dCmdDXSetPSConstantBufferOffset(PVGASTATECC pThisCC, SVGA3dCmdDXSetPSConstantBufferOffset const *pCmd)
2539{
2540ASMBreakpoint();
2541 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2542 if (pSvgaR3State->pFuncsDX)
2543 {
2544 RT_NOREF(pCmd);
2545 pSvgaR3State->pFuncsDX->pfnDXSetPSConstantBufferOffset(pThisCC->svga.p3dState);
2546 }
2547}
2548
2549
2550/* SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET 1222 */
2551static void vmsvga3dCmdDXSetGSConstantBufferOffset(PVGASTATECC pThisCC, SVGA3dCmdDXSetGSConstantBufferOffset const *pCmd)
2552{
2553ASMBreakpoint();
2554 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2555 if (pSvgaR3State->pFuncsDX)
2556 {
2557 RT_NOREF(pCmd);
2558 pSvgaR3State->pFuncsDX->pfnDXSetGSConstantBufferOffset(pThisCC->svga.p3dState);
2559 }
2560}
2561
2562
2563/* SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER 1226 */
2564static void vmsvga3dCmdDXCondBindAllShader(PVGASTATECC pThisCC, SVGA3dCmdDXCondBindAllShader const *pCmd)
2565{
2566ASMBreakpoint();
2567 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2568 if (pSvgaR3State->pFuncsDX)
2569 {
2570 RT_NOREF(pCmd);
2571 pSvgaR3State->pFuncsDX->pfnDXCondBindAllShader(pThisCC->svga.p3dState);
2572 }
2573}
2574
2575
2576/** @def VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK
2577 * Check that the 3D command has at least a_cbMin of payload bytes after the
2578 * header. Will break out of the switch if it doesn't.
2579 */
2580# define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \
2581 if (1) { \
2582 AssertMsgBreak(cbCmd >= (a_cbMin), ("size=%#x a_cbMin=%#zx\n", cbCmd, (size_t)(a_cbMin))); \
2583 RT_UNTRUSTED_VALIDATED_FENCE(); \
2584 } else do {} while (0)
2585
2586# define VMSVGA_3D_CMD_NOTIMPL() \
2587 if (1) { \
2588 AssertMsgFailed(("Not implemented %d %s\n", enmCmdId, vmsvgaR3FifoCmdToString(enmCmdId))); \
2589 } else do {} while (0)
2590
2591/** SVGA_3D_CMD_* handler.
2592 * This function parses the command and calls the corresponding command handler.
2593 *
2594 * @param pThis The shared VGA/VMSVGA state.
2595 * @param pThisCC The VGA/VMSVGA state for the current context.
2596 * @param enmCmdId SVGA_3D_CMD_* command identifier.
2597 * @param cbCmd Size of the command in bytes.
2598 * @param pvCmd Pointer to the command.
2599 * @returns VBox status code if an error was detected parsing a command.
2600 */
2601int vmsvgaR3Process3dCmd(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifo3dCmdId enmCmdId, uint32_t cbCmd, void const *pvCmd)
2602{
2603 if (enmCmdId > SVGA_3D_CMD_MAX)
2604 {
2605 LogRelMax(16, ("VMSVGA: unsupported 3D command %d\n", enmCmdId));
2606 ASSERT_GUEST_FAILED_RETURN(VERR_NOT_IMPLEMENTED);
2607 }
2608
2609 int rcParse = VINF_SUCCESS;
2610 PVMSVGAR3STATE pSvgaR3State = pThisCC->svga.pSvgaR3State;
2611
2612 switch (enmCmdId)
2613 {
2614 case SVGA_3D_CMD_SURFACE_DEFINE:
2615 {
2616 SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)pvCmd;
2617 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2618 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefine);
2619
2620 SVGA3dCmdDefineSurface_v2 cmd;
2621 cmd.sid = pCmd->sid;
2622 cmd.surfaceFlags = pCmd->surfaceFlags;
2623 cmd.format = pCmd->format;
2624 memcpy(cmd.face, pCmd->face, sizeof(cmd.face));
2625 cmd.multisampleCount = 0;
2626 cmd.autogenFilter = SVGA3D_TEX_FILTER_NONE;
2627
2628 uint32_t const cMipLevelSizes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
2629 vmsvga3dCmdDefineSurface(pThisCC, &cmd, cMipLevelSizes, (SVGA3dSize *)(pCmd + 1));
2630# ifdef DEBUG_GMR_ACCESS
2631 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis);
2632# endif
2633 break;
2634 }
2635
2636 case SVGA_3D_CMD_SURFACE_DEFINE_V2:
2637 {
2638 SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)pvCmd;
2639 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2640 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefineV2);
2641
2642 uint32_t const cMipLevelSizes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
2643 vmsvga3dCmdDefineSurface(pThisCC, pCmd, cMipLevelSizes, (SVGA3dSize *)(pCmd + 1));
2644# ifdef DEBUG_GMR_ACCESS
2645 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis);
2646# endif
2647 break;
2648 }
2649
2650 case SVGA_3D_CMD_SURFACE_DESTROY:
2651 {
2652 SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)pvCmd;
2653 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2654 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDestroy);
2655
2656 vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid);
2657 break;
2658 }
2659
2660 case SVGA_3D_CMD_SURFACE_COPY:
2661 {
2662 SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)pvCmd;
2663 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2664 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceCopy);
2665
2666 uint32_t const cCopyBoxes = (cbCmd - sizeof(pCmd)) / sizeof(SVGA3dCopyBox);
2667 vmsvga3dSurfaceCopy(pThisCC, pCmd->dest, pCmd->src, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
2668 break;
2669 }
2670
2671 case SVGA_3D_CMD_SURFACE_STRETCHBLT:
2672 {
2673 SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)pvCmd;
2674 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2675 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceStretchBlt);
2676
2677 vmsvga3dSurfaceStretchBlt(pThis, pThisCC, &pCmd->dest, &pCmd->boxDest,
2678 &pCmd->src, &pCmd->boxSrc, pCmd->mode);
2679 break;
2680 }
2681
2682 case SVGA_3D_CMD_SURFACE_DMA:
2683 {
2684 SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)pvCmd;
2685 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2686 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDma);
2687
2688 uint64_t u64NanoTS = 0;
2689 if (LogRelIs3Enabled())
2690 u64NanoTS = RTTimeNanoTS();
2691 uint32_t const cCopyBoxes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox);
2692 STAM_PROFILE_START(&pSvgaR3State->StatR3Cmd3dSurfaceDmaProf, a);
2693 vmsvga3dSurfaceDMA(pThis, pThisCC, pCmd->guest, pCmd->host, pCmd->transfer,
2694 cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
2695 STAM_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dSurfaceDmaProf, a);
2696 if (LogRelIs3Enabled())
2697 {
2698 if (cCopyBoxes)
2699 {
2700 SVGA3dCopyBox *pFirstBox = (SVGA3dCopyBox *)(pCmd + 1);
2701 LogRel3(("VMSVGA: SURFACE_DMA: %d us %d boxes %d,%d %dx%d%s\n",
2702 (RTTimeNanoTS() - u64NanoTS) / 1000ULL, cCopyBoxes,
2703 pFirstBox->x, pFirstBox->y, pFirstBox->w, pFirstBox->h,
2704 pCmd->transfer == SVGA3D_READ_HOST_VRAM ? " readback!!!" : ""));
2705 }
2706 }
2707 break;
2708 }
2709
2710 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
2711 {
2712 SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)pvCmd;
2713 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2714 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceScreen);
2715
2716 static uint64_t u64FrameStartNanoTS = 0;
2717 static uint64_t u64ElapsedPerSecNano = 0;
2718 static int cFrames = 0;
2719 uint64_t u64NanoTS = 0;
2720 if (LogRelIs3Enabled())
2721 u64NanoTS = RTTimeNanoTS();
2722 uint32_t const cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGASignedRect);
2723 STAM_REL_PROFILE_START(&pSvgaR3State->StatR3Cmd3dBlitSurfaceToScreenProf, a);
2724 vmsvga3dSurfaceBlitToScreen(pThis, pThisCC, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage,
2725 pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1));
2726 STAM_REL_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dBlitSurfaceToScreenProf, a);
2727 if (LogRelIs3Enabled())
2728 {
2729 uint64_t u64ElapsedNano = RTTimeNanoTS() - u64NanoTS;
2730 u64ElapsedPerSecNano += u64ElapsedNano;
2731
2732 SVGASignedRect *pFirstRect = cRects ? (SVGASignedRect *)(pCmd + 1) : &pCmd->destRect;
2733 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: %d us %d rects %d,%d %dx%d\n",
2734 (u64ElapsedNano) / 1000ULL, cRects,
2735 pFirstRect->left, pFirstRect->top,
2736 pFirstRect->right - pFirstRect->left, pFirstRect->bottom - pFirstRect->top));
2737
2738 ++cFrames;
2739 if (u64NanoTS - u64FrameStartNanoTS >= UINT64_C(1000000000))
2740 {
2741 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: FPS %d, elapsed %llu us\n",
2742 cFrames, u64ElapsedPerSecNano / 1000ULL));
2743 u64FrameStartNanoTS = u64NanoTS;
2744 cFrames = 0;
2745 u64ElapsedPerSecNano = 0;
2746 }
2747 }
2748 break;
2749 }
2750
2751 case SVGA_3D_CMD_CONTEXT_DEFINE:
2752 {
2753 SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)pvCmd;
2754 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2755 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dContextDefine);
2756
2757 vmsvga3dContextDefine(pThisCC, pCmd->cid);
2758 break;
2759 }
2760
2761 case SVGA_3D_CMD_CONTEXT_DESTROY:
2762 {
2763 SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)pvCmd;
2764 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2765 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dContextDestroy);
2766
2767 vmsvga3dContextDestroy(pThisCC, pCmd->cid);
2768 break;
2769 }
2770
2771 case SVGA_3D_CMD_SETTRANSFORM:
2772 {
2773 SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)pvCmd;
2774 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2775 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetTransform);
2776
2777 vmsvga3dSetTransform(pThisCC, pCmd->cid, pCmd->type, pCmd->matrix);
2778 break;
2779 }
2780
2781 case SVGA_3D_CMD_SETZRANGE:
2782 {
2783 SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)pvCmd;
2784 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2785 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetZRange);
2786
2787 vmsvga3dSetZRange(pThisCC, pCmd->cid, pCmd->zRange);
2788 break;
2789 }
2790
2791 case SVGA_3D_CMD_SETRENDERSTATE:
2792 {
2793 SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)pvCmd;
2794 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2795 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetRenderState);
2796
2797 uint32_t const cRenderStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRenderState);
2798 vmsvga3dSetRenderState(pThisCC, pCmd->cid, cRenderStates, (SVGA3dRenderState *)(pCmd + 1));
2799 break;
2800 }
2801
2802 case SVGA_3D_CMD_SETRENDERTARGET:
2803 {
2804 SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)pvCmd;
2805 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2806 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetRenderTarget);
2807
2808 vmsvga3dSetRenderTarget(pThisCC, pCmd->cid, pCmd->type, pCmd->target);
2809 break;
2810 }
2811
2812 case SVGA_3D_CMD_SETTEXTURESTATE:
2813 {
2814 SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)pvCmd;
2815 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2816 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetTextureState);
2817
2818 uint32_t const cTextureStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dTextureState);
2819 vmsvga3dSetTextureState(pThisCC, pCmd->cid, cTextureStates, (SVGA3dTextureState *)(pCmd + 1));
2820 break;
2821 }
2822
2823 case SVGA_3D_CMD_SETMATERIAL:
2824 {
2825 SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)pvCmd;
2826 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2827 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetMaterial);
2828
2829 vmsvga3dSetMaterial(pThisCC, pCmd->cid, pCmd->face, &pCmd->material);
2830 break;
2831 }
2832
2833 case SVGA_3D_CMD_SETLIGHTDATA:
2834 {
2835 SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)pvCmd;
2836 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2837 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetLightData);
2838
2839 vmsvga3dSetLightData(pThisCC, pCmd->cid, pCmd->index, &pCmd->data);
2840 break;
2841 }
2842
2843 case SVGA_3D_CMD_SETLIGHTENABLED:
2844 {
2845 SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)pvCmd;
2846 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2847 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetLightEnable);
2848
2849 vmsvga3dSetLightEnabled(pThisCC, pCmd->cid, pCmd->index, pCmd->enabled);
2850 break;
2851 }
2852
2853 case SVGA_3D_CMD_SETVIEWPORT:
2854 {
2855 SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)pvCmd;
2856 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2857 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetViewPort);
2858
2859 vmsvga3dSetViewPort(pThisCC, pCmd->cid, &pCmd->rect);
2860 break;
2861 }
2862
2863 case SVGA_3D_CMD_SETCLIPPLANE:
2864 {
2865 SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)pvCmd;
2866 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2867 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetClipPlane);
2868
2869 vmsvga3dSetClipPlane(pThisCC, pCmd->cid, pCmd->index, pCmd->plane);
2870 break;
2871 }
2872
2873 case SVGA_3D_CMD_CLEAR:
2874 {
2875 SVGA3dCmdClear *pCmd = (SVGA3dCmdClear *)pvCmd;
2876 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2877 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dClear);
2878
2879 uint32_t const cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRect);
2880 vmsvga3dCommandClear(pThisCC, pCmd->cid, pCmd->clearFlag, pCmd->color, pCmd->depth, pCmd->stencil, cRects, (SVGA3dRect *)(pCmd + 1));
2881 break;
2882 }
2883
2884 case SVGA_3D_CMD_PRESENT:
2885 case SVGA_3D_CMD_PRESENT_READBACK: /** @todo SVGA_3D_CMD_PRESENT_READBACK isn't quite the same as present... */
2886 {
2887 SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)pvCmd;
2888 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2889 if (enmCmdId == SVGA_3D_CMD_PRESENT)
2890 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dPresent);
2891 else
2892 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dPresentReadBack);
2893
2894 uint32_t const cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyRect);
2895 STAM_PROFILE_START(&pSvgaR3State->StatR3Cmd3dPresentProf, a);
2896 vmsvga3dCommandPresent(pThis, pThisCC, pCmd->sid, cRects, (SVGA3dCopyRect *)(pCmd + 1));
2897 STAM_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dPresentProf, a);
2898 break;
2899 }
2900
2901 case SVGA_3D_CMD_SHADER_DEFINE:
2902 {
2903 SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)pvCmd;
2904 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2905 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dShaderDefine);
2906
2907 uint32_t const cbData = (cbCmd - sizeof(*pCmd));
2908 vmsvga3dShaderDefine(pThisCC, pCmd->cid, pCmd->shid, pCmd->type, cbData, (uint32_t *)(pCmd + 1));
2909 break;
2910 }
2911
2912 case SVGA_3D_CMD_SHADER_DESTROY:
2913 {
2914 SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)pvCmd;
2915 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2916 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dShaderDestroy);
2917
2918 vmsvga3dShaderDestroy(pThisCC, pCmd->cid, pCmd->shid, pCmd->type);
2919 break;
2920 }
2921
2922 case SVGA_3D_CMD_SET_SHADER:
2923 {
2924 SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)pvCmd;
2925 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2926 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetShader);
2927
2928 vmsvga3dShaderSet(pThisCC, NULL, pCmd->cid, pCmd->type, pCmd->shid);
2929 break;
2930 }
2931
2932 case SVGA_3D_CMD_SET_SHADER_CONST:
2933 {
2934 SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)pvCmd;
2935 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2936 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetShaderConst);
2937
2938 uint32_t const cRegisters = (cbCmd - sizeof(*pCmd)) / sizeof(pCmd->values) + 1;
2939 vmsvga3dShaderSetConst(pThisCC, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values);
2940 break;
2941 }
2942
2943 case SVGA_3D_CMD_DRAW_PRIMITIVES:
2944 {
2945 SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)pvCmd;
2946 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2947 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dDrawPrimitives);
2948
2949 ASSERT_GUEST_STMT_BREAK(pCmd->numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES, rcParse = VERR_INVALID_PARAMETER);
2950 ASSERT_GUEST_STMT_BREAK(pCmd->numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS, rcParse = VERR_INVALID_PARAMETER);
2951 uint32_t const cbRangesAndVertexDecls = pCmd->numVertexDecls * sizeof(SVGA3dVertexDecl)
2952 + pCmd->numRanges * sizeof(SVGA3dPrimitiveRange);
2953 ASSERT_GUEST_STMT_BREAK(cbRangesAndVertexDecls <= cbCmd - sizeof(*pCmd), rcParse = VERR_INVALID_PARAMETER);
2954
2955 uint32_t const cVertexDivisor = (cbCmd - sizeof(*pCmd) - cbRangesAndVertexDecls) / sizeof(uint32_t);
2956 ASSERT_GUEST_STMT_BREAK(!cVertexDivisor || cVertexDivisor == pCmd->numVertexDecls, rcParse = VERR_INVALID_PARAMETER);
2957 RT_UNTRUSTED_VALIDATED_FENCE();
2958
2959 SVGA3dVertexDecl *pVertexDecl = (SVGA3dVertexDecl *)(pCmd + 1);
2960 SVGA3dPrimitiveRange *pNumRange = (SVGA3dPrimitiveRange *)&pVertexDecl[pCmd->numVertexDecls];
2961 SVGA3dVertexDivisor *pVertexDivisor = cVertexDivisor ? (SVGA3dVertexDivisor *)&pNumRange[pCmd->numRanges] : NULL;
2962
2963 STAM_PROFILE_START(&pSvgaR3State->StatR3Cmd3dDrawPrimitivesProf, a);
2964 vmsvga3dDrawPrimitives(pThisCC, pCmd->cid, pCmd->numVertexDecls, pVertexDecl, pCmd->numRanges,
2965 pNumRange, cVertexDivisor, pVertexDivisor);
2966 STAM_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dDrawPrimitivesProf, a);
2967 break;
2968 }
2969
2970 case SVGA_3D_CMD_SETSCISSORRECT:
2971 {
2972 SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)pvCmd;
2973 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2974 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetScissorRect);
2975
2976 vmsvga3dSetScissorRect(pThisCC, pCmd->cid, &pCmd->rect);
2977 break;
2978 }
2979
2980 case SVGA_3D_CMD_BEGIN_QUERY:
2981 {
2982 SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)pvCmd;
2983 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2984 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dBeginQuery);
2985
2986 vmsvga3dQueryBegin(pThisCC, pCmd->cid, pCmd->type);
2987 break;
2988 }
2989
2990 case SVGA_3D_CMD_END_QUERY:
2991 {
2992 SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)pvCmd;
2993 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
2994 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dEndQuery);
2995
2996 vmsvga3dQueryEnd(pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult);
2997 break;
2998 }
2999
3000 case SVGA_3D_CMD_WAIT_FOR_QUERY:
3001 {
3002 SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)pvCmd;
3003 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3004 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dWaitForQuery);
3005
3006 vmsvga3dQueryWait(pThis, pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult);
3007 break;
3008 }
3009
3010 case SVGA_3D_CMD_GENERATE_MIPMAPS:
3011 {
3012 SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)pvCmd;
3013 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3014 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dGenerateMipmaps);
3015
3016 vmsvga3dGenerateMipmaps(pThisCC, pCmd->sid, pCmd->filter);
3017 break;
3018 }
3019
3020 case SVGA_3D_CMD_ACTIVATE_SURFACE:
3021 /* context id + surface id? */
3022 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dActivateSurface);
3023 break;
3024
3025 case SVGA_3D_CMD_DEACTIVATE_SURFACE:
3026 /* context id + surface id? */
3027 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dDeactivateSurface);
3028 break;
3029
3030 /*
3031 *
3032 * VPGU10: SVGA_CAP_GBOBJECTS+ commands.
3033 *
3034 */
3035 case SVGA_3D_CMD_SCREEN_DMA:
3036 {
3037 SVGA3dCmdScreenDMA *pCmd = (SVGA3dCmdScreenDMA *)pvCmd;
3038 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3039 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3040 break;
3041 }
3042
3043 case SVGA_3D_CMD_DEAD1:
3044 case SVGA_3D_CMD_DEAD2:
3045 {
3046 VMSVGA_3D_CMD_NOTIMPL();
3047 break;
3048 }
3049
3050 case SVGA_3D_CMD_LOGICOPS_BITBLT:
3051 {
3052 SVGA3dCmdLogicOpsBitBlt *pCmd = (SVGA3dCmdLogicOpsBitBlt *)pvCmd;
3053 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3054 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3055 break;
3056 }
3057
3058 case SVGA_3D_CMD_LOGICOPS_TRANSBLT:
3059 {
3060 SVGA3dCmdLogicOpsTransBlt *pCmd = (SVGA3dCmdLogicOpsTransBlt *)pvCmd;
3061 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3062 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3063 break;
3064 }
3065
3066 case SVGA_3D_CMD_LOGICOPS_STRETCHBLT:
3067 {
3068 SVGA3dCmdLogicOpsStretchBlt *pCmd = (SVGA3dCmdLogicOpsStretchBlt *)pvCmd;
3069 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3070 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3071 break;
3072 }
3073
3074 case SVGA_3D_CMD_LOGICOPS_COLORFILL:
3075 {
3076 SVGA3dCmdLogicOpsColorFill *pCmd = (SVGA3dCmdLogicOpsColorFill *)pvCmd;
3077 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3078 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3079 break;
3080 }
3081
3082 case SVGA_3D_CMD_LOGICOPS_ALPHABLEND:
3083 {
3084 SVGA3dCmdLogicOpsAlphaBlend *pCmd = (SVGA3dCmdLogicOpsAlphaBlend *)pvCmd;
3085 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3086 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3087 break;
3088 }
3089
3090 case SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND:
3091 {
3092 SVGA3dCmdLogicOpsClearTypeBlend *pCmd = (SVGA3dCmdLogicOpsClearTypeBlend *)pvCmd;
3093 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3094 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3095 break;
3096 }
3097
3098 case SVGA_3D_CMD_SET_OTABLE_BASE:
3099 {
3100 SVGA3dCmdSetOTableBase *pCmd = (SVGA3dCmdSetOTableBase *)pvCmd;
3101 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3102 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3103 break;
3104 }
3105
3106 case SVGA_3D_CMD_READBACK_OTABLE:
3107 {
3108 SVGA3dCmdReadbackOTable *pCmd = (SVGA3dCmdReadbackOTable *)pvCmd;
3109 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3110 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3111 break;
3112 }
3113
3114 case SVGA_3D_CMD_DEFINE_GB_MOB:
3115 {
3116 SVGA3dCmdDefineGBMob *pCmd = (SVGA3dCmdDefineGBMob *)pvCmd;
3117 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3118 vmsvga3dCmdDefineGBMob(pThisCC, pCmd);
3119 break;
3120 }
3121
3122 case SVGA_3D_CMD_DESTROY_GB_MOB:
3123 {
3124 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd;
3125 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3126 vmsvga3dCmdDestroyGBMob(pThisCC, pCmd);
3127 break;
3128 }
3129
3130 case SVGA_3D_CMD_DEAD3:
3131 {
3132 VMSVGA_3D_CMD_NOTIMPL();
3133 break;
3134 }
3135
3136 case SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING:
3137 {
3138 SVGA3dCmdUpdateGBMobMapping *pCmd = (SVGA3dCmdUpdateGBMobMapping *)pvCmd;
3139 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3140 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3141 break;
3142 }
3143
3144 case SVGA_3D_CMD_DEFINE_GB_SURFACE:
3145 {
3146 SVGA3dCmdDefineGBSurface *pCmd = (SVGA3dCmdDefineGBSurface *)pvCmd;
3147 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3148 vmsvga3dCmdDefineGBSurface(pThisCC, pCmd);
3149 break;
3150 }
3151
3152 case SVGA_3D_CMD_DESTROY_GB_SURFACE:
3153 {
3154 SVGA3dCmdDestroyGBSurface *pCmd = (SVGA3dCmdDestroyGBSurface *)pvCmd;
3155 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3156 vmsvga3dCmdDestroyGBSurface(pThisCC, pCmd);
3157 break;
3158 }
3159
3160 case SVGA_3D_CMD_BIND_GB_SURFACE:
3161 {
3162 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd;
3163 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3164 vmsvga3dCmdBindGBSurface(pThisCC, pCmd);
3165 break;
3166 }
3167
3168 case SVGA_3D_CMD_COND_BIND_GB_SURFACE:
3169 {
3170 SVGA3dCmdCondBindGBSurface *pCmd = (SVGA3dCmdCondBindGBSurface *)pvCmd;
3171 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3172 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3173 break;
3174 }
3175
3176 case SVGA_3D_CMD_UPDATE_GB_IMAGE:
3177 {
3178 SVGA3dCmdUpdateGBImage *pCmd = (SVGA3dCmdUpdateGBImage *)pvCmd;
3179 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3180 vmsvga3dCmdUpdateGBImage(pThisCC, pCmd);
3181 break;
3182 }
3183
3184 case SVGA_3D_CMD_UPDATE_GB_SURFACE:
3185 {
3186 SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pvCmd;
3187 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3188 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3189 break;
3190 }
3191
3192 case SVGA_3D_CMD_READBACK_GB_IMAGE:
3193 {
3194 SVGA3dCmdReadbackGBImage *pCmd = (SVGA3dCmdReadbackGBImage *)pvCmd;
3195 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3196 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3197 break;
3198 }
3199
3200 case SVGA_3D_CMD_READBACK_GB_SURFACE:
3201 {
3202 SVGA3dCmdReadbackGBSurface *pCmd = (SVGA3dCmdReadbackGBSurface *)pvCmd;
3203 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3204 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3205 break;
3206 }
3207
3208 case SVGA_3D_CMD_INVALIDATE_GB_IMAGE:
3209 {
3210 SVGA3dCmdInvalidateGBImage *pCmd = (SVGA3dCmdInvalidateGBImage *)pvCmd;
3211 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3212 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3213 break;
3214 }
3215
3216 case SVGA_3D_CMD_INVALIDATE_GB_SURFACE:
3217 {
3218 SVGA3dCmdInvalidateGBSurface *pCmd = (SVGA3dCmdInvalidateGBSurface *)pvCmd;
3219 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3220 vmsvga3dCmdInvalidateGBSurface(pThisCC, pCmd);
3221 break;
3222 }
3223
3224 case SVGA_3D_CMD_DEFINE_GB_CONTEXT:
3225 {
3226 SVGA3dCmdDefineGBContext *pCmd = (SVGA3dCmdDefineGBContext *)pvCmd;
3227 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3228 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3229 break;
3230 }
3231
3232 case SVGA_3D_CMD_DESTROY_GB_CONTEXT:
3233 {
3234 SVGA3dCmdDestroyGBContext *pCmd = (SVGA3dCmdDestroyGBContext *)pvCmd;
3235 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3236 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3237 break;
3238 }
3239
3240 case SVGA_3D_CMD_BIND_GB_CONTEXT:
3241 {
3242 SVGA3dCmdBindGBContext *pCmd = (SVGA3dCmdBindGBContext *)pvCmd;
3243 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3244 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3245 break;
3246 }
3247
3248 case SVGA_3D_CMD_READBACK_GB_CONTEXT:
3249 {
3250 SVGA3dCmdReadbackGBContext *pCmd = (SVGA3dCmdReadbackGBContext *)pvCmd;
3251 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3252 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3253 break;
3254 }
3255
3256 case SVGA_3D_CMD_INVALIDATE_GB_CONTEXT:
3257 {
3258 SVGA3dCmdInvalidateGBContext *pCmd = (SVGA3dCmdInvalidateGBContext *)pvCmd;
3259 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3260 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3261 break;
3262 }
3263
3264 case SVGA_3D_CMD_DEFINE_GB_SHADER:
3265 {
3266 SVGA3dCmdDefineGBShader *pCmd = (SVGA3dCmdDefineGBShader *)pvCmd;
3267 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3268 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3269 break;
3270 }
3271
3272 case SVGA_3D_CMD_DESTROY_GB_SHADER:
3273 {
3274 SVGA3dCmdDestroyGBShader *pCmd = (SVGA3dCmdDestroyGBShader *)pvCmd;
3275 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3276 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3277 break;
3278 }
3279
3280 case SVGA_3D_CMD_BIND_GB_SHADER:
3281 {
3282 SVGA3dCmdBindGBShader *pCmd = (SVGA3dCmdBindGBShader *)pvCmd;
3283 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3284 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3285 break;
3286 }
3287
3288 case SVGA_3D_CMD_SET_OTABLE_BASE64:
3289 {
3290 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd;
3291 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3292 vmsvga3dCmdSetOTableBase64(pThisCC, pCmd);
3293 break;
3294 }
3295
3296 case SVGA_3D_CMD_BEGIN_GB_QUERY:
3297 {
3298 SVGA3dCmdBeginGBQuery *pCmd = (SVGA3dCmdBeginGBQuery *)pvCmd;
3299 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3300 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3301 break;
3302 }
3303
3304 case SVGA_3D_CMD_END_GB_QUERY:
3305 {
3306 SVGA3dCmdEndGBQuery *pCmd = (SVGA3dCmdEndGBQuery *)pvCmd;
3307 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3308 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3309 break;
3310 }
3311
3312 case SVGA_3D_CMD_WAIT_FOR_GB_QUERY:
3313 {
3314 SVGA3dCmdWaitForGBQuery *pCmd = (SVGA3dCmdWaitForGBQuery *)pvCmd;
3315 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3316 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3317 break;
3318 }
3319
3320 case SVGA_3D_CMD_NOP:
3321 {
3322 /* Apparently there is nothing to do. */
3323 break;
3324 }
3325
3326 case SVGA_3D_CMD_ENABLE_GART:
3327 {
3328 SVGA3dCmdEnableGart *pCmd = (SVGA3dCmdEnableGart *)pvCmd;
3329 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3330 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3331 break;
3332 }
3333
3334 case SVGA_3D_CMD_DISABLE_GART:
3335 {
3336 /* No corresponding SVGA3dCmd structure. */
3337 VMSVGA_3D_CMD_NOTIMPL();
3338 break;
3339 }
3340
3341 case SVGA_3D_CMD_MAP_MOB_INTO_GART:
3342 {
3343 SVGA3dCmdMapMobIntoGart *pCmd = (SVGA3dCmdMapMobIntoGart *)pvCmd;
3344 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3345 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3346 break;
3347 }
3348
3349 case SVGA_3D_CMD_UNMAP_GART_RANGE:
3350 {
3351 SVGA3dCmdUnmapGartRange *pCmd = (SVGA3dCmdUnmapGartRange *)pvCmd;
3352 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3353 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3354 break;
3355 }
3356
3357 case SVGA_3D_CMD_DEFINE_GB_SCREENTARGET:
3358 {
3359 SVGA3dCmdDefineGBScreenTarget *pCmd = (SVGA3dCmdDefineGBScreenTarget *)pvCmd;
3360 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3361 vmsvga3dCmdDefineGBScreenTarget(pThis, pThisCC, pCmd);
3362 break;
3363 }
3364
3365 case SVGA_3D_CMD_DESTROY_GB_SCREENTARGET:
3366 {
3367 SVGA3dCmdDestroyGBScreenTarget *pCmd = (SVGA3dCmdDestroyGBScreenTarget *)pvCmd;
3368 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3369 vmsvga3dCmdDestroyGBScreenTarget(pThis, pThisCC, pCmd);
3370 break;
3371 }
3372
3373 case SVGA_3D_CMD_BIND_GB_SCREENTARGET:
3374 {
3375 SVGA3dCmdBindGBScreenTarget *pCmd = (SVGA3dCmdBindGBScreenTarget *)pvCmd;
3376 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3377 vmsvga3dCmdBindGBScreenTarget(pThisCC, pCmd);
3378 break;
3379 }
3380
3381 case SVGA_3D_CMD_UPDATE_GB_SCREENTARGET:
3382 {
3383 SVGA3dCmdUpdateGBScreenTarget *pCmd = (SVGA3dCmdUpdateGBScreenTarget *)pvCmd;
3384 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3385 vmsvga3dCmdUpdateGBScreenTarget(pThisCC, pCmd);
3386 break;
3387 }
3388
3389 case SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL:
3390 {
3391 SVGA3dCmdReadbackGBImagePartial *pCmd = (SVGA3dCmdReadbackGBImagePartial *)pvCmd;
3392 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3393 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3394 break;
3395 }
3396
3397 case SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL:
3398 {
3399 SVGA3dCmdInvalidateGBImagePartial *pCmd = (SVGA3dCmdInvalidateGBImagePartial *)pvCmd;
3400 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3401 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3402 break;
3403 }
3404
3405 case SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE:
3406 {
3407 SVGA3dCmdSetGBShaderConstInline *pCmd = (SVGA3dCmdSetGBShaderConstInline *)pvCmd;
3408 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3409 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3410 break;
3411 }
3412
3413 case SVGA_3D_CMD_GB_SCREEN_DMA:
3414 {
3415 SVGA3dCmdGBScreenDMA *pCmd = (SVGA3dCmdGBScreenDMA *)pvCmd;
3416 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3417 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3418 break;
3419 }
3420
3421 case SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH:
3422 {
3423 SVGA3dCmdBindGBSurfaceWithPitch *pCmd = (SVGA3dCmdBindGBSurfaceWithPitch *)pvCmd;
3424 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3425 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3426 break;
3427 }
3428
3429 case SVGA_3D_CMD_GB_MOB_FENCE:
3430 {
3431 SVGA3dCmdGBMobFence *pCmd = (SVGA3dCmdGBMobFence *)pvCmd;
3432 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3433 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3434 break;
3435 }
3436
3437 case SVGA_3D_CMD_DEFINE_GB_SURFACE_V2:
3438 {
3439 /// @todo SVGA3dCmdDefineGBSurface_v2 is not defined in Mesa 17 header. Mesa 20 has it.
3440 //SVGA3dCmdDefineGBSurface_v2 *pCmd = (SVGA3dCmdDefineGBSurface_v2 *)pvCmd;
3441 //VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3442 VMSVGA_3D_CMD_NOTIMPL();
3443 break;
3444 }
3445
3446 case SVGA_3D_CMD_DEFINE_GB_MOB64:
3447 {
3448 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd;
3449 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3450 vmsvga3dCmdDefineGBMob64(pThisCC, pCmd);
3451 break;
3452 }
3453
3454 case SVGA_3D_CMD_REDEFINE_GB_MOB64:
3455 {
3456 SVGA3dCmdRedefineGBMob64 *pCmd = (SVGA3dCmdRedefineGBMob64 *)pvCmd;
3457 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3458 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3459 break;
3460 }
3461
3462 case SVGA_3D_CMD_NOP_ERROR:
3463 {
3464 /* Apparently there is nothing to do. */
3465 break;
3466 }
3467
3468 case SVGA_3D_CMD_SET_VERTEX_STREAMS:
3469 {
3470 SVGA3dCmdSetVertexStreams *pCmd = (SVGA3dCmdSetVertexStreams *)pvCmd;
3471 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3472 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3473 break;
3474 }
3475
3476 case SVGA_3D_CMD_SET_VERTEX_DECLS:
3477 {
3478 SVGA3dCmdSetVertexDecls *pCmd = (SVGA3dCmdSetVertexDecls *)pvCmd;
3479 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3480 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3481 break;
3482 }
3483
3484 case SVGA_3D_CMD_SET_VERTEX_DIVISORS:
3485 {
3486 SVGA3dCmdSetVertexDivisors *pCmd = (SVGA3dCmdSetVertexDivisors *)pvCmd;
3487 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3488 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
3489 break;
3490 }
3491
3492 case SVGA_3D_CMD_DRAW:
3493 {
3494 /* No corresponding SVGA3dCmd structure. */
3495 VMSVGA_3D_CMD_NOTIMPL();
3496 break;
3497 }
3498
3499 case SVGA_3D_CMD_DRAW_INDEXED:
3500 {
3501 /* No corresponding SVGA3dCmd structure. */
3502 VMSVGA_3D_CMD_NOTIMPL();
3503 break;
3504 }
3505
3506 case SVGA_3D_CMD_DX_DEFINE_CONTEXT:
3507 {
3508 SVGA3dCmdDXDefineContext *pCmd = (SVGA3dCmdDXDefineContext *)pvCmd;
3509 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3510 vmsvga3dCmdDXDefineContext(pThisCC, pCmd);
3511 break;
3512 }
3513
3514 case SVGA_3D_CMD_DX_DESTROY_CONTEXT:
3515 {
3516 SVGA3dCmdDXDestroyContext *pCmd = (SVGA3dCmdDXDestroyContext *)pvCmd;
3517 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3518 vmsvga3dCmdDXDestroyContext(pThisCC, pCmd);
3519 break;
3520 }
3521
3522 case SVGA_3D_CMD_DX_BIND_CONTEXT:
3523 {
3524 SVGA3dCmdDXBindContext *pCmd = (SVGA3dCmdDXBindContext *)pvCmd;
3525 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3526 vmsvga3dCmdDXBindContext(pThisCC, pCmd);
3527 break;
3528 }
3529
3530 case SVGA_3D_CMD_DX_READBACK_CONTEXT:
3531 {
3532 SVGA3dCmdDXReadbackContext *pCmd = (SVGA3dCmdDXReadbackContext *)pvCmd;
3533 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3534 vmsvga3dCmdDXReadbackContext(pThisCC, pCmd);
3535 break;
3536 }
3537
3538 case SVGA_3D_CMD_DX_INVALIDATE_CONTEXT:
3539 {
3540 SVGA3dCmdDXInvalidateContext *pCmd = (SVGA3dCmdDXInvalidateContext *)pvCmd;
3541 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3542 vmsvga3dCmdDXInvalidateContext(pThisCC, pCmd);
3543 break;
3544 }
3545
3546 case SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER:
3547 {
3548 SVGA3dCmdDXSetSingleConstantBuffer *pCmd = (SVGA3dCmdDXSetSingleConstantBuffer *)pvCmd;
3549 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3550 vmsvga3dCmdDXSetSingleConstantBuffer(pThisCC, pCmd);
3551 break;
3552 }
3553
3554 case SVGA_3D_CMD_DX_SET_SHADER_RESOURCES:
3555 {
3556 SVGA3dCmdDXSetShaderResources *pCmd = (SVGA3dCmdDXSetShaderResources *)pvCmd;
3557 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3558 vmsvga3dCmdDXSetShaderResources(pThisCC, pCmd);
3559 break;
3560 }
3561
3562 case SVGA_3D_CMD_DX_SET_SHADER:
3563 {
3564 SVGA3dCmdDXSetShader *pCmd = (SVGA3dCmdDXSetShader *)pvCmd;
3565 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3566 vmsvga3dCmdDXSetShader(pThisCC, pCmd);
3567 break;
3568 }
3569
3570 case SVGA_3D_CMD_DX_SET_SAMPLERS:
3571 {
3572 SVGA3dCmdDXSetSamplers *pCmd = (SVGA3dCmdDXSetSamplers *)pvCmd;
3573 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3574 vmsvga3dCmdDXSetSamplers(pThisCC, pCmd);
3575 break;
3576 }
3577
3578 case SVGA_3D_CMD_DX_DRAW:
3579 {
3580 SVGA3dCmdDXDraw *pCmd = (SVGA3dCmdDXDraw *)pvCmd;
3581 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3582 vmsvga3dCmdDXDraw(pThisCC, pCmd);
3583 break;
3584 }
3585
3586 case SVGA_3D_CMD_DX_DRAW_INDEXED:
3587 {
3588 SVGA3dCmdDXDrawIndexed *pCmd = (SVGA3dCmdDXDrawIndexed *)pvCmd;
3589 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3590 vmsvga3dCmdDXDrawIndexed(pThisCC, pCmd);
3591 break;
3592 }
3593
3594 case SVGA_3D_CMD_DX_DRAW_INSTANCED:
3595 {
3596 SVGA3dCmdDXDrawInstanced *pCmd = (SVGA3dCmdDXDrawInstanced *)pvCmd;
3597 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3598 vmsvga3dCmdDXDrawInstanced(pThisCC, pCmd);
3599 break;
3600 }
3601
3602 case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
3603 {
3604 SVGA3dCmdDXDrawIndexedInstanced *pCmd = (SVGA3dCmdDXDrawIndexedInstanced *)pvCmd;
3605 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3606 vmsvga3dCmdDXDrawIndexedInstanced(pThisCC, pCmd);
3607 break;
3608 }
3609
3610 case SVGA_3D_CMD_DX_DRAW_AUTO:
3611 {
3612 SVGA3dCmdDXDrawAuto *pCmd = (SVGA3dCmdDXDrawAuto *)pvCmd;
3613 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3614 vmsvga3dCmdDXDrawAuto(pThisCC, pCmd);
3615 break;
3616 }
3617
3618 case SVGA_3D_CMD_DX_SET_INPUT_LAYOUT:
3619 {
3620 SVGA3dCmdDXSetInputLayout *pCmd = (SVGA3dCmdDXSetInputLayout *)pvCmd;
3621 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3622 vmsvga3dCmdDXSetInputLayout(pThisCC, pCmd);
3623 break;
3624 }
3625
3626 case SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS:
3627 {
3628 SVGA3dCmdDXSetVertexBuffers *pCmd = (SVGA3dCmdDXSetVertexBuffers *)pvCmd;
3629 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3630 vmsvga3dCmdDXSetVertexBuffers(pThisCC, pCmd);
3631 break;
3632 }
3633
3634 case SVGA_3D_CMD_DX_SET_INDEX_BUFFER:
3635 {
3636 SVGA3dCmdDXSetIndexBuffer *pCmd = (SVGA3dCmdDXSetIndexBuffer *)pvCmd;
3637 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3638 vmsvga3dCmdDXSetIndexBuffer(pThisCC, pCmd);
3639 break;
3640 }
3641
3642 case SVGA_3D_CMD_DX_SET_TOPOLOGY:
3643 {
3644 SVGA3dCmdDXSetTopology *pCmd = (SVGA3dCmdDXSetTopology *)pvCmd;
3645 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3646 vmsvga3dCmdDXSetTopology(pThisCC, pCmd);
3647 break;
3648 }
3649
3650 case SVGA_3D_CMD_DX_SET_RENDERTARGETS:
3651 {
3652 SVGA3dCmdDXSetRenderTargets *pCmd = (SVGA3dCmdDXSetRenderTargets *)pvCmd;
3653 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3654 vmsvga3dCmdDXSetRenderTargets(pThisCC, pCmd);
3655 break;
3656 }
3657
3658 case SVGA_3D_CMD_DX_SET_BLEND_STATE:
3659 {
3660 SVGA3dCmdDXSetBlendState *pCmd = (SVGA3dCmdDXSetBlendState *)pvCmd;
3661 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3662 vmsvga3dCmdDXSetBlendState(pThisCC, pCmd);
3663 break;
3664 }
3665
3666 case SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE:
3667 {
3668 SVGA3dCmdDXSetDepthStencilState *pCmd = (SVGA3dCmdDXSetDepthStencilState *)pvCmd;
3669 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3670 vmsvga3dCmdDXSetDepthStencilState(pThisCC, pCmd);
3671 break;
3672 }
3673
3674 case SVGA_3D_CMD_DX_SET_RASTERIZER_STATE:
3675 {
3676 SVGA3dCmdDXSetRasterizerState *pCmd = (SVGA3dCmdDXSetRasterizerState *)pvCmd;
3677 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3678 vmsvga3dCmdDXSetRasterizerState(pThisCC, pCmd);
3679 break;
3680 }
3681
3682 case SVGA_3D_CMD_DX_DEFINE_QUERY:
3683 {
3684 SVGA3dCmdDXDefineQuery *pCmd = (SVGA3dCmdDXDefineQuery *)pvCmd;
3685 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3686 vmsvga3dCmdDXDefineQuery(pThisCC, pCmd);
3687 break;
3688 }
3689
3690 case SVGA_3D_CMD_DX_DESTROY_QUERY:
3691 {
3692 SVGA3dCmdDXDestroyQuery *pCmd = (SVGA3dCmdDXDestroyQuery *)pvCmd;
3693 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3694 vmsvga3dCmdDXDestroyQuery(pThisCC, pCmd);
3695 break;
3696 }
3697
3698 case SVGA_3D_CMD_DX_BIND_QUERY:
3699 {
3700 SVGA3dCmdDXBindQuery *pCmd = (SVGA3dCmdDXBindQuery *)pvCmd;
3701 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3702 vmsvga3dCmdDXBindQuery(pThisCC, pCmd);
3703 break;
3704 }
3705
3706 case SVGA_3D_CMD_DX_SET_QUERY_OFFSET:
3707 {
3708 SVGA3dCmdDXSetQueryOffset *pCmd = (SVGA3dCmdDXSetQueryOffset *)pvCmd;
3709 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3710 vmsvga3dCmdDXSetQueryOffset(pThisCC, pCmd);
3711 break;
3712 }
3713
3714 case SVGA_3D_CMD_DX_BEGIN_QUERY:
3715 {
3716 SVGA3dCmdDXBeginQuery *pCmd = (SVGA3dCmdDXBeginQuery *)pvCmd;
3717 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3718 vmsvga3dCmdDXBeginQuery(pThisCC, pCmd);
3719 break;
3720 }
3721
3722 case SVGA_3D_CMD_DX_END_QUERY:
3723 {
3724 SVGA3dCmdDXEndQuery *pCmd = (SVGA3dCmdDXEndQuery *)pvCmd;
3725 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3726 vmsvga3dCmdDXEndQuery(pThisCC, pCmd);
3727 break;
3728 }
3729
3730 case SVGA_3D_CMD_DX_READBACK_QUERY:
3731 {
3732 SVGA3dCmdDXReadbackQuery *pCmd = (SVGA3dCmdDXReadbackQuery *)pvCmd;
3733 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3734 vmsvga3dCmdDXReadbackQuery(pThisCC, pCmd);
3735 break;
3736 }
3737
3738 case SVGA_3D_CMD_DX_SET_PREDICATION:
3739 {
3740 SVGA3dCmdDXSetPredication *pCmd = (SVGA3dCmdDXSetPredication *)pvCmd;
3741 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3742 vmsvga3dCmdDXSetPredication(pThisCC, pCmd);
3743 break;
3744 }
3745
3746 case SVGA_3D_CMD_DX_SET_SOTARGETS:
3747 {
3748 SVGA3dCmdDXSetSOTargets *pCmd = (SVGA3dCmdDXSetSOTargets *)pvCmd;
3749 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3750 vmsvga3dCmdDXSetSOTargets(pThisCC, pCmd);
3751 break;
3752 }
3753
3754 case SVGA_3D_CMD_DX_SET_VIEWPORTS:
3755 {
3756 SVGA3dCmdDXSetViewports *pCmd = (SVGA3dCmdDXSetViewports *)pvCmd;
3757 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3758 vmsvga3dCmdDXSetViewports(pThisCC, pCmd);
3759 break;
3760 }
3761
3762 case SVGA_3D_CMD_DX_SET_SCISSORRECTS:
3763 {
3764 SVGA3dCmdDXSetScissorRects *pCmd = (SVGA3dCmdDXSetScissorRects *)pvCmd;
3765 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3766 vmsvga3dCmdDXSetScissorRects(pThisCC, pCmd);
3767 break;
3768 }
3769
3770 case SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW:
3771 {
3772 SVGA3dCmdDXClearRenderTargetView *pCmd = (SVGA3dCmdDXClearRenderTargetView *)pvCmd;
3773 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3774 vmsvga3dCmdDXClearRenderTargetView(pThisCC, pCmd);
3775 break;
3776 }
3777
3778 case SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW:
3779 {
3780 SVGA3dCmdDXClearDepthStencilView *pCmd = (SVGA3dCmdDXClearDepthStencilView *)pvCmd;
3781 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3782 vmsvga3dCmdDXClearDepthStencilView(pThisCC, pCmd);
3783 break;
3784 }
3785
3786 case SVGA_3D_CMD_DX_PRED_COPY_REGION:
3787 {
3788 SVGA3dCmdDXPredCopyRegion *pCmd = (SVGA3dCmdDXPredCopyRegion *)pvCmd;
3789 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3790 vmsvga3dCmdDXPredCopyRegion(pThisCC, pCmd);
3791 break;
3792 }
3793
3794 case SVGA_3D_CMD_DX_PRED_COPY:
3795 {
3796 SVGA3dCmdDXPredCopy *pCmd = (SVGA3dCmdDXPredCopy *)pvCmd;
3797 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3798 vmsvga3dCmdDXPredCopy(pThisCC, pCmd);
3799 break;
3800 }
3801
3802 case SVGA_3D_CMD_DX_STRETCHBLT:
3803 {
3804 SVGA3dCmdDXStretchBlt *pCmd = (SVGA3dCmdDXStretchBlt *)pvCmd;
3805 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3806 vmsvga3dCmdDXStretchBlt(pThisCC, pCmd);
3807 break;
3808 }
3809
3810 case SVGA_3D_CMD_DX_GENMIPS:
3811 {
3812 SVGA3dCmdDXGenMips *pCmd = (SVGA3dCmdDXGenMips *)pvCmd;
3813 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3814 vmsvga3dCmdDXGenMips(pThisCC, pCmd);
3815 break;
3816 }
3817
3818 case SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE:
3819 {
3820 SVGA3dCmdDXUpdateSubResource *pCmd = (SVGA3dCmdDXUpdateSubResource *)pvCmd;
3821 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3822 vmsvga3dCmdDXUpdateSubResource(pThisCC, pCmd);
3823 break;
3824 }
3825
3826 case SVGA_3D_CMD_DX_READBACK_SUBRESOURCE:
3827 {
3828 SVGA3dCmdDXReadbackSubResource *pCmd = (SVGA3dCmdDXReadbackSubResource *)pvCmd;
3829 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3830 vmsvga3dCmdDXReadbackSubResource(pThisCC, pCmd);
3831 break;
3832 }
3833
3834 case SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE:
3835 {
3836 SVGA3dCmdDXInvalidateSubResource *pCmd = (SVGA3dCmdDXInvalidateSubResource *)pvCmd;
3837 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3838 vmsvga3dCmdDXInvalidateSubResource(pThisCC, pCmd);
3839 break;
3840 }
3841
3842 case SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW:
3843 {
3844 SVGA3dCmdDXDefineShaderResourceView *pCmd = (SVGA3dCmdDXDefineShaderResourceView *)pvCmd;
3845 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3846 vmsvga3dCmdDXDefineShaderResourceView(pThisCC, pCmd);
3847 break;
3848 }
3849
3850 case SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW:
3851 {
3852 SVGA3dCmdDXDestroyShaderResourceView *pCmd = (SVGA3dCmdDXDestroyShaderResourceView *)pvCmd;
3853 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3854 vmsvga3dCmdDXDestroyShaderResourceView(pThisCC, pCmd);
3855 break;
3856 }
3857
3858 case SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW:
3859 {
3860 SVGA3dCmdDXDefineRenderTargetView *pCmd = (SVGA3dCmdDXDefineRenderTargetView *)pvCmd;
3861 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3862 vmsvga3dCmdDXDefineRenderTargetView(pThisCC, pCmd);
3863 break;
3864 }
3865
3866 case SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW:
3867 {
3868 SVGA3dCmdDXDestroyRenderTargetView *pCmd = (SVGA3dCmdDXDestroyRenderTargetView *)pvCmd;
3869 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3870 vmsvga3dCmdDXDestroyRenderTargetView(pThisCC, pCmd);
3871 break;
3872 }
3873
3874 case SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW:
3875 {
3876 SVGA3dCmdDXDefineDepthStencilView *pCmd = (SVGA3dCmdDXDefineDepthStencilView *)pvCmd;
3877 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3878 vmsvga3dCmdDXDefineDepthStencilView(pThisCC, pCmd);
3879 break;
3880 }
3881
3882 case SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW:
3883 {
3884 SVGA3dCmdDXDestroyDepthStencilView *pCmd = (SVGA3dCmdDXDestroyDepthStencilView *)pvCmd;
3885 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3886 vmsvga3dCmdDXDestroyDepthStencilView(pThisCC, pCmd);
3887 break;
3888 }
3889
3890 case SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT:
3891 {
3892 SVGA3dCmdDXDefineElementLayout *pCmd = (SVGA3dCmdDXDefineElementLayout *)pvCmd;
3893 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3894 vmsvga3dCmdDXDefineElementLayout(pThisCC, pCmd);
3895 break;
3896 }
3897
3898 case SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT:
3899 {
3900 SVGA3dCmdDXDestroyElementLayout *pCmd = (SVGA3dCmdDXDestroyElementLayout *)pvCmd;
3901 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3902 vmsvga3dCmdDXDestroyElementLayout(pThisCC, pCmd);
3903 break;
3904 }
3905
3906 case SVGA_3D_CMD_DX_DEFINE_BLEND_STATE:
3907 {
3908 SVGA3dCmdDXDefineBlendState *pCmd = (SVGA3dCmdDXDefineBlendState *)pvCmd;
3909 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3910 vmsvga3dCmdDXDefineBlendState(pThisCC, pCmd);
3911 break;
3912 }
3913
3914 case SVGA_3D_CMD_DX_DESTROY_BLEND_STATE:
3915 {
3916 SVGA3dCmdDXDestroyBlendState *pCmd = (SVGA3dCmdDXDestroyBlendState *)pvCmd;
3917 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3918 vmsvga3dCmdDXDestroyBlendState(pThisCC, pCmd);
3919 break;
3920 }
3921
3922 case SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE:
3923 {
3924 SVGA3dCmdDXDefineDepthStencilState *pCmd = (SVGA3dCmdDXDefineDepthStencilState *)pvCmd;
3925 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3926 vmsvga3dCmdDXDefineDepthStencilState(pThisCC, pCmd);
3927 break;
3928 }
3929
3930 case SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE:
3931 {
3932 SVGA3dCmdDXDestroyDepthStencilState *pCmd = (SVGA3dCmdDXDestroyDepthStencilState *)pvCmd;
3933 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3934 vmsvga3dCmdDXDestroyDepthStencilState(pThisCC, pCmd);
3935 break;
3936 }
3937
3938 case SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE:
3939 {
3940 SVGA3dCmdDXDefineRasterizerState *pCmd = (SVGA3dCmdDXDefineRasterizerState *)pvCmd;
3941 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3942 vmsvga3dCmdDXDefineRasterizerState(pThisCC, pCmd);
3943 break;
3944 }
3945
3946 case SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE:
3947 {
3948 SVGA3dCmdDXDestroyRasterizerState *pCmd = (SVGA3dCmdDXDestroyRasterizerState *)pvCmd;
3949 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3950 vmsvga3dCmdDXDestroyRasterizerState(pThisCC, pCmd);
3951 break;
3952 }
3953
3954 case SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE:
3955 {
3956 SVGA3dCmdDXDefineSamplerState *pCmd = (SVGA3dCmdDXDefineSamplerState *)pvCmd;
3957 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3958 vmsvga3dCmdDXDefineSamplerState(pThisCC, pCmd);
3959 break;
3960 }
3961
3962 case SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE:
3963 {
3964 SVGA3dCmdDXDestroySamplerState *pCmd = (SVGA3dCmdDXDestroySamplerState *)pvCmd;
3965 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3966 vmsvga3dCmdDXDestroySamplerState(pThisCC, pCmd);
3967 break;
3968 }
3969
3970 case SVGA_3D_CMD_DX_DEFINE_SHADER:
3971 {
3972 SVGA3dCmdDXDefineShader *pCmd = (SVGA3dCmdDXDefineShader *)pvCmd;
3973 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3974 vmsvga3dCmdDXDefineShader(pThisCC, pCmd);
3975 break;
3976 }
3977
3978 case SVGA_3D_CMD_DX_DESTROY_SHADER:
3979 {
3980 SVGA3dCmdDXDestroyShader *pCmd = (SVGA3dCmdDXDestroyShader *)pvCmd;
3981 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3982 vmsvga3dCmdDXDestroyShader(pThisCC, pCmd);
3983 break;
3984 }
3985
3986 case SVGA_3D_CMD_DX_BIND_SHADER:
3987 {
3988 SVGA3dCmdDXBindShader *pCmd = (SVGA3dCmdDXBindShader *)pvCmd;
3989 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3990 vmsvga3dCmdDXBindShader(pThisCC, pCmd);
3991 break;
3992 }
3993
3994 case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT:
3995 {
3996 SVGA3dCmdDXDefineStreamOutput *pCmd = (SVGA3dCmdDXDefineStreamOutput *)pvCmd;
3997 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
3998 vmsvga3dCmdDXDefineStreamOutput(pThisCC, pCmd);
3999 break;
4000 }
4001
4002 case SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT:
4003 {
4004 SVGA3dCmdDXDestroyStreamOutput *pCmd = (SVGA3dCmdDXDestroyStreamOutput *)pvCmd;
4005 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4006 vmsvga3dCmdDXDestroyStreamOutput(pThisCC, pCmd);
4007 break;
4008 }
4009
4010 case SVGA_3D_CMD_DX_SET_STREAMOUTPUT:
4011 {
4012 SVGA3dCmdDXSetStreamOutput *pCmd = (SVGA3dCmdDXSetStreamOutput *)pvCmd;
4013 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4014 vmsvga3dCmdDXSetStreamOutput(pThisCC, pCmd);
4015 break;
4016 }
4017
4018 case SVGA_3D_CMD_DX_SET_COTABLE:
4019 {
4020 SVGA3dCmdDXSetCOTable *pCmd = (SVGA3dCmdDXSetCOTable *)pvCmd;
4021 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4022 vmsvga3dCmdDXSetCOTable(pThisCC, pCmd);
4023 break;
4024 }
4025
4026 case SVGA_3D_CMD_DX_READBACK_COTABLE:
4027 {
4028 SVGA3dCmdDXReadbackCOTable *pCmd = (SVGA3dCmdDXReadbackCOTable *)pvCmd;
4029 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4030 vmsvga3dCmdDXReadbackCOTable(pThisCC, pCmd);
4031 break;
4032 }
4033
4034 case SVGA_3D_CMD_DX_BUFFER_COPY:
4035 {
4036 SVGA3dCmdDXBufferCopy *pCmd = (SVGA3dCmdDXBufferCopy *)pvCmd;
4037 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4038 vmsvga3dCmdDXBufferCopy(pThisCC, pCmd);
4039 break;
4040 }
4041
4042 case SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER:
4043 {
4044 SVGA3dCmdDXTransferFromBuffer *pCmd = (SVGA3dCmdDXTransferFromBuffer *)pvCmd;
4045 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4046 vmsvga3dCmdDXTransferFromBuffer(pThisCC, pCmd);
4047 break;
4048 }
4049
4050 case SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK:
4051 {
4052 SVGA3dCmdDXSurfaceCopyAndReadback *pCmd = (SVGA3dCmdDXSurfaceCopyAndReadback *)pvCmd;
4053 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4054 vmsvga3dCmdDXSurfaceCopyAndReadback(pThisCC, pCmd);
4055 break;
4056 }
4057
4058 case SVGA_3D_CMD_DX_MOVE_QUERY:
4059 {
4060 SVGA3dCmdDXMoveQuery *pCmd = (SVGA3dCmdDXMoveQuery *)pvCmd;
4061 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4062 vmsvga3dCmdDXMoveQuery(pThisCC, pCmd);
4063 break;
4064 }
4065
4066 case SVGA_3D_CMD_DX_BIND_ALL_QUERY:
4067 {
4068 SVGA3dCmdDXBindAllQuery *pCmd = (SVGA3dCmdDXBindAllQuery *)pvCmd;
4069 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4070 vmsvga3dCmdDXBindAllQuery(pThisCC, pCmd);
4071 break;
4072 }
4073
4074 case SVGA_3D_CMD_DX_READBACK_ALL_QUERY:
4075 {
4076 SVGA3dCmdDXReadbackAllQuery *pCmd = (SVGA3dCmdDXReadbackAllQuery *)pvCmd;
4077 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4078 vmsvga3dCmdDXReadbackAllQuery(pThisCC, pCmd);
4079 break;
4080 }
4081
4082 case SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER:
4083 {
4084 SVGA3dCmdDXPredTransferFromBuffer *pCmd = (SVGA3dCmdDXPredTransferFromBuffer *)pvCmd;
4085 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4086 vmsvga3dCmdDXPredTransferFromBuffer(pThisCC, pCmd);
4087 break;
4088 }
4089
4090 case SVGA_3D_CMD_DX_MOB_FENCE_64:
4091 {
4092 SVGA3dCmdDXMobFence64 *pCmd = (SVGA3dCmdDXMobFence64 *)pvCmd;
4093 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4094 vmsvga3dCmdDXMobFence64(pThisCC, pCmd);
4095 break;
4096 }
4097
4098 case SVGA_3D_CMD_DX_BIND_ALL_SHADER:
4099 {
4100 SVGA3dCmdDXBindAllShader *pCmd = (SVGA3dCmdDXBindAllShader *)pvCmd;
4101 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4102 vmsvga3dCmdDXBindAllShader(pThisCC, pCmd);
4103 break;
4104 }
4105
4106 case SVGA_3D_CMD_DX_HINT:
4107 {
4108 SVGA3dCmdDXHint *pCmd = (SVGA3dCmdDXHint *)pvCmd;
4109 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4110 vmsvga3dCmdDXHint(pThisCC, pCmd);
4111 break;
4112 }
4113
4114 case SVGA_3D_CMD_DX_BUFFER_UPDATE:
4115 {
4116 SVGA3dCmdDXBufferUpdate *pCmd = (SVGA3dCmdDXBufferUpdate *)pvCmd;
4117 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4118 vmsvga3dCmdDXBufferUpdate(pThisCC, pCmd);
4119 break;
4120 }
4121
4122 case SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET:
4123 {
4124 SVGA3dCmdDXSetVSConstantBufferOffset *pCmd = (SVGA3dCmdDXSetVSConstantBufferOffset *)pvCmd;
4125 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4126 vmsvga3dCmdDXSetVSConstantBufferOffset(pThisCC, pCmd);
4127 break;
4128 }
4129
4130 case SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET:
4131 {
4132 SVGA3dCmdDXSetPSConstantBufferOffset *pCmd = (SVGA3dCmdDXSetPSConstantBufferOffset *)pvCmd;
4133 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4134 vmsvga3dCmdDXSetPSConstantBufferOffset(pThisCC, pCmd);
4135 break;
4136 }
4137
4138 case SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET:
4139 {
4140 SVGA3dCmdDXSetGSConstantBufferOffset *pCmd = (SVGA3dCmdDXSetGSConstantBufferOffset *)pvCmd;
4141 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4142 vmsvga3dCmdDXSetGSConstantBufferOffset(pThisCC, pCmd);
4143 break;
4144 }
4145
4146 case SVGA_3D_CMD_DX_RESERVED1:
4147 {
4148 VMSVGA_3D_CMD_NOTIMPL();
4149 break;
4150 }
4151
4152 case SVGA_3D_CMD_DX_RESERVED2:
4153 {
4154 VMSVGA_3D_CMD_NOTIMPL();
4155 break;
4156 }
4157
4158 case SVGA_3D_CMD_DX_RESERVED3:
4159 {
4160 VMSVGA_3D_CMD_NOTIMPL();
4161 break;
4162 }
4163
4164 case SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER:
4165 {
4166 SVGA3dCmdDXCondBindAllShader *pCmd = (SVGA3dCmdDXCondBindAllShader *)pvCmd;
4167 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
4168 vmsvga3dCmdDXCondBindAllShader(pThisCC, pCmd);
4169 break;
4170 }
4171
4172 /* Unsupported commands. */
4173 case SVGA_3D_CMD_VIDEO_CREATE_DECODER:
4174 case SVGA_3D_CMD_VIDEO_DESTROY_DECODER:
4175 case SVGA_3D_CMD_VIDEO_CREATE_PROCESSOR:
4176 case SVGA_3D_CMD_VIDEO_DESTROY_PROCESSOR:
4177 case SVGA_3D_CMD_VIDEO_DECODE_START_FRAME:
4178 case SVGA_3D_CMD_VIDEO_DECODE_RENDER:
4179 case SVGA_3D_CMD_VIDEO_DECODE_END_FRAME:
4180 case SVGA_3D_CMD_VIDEO_PROCESS_FRAME:
4181 /* Prevent the compiler warning. */
4182 case SVGA_3D_CMD_LEGACY_BASE:
4183 case SVGA_3D_CMD_MAX:
4184 case SVGA_3D_CMD_FUTURE_MAX:
4185 /* No 'default' case */
4186 STAM_REL_COUNTER_INC(&pSvgaR3State->StatFifoUnkCmds);
4187 ASSERT_GUEST_MSG_FAILED(("enmCmdId=%d\n", enmCmdId));
4188 LogRelMax(16, ("VMSVGA: unsupported 3D command %d\n", enmCmdId));
4189 rcParse = VERR_NOT_IMPLEMENTED;
4190 break;
4191 }
4192
4193 return rcParse;
4194}
4195# undef VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK
4196#endif /* VBOX_WITH_VMSVGA3D */
4197
4198
4199/*
4200 *
4201 * Handlers for FIFO commands.
4202 *
4203 * Every handler takes the following parameters:
4204 *
4205 * pThis The shared VGA/VMSVGA state.
4206 * pThisCC The VGA/VMSVGA state for ring-3.
4207 * pCmd The command data.
4208 */
4209
4210
4211/* SVGA_CMD_UPDATE */
4212void vmsvgaR3CmdUpdate(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdUpdate const *pCmd)
4213{
4214 RT_NOREF(pThis);
4215 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4216
4217 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdUpdate);
4218 Log(("SVGA_CMD_UPDATE %d,%d %dx%d\n", pCmd->x, pCmd->y, pCmd->width, pCmd->height));
4219
4220 /** @todo Multiple screens? */
4221 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
4222 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */
4223 return;
4224
4225 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->x, pCmd->y, pCmd->width, pCmd->height);
4226}
4227
4228
4229/* SVGA_CMD_UPDATE_VERBOSE */
4230void vmsvgaR3CmdUpdateVerbose(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdUpdateVerbose const *pCmd)
4231{
4232 RT_NOREF(pThis);
4233 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4234
4235 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdUpdateVerbose);
4236 Log(("SVGA_CMD_UPDATE_VERBOSE %d,%d %dx%d reason %#x\n", pCmd->x, pCmd->y, pCmd->width, pCmd->height, pCmd->reason));
4237
4238 /** @todo Multiple screens? */
4239 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
4240 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */
4241 return;
4242
4243 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->x, pCmd->y, pCmd->width, pCmd->height);
4244}
4245
4246
4247/* SVGA_CMD_RECT_FILL */
4248void vmsvgaR3CmdRectFill(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectFill const *pCmd)
4249{
4250 RT_NOREF(pThis, pCmd);
4251 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4252
4253 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectFill);
4254 Log(("SVGA_CMD_RECT_FILL %08X @ %d,%d (%dx%d)\n", pCmd->pixel, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height));
4255 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_RECT_FILL command ignored.\n"));
4256}
4257
4258
4259/* SVGA_CMD_RECT_COPY */
4260void vmsvgaR3CmdRectCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectCopy const *pCmd)
4261{
4262 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4263
4264 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectCopy);
4265 Log(("SVGA_CMD_RECT_COPY %d,%d -> %d,%d %dx%d\n", pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height));
4266
4267 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
4268 AssertPtrReturnVoid(pScreen);
4269
4270 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */
4271 ASSERT_GUEST_RETURN_VOID(pCmd->srcX < pThis->svga.u32MaxWidth);
4272 ASSERT_GUEST_RETURN_VOID(pCmd->destX < pThis->svga.u32MaxWidth);
4273 ASSERT_GUEST_RETURN_VOID(pCmd->width < pThis->svga.u32MaxWidth);
4274 ASSERT_GUEST_RETURN_VOID(pCmd->srcY < pThis->svga.u32MaxHeight);
4275 ASSERT_GUEST_RETURN_VOID(pCmd->destY < pThis->svga.u32MaxHeight);
4276 ASSERT_GUEST_RETURN_VOID(pCmd->height < pThis->svga.u32MaxHeight);
4277
4278 vmsvgaR3RectCopy(pThisCC, pScreen, pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY,
4279 pCmd->width, pCmd->height, pThis->vram_size);
4280 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height);
4281}
4282
4283
4284/* SVGA_CMD_RECT_ROP_COPY */
4285void vmsvgaR3CmdRectRopCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectRopCopy const *pCmd)
4286{
4287 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4288
4289 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectRopCopy);
4290 Log(("SVGA_CMD_RECT_ROP_COPY %d,%d -> %d,%d %dx%d ROP %#X\n", pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height, pCmd->rop));
4291
4292 if (pCmd->rop != SVGA_ROP_COPY)
4293 {
4294 /* We only support the plain copy ROP which makes SVGA_CMD_RECT_ROP_COPY exactly the same
4295 * as SVGA_CMD_RECT_COPY. XFree86 4.1.0 and 4.2.0 drivers (driver version 10.4.0 and 10.7.0,
4296 * respectively) issue SVGA_CMD_RECT_ROP_COPY when SVGA_CAP_RECT_COPY is present even when
4297 * SVGA_CAP_RASTER_OP is not. However, the ROP will always be SVGA_ROP_COPY.
4298 */
4299 LogRelMax(4, ("VMSVGA: SVGA_CMD_RECT_ROP_COPY %d,%d -> %d,%d (%dx%d) ROP %X unsupported\n",
4300 pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height, pCmd->rop));
4301 return;
4302 }
4303
4304 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
4305 AssertPtrReturnVoid(pScreen);
4306
4307 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */
4308 ASSERT_GUEST_RETURN_VOID(pCmd->srcX < pThis->svga.u32MaxWidth);
4309 ASSERT_GUEST_RETURN_VOID(pCmd->destX < pThis->svga.u32MaxWidth);
4310 ASSERT_GUEST_RETURN_VOID(pCmd->width < pThis->svga.u32MaxWidth);
4311 ASSERT_GUEST_RETURN_VOID(pCmd->srcY < pThis->svga.u32MaxHeight);
4312 ASSERT_GUEST_RETURN_VOID(pCmd->destY < pThis->svga.u32MaxHeight);
4313 ASSERT_GUEST_RETURN_VOID(pCmd->height < pThis->svga.u32MaxHeight);
4314
4315 vmsvgaR3RectCopy(pThisCC, pScreen, pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY,
4316 pCmd->width, pCmd->height, pThis->vram_size);
4317 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height);
4318}
4319
4320
4321/* SVGA_CMD_DISPLAY_CURSOR */
4322void vmsvgaR3CmdDisplayCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDisplayCursor const *pCmd)
4323{
4324 RT_NOREF(pThis, pCmd);
4325 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4326
4327 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDisplayCursor);
4328 Log(("SVGA_CMD_DISPLAY_CURSOR id=%d state=%d\n", pCmd->id, pCmd->state));
4329 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_DISPLAY_CURSOR command ignored.\n"));
4330}
4331
4332
4333/* SVGA_CMD_MOVE_CURSOR */
4334void vmsvgaR3CmdMoveCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdMoveCursor const *pCmd)
4335{
4336 RT_NOREF(pThis, pCmd);
4337 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4338
4339 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdMoveCursor);
4340 Log(("SVGA_CMD_MOVE_CURSOR to %d,%d\n", pCmd->pos.x, pCmd->pos.y));
4341 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_MOVE_CURSOR command ignored.\n"));
4342}
4343
4344
4345/* SVGA_CMD_DEFINE_CURSOR */
4346void vmsvgaR3CmdDefineCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineCursor const *pCmd)
4347{
4348 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4349
4350 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineCursor);
4351 Log(("SVGA_CMD_DEFINE_CURSOR id=%d size (%dx%d) hotspot (%d,%d) andMaskDepth=%d xorMaskDepth=%d\n",
4352 pCmd->id, pCmd->width, pCmd->height, pCmd->hotspotX, pCmd->hotspotY, pCmd->andMaskDepth, pCmd->xorMaskDepth));
4353
4354 ASSERT_GUEST_RETURN_VOID(pCmd->height < 2048 && pCmd->width < 2048);
4355 ASSERT_GUEST_RETURN_VOID(pCmd->andMaskDepth <= 32);
4356 ASSERT_GUEST_RETURN_VOID(pCmd->xorMaskDepth <= 32);
4357 RT_UNTRUSTED_VALIDATED_FENCE();
4358
4359 uint32_t const cbSrcAndLine = RT_ALIGN_32(pCmd->width * (pCmd->andMaskDepth + (pCmd->andMaskDepth == 15)), 32) / 8;
4360 uint32_t const cbSrcAndMask = cbSrcAndLine * pCmd->height;
4361 uint32_t const cbSrcXorLine = RT_ALIGN_32(pCmd->width * (pCmd->xorMaskDepth + (pCmd->xorMaskDepth == 15)), 32) / 8;
4362
4363 uint8_t const *pbSrcAndMask = (uint8_t const *)(pCmd + 1);
4364 uint8_t const *pbSrcXorMask = (uint8_t const *)(pCmd + 1) + cbSrcAndMask;
4365
4366 uint32_t const cx = pCmd->width;
4367 uint32_t const cy = pCmd->height;
4368
4369 /*
4370 * Convert the input to 1-bit AND mask and a 32-bit BRGA XOR mask.
4371 * The AND data uses 8-bit aligned scanlines.
4372 * The XOR data must be starting on a 32-bit boundrary.
4373 */
4374 uint32_t cbDstAndLine = RT_ALIGN_32(cx, 8) / 8;
4375 uint32_t cbDstAndMask = cbDstAndLine * cy;
4376 uint32_t cbDstXorMask = cx * sizeof(uint32_t) * cy;
4377 uint32_t cbCopy = RT_ALIGN_32(cbDstAndMask, 4) + cbDstXorMask;
4378
4379 uint8_t *pbCopy = (uint8_t *)RTMemAlloc(cbCopy);
4380 AssertReturnVoid(pbCopy);
4381
4382 /* Convert the AND mask. */
4383 uint8_t *pbDst = pbCopy;
4384 uint8_t const *pbSrc = pbSrcAndMask;
4385 switch (pCmd->andMaskDepth)
4386 {
4387 case 1:
4388 if (cbSrcAndLine == cbDstAndLine)
4389 memcpy(pbDst, pbSrc, cbSrcAndLine * cy);
4390 else
4391 {
4392 Assert(cbSrcAndLine > cbDstAndLine); /* lines are dword alined in source, but only byte in destination. */
4393 for (uint32_t y = 0; y < cy; y++)
4394 {
4395 memcpy(pbDst, pbSrc, cbDstAndLine);
4396 pbDst += cbDstAndLine;
4397 pbSrc += cbSrcAndLine;
4398 }
4399 }
4400 break;
4401 /* Should take the XOR mask into account for the multi-bit AND mask. */
4402 case 8:
4403 for (uint32_t y = 0; y < cy; y++)
4404 {
4405 for (uint32_t x = 0; x < cx; )
4406 {
4407 uint8_t bDst = 0;
4408 uint8_t fBit = 0x80;
4409 do
4410 {
4411 uintptr_t const idxPal = pbSrc[x] * 3;
4412 if ((( pThis->last_palette[idxPal]
4413 | (pThis->last_palette[idxPal] >> 8)
4414 | (pThis->last_palette[idxPal] >> 16)) & 0xff) > 0xfc)
4415 bDst |= fBit;
4416 fBit >>= 1;
4417 x++;
4418 } while (x < cx && (x & 7));
4419 pbDst[(x - 1) / 8] = bDst;
4420 }
4421 pbDst += cbDstAndLine;
4422 pbSrc += cbSrcAndLine;
4423 }
4424 break;
4425 case 15:
4426 for (uint32_t y = 0; y < cy; y++)
4427 {
4428 for (uint32_t x = 0; x < cx; )
4429 {
4430 uint8_t bDst = 0;
4431 uint8_t fBit = 0x80;
4432 do
4433 {
4434 if ((pbSrc[x * 2] | (pbSrc[x * 2 + 1] & 0x7f)) >= 0xfc)
4435 bDst |= fBit;
4436 fBit >>= 1;
4437 x++;
4438 } while (x < cx && (x & 7));
4439 pbDst[(x - 1) / 8] = bDst;
4440 }
4441 pbDst += cbDstAndLine;
4442 pbSrc += cbSrcAndLine;
4443 }
4444 break;
4445 case 16:
4446 for (uint32_t y = 0; y < cy; y++)
4447 {
4448 for (uint32_t x = 0; x < cx; )
4449 {
4450 uint8_t bDst = 0;
4451 uint8_t fBit = 0x80;
4452 do
4453 {
4454 if ((pbSrc[x * 2] | pbSrc[x * 2 + 1]) >= 0xfc)
4455 bDst |= fBit;
4456 fBit >>= 1;
4457 x++;
4458 } while (x < cx && (x & 7));
4459 pbDst[(x - 1) / 8] = bDst;
4460 }
4461 pbDst += cbDstAndLine;
4462 pbSrc += cbSrcAndLine;
4463 }
4464 break;
4465 case 24:
4466 for (uint32_t y = 0; y < cy; y++)
4467 {
4468 for (uint32_t x = 0; x < cx; )
4469 {
4470 uint8_t bDst = 0;
4471 uint8_t fBit = 0x80;
4472 do
4473 {
4474 if ((pbSrc[x * 3] | pbSrc[x * 3 + 1] | pbSrc[x * 3 + 2]) >= 0xfc)
4475 bDst |= fBit;
4476 fBit >>= 1;
4477 x++;
4478 } while (x < cx && (x & 7));
4479 pbDst[(x - 1) / 8] = bDst;
4480 }
4481 pbDst += cbDstAndLine;
4482 pbSrc += cbSrcAndLine;
4483 }
4484 break;
4485 case 32:
4486 for (uint32_t y = 0; y < cy; y++)
4487 {
4488 for (uint32_t x = 0; x < cx; )
4489 {
4490 uint8_t bDst = 0;
4491 uint8_t fBit = 0x80;
4492 do
4493 {
4494 if ((pbSrc[x * 4] | pbSrc[x * 4 + 1] | pbSrc[x * 4 + 2] | pbSrc[x * 4 + 3]) >= 0xfc)
4495 bDst |= fBit;
4496 fBit >>= 1;
4497 x++;
4498 } while (x < cx && (x & 7));
4499 pbDst[(x - 1) / 8] = bDst;
4500 }
4501 pbDst += cbDstAndLine;
4502 pbSrc += cbSrcAndLine;
4503 }
4504 break;
4505 default:
4506 RTMemFreeZ(pbCopy, cbCopy);
4507 AssertFailedReturnVoid();
4508 }
4509
4510 /* Convert the XOR mask. */
4511 uint32_t *pu32Dst = (uint32_t *)(pbCopy + RT_ALIGN_32(cbDstAndMask, 4));
4512 pbSrc = pbSrcXorMask;
4513 switch (pCmd->xorMaskDepth)
4514 {
4515 case 1:
4516 for (uint32_t y = 0; y < cy; y++)
4517 {
4518 for (uint32_t x = 0; x < cx; )
4519 {
4520 /* most significant bit is the left most one. */
4521 uint8_t bSrc = pbSrc[x / 8];
4522 do
4523 {
4524 *pu32Dst++ = bSrc & 0x80 ? UINT32_C(0x00ffffff) : 0;
4525 bSrc <<= 1;
4526 x++;
4527 } while ((x & 7) && x < cx);
4528 }
4529 pbSrc += cbSrcXorLine;
4530 }
4531 break;
4532 case 8:
4533 for (uint32_t y = 0; y < cy; y++)
4534 {
4535 for (uint32_t x = 0; x < cx; x++)
4536 {
4537 uint32_t u = pThis->last_palette[pbSrc[x]];
4538 *pu32Dst++ = u;//RT_MAKE_U32_FROM_U8(RT_BYTE1(u), RT_BYTE2(u), RT_BYTE3(u), 0);
4539 }
4540 pbSrc += cbSrcXorLine;
4541 }
4542 break;
4543 case 15: /* Src: RGB-5-5-5 */
4544 for (uint32_t y = 0; y < cy; y++)
4545 {
4546 for (uint32_t x = 0; x < cx; x++)
4547 {
4548 uint32_t const uValue = RT_MAKE_U16(pbSrc[x * 2], pbSrc[x * 2 + 1]);
4549 *pu32Dst++ = RT_MAKE_U32_FROM_U8(( uValue & 0x1f) << 3,
4550 ((uValue >> 5) & 0x1f) << 3,
4551 ((uValue >> 10) & 0x1f) << 3, 0);
4552 }
4553 pbSrc += cbSrcXorLine;
4554 }
4555 break;
4556 case 16: /* Src: RGB-5-6-5 */
4557 for (uint32_t y = 0; y < cy; y++)
4558 {
4559 for (uint32_t x = 0; x < cx; x++)
4560 {
4561 uint32_t const uValue = RT_MAKE_U16(pbSrc[x * 2], pbSrc[x * 2 + 1]);
4562 *pu32Dst++ = RT_MAKE_U32_FROM_U8(( uValue & 0x1f) << 3,
4563 ((uValue >> 5) & 0x3f) << 2,
4564 ((uValue >> 11) & 0x1f) << 3, 0);
4565 }
4566 pbSrc += cbSrcXorLine;
4567 }
4568 break;
4569 case 24:
4570 for (uint32_t y = 0; y < cy; y++)
4571 {
4572 for (uint32_t x = 0; x < cx; x++)
4573 *pu32Dst++ = RT_MAKE_U32_FROM_U8(pbSrc[x*3], pbSrc[x*3 + 1], pbSrc[x*3 + 2], 0);
4574 pbSrc += cbSrcXorLine;
4575 }
4576 break;
4577 case 32:
4578 for (uint32_t y = 0; y < cy; y++)
4579 {
4580 for (uint32_t x = 0; x < cx; x++)
4581 *pu32Dst++ = RT_MAKE_U32_FROM_U8(pbSrc[x*4], pbSrc[x*4 + 1], pbSrc[x*4 + 2], 0);
4582 pbSrc += cbSrcXorLine;
4583 }
4584 break;
4585 default:
4586 RTMemFreeZ(pbCopy, cbCopy);
4587 AssertFailedReturnVoid();
4588 }
4589
4590 /*
4591 * Pass it to the frontend/whatever.
4592 */
4593 vmsvgaR3InstallNewCursor(pThisCC, pSvgaR3State, false /*fAlpha*/, pCmd->hotspotX, pCmd->hotspotY,
4594 cx, cy, pbCopy, cbCopy);
4595}
4596
4597
4598/* SVGA_CMD_DEFINE_ALPHA_CURSOR */
4599void vmsvgaR3CmdDefineAlphaCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineAlphaCursor const *pCmd)
4600{
4601 RT_NOREF(pThis);
4602 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4603
4604 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineAlphaCursor);
4605 Log(("VMSVGA cmd: SVGA_CMD_DEFINE_ALPHA_CURSOR id=%d size (%dx%d) hotspot (%d,%d)\n", pCmd->id, pCmd->width, pCmd->height, pCmd->hotspotX, pCmd->hotspotY));
4606
4607 /* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */
4608 ASSERT_GUEST_RETURN_VOID(pCmd->height < 2048 && pCmd->width < 2048);
4609 RT_UNTRUSTED_VALIDATED_FENCE();
4610
4611 /* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */
4612 uint32_t cbAndMask = (pCmd->width + 7) / 8 * pCmd->height; /* size of the AND mask */
4613 cbAndMask = ((cbAndMask + 3) & ~3); /* + gap for alignment */
4614 uint32_t cbXorMask = pCmd->width * sizeof(uint32_t) * pCmd->height; /* + size of the XOR mask (32-bit BRGA format) */
4615 uint32_t cbCursorShape = cbAndMask + cbXorMask;
4616
4617 uint8_t *pCursorCopy = (uint8_t *)RTMemAlloc(cbCursorShape);
4618 AssertPtrReturnVoid(pCursorCopy);
4619
4620 /* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */
4621 memset(pCursorCopy, 0xff, cbAndMask);
4622 /* Colour data */
4623 memcpy(pCursorCopy + cbAndMask, pCmd + 1, cbXorMask);
4624
4625 vmsvgaR3InstallNewCursor(pThisCC, pSvgaR3State, true /*fAlpha*/, pCmd->hotspotX, pCmd->hotspotY,
4626 pCmd->width, pCmd->height, pCursorCopy, cbCursorShape);
4627}
4628
4629
4630/* SVGA_CMD_ESCAPE */
4631void vmsvgaR3CmdEscape(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdEscape const *pCmd)
4632{
4633 RT_NOREF(pThis);
4634 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4635
4636 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdEscape);
4637
4638 if (pCmd->nsid == SVGA_ESCAPE_NSID_VMWARE)
4639 {
4640 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(uint32_t));
4641 RT_UNTRUSTED_VALIDATED_FENCE();
4642
4643 uint32_t const cmd = *(uint32_t *)(pCmd + 1);
4644 Log(("SVGA_CMD_ESCAPE (%#x %#x) VMWARE cmd=%#x\n", pCmd->nsid, pCmd->size, cmd));
4645
4646 switch (cmd)
4647 {
4648 case SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS:
4649 {
4650 SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pCmd + 1);
4651 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(pVideoCmd->header));
4652 RT_UNTRUSTED_VALIDATED_FENCE();
4653
4654 uint32_t const cRegs = (pCmd->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]);
4655
4656 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: stream %#x\n", pVideoCmd->header.streamId));
4657 for (uint32_t iReg = 0; iReg < cRegs; iReg++)
4658 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: reg %#x val %#x\n", pVideoCmd->items[iReg].registerId, pVideoCmd->items[iReg].value));
4659 RT_NOREF_PV(pVideoCmd);
4660 break;
4661 }
4662
4663 case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH:
4664 {
4665 SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pCmd + 1);
4666 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(*pVideoCmd));
4667 Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %#x\n", pVideoCmd->streamId));
4668 RT_NOREF_PV(pVideoCmd);
4669 break;
4670 }
4671
4672 default:
4673 Log(("SVGA_CMD_ESCAPE: Unknown vmware escape: %#x\n", cmd));
4674 break;
4675 }
4676 }
4677 else
4678 Log(("SVGA_CMD_ESCAPE %#x %#x\n", pCmd->nsid, pCmd->size));
4679}
4680
4681
4682/* SVGA_CMD_DEFINE_SCREEN */
4683void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineScreen const *pCmd)
4684{
4685 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4686
4687 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineScreen);
4688 Log(("SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d) %d:0x%x 0x%x\n",
4689 pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y,
4690 pCmd->screen.backingStore.ptr.gmrId, pCmd->screen.backingStore.ptr.offset, pCmd->screen.backingStore.pitch));
4691
4692 uint32_t const idScreen = pCmd->screen.id;
4693 ASSERT_GUEST_RETURN_VOID(idScreen < RT_ELEMENTS(pSvgaR3State->aScreens));
4694
4695 uint32_t const uWidth = pCmd->screen.size.width;
4696 ASSERT_GUEST_RETURN_VOID(uWidth <= pThis->svga.u32MaxWidth);
4697
4698 uint32_t const uHeight = pCmd->screen.size.height;
4699 ASSERT_GUEST_RETURN_VOID(uHeight <= pThis->svga.u32MaxHeight);
4700
4701 uint32_t const cbWidth = uWidth * ((32 + 7) / 8); /** @todo 32? */
4702 uint32_t const cbPitch = pCmd->screen.backingStore.pitch ? pCmd->screen.backingStore.pitch : cbWidth;
4703 ASSERT_GUEST_RETURN_VOID(cbWidth <= cbPitch);
4704
4705 uint32_t const uScreenOffset = pCmd->screen.backingStore.ptr.offset;
4706 ASSERT_GUEST_RETURN_VOID(uScreenOffset < pThis->vram_size);
4707
4708 uint32_t const cbVram = pThis->vram_size - uScreenOffset;
4709 /* If we have a not zero pitch, then height can't exceed the available VRAM. */
4710 ASSERT_GUEST_RETURN_VOID( (uHeight == 0 && cbPitch == 0)
4711 || (cbPitch > 0 && uHeight <= cbVram / cbPitch));
4712 RT_UNTRUSTED_VALIDATED_FENCE();
4713
4714 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen];
4715 pScreen->fDefined = true;
4716 pScreen->fModified = true;
4717 pScreen->fuScreen = pCmd->screen.flags;
4718 pScreen->idScreen = idScreen;
4719 if (!RT_BOOL(pCmd->screen.flags & (SVGA_SCREEN_DEACTIVATE | SVGA_SCREEN_BLANKING)))
4720 {
4721 /* Not blanked. */
4722 ASSERT_GUEST_RETURN_VOID(uWidth > 0 && uHeight > 0);
4723 RT_UNTRUSTED_VALIDATED_FENCE();
4724
4725 pScreen->xOrigin = pCmd->screen.root.x;
4726 pScreen->yOrigin = pCmd->screen.root.y;
4727 pScreen->cWidth = uWidth;
4728 pScreen->cHeight = uHeight;
4729 pScreen->offVRAM = uScreenOffset;
4730 pScreen->cbPitch = cbPitch;
4731 pScreen->cBpp = 32;
4732 }
4733 else
4734 {
4735 /* Screen blanked. Keep old values. */
4736 }
4737
4738 pThis->svga.fGFBRegisters = false;
4739 vmsvgaR3ChangeMode(pThis, pThisCC);
4740
4741#ifdef VBOX_WITH_VMSVGA3D
4742 if (RT_LIKELY(pThis->svga.f3DEnabled))
4743 vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
4744#endif
4745}
4746
4747
4748/* SVGA_CMD_DESTROY_SCREEN */
4749void vmsvgaR3CmdDestroyScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDestroyScreen const *pCmd)
4750{
4751 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4752
4753 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDestroyScreen);
4754 Log(("SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId));
4755
4756 uint32_t const idScreen = pCmd->screenId;
4757 ASSERT_GUEST_RETURN_VOID(idScreen < RT_ELEMENTS(pSvgaR3State->aScreens));
4758 RT_UNTRUSTED_VALIDATED_FENCE();
4759
4760 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen];
4761 pScreen->fModified = true;
4762 pScreen->fDefined = false;
4763 pScreen->idScreen = idScreen;
4764
4765#ifdef VBOX_WITH_VMSVGA3D
4766 if (RT_LIKELY(pThis->svga.f3DEnabled))
4767 vmsvga3dDestroyScreen(pThisCC, pScreen);
4768#endif
4769 vmsvgaR3ChangeMode(pThis, pThisCC);
4770}
4771
4772
4773/* SVGA_CMD_DEFINE_GMRFB */
4774void vmsvgaR3CmdDefineGMRFB(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineGMRFB const *pCmd)
4775{
4776 RT_NOREF(pThis);
4777 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4778
4779 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmrFb);
4780 Log(("SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n",
4781 pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.bitsPerPixel, pCmd->format.colorDepth));
4782
4783 pSvgaR3State->GMRFB.ptr = pCmd->ptr;
4784 pSvgaR3State->GMRFB.bytesPerLine = pCmd->bytesPerLine;
4785 pSvgaR3State->GMRFB.format = pCmd->format;
4786}
4787
4788
4789/* SVGA_CMD_BLIT_GMRFB_TO_SCREEN */
4790void vmsvgaR3CmdBlitGMRFBToScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdBlitGMRFBToScreen const *pCmd)
4791{
4792 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4793
4794 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdBlitGmrFbToScreen);
4795 Log(("SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n",
4796 pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom));
4797
4798 ASSERT_GUEST_RETURN_VOID(pCmd->destScreenId < RT_ELEMENTS(pSvgaR3State->aScreens));
4799 RT_UNTRUSTED_VALIDATED_FENCE();
4800
4801 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->destScreenId);
4802 AssertPtrReturnVoid(pScreen);
4803
4804 /** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp ? */
4805 AssertReturnVoid(pSvgaR3State->GMRFB.format.bitsPerPixel == pScreen->cBpp);
4806
4807 /* Clip destRect to the screen dimensions. */
4808 SVGASignedRect screenRect;
4809 screenRect.left = 0;
4810 screenRect.top = 0;
4811 screenRect.right = pScreen->cWidth;
4812 screenRect.bottom = pScreen->cHeight;
4813 SVGASignedRect clipRect = pCmd->destRect;
4814 vmsvgaR3ClipRect(&screenRect, &clipRect);
4815 RT_UNTRUSTED_VALIDATED_FENCE();
4816
4817 uint32_t const width = clipRect.right - clipRect.left;
4818 uint32_t const height = clipRect.bottom - clipRect.top;
4819
4820 if ( width == 0
4821 || height == 0)
4822 return; /* Nothing to do. */
4823
4824 int32_t const srcx = pCmd->srcOrigin.x + (clipRect.left - pCmd->destRect.left);
4825 int32_t const srcy = pCmd->srcOrigin.y + (clipRect.top - pCmd->destRect.top);
4826
4827 /* Copy the defined by GMRFB image to the screen 0 VRAM area.
4828 * Prepare parameters for vmsvgaR3GmrTransfer.
4829 */
4830 AssertReturnVoid(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */
4831
4832 /* Destination: host buffer which describes the screen 0 VRAM.
4833 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer.
4834 */
4835 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM;
4836 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch :
4837 width * (RT_ALIGN(pScreen->cBpp, 8) / 8);
4838 uint32_t cbHstBuf = cbScanline * pScreen->cHeight;
4839 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM)
4840 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */
4841 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8
4842 + cbScanline * clipRect.top;
4843 int32_t const cbHstPitch = cbScanline;
4844
4845 /* Source: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */
4846 SVGAGuestPtr const gstPtr = pSvgaR3State->GMRFB.ptr;
4847 uint32_t const offGst = (srcx * RT_ALIGN(pSvgaR3State->GMRFB.format.bitsPerPixel, 8)) / 8
4848 + pSvgaR3State->GMRFB.bytesPerLine * srcy;
4849 int32_t const cbGstPitch = pSvgaR3State->GMRFB.bytesPerLine;
4850
4851 int rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_WRITE_HOST_VRAM,
4852 pbHstBuf, cbHstBuf, offHst, cbHstPitch,
4853 gstPtr, offGst, cbGstPitch,
4854 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height);
4855 AssertRC(rc);
4856 vmsvgaR3UpdateScreen(pThisCC, pScreen, clipRect.left, clipRect.top, width, height);
4857}
4858
4859
4860/* SVGA_CMD_BLIT_SCREEN_TO_GMRFB */
4861void vmsvgaR3CmdBlitScreenToGMRFB(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdBlitScreenToGMRFB const *pCmd)
4862{
4863 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4864
4865 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdBlitScreentoGmrFb);
4866 /* Note! This can fetch 3d render results as well!! */
4867 Log(("SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n",
4868 pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom));
4869
4870 ASSERT_GUEST_RETURN_VOID(pCmd->srcScreenId < RT_ELEMENTS(pSvgaR3State->aScreens));
4871 RT_UNTRUSTED_VALIDATED_FENCE();
4872
4873 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->srcScreenId);
4874 AssertPtrReturnVoid(pScreen);
4875
4876 /** @todo Support GMRFB.format.bitsPerPixel != pThis->svga.uBpp ? */
4877 AssertReturnVoid(pSvgaR3State->GMRFB.format.bitsPerPixel == pScreen->cBpp);
4878
4879 /* Clip destRect to the screen dimensions. */
4880 SVGASignedRect screenRect;
4881 screenRect.left = 0;
4882 screenRect.top = 0;
4883 screenRect.right = pScreen->cWidth;
4884 screenRect.bottom = pScreen->cHeight;
4885 SVGASignedRect clipRect = pCmd->srcRect;
4886 vmsvgaR3ClipRect(&screenRect, &clipRect);
4887 RT_UNTRUSTED_VALIDATED_FENCE();
4888
4889 uint32_t const width = clipRect.right - clipRect.left;
4890 uint32_t const height = clipRect.bottom - clipRect.top;
4891
4892 if ( width == 0
4893 || height == 0)
4894 return; /* Nothing to do. */
4895
4896 int32_t const dstx = pCmd->destOrigin.x + (clipRect.left - pCmd->srcRect.left);
4897 int32_t const dsty = pCmd->destOrigin.y + (clipRect.top - pCmd->srcRect.top);
4898
4899 /* Copy the defined by GMRFB image to the screen 0 VRAM area.
4900 * Prepare parameters for vmsvgaR3GmrTransfer.
4901 */
4902 AssertReturnVoid(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */
4903
4904 /* Source: host buffer which describes the screen 0 VRAM.
4905 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer.
4906 */
4907 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM;
4908 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch :
4909 width * (RT_ALIGN(pScreen->cBpp, 8) / 8);
4910 uint32_t cbHstBuf = cbScanline * pScreen->cHeight;
4911 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM)
4912 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */
4913 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8
4914 + cbScanline * clipRect.top;
4915 int32_t const cbHstPitch = cbScanline;
4916
4917 /* Destination: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */
4918 SVGAGuestPtr const gstPtr = pSvgaR3State->GMRFB.ptr;
4919 uint32_t const offGst = (dstx * RT_ALIGN(pSvgaR3State->GMRFB.format.bitsPerPixel, 8)) / 8
4920 + pSvgaR3State->GMRFB.bytesPerLine * dsty;
4921 int32_t const cbGstPitch = pSvgaR3State->GMRFB.bytesPerLine;
4922
4923 int rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_READ_HOST_VRAM,
4924 pbHstBuf, cbHstBuf, offHst, cbHstPitch,
4925 gstPtr, offGst, cbGstPitch,
4926 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height);
4927 AssertRC(rc);
4928}
4929
4930
4931/* SVGA_CMD_ANNOTATION_FILL */
4932void vmsvgaR3CmdAnnotationFill(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdAnnotationFill const *pCmd)
4933{
4934 RT_NOREF(pThis);
4935 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4936
4937 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdAnnotationFill);
4938 Log(("SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.r, pCmd->color.g, pCmd->color.b));
4939
4940 pSvgaR3State->colorAnnotation = pCmd->color;
4941}
4942
4943
4944/* SVGA_CMD_ANNOTATION_COPY */
4945void vmsvgaR3CmdAnnotationCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdAnnotationCopy const *pCmd)
4946{
4947 RT_NOREF(pThis, pCmd);
4948 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4949
4950 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdAnnotationCopy);
4951 Log(("SVGA_CMD_ANNOTATION_COPY srcOrigin %d,%d, srcScreenId %u\n", pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->srcScreenId));
4952
4953 AssertFailed();
4954}
4955
4956
4957#ifdef VBOX_WITH_VMSVGA3D
4958/* SVGA_CMD_DEFINE_GMR2 */
4959void vmsvgaR3CmdDefineGMR2(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineGMR2 const *pCmd)
4960{
4961 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4962
4963 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2);
4964 Log(("SVGA_CMD_DEFINE_GMR2 id=%#x %#x pages\n", pCmd->gmrId, pCmd->numPages));
4965
4966 /* Validate current GMR id. */
4967 ASSERT_GUEST_RETURN_VOID(pCmd->gmrId < pThis->svga.cGMR);
4968 ASSERT_GUEST_RETURN_VOID(pCmd->numPages <= VMSVGA_MAX_GMR_PAGES);
4969 RT_UNTRUSTED_VALIDATED_FENCE();
4970
4971 if (!pCmd->numPages)
4972 {
4973 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2Free);
4974 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId);
4975 }
4976 else
4977 {
4978 PGMR pGMR = &pSvgaR3State->paGMR[pCmd->gmrId];
4979 if (pGMR->cMaxPages)
4980 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2Modify);
4981
4982 /* Not sure if we should always free the descriptor, but for simplicity
4983 we do so if the new size is smaller than the current. */
4984 /** @todo always free the descriptor in SVGA_CMD_DEFINE_GMR2? */
4985 if (pGMR->cbTotal / X86_PAGE_SIZE > pGMR->cMaxPages)
4986 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId);
4987
4988 pGMR->cMaxPages = pCmd->numPages;
4989 /* The rest is done by the REMAP_GMR2 command. */
4990 }
4991}
4992
4993
4994/* SVGA_CMD_REMAP_GMR2 */
4995void vmsvgaR3CmdRemapGMR2(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRemapGMR2 const *pCmd)
4996{
4997 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
4998
4999 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRemapGmr2);
5000 Log(("SVGA_CMD_REMAP_GMR2 id=%#x flags=%#x offset=%#x npages=%#x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));
5001
5002 /* Validate current GMR id and size. */
5003 ASSERT_GUEST_RETURN_VOID(pCmd->gmrId < pThis->svga.cGMR);
5004 RT_UNTRUSTED_VALIDATED_FENCE();
5005 PGMR pGMR = &pSvgaR3State->paGMR[pCmd->gmrId];
5006 ASSERT_GUEST_RETURN_VOID( (uint64_t)pCmd->offsetPages + pCmd->numPages
5007 <= RT_MIN(pGMR->cMaxPages, RT_MIN(VMSVGA_MAX_GMR_PAGES, UINT32_MAX / X86_PAGE_SIZE)));
5008 ASSERT_GUEST_RETURN_VOID(!pCmd->offsetPages || pGMR->paDesc); /** @todo */
5009
5010 if (pCmd->numPages == 0)
5011 return;
5012 RT_UNTRUSTED_VALIDATED_FENCE();
5013
5014 /* Calc new total page count so we can use it instead of cMaxPages for allocations below. */
5015 uint32_t const cNewTotalPages = RT_MAX(pGMR->cbTotal >> X86_PAGE_SHIFT, pCmd->offsetPages + pCmd->numPages);
5016
5017 /*
5018 * We flatten the existing descriptors into a page array, overwrite the
5019 * pages specified in this command and then recompress the descriptor.
5020 */
5021 /** @todo Optimize the GMR remap algorithm! */
5022
5023 /* Save the old page descriptors as an array of page frame numbers (address >> X86_PAGE_SHIFT) */
5024 uint64_t *paNewPage64 = NULL;
5025 if (pGMR->paDesc)
5026 {
5027 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRemapGmr2Modify);
5028
5029 paNewPage64 = (uint64_t *)RTMemAllocZ(cNewTotalPages * sizeof(uint64_t));
5030 AssertPtrReturnVoid(paNewPage64);
5031
5032 uint32_t idxPage = 0;
5033 for (uint32_t i = 0; i < pGMR->numDescriptors; i++)
5034 for (uint32_t j = 0; j < pGMR->paDesc[i].numPages; j++)
5035 paNewPage64[idxPage++] = (pGMR->paDesc[i].GCPhys + j * X86_PAGE_SIZE) >> X86_PAGE_SHIFT;
5036 AssertReturnVoidStmt(idxPage == pGMR->cbTotal >> X86_PAGE_SHIFT, RTMemFree(paNewPage64));
5037 RT_UNTRUSTED_VALIDATED_FENCE();
5038 }
5039
5040 /* Free the old GMR if present. */
5041 if (pGMR->paDesc)
5042 RTMemFree(pGMR->paDesc);
5043
5044 /* Allocate the maximum amount possible (everything non-continuous) */
5045 PVMSVGAGMRDESCRIPTOR paDescs;
5046 pGMR->paDesc = paDescs = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(cNewTotalPages * sizeof(VMSVGAGMRDESCRIPTOR));
5047 AssertReturnVoidStmt(paDescs, RTMemFree(paNewPage64));
5048
5049 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
5050 {
5051 /** @todo */
5052 AssertFailed();
5053 pGMR->numDescriptors = 0;
5054 }
5055 else
5056 {
5057 uint32_t *paPages32 = (uint32_t *)(pCmd + 1);
5058 uint64_t *paPages64 = (uint64_t *)(pCmd + 1);
5059 bool fGCPhys64 = RT_BOOL(pCmd->flags & SVGA_REMAP_GMR2_PPN64);
5060
5061 uint32_t cPages;
5062 if (paNewPage64)
5063 {
5064 /* Overwrite the old page array with the new page values. */
5065 if (fGCPhys64)
5066 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++)
5067 paNewPage64[i] = paPages64[i - pCmd->offsetPages];
5068 else
5069 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++)
5070 paNewPage64[i] = paPages32[i - pCmd->offsetPages];
5071
5072 /* Use the updated page array instead of the command data. */
5073 fGCPhys64 = true;
5074 paPages64 = paNewPage64;
5075 cPages = cNewTotalPages;
5076 }
5077 else
5078 cPages = pCmd->numPages;
5079
5080 /* The first page. */
5081 /** @todo The 0x00000FFFFFFFFFFF mask limits to 44 bits and should not be
5082 * applied to paNewPage64. */
5083 RTGCPHYS GCPhys;
5084 if (fGCPhys64)
5085 GCPhys = (paPages64[0] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
5086 else
5087 GCPhys = (RTGCPHYS)paPages32[0] << PAGE_SHIFT;
5088 paDescs[0].GCPhys = GCPhys;
5089 paDescs[0].numPages = 1;
5090
5091 /* Subsequent pages. */
5092 uint32_t iDescriptor = 0;
5093 for (uint32_t i = 1; i < cPages; i++)
5094 {
5095 if (pCmd->flags & SVGA_REMAP_GMR2_PPN64)
5096 GCPhys = (paPages64[i] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
5097 else
5098 GCPhys = (RTGCPHYS)paPages32[i] << X86_PAGE_SHIFT;
5099
5100 /* Continuous physical memory? */
5101 if (GCPhys == paDescs[iDescriptor].GCPhys + paDescs[iDescriptor].numPages * X86_PAGE_SIZE)
5102 {
5103 Assert(paDescs[iDescriptor].numPages);
5104 paDescs[iDescriptor].numPages++;
5105 Log5Func(("Page %x GCPhys=%RGp successor\n", i, GCPhys));
5106 }
5107 else
5108 {
5109 iDescriptor++;
5110 paDescs[iDescriptor].GCPhys = GCPhys;
5111 paDescs[iDescriptor].numPages = 1;
5112 Log5Func(("Page %x GCPhys=%RGp\n", i, paDescs[iDescriptor].GCPhys));
5113 }
5114 }
5115
5116 pGMR->cbTotal = cNewTotalPages << X86_PAGE_SHIFT;
5117 Log5Func(("Nr of descriptors %x; cbTotal=%#x\n", iDescriptor + 1, cNewTotalPages));
5118 pGMR->numDescriptors = iDescriptor + 1;
5119 }
5120
5121 if (paNewPage64)
5122 RTMemFree(paNewPage64);
5123}
5124
5125
5126/**
5127 * Free the specified GMR
5128 *
5129 * @param pThisCC The VGA/VMSVGA state for ring-3.
5130 * @param idGMR GMR id
5131 */
5132void vmsvgaR3GmrFree(PVGASTATECC pThisCC, uint32_t idGMR)
5133{
5134 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
5135
5136 /* Free the old descriptor if present. */
5137 PGMR pGMR = &pSVGAState->paGMR[idGMR];
5138 if ( pGMR->numDescriptors
5139 || pGMR->paDesc /* needed till we implement SVGA_REMAP_GMR2_VIA_GMR */)
5140 {
5141# ifdef DEBUG_GMR_ACCESS
5142 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pThisCC->pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3DeregisterGmr, 2, pDevIns, idGMR);
5143# endif
5144
5145 Assert(pGMR->paDesc);
5146 RTMemFree(pGMR->paDesc);
5147 pGMR->paDesc = NULL;
5148 pGMR->numDescriptors = 0;
5149 pGMR->cbTotal = 0;
5150 pGMR->cMaxPages = 0;
5151 }
5152 Assert(!pGMR->cMaxPages);
5153 Assert(!pGMR->cbTotal);
5154}
5155#endif /* VBOX_WITH_VMSVGA3D */
5156
5157
5158/**
5159 * Copy between a GMR and a host memory buffer.
5160 *
5161 * @returns VBox status code.
5162 * @param pThis The shared VGA/VMSVGA instance data.
5163 * @param pThisCC The VGA/VMSVGA state for ring-3.
5164 * @param enmTransferType Transfer type (read/write)
5165 * @param pbHstBuf Host buffer pointer (valid)
5166 * @param cbHstBuf Size of host buffer (valid)
5167 * @param offHst Host buffer offset of the first scanline
5168 * @param cbHstPitch Destination buffer pitch
5169 * @param gstPtr GMR description
5170 * @param offGst Guest buffer offset of the first scanline
5171 * @param cbGstPitch Guest buffer pitch
5172 * @param cbWidth Width in bytes to copy
5173 * @param cHeight Number of scanllines to copy
5174 */
5175int vmsvgaR3GmrTransfer(PVGASTATE pThis, PVGASTATECC pThisCC, const SVGA3dTransferType enmTransferType,
5176 uint8_t *pbHstBuf, uint32_t cbHstBuf, uint32_t offHst, int32_t cbHstPitch,
5177 SVGAGuestPtr gstPtr, uint32_t offGst, int32_t cbGstPitch,
5178 uint32_t cbWidth, uint32_t cHeight)
5179{
5180 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
5181 PPDMDEVINS pDevIns = pThisCC->pDevIns; /* simpler */
5182 int rc;
5183
5184 LogFunc(("%s host %p size=%d offset %d pitch=%d; guest gmr=%#x:%#x offset=%d pitch=%d cbWidth=%d cHeight=%d\n",
5185 enmTransferType == SVGA3D_READ_HOST_VRAM ? "WRITE" : "READ", /* GMR op: READ host VRAM means WRITE GMR */
5186 pbHstBuf, cbHstBuf, offHst, cbHstPitch,
5187 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cbWidth, cHeight));
5188 AssertReturn(cbWidth && cHeight, VERR_INVALID_PARAMETER);
5189
5190 PGMR pGMR;
5191 uint32_t cbGmr; /* The GMR size in bytes. */
5192 if (gstPtr.gmrId == SVGA_GMR_FRAMEBUFFER)
5193 {
5194 pGMR = NULL;
5195 cbGmr = pThis->vram_size;
5196 }
5197 else
5198 {
5199 AssertReturn(gstPtr.gmrId < pThis->svga.cGMR, VERR_INVALID_PARAMETER);
5200 RT_UNTRUSTED_VALIDATED_FENCE();
5201 pGMR = &pSVGAState->paGMR[gstPtr.gmrId];
5202 cbGmr = pGMR->cbTotal;
5203 }
5204
5205 /*
5206 * GMR
5207 */
5208 /* Calculate GMR offset of the data to be copied. */
5209 AssertMsgReturn(gstPtr.offset < cbGmr,
5210 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
5211 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
5212 VERR_INVALID_PARAMETER);
5213 RT_UNTRUSTED_VALIDATED_FENCE();
5214 AssertMsgReturn(offGst < cbGmr - gstPtr.offset,
5215 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
5216 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
5217 VERR_INVALID_PARAMETER);
5218 RT_UNTRUSTED_VALIDATED_FENCE();
5219 uint32_t const offGmr = offGst + gstPtr.offset; /* Offset in the GMR, where the first scanline is located. */
5220
5221 /* Verify that cbWidth is less than scanline and fits into the GMR. */
5222 uint32_t const cbGmrScanline = cbGstPitch > 0 ? cbGstPitch : -cbGstPitch;
5223 AssertMsgReturn(cbGmrScanline != 0,
5224 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
5225 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
5226 VERR_INVALID_PARAMETER);
5227 RT_UNTRUSTED_VALIDATED_FENCE();
5228 AssertMsgReturn(cbWidth <= cbGmrScanline,
5229 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
5230 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
5231 VERR_INVALID_PARAMETER);
5232 AssertMsgReturn(cbWidth <= cbGmr - offGmr,
5233 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
5234 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
5235 VERR_INVALID_PARAMETER);
5236 RT_UNTRUSTED_VALIDATED_FENCE();
5237
5238 /* How many bytes are available for the data in the GMR. */
5239 uint32_t const cbGmrLeft = cbGstPitch > 0 ? cbGmr - offGmr : offGmr + cbWidth;
5240
5241 /* How many scanlines would fit into the available data. */
5242 uint32_t cGmrScanlines = cbGmrLeft / cbGmrScanline;
5243 uint32_t const cbGmrLastScanline = cbGmrLeft - cGmrScanlines * cbGmrScanline; /* Slack space. */
5244 if (cbWidth <= cbGmrLastScanline)
5245 ++cGmrScanlines;
5246
5247 if (cHeight > cGmrScanlines)
5248 cHeight = cGmrScanlines;
5249
5250 AssertMsgReturn(cHeight > 0,
5251 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
5252 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
5253 VERR_INVALID_PARAMETER);
5254 RT_UNTRUSTED_VALIDATED_FENCE();
5255
5256 /*
5257 * Host buffer.
5258 */
5259 AssertMsgReturn(offHst < cbHstBuf,
5260 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
5261 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
5262 VERR_INVALID_PARAMETER);
5263
5264 /* Verify that cbWidth is less than scanline and fits into the buffer. */
5265 uint32_t const cbHstScanline = cbHstPitch > 0 ? cbHstPitch : -cbHstPitch;
5266 AssertMsgReturn(cbHstScanline != 0,
5267 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
5268 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
5269 VERR_INVALID_PARAMETER);
5270 AssertMsgReturn(cbWidth <= cbHstScanline,
5271 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
5272 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
5273 VERR_INVALID_PARAMETER);
5274 AssertMsgReturn(cbWidth <= cbHstBuf - offHst,
5275 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
5276 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
5277 VERR_INVALID_PARAMETER);
5278
5279 /* How many bytes are available for the data in the buffer. */
5280 uint32_t const cbHstLeft = cbHstPitch > 0 ? cbHstBuf - offHst : offHst + cbWidth;
5281
5282 /* How many scanlines would fit into the available data. */
5283 uint32_t cHstScanlines = cbHstLeft / cbHstScanline;
5284 uint32_t const cbHstLastScanline = cbHstLeft - cHstScanlines * cbHstScanline; /* Slack space. */
5285 if (cbWidth <= cbHstLastScanline)
5286 ++cHstScanlines;
5287
5288 if (cHeight > cHstScanlines)
5289 cHeight = cHstScanlines;
5290
5291 AssertMsgReturn(cHeight > 0,
5292 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
5293 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
5294 VERR_INVALID_PARAMETER);
5295
5296 uint8_t *pbHst = pbHstBuf + offHst;
5297
5298 /* Shortcut for the framebuffer. */
5299 if (gstPtr.gmrId == SVGA_GMR_FRAMEBUFFER)
5300 {
5301 uint8_t *pbGst = pThisCC->pbVRam + offGmr;
5302
5303 uint8_t const *pbSrc;
5304 int32_t cbSrcPitch;
5305 uint8_t *pbDst;
5306 int32_t cbDstPitch;
5307
5308 if (enmTransferType == SVGA3D_READ_HOST_VRAM)
5309 {
5310 pbSrc = pbHst;
5311 cbSrcPitch = cbHstPitch;
5312 pbDst = pbGst;
5313 cbDstPitch = cbGstPitch;
5314 }
5315 else
5316 {
5317 pbSrc = pbGst;
5318 cbSrcPitch = cbGstPitch;
5319 pbDst = pbHst;
5320 cbDstPitch = cbHstPitch;
5321 }
5322
5323 if ( cbWidth == (uint32_t)cbGstPitch
5324 && cbGstPitch == cbHstPitch)
5325 {
5326 /* Entire scanlines, positive pitch. */
5327 memcpy(pbDst, pbSrc, cbWidth * cHeight);
5328 }
5329 else
5330 {
5331 for (uint32_t i = 0; i < cHeight; ++i)
5332 {
5333 memcpy(pbDst, pbSrc, cbWidth);
5334
5335 pbDst += cbDstPitch;
5336 pbSrc += cbSrcPitch;
5337 }
5338 }
5339 return VINF_SUCCESS;
5340 }
5341
5342 AssertPtrReturn(pGMR, VERR_INVALID_PARAMETER);
5343 AssertReturn(pGMR->numDescriptors > 0, VERR_INVALID_PARAMETER);
5344
5345 PVMSVGAGMRDESCRIPTOR const paDesc = pGMR->paDesc; /* Local copy of the pointer. */
5346 uint32_t iDesc = 0; /* Index in the descriptor array. */
5347 uint32_t offDesc = 0; /* GMR offset of the current descriptor. */
5348 uint32_t offGmrScanline = offGmr; /* GMR offset of the scanline which is being copied. */
5349 uint8_t *pbHstScanline = pbHst; /* Host address of the scanline which is being copied. */
5350 for (uint32_t i = 0; i < cHeight; ++i)
5351 {
5352 uint32_t cbCurrentWidth = cbWidth;
5353 uint32_t offGmrCurrent = offGmrScanline;
5354 uint8_t *pbCurrentHost = pbHstScanline;
5355
5356 /* Find the right descriptor */
5357 while (offDesc + paDesc[iDesc].numPages * PAGE_SIZE <= offGmrCurrent)
5358 {
5359 offDesc += paDesc[iDesc].numPages * PAGE_SIZE;
5360 AssertReturn(offDesc < pGMR->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
5361 ++iDesc;
5362 AssertReturn(iDesc < pGMR->numDescriptors, VERR_INTERNAL_ERROR);
5363 }
5364
5365 while (cbCurrentWidth)
5366 {
5367 uint32_t cbToCopy;
5368
5369 if (offGmrCurrent + cbCurrentWidth <= offDesc + paDesc[iDesc].numPages * PAGE_SIZE)
5370 {
5371 cbToCopy = cbCurrentWidth;
5372 }
5373 else
5374 {
5375 cbToCopy = (offDesc + paDesc[iDesc].numPages * PAGE_SIZE - offGmrCurrent);
5376 AssertReturn(cbToCopy <= cbCurrentWidth, VERR_INVALID_PARAMETER);
5377 }
5378
5379 RTGCPHYS const GCPhys = paDesc[iDesc].GCPhys + offGmrCurrent - offDesc;
5380
5381 Log5Func(("%s phys=%RGp\n", (enmTransferType == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", GCPhys));
5382
5383 if (enmTransferType == SVGA3D_WRITE_HOST_VRAM)
5384 rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhys, pbCurrentHost, cbToCopy);
5385 else
5386 rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhys, pbCurrentHost, cbToCopy);
5387 AssertRCBreak(rc);
5388
5389 cbCurrentWidth -= cbToCopy;
5390 offGmrCurrent += cbToCopy;
5391 pbCurrentHost += cbToCopy;
5392
5393 /* Go to the next descriptor if there's anything left. */
5394 if (cbCurrentWidth)
5395 {
5396 offDesc += paDesc[iDesc].numPages * PAGE_SIZE;
5397 AssertReturn(offDesc < pGMR->cbTotal, VERR_INTERNAL_ERROR);
5398 ++iDesc;
5399 AssertReturn(iDesc < pGMR->numDescriptors, VERR_INTERNAL_ERROR);
5400 }
5401 }
5402
5403 offGmrScanline += cbGstPitch;
5404 pbHstScanline += cbHstPitch;
5405 }
5406
5407 return VINF_SUCCESS;
5408}
5409
5410
5411/**
5412 * Unsigned coordinates in pBox. Clip to [0; pSizeSrc), [0; pSizeDest).
5413 *
5414 * @param pSizeSrc Source surface dimensions.
5415 * @param pSizeDest Destination surface dimensions.
5416 * @param pBox Coordinates to be clipped.
5417 */
5418void vmsvgaR3ClipCopyBox(const SVGA3dSize *pSizeSrc, const SVGA3dSize *pSizeDest, SVGA3dCopyBox *pBox)
5419{
5420 /* Src x, w */
5421 if (pBox->srcx > pSizeSrc->width)
5422 pBox->srcx = pSizeSrc->width;
5423 if (pBox->w > pSizeSrc->width - pBox->srcx)
5424 pBox->w = pSizeSrc->width - pBox->srcx;
5425
5426 /* Src y, h */
5427 if (pBox->srcy > pSizeSrc->height)
5428 pBox->srcy = pSizeSrc->height;
5429 if (pBox->h > pSizeSrc->height - pBox->srcy)
5430 pBox->h = pSizeSrc->height - pBox->srcy;
5431
5432 /* Src z, d */
5433 if (pBox->srcz > pSizeSrc->depth)
5434 pBox->srcz = pSizeSrc->depth;
5435 if (pBox->d > pSizeSrc->depth - pBox->srcz)
5436 pBox->d = pSizeSrc->depth - pBox->srcz;
5437
5438 /* Dest x, w */
5439 if (pBox->x > pSizeDest->width)
5440 pBox->x = pSizeDest->width;
5441 if (pBox->w > pSizeDest->width - pBox->x)
5442 pBox->w = pSizeDest->width - pBox->x;
5443
5444 /* Dest y, h */
5445 if (pBox->y > pSizeDest->height)
5446 pBox->y = pSizeDest->height;
5447 if (pBox->h > pSizeDest->height - pBox->y)
5448 pBox->h = pSizeDest->height - pBox->y;
5449
5450 /* Dest z, d */
5451 if (pBox->z > pSizeDest->depth)
5452 pBox->z = pSizeDest->depth;
5453 if (pBox->d > pSizeDest->depth - pBox->z)
5454 pBox->d = pSizeDest->depth - pBox->z;
5455}
5456
5457
5458/**
5459 * Unsigned coordinates in pBox. Clip to [0; pSize).
5460 *
5461 * @param pSize Source surface dimensions.
5462 * @param pBox Coordinates to be clipped.
5463 */
5464void vmsvgaR3ClipBox(const SVGA3dSize *pSize, SVGA3dBox *pBox)
5465{
5466 /* x, w */
5467 if (pBox->x > pSize->width)
5468 pBox->x = pSize->width;
5469 if (pBox->w > pSize->width - pBox->x)
5470 pBox->w = pSize->width - pBox->x;
5471
5472 /* y, h */
5473 if (pBox->y > pSize->height)
5474 pBox->y = pSize->height;
5475 if (pBox->h > pSize->height - pBox->y)
5476 pBox->h = pSize->height - pBox->y;
5477
5478 /* z, d */
5479 if (pBox->z > pSize->depth)
5480 pBox->z = pSize->depth;
5481 if (pBox->d > pSize->depth - pBox->z)
5482 pBox->d = pSize->depth - pBox->z;
5483}
5484
5485
5486/**
5487 * Clip.
5488 *
5489 * @param pBound Bounding rectangle.
5490 * @param pRect Rectangle to be clipped.
5491 */
5492void vmsvgaR3ClipRect(SVGASignedRect const *pBound, SVGASignedRect *pRect)
5493{
5494 int32_t left;
5495 int32_t top;
5496 int32_t right;
5497 int32_t bottom;
5498
5499 /* Right order. */
5500 Assert(pBound->left <= pBound->right && pBound->top <= pBound->bottom);
5501 if (pRect->left < pRect->right)
5502 {
5503 left = pRect->left;
5504 right = pRect->right;
5505 }
5506 else
5507 {
5508 left = pRect->right;
5509 right = pRect->left;
5510 }
5511 if (pRect->top < pRect->bottom)
5512 {
5513 top = pRect->top;
5514 bottom = pRect->bottom;
5515 }
5516 else
5517 {
5518 top = pRect->bottom;
5519 bottom = pRect->top;
5520 }
5521
5522 if (left < pBound->left)
5523 left = pBound->left;
5524 if (right < pBound->left)
5525 right = pBound->left;
5526
5527 if (left > pBound->right)
5528 left = pBound->right;
5529 if (right > pBound->right)
5530 right = pBound->right;
5531
5532 if (top < pBound->top)
5533 top = pBound->top;
5534 if (bottom < pBound->top)
5535 bottom = pBound->top;
5536
5537 if (top > pBound->bottom)
5538 top = pBound->bottom;
5539 if (bottom > pBound->bottom)
5540 bottom = pBound->bottom;
5541
5542 pRect->left = left;
5543 pRect->right = right;
5544 pRect->top = top;
5545 pRect->bottom = bottom;
5546}
5547
5548
5549/**
5550 * Clip.
5551 *
5552 * @param pBound Bounding rectangle.
5553 * @param pRect Rectangle to be clipped.
5554 */
5555void vmsvgaR3Clip3dRect(SVGA3dRect const *pBound, SVGA3dRect RT_UNTRUSTED_GUEST *pRect)
5556{
5557 uint32_t const leftBound = pBound->x;
5558 uint32_t const rightBound = pBound->x + pBound->w;
5559 uint32_t const topBound = pBound->y;
5560 uint32_t const bottomBound = pBound->y + pBound->h;
5561
5562 uint32_t x = pRect->x;
5563 uint32_t y = pRect->y;
5564 uint32_t w = pRect->w;
5565 uint32_t h = pRect->h;
5566
5567 /* Make sure that right and bottom coordinates can be safely computed. */
5568 if (x > rightBound)
5569 x = rightBound;
5570 if (w > rightBound - x)
5571 w = rightBound - x;
5572 if (y > bottomBound)
5573 y = bottomBound;
5574 if (h > bottomBound - y)
5575 h = bottomBound - y;
5576
5577 /* Switch from x, y, w, h to left, top, right, bottom. */
5578 uint32_t left = x;
5579 uint32_t right = x + w;
5580 uint32_t top = y;
5581 uint32_t bottom = y + h;
5582
5583 /* A standard left, right, bottom, top clipping. */
5584 if (left < leftBound)
5585 left = leftBound;
5586 if (right < leftBound)
5587 right = leftBound;
5588
5589 if (left > rightBound)
5590 left = rightBound;
5591 if (right > rightBound)
5592 right = rightBound;
5593
5594 if (top < topBound)
5595 top = topBound;
5596 if (bottom < topBound)
5597 bottom = topBound;
5598
5599 if (top > bottomBound)
5600 top = bottomBound;
5601 if (bottom > bottomBound)
5602 bottom = bottomBound;
5603
5604 /* Back to x, y, w, h representation. */
5605 pRect->x = left;
5606 pRect->y = top;
5607 pRect->w = right - left;
5608 pRect->h = bottom - top;
5609}
5610
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