VirtualBox

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

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

AMD IOMMU: bugref:9654 DevVGA-SVGA: Use PCI interfaces while reading/writing guest physical memory.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 103.4 KB
Line 
1/* $Id: DevVGA-SVGA-cmd.cpp 86479 2020-10-08 06:50:49Z 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#include "DevVGA-SVGA-internal.h"
35#ifdef VBOX_WITH_VMSVGA3D
36# include "DevVGA-SVGA3d.h"
37#endif
38
39
40#if defined(LOG_ENABLED) || defined(VBOX_STRICT)
41# define SVGA_CASE_ID2STR(idx) case idx: return #idx
42/**
43 * FIFO command name lookup
44 *
45 * @returns FIFO command string or "UNKNOWN"
46 * @param u32Cmd FIFO command
47 */
48const char *vmsvgaR3FifoCmdToString(uint32_t u32Cmd)
49{
50 switch (u32Cmd)
51 {
52 SVGA_CASE_ID2STR(SVGA_CMD_INVALID_CMD);
53 SVGA_CASE_ID2STR(SVGA_CMD_UPDATE);
54 SVGA_CASE_ID2STR(SVGA_CMD_RECT_FILL);
55 SVGA_CASE_ID2STR(SVGA_CMD_RECT_COPY);
56 SVGA_CASE_ID2STR(SVGA_CMD_RECT_ROP_COPY);
57 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_CURSOR);
58 SVGA_CASE_ID2STR(SVGA_CMD_DISPLAY_CURSOR);
59 SVGA_CASE_ID2STR(SVGA_CMD_MOVE_CURSOR);
60 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_ALPHA_CURSOR);
61 SVGA_CASE_ID2STR(SVGA_CMD_UPDATE_VERBOSE);
62 SVGA_CASE_ID2STR(SVGA_CMD_FRONT_ROP_FILL);
63 SVGA_CASE_ID2STR(SVGA_CMD_FENCE);
64 SVGA_CASE_ID2STR(SVGA_CMD_ESCAPE);
65 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_SCREEN);
66 SVGA_CASE_ID2STR(SVGA_CMD_DESTROY_SCREEN);
67 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_GMRFB);
68 SVGA_CASE_ID2STR(SVGA_CMD_BLIT_GMRFB_TO_SCREEN);
69 SVGA_CASE_ID2STR(SVGA_CMD_BLIT_SCREEN_TO_GMRFB);
70 SVGA_CASE_ID2STR(SVGA_CMD_ANNOTATION_FILL);
71 SVGA_CASE_ID2STR(SVGA_CMD_ANNOTATION_COPY);
72 SVGA_CASE_ID2STR(SVGA_CMD_DEFINE_GMR2);
73 SVGA_CASE_ID2STR(SVGA_CMD_REMAP_GMR2);
74 SVGA_CASE_ID2STR(SVGA_CMD_DEAD);
75 SVGA_CASE_ID2STR(SVGA_CMD_DEAD_2);
76 SVGA_CASE_ID2STR(SVGA_CMD_NOP);
77 SVGA_CASE_ID2STR(SVGA_CMD_NOP_ERROR);
78 SVGA_CASE_ID2STR(SVGA_CMD_MAX);
79 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DEFINE);
80 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DESTROY);
81 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_COPY);
82 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_STRETCHBLT);
83 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DMA);
84 SVGA_CASE_ID2STR(SVGA_3D_CMD_CONTEXT_DEFINE);
85 SVGA_CASE_ID2STR(SVGA_3D_CMD_CONTEXT_DESTROY);
86 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETTRANSFORM);
87 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETZRANGE);
88 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETRENDERSTATE);
89 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETRENDERTARGET);
90 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETTEXTURESTATE);
91 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETMATERIAL);
92 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETLIGHTDATA);
93 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETLIGHTENABLED);
94 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETVIEWPORT);
95 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETCLIPPLANE);
96 SVGA_CASE_ID2STR(SVGA_3D_CMD_CLEAR);
97 SVGA_CASE_ID2STR(SVGA_3D_CMD_PRESENT);
98 SVGA_CASE_ID2STR(SVGA_3D_CMD_SHADER_DEFINE);
99 SVGA_CASE_ID2STR(SVGA_3D_CMD_SHADER_DESTROY);
100 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_SHADER);
101 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_SHADER_CONST);
102 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW_PRIMITIVES);
103 SVGA_CASE_ID2STR(SVGA_3D_CMD_SETSCISSORRECT);
104 SVGA_CASE_ID2STR(SVGA_3D_CMD_BEGIN_QUERY);
105 SVGA_CASE_ID2STR(SVGA_3D_CMD_END_QUERY);
106 SVGA_CASE_ID2STR(SVGA_3D_CMD_WAIT_FOR_QUERY);
107 SVGA_CASE_ID2STR(SVGA_3D_CMD_PRESENT_READBACK);
108 SVGA_CASE_ID2STR(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
109 SVGA_CASE_ID2STR(SVGA_3D_CMD_SURFACE_DEFINE_V2);
110 SVGA_CASE_ID2STR(SVGA_3D_CMD_GENERATE_MIPMAPS);
111 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_CREATE_DECODER);
112 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DESTROY_DECODER);
113 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_CREATE_PROCESSOR);
114 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DESTROY_PROCESSOR);
115 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_START_FRAME);
116 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_RENDER);
117 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_DECODE_END_FRAME);
118 SVGA_CASE_ID2STR(SVGA_3D_CMD_VIDEO_PROCESS_FRAME);
119 SVGA_CASE_ID2STR(SVGA_3D_CMD_ACTIVATE_SURFACE);
120 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEACTIVATE_SURFACE);
121 SVGA_CASE_ID2STR(SVGA_3D_CMD_SCREEN_DMA);
122 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD1);
123 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD2);
124 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_BITBLT);
125 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_TRANSBLT);
126 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_STRETCHBLT);
127 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_COLORFILL);
128 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_ALPHABLEND);
129 SVGA_CASE_ID2STR(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND);
130 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_OTABLE_BASE);
131 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_OTABLE);
132 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_MOB);
133 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_MOB);
134 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEAD3);
135 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING);
136 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SURFACE);
137 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SURFACE);
138 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SURFACE);
139 SVGA_CASE_ID2STR(SVGA_3D_CMD_COND_BIND_GB_SURFACE);
140 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_IMAGE);
141 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_SURFACE);
142 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_IMAGE);
143 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_SURFACE);
144 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_IMAGE);
145 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_SURFACE);
146 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_CONTEXT);
147 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_CONTEXT);
148 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_CONTEXT);
149 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_CONTEXT);
150 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_CONTEXT);
151 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SHADER);
152 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SHADER);
153 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SHADER);
154 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_OTABLE_BASE64);
155 SVGA_CASE_ID2STR(SVGA_3D_CMD_BEGIN_GB_QUERY);
156 SVGA_CASE_ID2STR(SVGA_3D_CMD_END_GB_QUERY);
157 SVGA_CASE_ID2STR(SVGA_3D_CMD_WAIT_FOR_GB_QUERY);
158 SVGA_CASE_ID2STR(SVGA_3D_CMD_NOP);
159 SVGA_CASE_ID2STR(SVGA_3D_CMD_ENABLE_GART);
160 SVGA_CASE_ID2STR(SVGA_3D_CMD_DISABLE_GART);
161 SVGA_CASE_ID2STR(SVGA_3D_CMD_MAP_MOB_INTO_GART);
162 SVGA_CASE_ID2STR(SVGA_3D_CMD_UNMAP_GART_RANGE);
163 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SCREENTARGET);
164 SVGA_CASE_ID2STR(SVGA_3D_CMD_DESTROY_GB_SCREENTARGET);
165 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SCREENTARGET);
166 SVGA_CASE_ID2STR(SVGA_3D_CMD_UPDATE_GB_SCREENTARGET);
167 SVGA_CASE_ID2STR(SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL);
168 SVGA_CASE_ID2STR(SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL);
169 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE);
170 SVGA_CASE_ID2STR(SVGA_3D_CMD_GB_SCREEN_DMA);
171 SVGA_CASE_ID2STR(SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH);
172 SVGA_CASE_ID2STR(SVGA_3D_CMD_GB_MOB_FENCE);
173 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_SURFACE_V2);
174 SVGA_CASE_ID2STR(SVGA_3D_CMD_DEFINE_GB_MOB64);
175 SVGA_CASE_ID2STR(SVGA_3D_CMD_REDEFINE_GB_MOB64);
176 SVGA_CASE_ID2STR(SVGA_3D_CMD_NOP_ERROR);
177 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_STREAMS);
178 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_DECLS);
179 SVGA_CASE_ID2STR(SVGA_3D_CMD_SET_VERTEX_DIVISORS);
180 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW);
181 SVGA_CASE_ID2STR(SVGA_3D_CMD_DRAW_INDEXED);
182 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_CONTEXT);
183 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_CONTEXT);
184 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_CONTEXT);
185 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_CONTEXT);
186 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_INVALIDATE_CONTEXT);
187 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER);
188 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SHADER_RESOURCES);
189 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SHADER);
190 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SAMPLERS);
191 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW);
192 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INDEXED);
193 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INSTANCED);
194 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED);
195 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DRAW_AUTO);
196 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT);
197 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS);
198 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_INDEX_BUFFER);
199 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_TOPOLOGY);
200 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_RENDERTARGETS);
201 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_BLEND_STATE);
202 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE);
203 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_RASTERIZER_STATE);
204 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_QUERY);
205 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_QUERY);
206 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_QUERY);
207 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_QUERY_OFFSET);
208 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BEGIN_QUERY);
209 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_END_QUERY);
210 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_QUERY);
211 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_PREDICATION);
212 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SOTARGETS);
213 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VIEWPORTS);
214 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_SCISSORRECTS);
215 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW);
216 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW);
217 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_COPY_REGION);
218 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_COPY);
219 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_STRETCHBLT);
220 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_GENMIPS);
221 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE);
222 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_SUBRESOURCE);
223 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE);
224 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW);
225 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW);
226 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW);
227 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW);
228 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW);
229 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW);
230 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT);
231 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT);
232 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_BLEND_STATE);
233 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_BLEND_STATE);
234 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE);
235 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE);
236 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE);
237 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE);
238 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE);
239 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE);
240 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_SHADER);
241 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_SHADER);
242 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_SHADER);
243 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT);
244 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT);
245 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_STREAMOUTPUT);
246 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_COTABLE);
247 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_COTABLE);
248 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BUFFER_COPY);
249 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER);
250 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK);
251 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MOVE_QUERY);
252 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_ALL_QUERY);
253 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_READBACK_ALL_QUERY);
254 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER);
255 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MOB_FENCE_64);
256 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BIND_ALL_SHADER);
257 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_HINT);
258 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_BUFFER_UPDATE);
259 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET);
260 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET);
261 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET);
262 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED1);
263 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED2);
264 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_RESERVED3);
265 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER);
266 SVGA_CASE_ID2STR(SVGA_3D_CMD_DX_MAX);
267 default: return "UNKNOWN";
268 }
269}
270# undef SVGA_CASE_ID2STR
271#endif /* LOG_ENABLED || VBOX_STRICT */
272
273
274VMSVGASCREENOBJECT *vmsvgaR3GetScreenObject(PVGASTATECC pThisCC, uint32_t idScreen)
275{
276 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
277 if ( idScreen < (uint32_t)RT_ELEMENTS(pSVGAState->aScreens)
278 && pSVGAState
279 && pSVGAState->aScreens[idScreen].fDefined)
280 {
281 return &pSVGAState->aScreens[idScreen];
282 }
283 return NULL;
284}
285
286void vmsvgaR3ResetScreens(PVGASTATE pThis, PVGASTATECC pThisCC)
287{
288#ifdef VBOX_WITH_VMSVGA3D
289 if (pThis->svga.f3DEnabled)
290 {
291 for (uint32_t idScreen = 0; idScreen < (uint32_t)RT_ELEMENTS(pThisCC->svga.pSvgaR3State->aScreens); ++idScreen)
292 {
293 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, idScreen);
294 if (pScreen)
295 vmsvga3dDestroyScreen(pThisCC, pScreen);
296 }
297 }
298#else
299 RT_NOREF(pThis, pThisCC);
300#endif
301}
302
303
304/**
305 * Copy a rectangle of pixels within guest VRAM.
306 */
307static void vmsvgaR3RectCopy(PVGASTATECC pThisCC, VMSVGASCREENOBJECT const *pScreen, uint32_t srcX, uint32_t srcY,
308 uint32_t dstX, uint32_t dstY, uint32_t width, uint32_t height, unsigned cbFrameBuffer)
309{
310 if (!width || !height)
311 return; /* Nothing to do, don't even bother. */
312
313 /*
314 * The guest VRAM (aka GFB) is considered to be a bitmap in the format
315 * corresponding to the current display mode.
316 */
317 uint32_t const cbPixel = RT_ALIGN(pScreen->cBpp, 8) / 8;
318 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch : width * cbPixel;
319 uint8_t const *pSrc;
320 uint8_t *pDst;
321 unsigned const cbRectWidth = width * cbPixel;
322 unsigned uMaxOffset;
323
324 uMaxOffset = (RT_MAX(srcY, dstY) + height) * cbScanline + (RT_MAX(srcX, dstX) + width) * cbPixel;
325 if (uMaxOffset >= cbFrameBuffer)
326 {
327 Log(("Max offset (%u) too big for framebuffer (%u bytes), ignoring!\n", uMaxOffset, cbFrameBuffer));
328 return; /* Just don't listen to a bad guest. */
329 }
330
331 pSrc = pDst = pThisCC->pbVRam;
332 pSrc += srcY * cbScanline + srcX * cbPixel;
333 pDst += dstY * cbScanline + dstX * cbPixel;
334
335 if (srcY >= dstY)
336 {
337 /* Source below destination, copy top to bottom. */
338 for (; height > 0; height--)
339 {
340 memmove(pDst, pSrc, cbRectWidth);
341 pSrc += cbScanline;
342 pDst += cbScanline;
343 }
344 }
345 else
346 {
347 /* Source above destination, copy bottom to top. */
348 pSrc += cbScanline * (height - 1);
349 pDst += cbScanline * (height - 1);
350 for (; height > 0; height--)
351 {
352 memmove(pDst, pSrc, cbRectWidth);
353 pSrc -= cbScanline;
354 pDst -= cbScanline;
355 }
356 }
357}
358
359
360/**
361 * Common worker for changing the pointer shape.
362 *
363 * @param pThisCC The VGA/VMSVGA state for ring-3.
364 * @param pSVGAState The VMSVGA ring-3 instance data.
365 * @param fAlpha Whether there is alpha or not.
366 * @param xHot Hotspot x coordinate.
367 * @param yHot Hotspot y coordinate.
368 * @param cx Width.
369 * @param cy Height.
370 * @param pbData Heap copy of the cursor data. Consumed.
371 * @param cbData The size of the data.
372 */
373static void vmsvgaR3InstallNewCursor(PVGASTATECC pThisCC, PVMSVGAR3STATE pSVGAState, bool fAlpha,
374 uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy, uint8_t *pbData, uint32_t cbData)
375{
376 LogRel2(("vmsvgaR3InstallNewCursor: cx=%d cy=%d xHot=%d yHot=%d fAlpha=%d cbData=%#x\n", cx, cy, xHot, yHot, fAlpha, cbData));
377#ifdef LOG_ENABLED
378 if (LogIs2Enabled())
379 {
380 uint32_t cbAndLine = RT_ALIGN(cx, 8) / 8;
381 if (!fAlpha)
382 {
383 Log2(("VMSVGA Cursor AND mask (%d,%d):\n", cx, cy));
384 for (uint32_t y = 0; y < cy; y++)
385 {
386 Log2(("%3u:", y));
387 uint8_t const *pbLine = &pbData[y * cbAndLine];
388 for (uint32_t x = 0; x < cx; x += 8)
389 {
390 uint8_t b = pbLine[x / 8];
391 char szByte[12];
392 szByte[0] = b & 0x80 ? '*' : ' '; /* most significant bit first */
393 szByte[1] = b & 0x40 ? '*' : ' ';
394 szByte[2] = b & 0x20 ? '*' : ' ';
395 szByte[3] = b & 0x10 ? '*' : ' ';
396 szByte[4] = b & 0x08 ? '*' : ' ';
397 szByte[5] = b & 0x04 ? '*' : ' ';
398 szByte[6] = b & 0x02 ? '*' : ' ';
399 szByte[7] = b & 0x01 ? '*' : ' ';
400 szByte[8] = '\0';
401 Log2(("%s", szByte));
402 }
403 Log2(("\n"));
404 }
405 }
406
407 Log2(("VMSVGA Cursor XOR mask (%d,%d):\n", cx, cy));
408 uint32_t const *pu32Xor = (uint32_t const *)&pbData[RT_ALIGN_32(cbAndLine * cy, 4)];
409 for (uint32_t y = 0; y < cy; y++)
410 {
411 Log2(("%3u:", y));
412 uint32_t const *pu32Line = &pu32Xor[y * cx];
413 for (uint32_t x = 0; x < cx; x++)
414 Log2((" %08x", pu32Line[x]));
415 Log2(("\n"));
416 }
417 }
418#endif
419
420 int rc = pThisCC->pDrv->pfnVBVAMousePointerShape(pThisCC->pDrv, true /*fVisible*/, fAlpha, xHot, yHot, cx, cy, pbData);
421 AssertRC(rc);
422
423 if (pSVGAState->Cursor.fActive)
424 RTMemFreeZ(pSVGAState->Cursor.pData, pSVGAState->Cursor.cbData);
425
426 pSVGAState->Cursor.fActive = true;
427 pSVGAState->Cursor.xHotspot = xHot;
428 pSVGAState->Cursor.yHotspot = yHot;
429 pSVGAState->Cursor.width = cx;
430 pSVGAState->Cursor.height = cy;
431 pSVGAState->Cursor.cbData = cbData;
432 pSVGAState->Cursor.pData = pbData;
433}
434
435
436#ifdef VBOX_WITH_VMSVGA3D
437/** @def VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK
438 * Check that the 3D command has at least a_cbMin of payload bytes after the
439 * header. Will break out of the switch if it doesn't.
440 */
441# define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \
442 if (1) { \
443 AssertMsgBreak(cbCmd >= (a_cbMin), ("size=%#x a_cbMin=%#zx\n", cbCmd, (size_t)(a_cbMin))); \
444 RT_UNTRUSTED_VALIDATED_FENCE(); \
445 } else do {} while (0)
446
447# define VMSVGA_3D_CMD_NOTIMPL() \
448 if (1) { \
449 AssertMsgFailed(("Not implemented %d %s\n", enmCmdId, vmsvgaR3FifoCmdToString(enmCmdId))); \
450 } else do {} while (0)
451
452/** SVGA_3D_CMD_* handler.
453 * This function parses the command and calls the corresponding command handler.
454 *
455 * @param pThis The shared VGA/VMSVGA state.
456 * @param pThisCC The VGA/VMSVGA state for the current context.
457 * @param enmCmdId SVGA_3D_CMD_* command identifier.
458 * @param cbCmd Size of the command in bytes.
459 * @param pvCmd Pointer to the command.
460 * @returns VBox status code if an error was detected parsing a command.
461 */
462int vmsvgaR3Process3dCmd(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifo3dCmdId enmCmdId, uint32_t cbCmd, void const *pvCmd)
463{
464 int rcParse = VINF_SUCCESS;
465 PVMSVGAR3STATE pSvgaR3State = pThisCC->svga.pSvgaR3State;
466
467 switch (enmCmdId)
468 {
469 case SVGA_3D_CMD_SURFACE_DEFINE:
470 {
471 SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)pvCmd;
472 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
473 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefine);
474
475 uint32_t const cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
476 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0,
477 SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1));
478# ifdef DEBUG_GMR_ACCESS
479 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3ResetGmrHandlers, 1, pThis);
480# endif
481 break;
482 }
483
484 case SVGA_3D_CMD_SURFACE_DEFINE_V2:
485 {
486 SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)pvCmd;
487 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
488 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDefineV2);
489
490 uint32_t const cMipLevels = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dSize);
491 vmsvga3dSurfaceDefine(pThisCC, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face,
492 pCmd->multisampleCount, pCmd->autogenFilter,
493 cMipLevels, (SVGA3dSize *)(pCmd + 1));
494 break;
495 }
496
497 case SVGA_3D_CMD_SURFACE_DESTROY:
498 {
499 SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)pvCmd;
500 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
501 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDestroy);
502
503 vmsvga3dSurfaceDestroy(pThisCC, pCmd->sid);
504 break;
505 }
506
507 case SVGA_3D_CMD_SURFACE_COPY:
508 {
509 SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)pvCmd;
510 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
511 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceCopy);
512
513 uint32_t const cCopyBoxes = (cbCmd - sizeof(pCmd)) / sizeof(SVGA3dCopyBox);
514 vmsvga3dSurfaceCopy(pThisCC, pCmd->dest, pCmd->src, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
515 break;
516 }
517
518 case SVGA_3D_CMD_SURFACE_STRETCHBLT:
519 {
520 SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)pvCmd;
521 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
522 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceStretchBlt);
523
524 vmsvga3dSurfaceStretchBlt(pThis, pThisCC, &pCmd->dest, &pCmd->boxDest,
525 &pCmd->src, &pCmd->boxSrc, pCmd->mode);
526 break;
527 }
528
529 case SVGA_3D_CMD_SURFACE_DMA:
530 {
531 SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)pvCmd;
532 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
533 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceDma);
534
535 uint64_t u64NanoTS = 0;
536 if (LogRelIs3Enabled())
537 u64NanoTS = RTTimeNanoTS();
538 uint32_t const cCopyBoxes = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox);
539 STAM_PROFILE_START(&pSvgaR3State->StatR3Cmd3dSurfaceDmaProf, a);
540 vmsvga3dSurfaceDMA(pThis, pThisCC, pCmd->guest, pCmd->host, pCmd->transfer,
541 cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
542 STAM_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dSurfaceDmaProf, a);
543 if (LogRelIs3Enabled())
544 {
545 if (cCopyBoxes)
546 {
547 SVGA3dCopyBox *pFirstBox = (SVGA3dCopyBox *)(pCmd + 1);
548 LogRel3(("VMSVGA: SURFACE_DMA: %d us %d boxes %d,%d %dx%d%s\n",
549 (RTTimeNanoTS() - u64NanoTS) / 1000ULL, cCopyBoxes,
550 pFirstBox->x, pFirstBox->y, pFirstBox->w, pFirstBox->h,
551 pCmd->transfer == SVGA3D_READ_HOST_VRAM ? " readback!!!" : ""));
552 }
553 }
554 break;
555 }
556
557 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
558 {
559 SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)pvCmd;
560 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
561 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSurfaceScreen);
562
563 static uint64_t u64FrameStartNanoTS = 0;
564 static uint64_t u64ElapsedPerSecNano = 0;
565 static int cFrames = 0;
566 uint64_t u64NanoTS = 0;
567 if (LogRelIs3Enabled())
568 u64NanoTS = RTTimeNanoTS();
569 uint32_t const cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGASignedRect);
570 STAM_REL_PROFILE_START(&pSvgaR3State->StatR3Cmd3dBlitSurfaceToScreenProf, a);
571 vmsvga3dSurfaceBlitToScreen(pThis, pThisCC, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage,
572 pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1));
573 STAM_REL_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dBlitSurfaceToScreenProf, a);
574 if (LogRelIs3Enabled())
575 {
576 uint64_t u64ElapsedNano = RTTimeNanoTS() - u64NanoTS;
577 u64ElapsedPerSecNano += u64ElapsedNano;
578
579 SVGASignedRect *pFirstRect = cRects ? (SVGASignedRect *)(pCmd + 1) : &pCmd->destRect;
580 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: %d us %d rects %d,%d %dx%d\n",
581 (u64ElapsedNano) / 1000ULL, cRects,
582 pFirstRect->left, pFirstRect->top,
583 pFirstRect->right - pFirstRect->left, pFirstRect->bottom - pFirstRect->top));
584
585 ++cFrames;
586 if (u64NanoTS - u64FrameStartNanoTS >= UINT64_C(1000000000))
587 {
588 LogRel3(("VMSVGA: SURFACE_TO_SCREEN: FPS %d, elapsed %llu us\n",
589 cFrames, u64ElapsedPerSecNano / 1000ULL));
590 u64FrameStartNanoTS = u64NanoTS;
591 cFrames = 0;
592 u64ElapsedPerSecNano = 0;
593 }
594 }
595 break;
596 }
597
598 case SVGA_3D_CMD_CONTEXT_DEFINE:
599 {
600 SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)pvCmd;
601 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
602 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dContextDefine);
603
604 vmsvga3dContextDefine(pThisCC, pCmd->cid);
605 break;
606 }
607
608 case SVGA_3D_CMD_CONTEXT_DESTROY:
609 {
610 SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)pvCmd;
611 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
612 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dContextDestroy);
613
614 vmsvga3dContextDestroy(pThisCC, pCmd->cid);
615 break;
616 }
617
618 case SVGA_3D_CMD_SETTRANSFORM:
619 {
620 SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)pvCmd;
621 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
622 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetTransform);
623
624 vmsvga3dSetTransform(pThisCC, pCmd->cid, pCmd->type, pCmd->matrix);
625 break;
626 }
627
628 case SVGA_3D_CMD_SETZRANGE:
629 {
630 SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)pvCmd;
631 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
632 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetZRange);
633
634 vmsvga3dSetZRange(pThisCC, pCmd->cid, pCmd->zRange);
635 break;
636 }
637
638 case SVGA_3D_CMD_SETRENDERSTATE:
639 {
640 SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)pvCmd;
641 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
642 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetRenderState);
643
644 uint32_t const cRenderStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRenderState);
645 vmsvga3dSetRenderState(pThisCC, pCmd->cid, cRenderStates, (SVGA3dRenderState *)(pCmd + 1));
646 break;
647 }
648
649 case SVGA_3D_CMD_SETRENDERTARGET:
650 {
651 SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)pvCmd;
652 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
653 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetRenderTarget);
654
655 vmsvga3dSetRenderTarget(pThisCC, pCmd->cid, pCmd->type, pCmd->target);
656 break;
657 }
658
659 case SVGA_3D_CMD_SETTEXTURESTATE:
660 {
661 SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)pvCmd;
662 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
663 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetTextureState);
664
665 uint32_t const cTextureStates = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dTextureState);
666 vmsvga3dSetTextureState(pThisCC, pCmd->cid, cTextureStates, (SVGA3dTextureState *)(pCmd + 1));
667 break;
668 }
669
670 case SVGA_3D_CMD_SETMATERIAL:
671 {
672 SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)pvCmd;
673 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
674 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetMaterial);
675
676 vmsvga3dSetMaterial(pThisCC, pCmd->cid, pCmd->face, &pCmd->material);
677 break;
678 }
679
680 case SVGA_3D_CMD_SETLIGHTDATA:
681 {
682 SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)pvCmd;
683 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
684 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetLightData);
685
686 vmsvga3dSetLightData(pThisCC, pCmd->cid, pCmd->index, &pCmd->data);
687 break;
688 }
689
690 case SVGA_3D_CMD_SETLIGHTENABLED:
691 {
692 SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)pvCmd;
693 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
694 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetLightEnable);
695
696 vmsvga3dSetLightEnabled(pThisCC, pCmd->cid, pCmd->index, pCmd->enabled);
697 break;
698 }
699
700 case SVGA_3D_CMD_SETVIEWPORT:
701 {
702 SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)pvCmd;
703 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
704 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetViewPort);
705
706 vmsvga3dSetViewPort(pThisCC, pCmd->cid, &pCmd->rect);
707 break;
708 }
709
710 case SVGA_3D_CMD_SETCLIPPLANE:
711 {
712 SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)pvCmd;
713 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
714 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetClipPlane);
715
716 vmsvga3dSetClipPlane(pThisCC, pCmd->cid, pCmd->index, pCmd->plane);
717 break;
718 }
719
720 case SVGA_3D_CMD_CLEAR:
721 {
722 SVGA3dCmdClear *pCmd = (SVGA3dCmdClear *)pvCmd;
723 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
724 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dClear);
725
726 uint32_t const cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dRect);
727 vmsvga3dCommandClear(pThisCC, pCmd->cid, pCmd->clearFlag, pCmd->color, pCmd->depth, pCmd->stencil, cRects, (SVGA3dRect *)(pCmd + 1));
728 break;
729 }
730
731 case SVGA_3D_CMD_PRESENT:
732 case SVGA_3D_CMD_PRESENT_READBACK: /** @todo SVGA_3D_CMD_PRESENT_READBACK isn't quite the same as present... */
733 {
734 SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)pvCmd;
735 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
736 if (enmCmdId == SVGA_3D_CMD_PRESENT)
737 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dPresent);
738 else
739 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dPresentReadBack);
740
741 uint32_t const cRects = (cbCmd - sizeof(*pCmd)) / sizeof(SVGA3dCopyRect);
742 STAM_PROFILE_START(&pSvgaR3State->StatR3Cmd3dPresentProf, a);
743 vmsvga3dCommandPresent(pThis, pThisCC, pCmd->sid, cRects, (SVGA3dCopyRect *)(pCmd + 1));
744 STAM_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dPresentProf, a);
745 break;
746 }
747
748 case SVGA_3D_CMD_SHADER_DEFINE:
749 {
750 SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)pvCmd;
751 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
752 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dShaderDefine);
753
754 uint32_t const cbData = (cbCmd - sizeof(*pCmd));
755 vmsvga3dShaderDefine(pThisCC, pCmd->cid, pCmd->shid, pCmd->type, cbData, (uint32_t *)(pCmd + 1));
756 break;
757 }
758
759 case SVGA_3D_CMD_SHADER_DESTROY:
760 {
761 SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)pvCmd;
762 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
763 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dShaderDestroy);
764
765 vmsvga3dShaderDestroy(pThisCC, pCmd->cid, pCmd->shid, pCmd->type);
766 break;
767 }
768
769 case SVGA_3D_CMD_SET_SHADER:
770 {
771 SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)pvCmd;
772 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
773 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetShader);
774
775 vmsvga3dShaderSet(pThisCC, NULL, pCmd->cid, pCmd->type, pCmd->shid);
776 break;
777 }
778
779 case SVGA_3D_CMD_SET_SHADER_CONST:
780 {
781 SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)pvCmd;
782 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
783 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetShaderConst);
784
785 uint32_t const cRegisters = (cbCmd - sizeof(*pCmd)) / sizeof(pCmd->values) + 1;
786 vmsvga3dShaderSetConst(pThisCC, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values);
787 break;
788 }
789
790 case SVGA_3D_CMD_DRAW_PRIMITIVES:
791 {
792 SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)pvCmd;
793 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
794 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dDrawPrimitives);
795
796 ASSERT_GUEST_STMT_BREAK(pCmd->numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES, rcParse = VERR_INVALID_PARAMETER);
797 ASSERT_GUEST_STMT_BREAK(pCmd->numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS, rcParse = VERR_INVALID_PARAMETER);
798 uint32_t const cbRangesAndVertexDecls = pCmd->numVertexDecls * sizeof(SVGA3dVertexDecl)
799 + pCmd->numRanges * sizeof(SVGA3dPrimitiveRange);
800 ASSERT_GUEST_STMT_BREAK(cbRangesAndVertexDecls <= cbCmd - sizeof(*pCmd), rcParse = VERR_INVALID_PARAMETER);
801
802 uint32_t const cVertexDivisor = (cbCmd - sizeof(*pCmd) - cbRangesAndVertexDecls) / sizeof(uint32_t);
803 ASSERT_GUEST_STMT_BREAK(!cVertexDivisor || cVertexDivisor == pCmd->numVertexDecls, rcParse = VERR_INVALID_PARAMETER);
804 RT_UNTRUSTED_VALIDATED_FENCE();
805
806 SVGA3dVertexDecl *pVertexDecl = (SVGA3dVertexDecl *)(pCmd + 1);
807 SVGA3dPrimitiveRange *pNumRange = (SVGA3dPrimitiveRange *)&pVertexDecl[pCmd->numVertexDecls];
808 SVGA3dVertexDivisor *pVertexDivisor = cVertexDivisor ? (SVGA3dVertexDivisor *)&pNumRange[pCmd->numRanges] : NULL;
809
810 STAM_PROFILE_START(&pSvgaR3State->StatR3Cmd3dDrawPrimitivesProf, a);
811 vmsvga3dDrawPrimitives(pThisCC, pCmd->cid, pCmd->numVertexDecls, pVertexDecl, pCmd->numRanges,
812 pNumRange, cVertexDivisor, pVertexDivisor);
813 STAM_PROFILE_STOP(&pSvgaR3State->StatR3Cmd3dDrawPrimitivesProf, a);
814 break;
815 }
816
817 case SVGA_3D_CMD_SETSCISSORRECT:
818 {
819 SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)pvCmd;
820 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
821 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dSetScissorRect);
822
823 vmsvga3dSetScissorRect(pThisCC, pCmd->cid, &pCmd->rect);
824 break;
825 }
826
827 case SVGA_3D_CMD_BEGIN_QUERY:
828 {
829 SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)pvCmd;
830 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
831 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dBeginQuery);
832
833 vmsvga3dQueryBegin(pThisCC, pCmd->cid, pCmd->type);
834 break;
835 }
836
837 case SVGA_3D_CMD_END_QUERY:
838 {
839 SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)pvCmd;
840 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
841 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dEndQuery);
842
843 vmsvga3dQueryEnd(pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult);
844 break;
845 }
846
847 case SVGA_3D_CMD_WAIT_FOR_QUERY:
848 {
849 SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)pvCmd;
850 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
851 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dWaitForQuery);
852
853 vmsvga3dQueryWait(pThis, pThisCC, pCmd->cid, pCmd->type, pCmd->guestResult);
854 break;
855 }
856
857 case SVGA_3D_CMD_GENERATE_MIPMAPS:
858 {
859 SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)pvCmd;
860 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
861 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dGenerateMipmaps);
862
863 vmsvga3dGenerateMipmaps(pThisCC, pCmd->sid, pCmd->filter);
864 break;
865 }
866
867 case SVGA_3D_CMD_ACTIVATE_SURFACE:
868 /* context id + surface id? */
869 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dActivateSurface);
870 break;
871
872 case SVGA_3D_CMD_DEACTIVATE_SURFACE:
873 /* context id + surface id? */
874 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3Cmd3dDeactivateSurface);
875 break;
876
877 /*
878 *
879 * VPGU10: SVGA_CAP_GBOBJECTS+ commands.
880 *
881 */
882 case SVGA_3D_CMD_SCREEN_DMA:
883 {
884 SVGA3dCmdScreenDMA *pCmd = (SVGA3dCmdScreenDMA *)pvCmd;
885 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
886 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
887 break;
888 }
889
890 case SVGA_3D_CMD_DEAD1:
891 case SVGA_3D_CMD_DEAD2:
892 {
893 VMSVGA_3D_CMD_NOTIMPL();
894 break;
895 }
896
897 case SVGA_3D_CMD_LOGICOPS_BITBLT:
898 {
899 SVGA3dCmdLogicOpsBitBlt *pCmd = (SVGA3dCmdLogicOpsBitBlt *)pvCmd;
900 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
901 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
902 break;
903 }
904
905 case SVGA_3D_CMD_LOGICOPS_TRANSBLT:
906 {
907 SVGA3dCmdLogicOpsTransBlt *pCmd = (SVGA3dCmdLogicOpsTransBlt *)pvCmd;
908 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
909 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
910 break;
911 }
912
913 case SVGA_3D_CMD_LOGICOPS_STRETCHBLT:
914 {
915 SVGA3dCmdLogicOpsStretchBlt *pCmd = (SVGA3dCmdLogicOpsStretchBlt *)pvCmd;
916 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
917 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
918 break;
919 }
920
921 case SVGA_3D_CMD_LOGICOPS_COLORFILL:
922 {
923 SVGA3dCmdLogicOpsColorFill *pCmd = (SVGA3dCmdLogicOpsColorFill *)pvCmd;
924 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
925 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
926 break;
927 }
928
929 case SVGA_3D_CMD_LOGICOPS_ALPHABLEND:
930 {
931 SVGA3dCmdLogicOpsAlphaBlend *pCmd = (SVGA3dCmdLogicOpsAlphaBlend *)pvCmd;
932 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
933 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
934 break;
935 }
936
937 case SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND:
938 {
939 SVGA3dCmdLogicOpsClearTypeBlend *pCmd = (SVGA3dCmdLogicOpsClearTypeBlend *)pvCmd;
940 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
941 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
942 break;
943 }
944
945 case SVGA_3D_CMD_SET_OTABLE_BASE:
946 {
947 SVGA3dCmdSetOTableBase *pCmd = (SVGA3dCmdSetOTableBase *)pvCmd;
948 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
949 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
950 break;
951 }
952
953 case SVGA_3D_CMD_READBACK_OTABLE:
954 {
955 SVGA3dCmdReadbackOTable *pCmd = (SVGA3dCmdReadbackOTable *)pvCmd;
956 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
957 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
958 break;
959 }
960
961 case SVGA_3D_CMD_DEFINE_GB_MOB:
962 {
963 SVGA3dCmdDefineGBMob *pCmd = (SVGA3dCmdDefineGBMob *)pvCmd;
964 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
965 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
966 break;
967 }
968
969 case SVGA_3D_CMD_DESTROY_GB_MOB:
970 {
971 SVGA3dCmdDestroyGBMob *pCmd = (SVGA3dCmdDestroyGBMob *)pvCmd;
972 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
973 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
974 break;
975 }
976
977 case SVGA_3D_CMD_DEAD3:
978 {
979 VMSVGA_3D_CMD_NOTIMPL();
980 break;
981 }
982
983 case SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING:
984 {
985 SVGA3dCmdUpdateGBMobMapping *pCmd = (SVGA3dCmdUpdateGBMobMapping *)pvCmd;
986 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
987 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
988 break;
989 }
990
991 case SVGA_3D_CMD_DEFINE_GB_SURFACE:
992 {
993 SVGA3dCmdDefineGBSurface *pCmd = (SVGA3dCmdDefineGBSurface *)pvCmd;
994 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
995 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
996 break;
997 }
998
999 case SVGA_3D_CMD_DESTROY_GB_SURFACE:
1000 {
1001 SVGA3dCmdDestroyGBSurface *pCmd = (SVGA3dCmdDestroyGBSurface *)pvCmd;
1002 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1003 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1004 break;
1005 }
1006
1007 case SVGA_3D_CMD_BIND_GB_SURFACE:
1008 {
1009 SVGA3dCmdBindGBSurface *pCmd = (SVGA3dCmdBindGBSurface *)pvCmd;
1010 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1011 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1012 break;
1013 }
1014
1015 case SVGA_3D_CMD_COND_BIND_GB_SURFACE:
1016 {
1017 SVGA3dCmdCondBindGBSurface *pCmd = (SVGA3dCmdCondBindGBSurface *)pvCmd;
1018 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1019 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1020 break;
1021 }
1022
1023 case SVGA_3D_CMD_UPDATE_GB_IMAGE:
1024 {
1025 SVGA3dCmdUpdateGBImage *pCmd = (SVGA3dCmdUpdateGBImage *)pvCmd;
1026 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1027 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1028 break;
1029 }
1030
1031 case SVGA_3D_CMD_UPDATE_GB_SURFACE:
1032 {
1033 SVGA3dCmdUpdateGBSurface *pCmd = (SVGA3dCmdUpdateGBSurface *)pvCmd;
1034 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1035 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1036 break;
1037 }
1038
1039 case SVGA_3D_CMD_READBACK_GB_IMAGE:
1040 {
1041 SVGA3dCmdReadbackGBImage *pCmd = (SVGA3dCmdReadbackGBImage *)pvCmd;
1042 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1043 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1044 break;
1045 }
1046
1047 case SVGA_3D_CMD_READBACK_GB_SURFACE:
1048 {
1049 SVGA3dCmdReadbackGBSurface *pCmd = (SVGA3dCmdReadbackGBSurface *)pvCmd;
1050 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1051 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1052 break;
1053 }
1054
1055 case SVGA_3D_CMD_INVALIDATE_GB_IMAGE:
1056 {
1057 SVGA3dCmdInvalidateGBImage *pCmd = (SVGA3dCmdInvalidateGBImage *)pvCmd;
1058 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1059 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1060 break;
1061 }
1062
1063 case SVGA_3D_CMD_INVALIDATE_GB_SURFACE:
1064 {
1065 SVGA3dCmdInvalidateGBSurface *pCmd = (SVGA3dCmdInvalidateGBSurface *)pvCmd;
1066 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1067 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1068 break;
1069 }
1070
1071 case SVGA_3D_CMD_DEFINE_GB_CONTEXT:
1072 {
1073 SVGA3dCmdDefineGBContext *pCmd = (SVGA3dCmdDefineGBContext *)pvCmd;
1074 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1075 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1076 break;
1077 }
1078
1079 case SVGA_3D_CMD_DESTROY_GB_CONTEXT:
1080 {
1081 SVGA3dCmdDestroyGBContext *pCmd = (SVGA3dCmdDestroyGBContext *)pvCmd;
1082 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1083 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1084 break;
1085 }
1086
1087 case SVGA_3D_CMD_BIND_GB_CONTEXT:
1088 {
1089 SVGA3dCmdBindGBContext *pCmd = (SVGA3dCmdBindGBContext *)pvCmd;
1090 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1091 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1092 break;
1093 }
1094
1095 case SVGA_3D_CMD_READBACK_GB_CONTEXT:
1096 {
1097 SVGA3dCmdReadbackGBContext *pCmd = (SVGA3dCmdReadbackGBContext *)pvCmd;
1098 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1099 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1100 break;
1101 }
1102
1103 case SVGA_3D_CMD_INVALIDATE_GB_CONTEXT:
1104 {
1105 SVGA3dCmdInvalidateGBContext *pCmd = (SVGA3dCmdInvalidateGBContext *)pvCmd;
1106 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1107 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1108 break;
1109 }
1110
1111 case SVGA_3D_CMD_DEFINE_GB_SHADER:
1112 {
1113 SVGA3dCmdDefineGBShader *pCmd = (SVGA3dCmdDefineGBShader *)pvCmd;
1114 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1115 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1116 break;
1117 }
1118
1119 case SVGA_3D_CMD_DESTROY_GB_SHADER:
1120 {
1121 SVGA3dCmdDestroyGBShader *pCmd = (SVGA3dCmdDestroyGBShader *)pvCmd;
1122 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1123 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1124 break;
1125 }
1126
1127 case SVGA_3D_CMD_BIND_GB_SHADER:
1128 {
1129 SVGA3dCmdBindGBShader *pCmd = (SVGA3dCmdBindGBShader *)pvCmd;
1130 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1131 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1132 break;
1133 }
1134
1135 case SVGA_3D_CMD_SET_OTABLE_BASE64:
1136 {
1137 SVGA3dCmdSetOTableBase64 *pCmd = (SVGA3dCmdSetOTableBase64 *)pvCmd;
1138 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1139 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1140 break;
1141 }
1142
1143 case SVGA_3D_CMD_BEGIN_GB_QUERY:
1144 {
1145 SVGA3dCmdBeginGBQuery *pCmd = (SVGA3dCmdBeginGBQuery *)pvCmd;
1146 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1147 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1148 break;
1149 }
1150
1151 case SVGA_3D_CMD_END_GB_QUERY:
1152 {
1153 SVGA3dCmdEndGBQuery *pCmd = (SVGA3dCmdEndGBQuery *)pvCmd;
1154 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1155 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1156 break;
1157 }
1158
1159 case SVGA_3D_CMD_WAIT_FOR_GB_QUERY:
1160 {
1161 SVGA3dCmdWaitForGBQuery *pCmd = (SVGA3dCmdWaitForGBQuery *)pvCmd;
1162 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1163 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1164 break;
1165 }
1166
1167 case SVGA_3D_CMD_NOP:
1168 {
1169 /* Apparently there is nothing to do. */
1170 break;
1171 }
1172
1173 case SVGA_3D_CMD_ENABLE_GART:
1174 {
1175 SVGA3dCmdEnableGart *pCmd = (SVGA3dCmdEnableGart *)pvCmd;
1176 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1177 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1178 break;
1179 }
1180
1181 case SVGA_3D_CMD_DISABLE_GART:
1182 {
1183 /* No corresponding SVGA3dCmd structure. */
1184 VMSVGA_3D_CMD_NOTIMPL();
1185 break;
1186 }
1187
1188 case SVGA_3D_CMD_MAP_MOB_INTO_GART:
1189 {
1190 SVGA3dCmdMapMobIntoGart *pCmd = (SVGA3dCmdMapMobIntoGart *)pvCmd;
1191 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1192 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1193 break;
1194 }
1195
1196 case SVGA_3D_CMD_UNMAP_GART_RANGE:
1197 {
1198 SVGA3dCmdUnmapGartRange *pCmd = (SVGA3dCmdUnmapGartRange *)pvCmd;
1199 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1200 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1201 break;
1202 }
1203
1204 case SVGA_3D_CMD_DEFINE_GB_SCREENTARGET:
1205 {
1206 SVGA3dCmdDefineGBScreenTarget *pCmd = (SVGA3dCmdDefineGBScreenTarget *)pvCmd;
1207 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1208 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1209 break;
1210 }
1211
1212 case SVGA_3D_CMD_DESTROY_GB_SCREENTARGET:
1213 {
1214 SVGA3dCmdDestroyGBScreenTarget *pCmd = (SVGA3dCmdDestroyGBScreenTarget *)pvCmd;
1215 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1216 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1217 break;
1218 }
1219
1220 case SVGA_3D_CMD_BIND_GB_SCREENTARGET:
1221 {
1222 SVGA3dCmdBindGBScreenTarget *pCmd = (SVGA3dCmdBindGBScreenTarget *)pvCmd;
1223 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1224 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1225 break;
1226 }
1227
1228 case SVGA_3D_CMD_UPDATE_GB_SCREENTARGET:
1229 {
1230 SVGA3dCmdUpdateGBScreenTarget *pCmd = (SVGA3dCmdUpdateGBScreenTarget *)pvCmd;
1231 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1232 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1233 break;
1234 }
1235
1236 case SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL:
1237 {
1238 SVGA3dCmdReadbackGBImagePartial *pCmd = (SVGA3dCmdReadbackGBImagePartial *)pvCmd;
1239 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1240 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1241 break;
1242 }
1243
1244 case SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL:
1245 {
1246 SVGA3dCmdInvalidateGBImagePartial *pCmd = (SVGA3dCmdInvalidateGBImagePartial *)pvCmd;
1247 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1248 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1249 break;
1250 }
1251
1252 case SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE:
1253 {
1254 SVGA3dCmdSetGBShaderConstInline *pCmd = (SVGA3dCmdSetGBShaderConstInline *)pvCmd;
1255 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1256 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1257 break;
1258 }
1259
1260 case SVGA_3D_CMD_GB_SCREEN_DMA:
1261 {
1262 SVGA3dCmdGBScreenDMA *pCmd = (SVGA3dCmdGBScreenDMA *)pvCmd;
1263 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1264 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1265 break;
1266 }
1267
1268 case SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH:
1269 {
1270 SVGA3dCmdBindGBSurfaceWithPitch *pCmd = (SVGA3dCmdBindGBSurfaceWithPitch *)pvCmd;
1271 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1272 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1273 break;
1274 }
1275
1276 case SVGA_3D_CMD_GB_MOB_FENCE:
1277 {
1278 SVGA3dCmdGBMobFence *pCmd = (SVGA3dCmdGBMobFence *)pvCmd;
1279 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1280 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1281 break;
1282 }
1283
1284 case SVGA_3D_CMD_DEFINE_GB_SURFACE_V2:
1285 {
1286 /// @todo SVGA3dCmdDefineGBSurface_v2 is not defined in Mesa 17 header. Mesa 20 has it.
1287 //SVGA3dCmdDefineGBSurface_v2 *pCmd = (SVGA3dCmdDefineGBSurface_v2 *)pvCmd;
1288 //VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1289 VMSVGA_3D_CMD_NOTIMPL();
1290 break;
1291 }
1292
1293 case SVGA_3D_CMD_DEFINE_GB_MOB64:
1294 {
1295 SVGA3dCmdDefineGBMob64 *pCmd = (SVGA3dCmdDefineGBMob64 *)pvCmd;
1296 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1297 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1298 break;
1299 }
1300
1301 case SVGA_3D_CMD_REDEFINE_GB_MOB64:
1302 {
1303 SVGA3dCmdRedefineGBMob64 *pCmd = (SVGA3dCmdRedefineGBMob64 *)pvCmd;
1304 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1305 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1306 break;
1307 }
1308
1309 case SVGA_3D_CMD_NOP_ERROR:
1310 {
1311 /* Apparently there is nothing to do. */
1312 break;
1313 }
1314
1315 case SVGA_3D_CMD_SET_VERTEX_STREAMS:
1316 {
1317 SVGA3dCmdSetVertexStreams *pCmd = (SVGA3dCmdSetVertexStreams *)pvCmd;
1318 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1319 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1320 break;
1321 }
1322
1323 case SVGA_3D_CMD_SET_VERTEX_DECLS:
1324 {
1325 SVGA3dCmdSetVertexDecls *pCmd = (SVGA3dCmdSetVertexDecls *)pvCmd;
1326 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1327 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1328 break;
1329 }
1330
1331 case SVGA_3D_CMD_SET_VERTEX_DIVISORS:
1332 {
1333 SVGA3dCmdSetVertexDivisors *pCmd = (SVGA3dCmdSetVertexDivisors *)pvCmd;
1334 VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
1335 VMSVGA_3D_CMD_NOTIMPL(); RT_NOREF(pCmd);
1336 break;
1337 }
1338
1339 case SVGA_3D_CMD_DRAW:
1340 {
1341 /* No corresponding SVGA3dCmd structure. */
1342 VMSVGA_3D_CMD_NOTIMPL();
1343 break;
1344 }
1345
1346 case SVGA_3D_CMD_DRAW_INDEXED:
1347 {
1348 /* No corresponding SVGA3dCmd structure. */
1349 VMSVGA_3D_CMD_NOTIMPL();
1350 break;
1351 }
1352
1353 default:
1354 STAM_REL_COUNTER_INC(&pSvgaR3State->StatFifoUnkCmds);
1355 ASSERT_GUEST_MSG_FAILED(("enmCmdId=%d\n", enmCmdId));
1356 rcParse = VERR_NOT_IMPLEMENTED;
1357 break;
1358 }
1359
1360 return rcParse;
1361}
1362# undef VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK
1363#endif /* VBOX_WITH_VMSVGA3D */
1364
1365
1366/*
1367 *
1368 * Handlers for FIFO commands.
1369 *
1370 * Every handler takes the following parameters:
1371 *
1372 * pThis The shared VGA/VMSVGA state.
1373 * pThisCC The VGA/VMSVGA state for ring-3.
1374 * pCmd The command data.
1375 */
1376
1377
1378/* SVGA_CMD_UPDATE */
1379void vmsvgaR3CmdUpdate(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdUpdate const *pCmd)
1380{
1381 RT_NOREF(pThis);
1382 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1383
1384 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdUpdate);
1385 Log(("SVGA_CMD_UPDATE %d,%d %dx%d\n", pCmd->x, pCmd->y, pCmd->width, pCmd->height));
1386
1387 /** @todo Multiple screens? */
1388 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
1389 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */
1390 return;
1391
1392 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->x, pCmd->y, pCmd->width, pCmd->height);
1393}
1394
1395
1396/* SVGA_CMD_UPDATE_VERBOSE */
1397void vmsvgaR3CmdUpdateVerbose(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdUpdateVerbose const *pCmd)
1398{
1399 RT_NOREF(pThis);
1400 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1401
1402 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdUpdateVerbose);
1403 Log(("SVGA_CMD_UPDATE_VERBOSE %d,%d %dx%d reason %#x\n", pCmd->x, pCmd->y, pCmd->width, pCmd->height, pCmd->reason));
1404
1405 /** @todo Multiple screens? */
1406 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
1407 if (!pScreen) /* Can happen if screen is not defined (aScreens[idScreen].fDefined == false) yet. */
1408 return;
1409
1410 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->x, pCmd->y, pCmd->width, pCmd->height);
1411}
1412
1413
1414/* SVGA_CMD_RECT_FILL */
1415void vmsvgaR3CmdRectFill(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectFill const *pCmd)
1416{
1417 RT_NOREF(pThis, pCmd);
1418 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1419
1420 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectFill);
1421 Log(("SVGA_CMD_RECT_FILL %08X @ %d,%d (%dx%d)\n", pCmd->pixel, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height));
1422 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_RECT_FILL command ignored.\n"));
1423}
1424
1425
1426/* SVGA_CMD_RECT_COPY */
1427void vmsvgaR3CmdRectCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectCopy const *pCmd)
1428{
1429 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1430
1431 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectCopy);
1432 Log(("SVGA_CMD_RECT_COPY %d,%d -> %d,%d %dx%d\n", pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height));
1433
1434 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
1435 AssertPtrReturnVoid(pScreen);
1436
1437 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */
1438 ASSERT_GUEST_RETURN_VOID(pCmd->srcX < pThis->svga.u32MaxWidth);
1439 ASSERT_GUEST_RETURN_VOID(pCmd->destX < pThis->svga.u32MaxWidth);
1440 ASSERT_GUEST_RETURN_VOID(pCmd->width < pThis->svga.u32MaxWidth);
1441 ASSERT_GUEST_RETURN_VOID(pCmd->srcY < pThis->svga.u32MaxHeight);
1442 ASSERT_GUEST_RETURN_VOID(pCmd->destY < pThis->svga.u32MaxHeight);
1443 ASSERT_GUEST_RETURN_VOID(pCmd->height < pThis->svga.u32MaxHeight);
1444
1445 vmsvgaR3RectCopy(pThisCC, pScreen, pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY,
1446 pCmd->width, pCmd->height, pThis->vram_size);
1447 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height);
1448}
1449
1450
1451/* SVGA_CMD_RECT_ROP_COPY */
1452void vmsvgaR3CmdRectRopCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRectRopCopy const *pCmd)
1453{
1454 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1455
1456 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRectRopCopy);
1457 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));
1458
1459 if (pCmd->rop != SVGA_ROP_COPY)
1460 {
1461 /* We only support the plain copy ROP which makes SVGA_CMD_RECT_ROP_COPY exactly the same
1462 * as SVGA_CMD_RECT_COPY. XFree86 4.1.0 and 4.2.0 drivers (driver version 10.4.0 and 10.7.0,
1463 * respectively) issue SVGA_CMD_RECT_ROP_COPY when SVGA_CAP_RECT_COPY is present even when
1464 * SVGA_CAP_RASTER_OP is not. However, the ROP will always be SVGA_ROP_COPY.
1465 */
1466 LogRelMax(4, ("VMSVGA: SVGA_CMD_RECT_ROP_COPY %d,%d -> %d,%d (%dx%d) ROP %X unsupported\n",
1467 pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height, pCmd->rop));
1468 return;
1469 }
1470
1471 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, 0);
1472 AssertPtrReturnVoid(pScreen);
1473
1474 /* Check that arguments aren't complete junk. A precise check is done in vmsvgaR3RectCopy(). */
1475 ASSERT_GUEST_RETURN_VOID(pCmd->srcX < pThis->svga.u32MaxWidth);
1476 ASSERT_GUEST_RETURN_VOID(pCmd->destX < pThis->svga.u32MaxWidth);
1477 ASSERT_GUEST_RETURN_VOID(pCmd->width < pThis->svga.u32MaxWidth);
1478 ASSERT_GUEST_RETURN_VOID(pCmd->srcY < pThis->svga.u32MaxHeight);
1479 ASSERT_GUEST_RETURN_VOID(pCmd->destY < pThis->svga.u32MaxHeight);
1480 ASSERT_GUEST_RETURN_VOID(pCmd->height < pThis->svga.u32MaxHeight);
1481
1482 vmsvgaR3RectCopy(pThisCC, pScreen, pCmd->srcX, pCmd->srcY, pCmd->destX, pCmd->destY,
1483 pCmd->width, pCmd->height, pThis->vram_size);
1484 vmsvgaR3UpdateScreen(pThisCC, pScreen, pCmd->destX, pCmd->destY, pCmd->width, pCmd->height);
1485}
1486
1487
1488/* SVGA_CMD_DISPLAY_CURSOR */
1489void vmsvgaR3CmdDisplayCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDisplayCursor const *pCmd)
1490{
1491 RT_NOREF(pThis, pCmd);
1492 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1493
1494 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDisplayCursor);
1495 Log(("SVGA_CMD_DISPLAY_CURSOR id=%d state=%d\n", pCmd->id, pCmd->state));
1496 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_DISPLAY_CURSOR command ignored.\n"));
1497}
1498
1499
1500/* SVGA_CMD_MOVE_CURSOR */
1501void vmsvgaR3CmdMoveCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdMoveCursor const *pCmd)
1502{
1503 RT_NOREF(pThis, pCmd);
1504 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1505
1506 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdMoveCursor);
1507 Log(("SVGA_CMD_MOVE_CURSOR to %d,%d\n", pCmd->pos.x, pCmd->pos.y));
1508 LogRelMax(4, ("VMSVGA: Unsupported SVGA_CMD_MOVE_CURSOR command ignored.\n"));
1509}
1510
1511
1512/* SVGA_CMD_DEFINE_CURSOR */
1513void vmsvgaR3CmdDefineCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineCursor const *pCmd)
1514{
1515 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1516
1517 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineCursor);
1518 Log(("SVGA_CMD_DEFINE_CURSOR id=%d size (%dx%d) hotspot (%d,%d) andMaskDepth=%d xorMaskDepth=%d\n",
1519 pCmd->id, pCmd->width, pCmd->height, pCmd->hotspotX, pCmd->hotspotY, pCmd->andMaskDepth, pCmd->xorMaskDepth));
1520
1521 ASSERT_GUEST_RETURN_VOID(pCmd->height < 2048 && pCmd->width < 2048);
1522 ASSERT_GUEST_RETURN_VOID(pCmd->andMaskDepth <= 32);
1523 ASSERT_GUEST_RETURN_VOID(pCmd->xorMaskDepth <= 32);
1524 RT_UNTRUSTED_VALIDATED_FENCE();
1525
1526 uint32_t const cbSrcAndLine = RT_ALIGN_32(pCmd->width * (pCmd->andMaskDepth + (pCmd->andMaskDepth == 15)), 32) / 8;
1527 uint32_t const cbSrcAndMask = cbSrcAndLine * pCmd->height;
1528 uint32_t const cbSrcXorLine = RT_ALIGN_32(pCmd->width * (pCmd->xorMaskDepth + (pCmd->xorMaskDepth == 15)), 32) / 8;
1529
1530 uint8_t const *pbSrcAndMask = (uint8_t const *)(pCmd + 1);
1531 uint8_t const *pbSrcXorMask = (uint8_t const *)(pCmd + 1) + cbSrcAndMask;
1532
1533 uint32_t const cx = pCmd->width;
1534 uint32_t const cy = pCmd->height;
1535
1536 /*
1537 * Convert the input to 1-bit AND mask and a 32-bit BRGA XOR mask.
1538 * The AND data uses 8-bit aligned scanlines.
1539 * The XOR data must be starting on a 32-bit boundrary.
1540 */
1541 uint32_t cbDstAndLine = RT_ALIGN_32(cx, 8) / 8;
1542 uint32_t cbDstAndMask = cbDstAndLine * cy;
1543 uint32_t cbDstXorMask = cx * sizeof(uint32_t) * cy;
1544 uint32_t cbCopy = RT_ALIGN_32(cbDstAndMask, 4) + cbDstXorMask;
1545
1546 uint8_t *pbCopy = (uint8_t *)RTMemAlloc(cbCopy);
1547 AssertReturnVoid(pbCopy);
1548
1549 /* Convert the AND mask. */
1550 uint8_t *pbDst = pbCopy;
1551 uint8_t const *pbSrc = pbSrcAndMask;
1552 switch (pCmd->andMaskDepth)
1553 {
1554 case 1:
1555 if (cbSrcAndLine == cbDstAndLine)
1556 memcpy(pbDst, pbSrc, cbSrcAndLine * cy);
1557 else
1558 {
1559 Assert(cbSrcAndLine > cbDstAndLine); /* lines are dword alined in source, but only byte in destination. */
1560 for (uint32_t y = 0; y < cy; y++)
1561 {
1562 memcpy(pbDst, pbSrc, cbDstAndLine);
1563 pbDst += cbDstAndLine;
1564 pbSrc += cbSrcAndLine;
1565 }
1566 }
1567 break;
1568 /* Should take the XOR mask into account for the multi-bit AND mask. */
1569 case 8:
1570 for (uint32_t y = 0; y < cy; y++)
1571 {
1572 for (uint32_t x = 0; x < cx; )
1573 {
1574 uint8_t bDst = 0;
1575 uint8_t fBit = 0x80;
1576 do
1577 {
1578 uintptr_t const idxPal = pbSrc[x] * 3;
1579 if ((( pThis->last_palette[idxPal]
1580 | (pThis->last_palette[idxPal] >> 8)
1581 | (pThis->last_palette[idxPal] >> 16)) & 0xff) > 0xfc)
1582 bDst |= fBit;
1583 fBit >>= 1;
1584 x++;
1585 } while (x < cx && (x & 7));
1586 pbDst[(x - 1) / 8] = bDst;
1587 }
1588 pbDst += cbDstAndLine;
1589 pbSrc += cbSrcAndLine;
1590 }
1591 break;
1592 case 15:
1593 for (uint32_t y = 0; y < cy; y++)
1594 {
1595 for (uint32_t x = 0; x < cx; )
1596 {
1597 uint8_t bDst = 0;
1598 uint8_t fBit = 0x80;
1599 do
1600 {
1601 if ((pbSrc[x * 2] | (pbSrc[x * 2 + 1] & 0x7f)) >= 0xfc)
1602 bDst |= fBit;
1603 fBit >>= 1;
1604 x++;
1605 } while (x < cx && (x & 7));
1606 pbDst[(x - 1) / 8] = bDst;
1607 }
1608 pbDst += cbDstAndLine;
1609 pbSrc += cbSrcAndLine;
1610 }
1611 break;
1612 case 16:
1613 for (uint32_t y = 0; y < cy; y++)
1614 {
1615 for (uint32_t x = 0; x < cx; )
1616 {
1617 uint8_t bDst = 0;
1618 uint8_t fBit = 0x80;
1619 do
1620 {
1621 if ((pbSrc[x * 2] | pbSrc[x * 2 + 1]) >= 0xfc)
1622 bDst |= fBit;
1623 fBit >>= 1;
1624 x++;
1625 } while (x < cx && (x & 7));
1626 pbDst[(x - 1) / 8] = bDst;
1627 }
1628 pbDst += cbDstAndLine;
1629 pbSrc += cbSrcAndLine;
1630 }
1631 break;
1632 case 24:
1633 for (uint32_t y = 0; y < cy; y++)
1634 {
1635 for (uint32_t x = 0; x < cx; )
1636 {
1637 uint8_t bDst = 0;
1638 uint8_t fBit = 0x80;
1639 do
1640 {
1641 if ((pbSrc[x * 3] | pbSrc[x * 3 + 1] | pbSrc[x * 3 + 2]) >= 0xfc)
1642 bDst |= fBit;
1643 fBit >>= 1;
1644 x++;
1645 } while (x < cx && (x & 7));
1646 pbDst[(x - 1) / 8] = bDst;
1647 }
1648 pbDst += cbDstAndLine;
1649 pbSrc += cbSrcAndLine;
1650 }
1651 break;
1652 case 32:
1653 for (uint32_t y = 0; y < cy; y++)
1654 {
1655 for (uint32_t x = 0; x < cx; )
1656 {
1657 uint8_t bDst = 0;
1658 uint8_t fBit = 0x80;
1659 do
1660 {
1661 if ((pbSrc[x * 4] | pbSrc[x * 4 + 1] | pbSrc[x * 4 + 2] | pbSrc[x * 4 + 3]) >= 0xfc)
1662 bDst |= fBit;
1663 fBit >>= 1;
1664 x++;
1665 } while (x < cx && (x & 7));
1666 pbDst[(x - 1) / 8] = bDst;
1667 }
1668 pbDst += cbDstAndLine;
1669 pbSrc += cbSrcAndLine;
1670 }
1671 break;
1672 default:
1673 RTMemFreeZ(pbCopy, cbCopy);
1674 AssertFailedReturnVoid();
1675 }
1676
1677 /* Convert the XOR mask. */
1678 uint32_t *pu32Dst = (uint32_t *)(pbCopy + RT_ALIGN_32(cbDstAndMask, 4));
1679 pbSrc = pbSrcXorMask;
1680 switch (pCmd->xorMaskDepth)
1681 {
1682 case 1:
1683 for (uint32_t y = 0; y < cy; y++)
1684 {
1685 for (uint32_t x = 0; x < cx; )
1686 {
1687 /* most significant bit is the left most one. */
1688 uint8_t bSrc = pbSrc[x / 8];
1689 do
1690 {
1691 *pu32Dst++ = bSrc & 0x80 ? UINT32_C(0x00ffffff) : 0;
1692 bSrc <<= 1;
1693 x++;
1694 } while ((x & 7) && x < cx);
1695 }
1696 pbSrc += cbSrcXorLine;
1697 }
1698 break;
1699 case 8:
1700 for (uint32_t y = 0; y < cy; y++)
1701 {
1702 for (uint32_t x = 0; x < cx; x++)
1703 {
1704 uint32_t u = pThis->last_palette[pbSrc[x]];
1705 *pu32Dst++ = u;//RT_MAKE_U32_FROM_U8(RT_BYTE1(u), RT_BYTE2(u), RT_BYTE3(u), 0);
1706 }
1707 pbSrc += cbSrcXorLine;
1708 }
1709 break;
1710 case 15: /* Src: RGB-5-5-5 */
1711 for (uint32_t y = 0; y < cy; y++)
1712 {
1713 for (uint32_t x = 0; x < cx; x++)
1714 {
1715 uint32_t const uValue = RT_MAKE_U16(pbSrc[x * 2], pbSrc[x * 2 + 1]);
1716 *pu32Dst++ = RT_MAKE_U32_FROM_U8(( uValue & 0x1f) << 3,
1717 ((uValue >> 5) & 0x1f) << 3,
1718 ((uValue >> 10) & 0x1f) << 3, 0);
1719 }
1720 pbSrc += cbSrcXorLine;
1721 }
1722 break;
1723 case 16: /* Src: RGB-5-6-5 */
1724 for (uint32_t y = 0; y < cy; y++)
1725 {
1726 for (uint32_t x = 0; x < cx; x++)
1727 {
1728 uint32_t const uValue = RT_MAKE_U16(pbSrc[x * 2], pbSrc[x * 2 + 1]);
1729 *pu32Dst++ = RT_MAKE_U32_FROM_U8(( uValue & 0x1f) << 3,
1730 ((uValue >> 5) & 0x3f) << 2,
1731 ((uValue >> 11) & 0x1f) << 3, 0);
1732 }
1733 pbSrc += cbSrcXorLine;
1734 }
1735 break;
1736 case 24:
1737 for (uint32_t y = 0; y < cy; y++)
1738 {
1739 for (uint32_t x = 0; x < cx; x++)
1740 *pu32Dst++ = RT_MAKE_U32_FROM_U8(pbSrc[x*3], pbSrc[x*3 + 1], pbSrc[x*3 + 2], 0);
1741 pbSrc += cbSrcXorLine;
1742 }
1743 break;
1744 case 32:
1745 for (uint32_t y = 0; y < cy; y++)
1746 {
1747 for (uint32_t x = 0; x < cx; x++)
1748 *pu32Dst++ = RT_MAKE_U32_FROM_U8(pbSrc[x*4], pbSrc[x*4 + 1], pbSrc[x*4 + 2], 0);
1749 pbSrc += cbSrcXorLine;
1750 }
1751 break;
1752 default:
1753 RTMemFreeZ(pbCopy, cbCopy);
1754 AssertFailedReturnVoid();
1755 }
1756
1757 /*
1758 * Pass it to the frontend/whatever.
1759 */
1760 vmsvgaR3InstallNewCursor(pThisCC, pSvgaR3State, false /*fAlpha*/, pCmd->hotspotX, pCmd->hotspotY,
1761 cx, cy, pbCopy, cbCopy);
1762}
1763
1764
1765/* SVGA_CMD_DEFINE_ALPHA_CURSOR */
1766void vmsvgaR3CmdDefineAlphaCursor(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineAlphaCursor const *pCmd)
1767{
1768 RT_NOREF(pThis);
1769 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1770
1771 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineAlphaCursor);
1772 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));
1773
1774 /* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */
1775 ASSERT_GUEST_RETURN_VOID(pCmd->height < 2048 && pCmd->width < 2048);
1776 RT_UNTRUSTED_VALIDATED_FENCE();
1777
1778 /* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */
1779 uint32_t cbAndMask = (pCmd->width + 7) / 8 * pCmd->height; /* size of the AND mask */
1780 cbAndMask = ((cbAndMask + 3) & ~3); /* + gap for alignment */
1781 uint32_t cbXorMask = pCmd->width * sizeof(uint32_t) * pCmd->height; /* + size of the XOR mask (32-bit BRGA format) */
1782 uint32_t cbCursorShape = cbAndMask + cbXorMask;
1783
1784 uint8_t *pCursorCopy = (uint8_t *)RTMemAlloc(cbCursorShape);
1785 AssertPtrReturnVoid(pCursorCopy);
1786
1787 /* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */
1788 memset(pCursorCopy, 0xff, cbAndMask);
1789 /* Colour data */
1790 memcpy(pCursorCopy + cbAndMask, pCmd + 1, cbXorMask);
1791
1792 vmsvgaR3InstallNewCursor(pThisCC, pSvgaR3State, true /*fAlpha*/, pCmd->hotspotX, pCmd->hotspotY,
1793 pCmd->width, pCmd->height, pCursorCopy, cbCursorShape);
1794}
1795
1796
1797/* SVGA_CMD_ESCAPE */
1798void vmsvgaR3CmdEscape(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdEscape const *pCmd)
1799{
1800 RT_NOREF(pThis);
1801 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1802
1803 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdEscape);
1804
1805 if (pCmd->nsid == SVGA_ESCAPE_NSID_VMWARE)
1806 {
1807 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(uint32_t));
1808 RT_UNTRUSTED_VALIDATED_FENCE();
1809
1810 uint32_t const cmd = *(uint32_t *)(pCmd + 1);
1811 Log(("SVGA_CMD_ESCAPE (%#x %#x) VMWARE cmd=%#x\n", pCmd->nsid, pCmd->size, cmd));
1812
1813 switch (cmd)
1814 {
1815 case SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS:
1816 {
1817 SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pCmd + 1);
1818 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(pVideoCmd->header));
1819 RT_UNTRUSTED_VALIDATED_FENCE();
1820
1821 uint32_t const cRegs = (pCmd->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]);
1822
1823 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: stream %#x\n", pVideoCmd->header.streamId));
1824 for (uint32_t iReg = 0; iReg < cRegs; iReg++)
1825 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: reg %#x val %#x\n", pVideoCmd->items[iReg].registerId, pVideoCmd->items[iReg].value));
1826 RT_NOREF_PV(pVideoCmd);
1827 break;
1828 }
1829
1830 case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH:
1831 {
1832 SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pCmd + 1);
1833 ASSERT_GUEST_RETURN_VOID(pCmd->size >= sizeof(*pVideoCmd));
1834 Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %#x\n", pVideoCmd->streamId));
1835 RT_NOREF_PV(pVideoCmd);
1836 break;
1837 }
1838
1839 default:
1840 Log(("SVGA_CMD_ESCAPE: Unknown vmware escape: %#x\n", cmd));
1841 break;
1842 }
1843 }
1844 else
1845 Log(("SVGA_CMD_ESCAPE %#x %#x\n", pCmd->nsid, pCmd->size));
1846}
1847
1848
1849/* SVGA_CMD_DEFINE_SCREEN */
1850void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineScreen const *pCmd)
1851{
1852 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1853
1854 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineScreen);
1855 Log(("SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d) %d:0x%x 0x%x\n",
1856 pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y,
1857 pCmd->screen.backingStore.ptr.gmrId, pCmd->screen.backingStore.ptr.offset, pCmd->screen.backingStore.pitch));
1858
1859 uint32_t const idScreen = pCmd->screen.id;
1860 ASSERT_GUEST_RETURN_VOID(idScreen < RT_ELEMENTS(pSvgaR3State->aScreens));
1861
1862 uint32_t const uWidth = pCmd->screen.size.width;
1863 ASSERT_GUEST_RETURN_VOID(uWidth <= pThis->svga.u32MaxWidth);
1864
1865 uint32_t const uHeight = pCmd->screen.size.height;
1866 ASSERT_GUEST_RETURN_VOID(uHeight <= pThis->svga.u32MaxHeight);
1867
1868 uint32_t const cbWidth = uWidth * ((32 + 7) / 8); /** @todo 32? */
1869 uint32_t const cbPitch = pCmd->screen.backingStore.pitch ? pCmd->screen.backingStore.pitch : cbWidth;
1870 ASSERT_GUEST_RETURN_VOID(cbWidth <= cbPitch);
1871
1872 uint32_t const uScreenOffset = pCmd->screen.backingStore.ptr.offset;
1873 ASSERT_GUEST_RETURN_VOID(uScreenOffset < pThis->vram_size);
1874
1875 uint32_t const cbVram = pThis->vram_size - uScreenOffset;
1876 /* If we have a not zero pitch, then height can't exceed the available VRAM. */
1877 ASSERT_GUEST_RETURN_VOID( (uHeight == 0 && cbPitch == 0)
1878 || (cbPitch > 0 && uHeight <= cbVram / cbPitch));
1879 RT_UNTRUSTED_VALIDATED_FENCE();
1880
1881 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen];
1882 pScreen->fDefined = true;
1883 pScreen->fModified = true;
1884 pScreen->fuScreen = pCmd->screen.flags;
1885 pScreen->idScreen = idScreen;
1886 if (!RT_BOOL(pCmd->screen.flags & (SVGA_SCREEN_DEACTIVATE | SVGA_SCREEN_BLANKING)))
1887 {
1888 /* Not blanked. */
1889 ASSERT_GUEST_RETURN_VOID(uWidth > 0 && uHeight > 0);
1890 RT_UNTRUSTED_VALIDATED_FENCE();
1891
1892 pScreen->xOrigin = pCmd->screen.root.x;
1893 pScreen->yOrigin = pCmd->screen.root.y;
1894 pScreen->cWidth = uWidth;
1895 pScreen->cHeight = uHeight;
1896 pScreen->offVRAM = uScreenOffset;
1897 pScreen->cbPitch = cbPitch;
1898 pScreen->cBpp = 32;
1899 }
1900 else
1901 {
1902 /* Screen blanked. Keep old values. */
1903 }
1904
1905 pThis->svga.fGFBRegisters = false;
1906 vmsvgaR3ChangeMode(pThis, pThisCC);
1907
1908#ifdef VBOX_WITH_VMSVGA3D
1909 if (RT_LIKELY(pThis->svga.f3DEnabled))
1910 vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
1911#endif
1912}
1913
1914
1915/* SVGA_CMD_DESTROY_SCREEN */
1916void vmsvgaR3CmdDestroyScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDestroyScreen const *pCmd)
1917{
1918 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1919
1920 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDestroyScreen);
1921 Log(("SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId));
1922
1923 uint32_t const idScreen = pCmd->screenId;
1924 ASSERT_GUEST_RETURN_VOID(idScreen < RT_ELEMENTS(pSvgaR3State->aScreens));
1925 RT_UNTRUSTED_VALIDATED_FENCE();
1926
1927 VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen];
1928 pScreen->fModified = true;
1929 pScreen->fDefined = false;
1930 pScreen->idScreen = idScreen;
1931
1932#ifdef VBOX_WITH_VMSVGA3D
1933 if (RT_LIKELY(pThis->svga.f3DEnabled))
1934 vmsvga3dDestroyScreen(pThisCC, pScreen);
1935#endif
1936 vmsvgaR3ChangeMode(pThis, pThisCC);
1937}
1938
1939
1940/* SVGA_CMD_DEFINE_GMRFB */
1941void vmsvgaR3CmdDefineGMRFB(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineGMRFB const *pCmd)
1942{
1943 RT_NOREF(pThis);
1944 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1945
1946 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmrFb);
1947 Log(("SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n",
1948 pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.bitsPerPixel, pCmd->format.colorDepth));
1949
1950 pSvgaR3State->GMRFB.ptr = pCmd->ptr;
1951 pSvgaR3State->GMRFB.bytesPerLine = pCmd->bytesPerLine;
1952 pSvgaR3State->GMRFB.format = pCmd->format;
1953}
1954
1955
1956/* SVGA_CMD_BLIT_GMRFB_TO_SCREEN */
1957void vmsvgaR3CmdBlitGMRFBToScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdBlitGMRFBToScreen const *pCmd)
1958{
1959 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1960
1961 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdBlitGmrFbToScreen);
1962 Log(("SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n",
1963 pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom));
1964
1965 ASSERT_GUEST_RETURN_VOID(pCmd->destScreenId < RT_ELEMENTS(pSvgaR3State->aScreens));
1966 RT_UNTRUSTED_VALIDATED_FENCE();
1967
1968 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->destScreenId);
1969 AssertPtrReturnVoid(pScreen);
1970
1971 /** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp ? */
1972 AssertReturnVoid(pSvgaR3State->GMRFB.format.bitsPerPixel == pScreen->cBpp);
1973
1974 /* Clip destRect to the screen dimensions. */
1975 SVGASignedRect screenRect;
1976 screenRect.left = 0;
1977 screenRect.top = 0;
1978 screenRect.right = pScreen->cWidth;
1979 screenRect.bottom = pScreen->cHeight;
1980 SVGASignedRect clipRect = pCmd->destRect;
1981 vmsvgaR3ClipRect(&screenRect, &clipRect);
1982 RT_UNTRUSTED_VALIDATED_FENCE();
1983
1984 uint32_t const width = clipRect.right - clipRect.left;
1985 uint32_t const height = clipRect.bottom - clipRect.top;
1986
1987 if ( width == 0
1988 || height == 0)
1989 return; /* Nothing to do. */
1990
1991 int32_t const srcx = pCmd->srcOrigin.x + (clipRect.left - pCmd->destRect.left);
1992 int32_t const srcy = pCmd->srcOrigin.y + (clipRect.top - pCmd->destRect.top);
1993
1994 /* Copy the defined by GMRFB image to the screen 0 VRAM area.
1995 * Prepare parameters for vmsvgaR3GmrTransfer.
1996 */
1997 AssertReturnVoid(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */
1998
1999 /* Destination: host buffer which describes the screen 0 VRAM.
2000 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer.
2001 */
2002 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM;
2003 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch :
2004 width * (RT_ALIGN(pScreen->cBpp, 8) / 8);
2005 uint32_t cbHstBuf = cbScanline * pScreen->cHeight;
2006 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM)
2007 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */
2008 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8
2009 + cbScanline * clipRect.top;
2010 int32_t const cbHstPitch = cbScanline;
2011
2012 /* Source: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */
2013 SVGAGuestPtr const gstPtr = pSvgaR3State->GMRFB.ptr;
2014 uint32_t const offGst = (srcx * RT_ALIGN(pSvgaR3State->GMRFB.format.bitsPerPixel, 8)) / 8
2015 + pSvgaR3State->GMRFB.bytesPerLine * srcy;
2016 int32_t const cbGstPitch = pSvgaR3State->GMRFB.bytesPerLine;
2017
2018 int rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_WRITE_HOST_VRAM,
2019 pbHstBuf, cbHstBuf, offHst, cbHstPitch,
2020 gstPtr, offGst, cbGstPitch,
2021 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height);
2022 AssertRC(rc);
2023 vmsvgaR3UpdateScreen(pThisCC, pScreen, clipRect.left, clipRect.top, width, height);
2024}
2025
2026
2027/* SVGA_CMD_BLIT_SCREEN_TO_GMRFB */
2028void vmsvgaR3CmdBlitScreenToGMRFB(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdBlitScreenToGMRFB const *pCmd)
2029{
2030 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2031
2032 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdBlitScreentoGmrFb);
2033 /* Note! This can fetch 3d render results as well!! */
2034 Log(("SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n",
2035 pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom));
2036
2037 ASSERT_GUEST_RETURN_VOID(pCmd->srcScreenId < RT_ELEMENTS(pSvgaR3State->aScreens));
2038 RT_UNTRUSTED_VALIDATED_FENCE();
2039
2040 VMSVGASCREENOBJECT *pScreen = vmsvgaR3GetScreenObject(pThisCC, pCmd->srcScreenId);
2041 AssertPtrReturnVoid(pScreen);
2042
2043 /** @todo Support GMRFB.format.bitsPerPixel != pThis->svga.uBpp ? */
2044 AssertReturnVoid(pSvgaR3State->GMRFB.format.bitsPerPixel == pScreen->cBpp);
2045
2046 /* Clip destRect to the screen dimensions. */
2047 SVGASignedRect screenRect;
2048 screenRect.left = 0;
2049 screenRect.top = 0;
2050 screenRect.right = pScreen->cWidth;
2051 screenRect.bottom = pScreen->cHeight;
2052 SVGASignedRect clipRect = pCmd->srcRect;
2053 vmsvgaR3ClipRect(&screenRect, &clipRect);
2054 RT_UNTRUSTED_VALIDATED_FENCE();
2055
2056 uint32_t const width = clipRect.right - clipRect.left;
2057 uint32_t const height = clipRect.bottom - clipRect.top;
2058
2059 if ( width == 0
2060 || height == 0)
2061 return; /* Nothing to do. */
2062
2063 int32_t const dstx = pCmd->destOrigin.x + (clipRect.left - pCmd->srcRect.left);
2064 int32_t const dsty = pCmd->destOrigin.y + (clipRect.top - pCmd->srcRect.top);
2065
2066 /* Copy the defined by GMRFB image to the screen 0 VRAM area.
2067 * Prepare parameters for vmsvgaR3GmrTransfer.
2068 */
2069 AssertReturnVoid(pScreen->offVRAM < pThis->vram_size); /* Paranoia. Ensured by SVGA_CMD_DEFINE_SCREEN. */
2070
2071 /* Source: host buffer which describes the screen 0 VRAM.
2072 * Important are pbHstBuf and cbHstBuf. offHst and cbHstPitch are verified by vmsvgaR3GmrTransfer.
2073 */
2074 uint8_t * const pbHstBuf = (uint8_t *)pThisCC->pbVRam + pScreen->offVRAM;
2075 uint32_t const cbScanline = pScreen->cbPitch ? pScreen->cbPitch :
2076 width * (RT_ALIGN(pScreen->cBpp, 8) / 8);
2077 uint32_t cbHstBuf = cbScanline * pScreen->cHeight;
2078 if (cbHstBuf > pThis->vram_size - pScreen->offVRAM)
2079 cbHstBuf = pThis->vram_size - pScreen->offVRAM; /* Paranoia. */
2080 uint32_t const offHst = (clipRect.left * RT_ALIGN(pScreen->cBpp, 8)) / 8
2081 + cbScanline * clipRect.top;
2082 int32_t const cbHstPitch = cbScanline;
2083
2084 /* Destination: GMRFB. vmsvgaR3GmrTransfer ensures that no memory outside the GMR is read. */
2085 SVGAGuestPtr const gstPtr = pSvgaR3State->GMRFB.ptr;
2086 uint32_t const offGst = (dstx * RT_ALIGN(pSvgaR3State->GMRFB.format.bitsPerPixel, 8)) / 8
2087 + pSvgaR3State->GMRFB.bytesPerLine * dsty;
2088 int32_t const cbGstPitch = pSvgaR3State->GMRFB.bytesPerLine;
2089
2090 int rc = vmsvgaR3GmrTransfer(pThis, pThisCC, SVGA3D_READ_HOST_VRAM,
2091 pbHstBuf, cbHstBuf, offHst, cbHstPitch,
2092 gstPtr, offGst, cbGstPitch,
2093 (width * RT_ALIGN(pScreen->cBpp, 8)) / 8, height);
2094 AssertRC(rc);
2095}
2096
2097
2098/* SVGA_CMD_ANNOTATION_FILL */
2099void vmsvgaR3CmdAnnotationFill(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdAnnotationFill const *pCmd)
2100{
2101 RT_NOREF(pThis);
2102 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2103
2104 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdAnnotationFill);
2105 Log(("SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.r, pCmd->color.g, pCmd->color.b));
2106
2107 pSvgaR3State->colorAnnotation = pCmd->color;
2108}
2109
2110
2111/* SVGA_CMD_ANNOTATION_COPY */
2112void vmsvgaR3CmdAnnotationCopy(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdAnnotationCopy const *pCmd)
2113{
2114 RT_NOREF(pThis, pCmd);
2115 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2116
2117 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdAnnotationCopy);
2118 Log(("SVGA_CMD_ANNOTATION_COPY srcOrigin %d,%d, srcScreenId %u\n", pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->srcScreenId));
2119
2120 AssertFailed();
2121}
2122
2123
2124#ifdef VBOX_WITH_VMSVGA3D
2125/* SVGA_CMD_DEFINE_GMR2 */
2126void vmsvgaR3CmdDefineGMR2(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDefineGMR2 const *pCmd)
2127{
2128 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2129
2130 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2);
2131 Log(("SVGA_CMD_DEFINE_GMR2 id=%#x %#x pages\n", pCmd->gmrId, pCmd->numPages));
2132
2133 /* Validate current GMR id. */
2134 ASSERT_GUEST_RETURN_VOID(pCmd->gmrId < pThis->svga.cGMR);
2135 ASSERT_GUEST_RETURN_VOID(pCmd->numPages <= VMSVGA_MAX_GMR_PAGES);
2136 RT_UNTRUSTED_VALIDATED_FENCE();
2137
2138 if (!pCmd->numPages)
2139 {
2140 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2Free);
2141 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId);
2142 }
2143 else
2144 {
2145 PGMR pGMR = &pSvgaR3State->paGMR[pCmd->gmrId];
2146 if (pGMR->cMaxPages)
2147 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdDefineGmr2Modify);
2148
2149 /* Not sure if we should always free the descriptor, but for simplicity
2150 we do so if the new size is smaller than the current. */
2151 /** @todo always free the descriptor in SVGA_CMD_DEFINE_GMR2? */
2152 if (pGMR->cbTotal / X86_PAGE_SIZE > pGMR->cMaxPages)
2153 vmsvgaR3GmrFree(pThisCC, pCmd->gmrId);
2154
2155 pGMR->cMaxPages = pCmd->numPages;
2156 /* The rest is done by the REMAP_GMR2 command. */
2157 }
2158}
2159
2160
2161/* SVGA_CMD_REMAP_GMR2 */
2162void vmsvgaR3CmdRemapGMR2(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdRemapGMR2 const *pCmd)
2163{
2164 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
2165
2166 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRemapGmr2);
2167 Log(("SVGA_CMD_REMAP_GMR2 id=%#x flags=%#x offset=%#x npages=%#x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));
2168
2169 /* Validate current GMR id and size. */
2170 ASSERT_GUEST_RETURN_VOID(pCmd->gmrId < pThis->svga.cGMR);
2171 RT_UNTRUSTED_VALIDATED_FENCE();
2172 PGMR pGMR = &pSvgaR3State->paGMR[pCmd->gmrId];
2173 ASSERT_GUEST_RETURN_VOID( (uint64_t)pCmd->offsetPages + pCmd->numPages
2174 <= RT_MIN(pGMR->cMaxPages, RT_MIN(VMSVGA_MAX_GMR_PAGES, UINT32_MAX / X86_PAGE_SIZE)));
2175 ASSERT_GUEST_RETURN_VOID(!pCmd->offsetPages || pGMR->paDesc); /** @todo */
2176
2177 if (pCmd->numPages == 0)
2178 return;
2179 RT_UNTRUSTED_VALIDATED_FENCE();
2180
2181 /* Calc new total page count so we can use it instead of cMaxPages for allocations below. */
2182 uint32_t const cNewTotalPages = RT_MAX(pGMR->cbTotal >> X86_PAGE_SHIFT, pCmd->offsetPages + pCmd->numPages);
2183
2184 /*
2185 * We flatten the existing descriptors into a page array, overwrite the
2186 * pages specified in this command and then recompress the descriptor.
2187 */
2188 /** @todo Optimize the GMR remap algorithm! */
2189
2190 /* Save the old page descriptors as an array of page frame numbers (address >> X86_PAGE_SHIFT) */
2191 uint64_t *paNewPage64 = NULL;
2192 if (pGMR->paDesc)
2193 {
2194 STAM_REL_COUNTER_INC(&pSvgaR3State->StatR3CmdRemapGmr2Modify);
2195
2196 paNewPage64 = (uint64_t *)RTMemAllocZ(cNewTotalPages * sizeof(uint64_t));
2197 AssertPtrReturnVoid(paNewPage64);
2198
2199 uint32_t idxPage = 0;
2200 for (uint32_t i = 0; i < pGMR->numDescriptors; i++)
2201 for (uint32_t j = 0; j < pGMR->paDesc[i].numPages; j++)
2202 paNewPage64[idxPage++] = (pGMR->paDesc[i].GCPhys + j * X86_PAGE_SIZE) >> X86_PAGE_SHIFT;
2203 AssertReturnVoidStmt(idxPage == pGMR->cbTotal >> X86_PAGE_SHIFT, RTMemFree(paNewPage64));
2204 RT_UNTRUSTED_VALIDATED_FENCE();
2205 }
2206
2207 /* Free the old GMR if present. */
2208 if (pGMR->paDesc)
2209 RTMemFree(pGMR->paDesc);
2210
2211 /* Allocate the maximum amount possible (everything non-continuous) */
2212 PVMSVGAGMRDESCRIPTOR paDescs;
2213 pGMR->paDesc = paDescs = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(cNewTotalPages * sizeof(VMSVGAGMRDESCRIPTOR));
2214 AssertReturnVoidStmt(paDescs, RTMemFree(paNewPage64));
2215
2216 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
2217 {
2218 /** @todo */
2219 AssertFailed();
2220 pGMR->numDescriptors = 0;
2221 }
2222 else
2223 {
2224 uint32_t *paPages32 = (uint32_t *)(pCmd + 1);
2225 uint64_t *paPages64 = (uint64_t *)(pCmd + 1);
2226 bool fGCPhys64 = RT_BOOL(pCmd->flags & SVGA_REMAP_GMR2_PPN64);
2227
2228 uint32_t cPages;
2229 if (paNewPage64)
2230 {
2231 /* Overwrite the old page array with the new page values. */
2232 if (fGCPhys64)
2233 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++)
2234 paNewPage64[i] = paPages64[i - pCmd->offsetPages];
2235 else
2236 for (uint32_t i = pCmd->offsetPages; i < pCmd->offsetPages + pCmd->numPages; i++)
2237 paNewPage64[i] = paPages32[i - pCmd->offsetPages];
2238
2239 /* Use the updated page array instead of the command data. */
2240 fGCPhys64 = true;
2241 paPages64 = paNewPage64;
2242 cPages = cNewTotalPages;
2243 }
2244 else
2245 cPages = pCmd->numPages;
2246
2247 /* The first page. */
2248 /** @todo The 0x00000FFFFFFFFFFF mask limits to 44 bits and should not be
2249 * applied to paNewPage64. */
2250 RTGCPHYS GCPhys;
2251 if (fGCPhys64)
2252 GCPhys = (paPages64[0] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
2253 else
2254 GCPhys = (RTGCPHYS)paPages32[0] << PAGE_SHIFT;
2255 paDescs[0].GCPhys = GCPhys;
2256 paDescs[0].numPages = 1;
2257
2258 /* Subsequent pages. */
2259 uint32_t iDescriptor = 0;
2260 for (uint32_t i = 1; i < cPages; i++)
2261 {
2262 if (pCmd->flags & SVGA_REMAP_GMR2_PPN64)
2263 GCPhys = (paPages64[i] << X86_PAGE_SHIFT) & UINT64_C(0x00000FFFFFFFFFFF); /* Seeing rubbish in the top bits with certain linux guests. */
2264 else
2265 GCPhys = (RTGCPHYS)paPages32[i] << X86_PAGE_SHIFT;
2266
2267 /* Continuous physical memory? */
2268 if (GCPhys == paDescs[iDescriptor].GCPhys + paDescs[iDescriptor].numPages * X86_PAGE_SIZE)
2269 {
2270 Assert(paDescs[iDescriptor].numPages);
2271 paDescs[iDescriptor].numPages++;
2272 Log5Func(("Page %x GCPhys=%RGp successor\n", i, GCPhys));
2273 }
2274 else
2275 {
2276 iDescriptor++;
2277 paDescs[iDescriptor].GCPhys = GCPhys;
2278 paDescs[iDescriptor].numPages = 1;
2279 Log5Func(("Page %x GCPhys=%RGp\n", i, paDescs[iDescriptor].GCPhys));
2280 }
2281 }
2282
2283 pGMR->cbTotal = cNewTotalPages << X86_PAGE_SHIFT;
2284 Log5Func(("Nr of descriptors %x; cbTotal=%#x\n", iDescriptor + 1, cNewTotalPages));
2285 pGMR->numDescriptors = iDescriptor + 1;
2286 }
2287
2288 if (paNewPage64)
2289 RTMemFree(paNewPage64);
2290}
2291
2292
2293/**
2294 * Free the specified GMR
2295 *
2296 * @param pThisCC The VGA/VMSVGA state for ring-3.
2297 * @param idGMR GMR id
2298 */
2299void vmsvgaR3GmrFree(PVGASTATECC pThisCC, uint32_t idGMR)
2300{
2301 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
2302
2303 /* Free the old descriptor if present. */
2304 PGMR pGMR = &pSVGAState->paGMR[idGMR];
2305 if ( pGMR->numDescriptors
2306 || pGMR->paDesc /* needed till we implement SVGA_REMAP_GMR2_VIA_GMR */)
2307 {
2308# ifdef DEBUG_GMR_ACCESS
2309 VMR3ReqCallWaitU(PDMDevHlpGetUVM(pThisCC->pDevIns), VMCPUID_ANY, (PFNRT)vmsvgaR3DeregisterGmr, 2, pDevIns, idGMR);
2310# endif
2311
2312 Assert(pGMR->paDesc);
2313 RTMemFree(pGMR->paDesc);
2314 pGMR->paDesc = NULL;
2315 pGMR->numDescriptors = 0;
2316 pGMR->cbTotal = 0;
2317 pGMR->cMaxPages = 0;
2318 }
2319 Assert(!pGMR->cMaxPages);
2320 Assert(!pGMR->cbTotal);
2321}
2322#endif /* VBOX_WITH_VMSVGA3D */
2323
2324
2325/**
2326 * Copy between a GMR and a host memory buffer.
2327 *
2328 * @returns VBox status code.
2329 * @param pThis The shared VGA/VMSVGA instance data.
2330 * @param pThisCC The VGA/VMSVGA state for ring-3.
2331 * @param enmTransferType Transfer type (read/write)
2332 * @param pbHstBuf Host buffer pointer (valid)
2333 * @param cbHstBuf Size of host buffer (valid)
2334 * @param offHst Host buffer offset of the first scanline
2335 * @param cbHstPitch Destination buffer pitch
2336 * @param gstPtr GMR description
2337 * @param offGst Guest buffer offset of the first scanline
2338 * @param cbGstPitch Guest buffer pitch
2339 * @param cbWidth Width in bytes to copy
2340 * @param cHeight Number of scanllines to copy
2341 */
2342int vmsvgaR3GmrTransfer(PVGASTATE pThis, PVGASTATECC pThisCC, const SVGA3dTransferType enmTransferType,
2343 uint8_t *pbHstBuf, uint32_t cbHstBuf, uint32_t offHst, int32_t cbHstPitch,
2344 SVGAGuestPtr gstPtr, uint32_t offGst, int32_t cbGstPitch,
2345 uint32_t cbWidth, uint32_t cHeight)
2346{
2347 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
2348 PPDMDEVINS pDevIns = pThisCC->pDevIns; /* simpler */
2349 int rc;
2350
2351 LogFunc(("%s host %p size=%d offset %d pitch=%d; guest gmr=%#x:%#x offset=%d pitch=%d cbWidth=%d cHeight=%d\n",
2352 enmTransferType == SVGA3D_READ_HOST_VRAM ? "WRITE" : "READ", /* GMR op: READ host VRAM means WRITE GMR */
2353 pbHstBuf, cbHstBuf, offHst, cbHstPitch,
2354 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cbWidth, cHeight));
2355 AssertReturn(cbWidth && cHeight, VERR_INVALID_PARAMETER);
2356
2357 PGMR pGMR;
2358 uint32_t cbGmr; /* The GMR size in bytes. */
2359 if (gstPtr.gmrId == SVGA_GMR_FRAMEBUFFER)
2360 {
2361 pGMR = NULL;
2362 cbGmr = pThis->vram_size;
2363 }
2364 else
2365 {
2366 AssertReturn(gstPtr.gmrId < pThis->svga.cGMR, VERR_INVALID_PARAMETER);
2367 RT_UNTRUSTED_VALIDATED_FENCE();
2368 pGMR = &pSVGAState->paGMR[gstPtr.gmrId];
2369 cbGmr = pGMR->cbTotal;
2370 }
2371
2372 /*
2373 * GMR
2374 */
2375 /* Calculate GMR offset of the data to be copied. */
2376 AssertMsgReturn(gstPtr.offset < cbGmr,
2377 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
2378 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
2379 VERR_INVALID_PARAMETER);
2380 RT_UNTRUSTED_VALIDATED_FENCE();
2381 AssertMsgReturn(offGst < cbGmr - gstPtr.offset,
2382 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
2383 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
2384 VERR_INVALID_PARAMETER);
2385 RT_UNTRUSTED_VALIDATED_FENCE();
2386 uint32_t const offGmr = offGst + gstPtr.offset; /* Offset in the GMR, where the first scanline is located. */
2387
2388 /* Verify that cbWidth is less than scanline and fits into the GMR. */
2389 uint32_t const cbGmrScanline = cbGstPitch > 0 ? cbGstPitch : -cbGstPitch;
2390 AssertMsgReturn(cbGmrScanline != 0,
2391 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
2392 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
2393 VERR_INVALID_PARAMETER);
2394 RT_UNTRUSTED_VALIDATED_FENCE();
2395 AssertMsgReturn(cbWidth <= cbGmrScanline,
2396 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
2397 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
2398 VERR_INVALID_PARAMETER);
2399 AssertMsgReturn(cbWidth <= cbGmr - offGmr,
2400 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
2401 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
2402 VERR_INVALID_PARAMETER);
2403 RT_UNTRUSTED_VALIDATED_FENCE();
2404
2405 /* How many bytes are available for the data in the GMR. */
2406 uint32_t const cbGmrLeft = cbGstPitch > 0 ? cbGmr - offGmr : offGmr + cbWidth;
2407
2408 /* How many scanlines would fit into the available data. */
2409 uint32_t cGmrScanlines = cbGmrLeft / cbGmrScanline;
2410 uint32_t const cbGmrLastScanline = cbGmrLeft - cGmrScanlines * cbGmrScanline; /* Slack space. */
2411 if (cbWidth <= cbGmrLastScanline)
2412 ++cGmrScanlines;
2413
2414 if (cHeight > cGmrScanlines)
2415 cHeight = cGmrScanlines;
2416
2417 AssertMsgReturn(cHeight > 0,
2418 ("gmr=%#x:%#x offGst=%#x cbGstPitch=%#x cHeight=%#x cbWidth=%#x cbGmr=%#x\n",
2419 gstPtr.gmrId, gstPtr.offset, offGst, cbGstPitch, cHeight, cbWidth, cbGmr),
2420 VERR_INVALID_PARAMETER);
2421 RT_UNTRUSTED_VALIDATED_FENCE();
2422
2423 /*
2424 * Host buffer.
2425 */
2426 AssertMsgReturn(offHst < cbHstBuf,
2427 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
2428 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
2429 VERR_INVALID_PARAMETER);
2430
2431 /* Verify that cbWidth is less than scanline and fits into the buffer. */
2432 uint32_t const cbHstScanline = cbHstPitch > 0 ? cbHstPitch : -cbHstPitch;
2433 AssertMsgReturn(cbHstScanline != 0,
2434 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
2435 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
2436 VERR_INVALID_PARAMETER);
2437 AssertMsgReturn(cbWidth <= cbHstScanline,
2438 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
2439 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
2440 VERR_INVALID_PARAMETER);
2441 AssertMsgReturn(cbWidth <= cbHstBuf - offHst,
2442 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
2443 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
2444 VERR_INVALID_PARAMETER);
2445
2446 /* How many bytes are available for the data in the buffer. */
2447 uint32_t const cbHstLeft = cbHstPitch > 0 ? cbHstBuf - offHst : offHst + cbWidth;
2448
2449 /* How many scanlines would fit into the available data. */
2450 uint32_t cHstScanlines = cbHstLeft / cbHstScanline;
2451 uint32_t const cbHstLastScanline = cbHstLeft - cHstScanlines * cbHstScanline; /* Slack space. */
2452 if (cbWidth <= cbHstLastScanline)
2453 ++cHstScanlines;
2454
2455 if (cHeight > cHstScanlines)
2456 cHeight = cHstScanlines;
2457
2458 AssertMsgReturn(cHeight > 0,
2459 ("buffer=%p size %d offHst=%d cbHstPitch=%d cHeight=%d cbWidth=%d\n",
2460 pbHstBuf, cbHstBuf, offHst, cbHstPitch, cHeight, cbWidth),
2461 VERR_INVALID_PARAMETER);
2462
2463 uint8_t *pbHst = pbHstBuf + offHst;
2464
2465 /* Shortcut for the framebuffer. */
2466 if (gstPtr.gmrId == SVGA_GMR_FRAMEBUFFER)
2467 {
2468 uint8_t *pbGst = pThisCC->pbVRam + offGmr;
2469
2470 uint8_t const *pbSrc;
2471 int32_t cbSrcPitch;
2472 uint8_t *pbDst;
2473 int32_t cbDstPitch;
2474
2475 if (enmTransferType == SVGA3D_READ_HOST_VRAM)
2476 {
2477 pbSrc = pbHst;
2478 cbSrcPitch = cbHstPitch;
2479 pbDst = pbGst;
2480 cbDstPitch = cbGstPitch;
2481 }
2482 else
2483 {
2484 pbSrc = pbGst;
2485 cbSrcPitch = cbGstPitch;
2486 pbDst = pbHst;
2487 cbDstPitch = cbHstPitch;
2488 }
2489
2490 if ( cbWidth == (uint32_t)cbGstPitch
2491 && cbGstPitch == cbHstPitch)
2492 {
2493 /* Entire scanlines, positive pitch. */
2494 memcpy(pbDst, pbSrc, cbWidth * cHeight);
2495 }
2496 else
2497 {
2498 for (uint32_t i = 0; i < cHeight; ++i)
2499 {
2500 memcpy(pbDst, pbSrc, cbWidth);
2501
2502 pbDst += cbDstPitch;
2503 pbSrc += cbSrcPitch;
2504 }
2505 }
2506 return VINF_SUCCESS;
2507 }
2508
2509 AssertPtrReturn(pGMR, VERR_INVALID_PARAMETER);
2510 AssertReturn(pGMR->numDescriptors > 0, VERR_INVALID_PARAMETER);
2511
2512 PVMSVGAGMRDESCRIPTOR const paDesc = pGMR->paDesc; /* Local copy of the pointer. */
2513 uint32_t iDesc = 0; /* Index in the descriptor array. */
2514 uint32_t offDesc = 0; /* GMR offset of the current descriptor. */
2515 uint32_t offGmrScanline = offGmr; /* GMR offset of the scanline which is being copied. */
2516 uint8_t *pbHstScanline = pbHst; /* Host address of the scanline which is being copied. */
2517 for (uint32_t i = 0; i < cHeight; ++i)
2518 {
2519 uint32_t cbCurrentWidth = cbWidth;
2520 uint32_t offGmrCurrent = offGmrScanline;
2521 uint8_t *pbCurrentHost = pbHstScanline;
2522
2523 /* Find the right descriptor */
2524 while (offDesc + paDesc[iDesc].numPages * PAGE_SIZE <= offGmrCurrent)
2525 {
2526 offDesc += paDesc[iDesc].numPages * PAGE_SIZE;
2527 AssertReturn(offDesc < pGMR->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
2528 ++iDesc;
2529 AssertReturn(iDesc < pGMR->numDescriptors, VERR_INTERNAL_ERROR);
2530 }
2531
2532 while (cbCurrentWidth)
2533 {
2534 uint32_t cbToCopy;
2535
2536 if (offGmrCurrent + cbCurrentWidth <= offDesc + paDesc[iDesc].numPages * PAGE_SIZE)
2537 {
2538 cbToCopy = cbCurrentWidth;
2539 }
2540 else
2541 {
2542 cbToCopy = (offDesc + paDesc[iDesc].numPages * PAGE_SIZE - offGmrCurrent);
2543 AssertReturn(cbToCopy <= cbCurrentWidth, VERR_INVALID_PARAMETER);
2544 }
2545
2546 RTGCPHYS const GCPhys = paDesc[iDesc].GCPhys + offGmrCurrent - offDesc;
2547
2548 Log5Func(("%s phys=%RGp\n", (enmTransferType == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", GCPhys));
2549
2550 if (enmTransferType == SVGA3D_WRITE_HOST_VRAM)
2551 rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhys, pbCurrentHost, cbToCopy);
2552 else
2553 rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhys, pbCurrentHost, cbToCopy);
2554 AssertRCBreak(rc);
2555
2556 cbCurrentWidth -= cbToCopy;
2557 offGmrCurrent += cbToCopy;
2558 pbCurrentHost += cbToCopy;
2559
2560 /* Go to the next descriptor if there's anything left. */
2561 if (cbCurrentWidth)
2562 {
2563 offDesc += paDesc[iDesc].numPages * PAGE_SIZE;
2564 AssertReturn(offDesc < pGMR->cbTotal, VERR_INTERNAL_ERROR);
2565 ++iDesc;
2566 AssertReturn(iDesc < pGMR->numDescriptors, VERR_INTERNAL_ERROR);
2567 }
2568 }
2569
2570 offGmrScanline += cbGstPitch;
2571 pbHstScanline += cbHstPitch;
2572 }
2573
2574 return VINF_SUCCESS;
2575}
2576
2577
2578/**
2579 * Unsigned coordinates in pBox. Clip to [0; pSizeSrc), [0; pSizeDest).
2580 *
2581 * @param pSizeSrc Source surface dimensions.
2582 * @param pSizeDest Destination surface dimensions.
2583 * @param pBox Coordinates to be clipped.
2584 */
2585void vmsvgaR3ClipCopyBox(const SVGA3dSize *pSizeSrc, const SVGA3dSize *pSizeDest, SVGA3dCopyBox *pBox)
2586{
2587 /* Src x, w */
2588 if (pBox->srcx > pSizeSrc->width)
2589 pBox->srcx = pSizeSrc->width;
2590 if (pBox->w > pSizeSrc->width - pBox->srcx)
2591 pBox->w = pSizeSrc->width - pBox->srcx;
2592
2593 /* Src y, h */
2594 if (pBox->srcy > pSizeSrc->height)
2595 pBox->srcy = pSizeSrc->height;
2596 if (pBox->h > pSizeSrc->height - pBox->srcy)
2597 pBox->h = pSizeSrc->height - pBox->srcy;
2598
2599 /* Src z, d */
2600 if (pBox->srcz > pSizeSrc->depth)
2601 pBox->srcz = pSizeSrc->depth;
2602 if (pBox->d > pSizeSrc->depth - pBox->srcz)
2603 pBox->d = pSizeSrc->depth - pBox->srcz;
2604
2605 /* Dest x, w */
2606 if (pBox->x > pSizeDest->width)
2607 pBox->x = pSizeDest->width;
2608 if (pBox->w > pSizeDest->width - pBox->x)
2609 pBox->w = pSizeDest->width - pBox->x;
2610
2611 /* Dest y, h */
2612 if (pBox->y > pSizeDest->height)
2613 pBox->y = pSizeDest->height;
2614 if (pBox->h > pSizeDest->height - pBox->y)
2615 pBox->h = pSizeDest->height - pBox->y;
2616
2617 /* Dest z, d */
2618 if (pBox->z > pSizeDest->depth)
2619 pBox->z = pSizeDest->depth;
2620 if (pBox->d > pSizeDest->depth - pBox->z)
2621 pBox->d = pSizeDest->depth - pBox->z;
2622}
2623
2624
2625/**
2626 * Unsigned coordinates in pBox. Clip to [0; pSize).
2627 *
2628 * @param pSize Source surface dimensions.
2629 * @param pBox Coordinates to be clipped.
2630 */
2631void vmsvgaR3ClipBox(const SVGA3dSize *pSize, SVGA3dBox *pBox)
2632{
2633 /* x, w */
2634 if (pBox->x > pSize->width)
2635 pBox->x = pSize->width;
2636 if (pBox->w > pSize->width - pBox->x)
2637 pBox->w = pSize->width - pBox->x;
2638
2639 /* y, h */
2640 if (pBox->y > pSize->height)
2641 pBox->y = pSize->height;
2642 if (pBox->h > pSize->height - pBox->y)
2643 pBox->h = pSize->height - pBox->y;
2644
2645 /* z, d */
2646 if (pBox->z > pSize->depth)
2647 pBox->z = pSize->depth;
2648 if (pBox->d > pSize->depth - pBox->z)
2649 pBox->d = pSize->depth - pBox->z;
2650}
2651
2652
2653/**
2654 * Clip.
2655 *
2656 * @param pBound Bounding rectangle.
2657 * @param pRect Rectangle to be clipped.
2658 */
2659void vmsvgaR3ClipRect(SVGASignedRect const *pBound, SVGASignedRect *pRect)
2660{
2661 int32_t left;
2662 int32_t top;
2663 int32_t right;
2664 int32_t bottom;
2665
2666 /* Right order. */
2667 Assert(pBound->left <= pBound->right && pBound->top <= pBound->bottom);
2668 if (pRect->left < pRect->right)
2669 {
2670 left = pRect->left;
2671 right = pRect->right;
2672 }
2673 else
2674 {
2675 left = pRect->right;
2676 right = pRect->left;
2677 }
2678 if (pRect->top < pRect->bottom)
2679 {
2680 top = pRect->top;
2681 bottom = pRect->bottom;
2682 }
2683 else
2684 {
2685 top = pRect->bottom;
2686 bottom = pRect->top;
2687 }
2688
2689 if (left < pBound->left)
2690 left = pBound->left;
2691 if (right < pBound->left)
2692 right = pBound->left;
2693
2694 if (left > pBound->right)
2695 left = pBound->right;
2696 if (right > pBound->right)
2697 right = pBound->right;
2698
2699 if (top < pBound->top)
2700 top = pBound->top;
2701 if (bottom < pBound->top)
2702 bottom = pBound->top;
2703
2704 if (top > pBound->bottom)
2705 top = pBound->bottom;
2706 if (bottom > pBound->bottom)
2707 bottom = pBound->bottom;
2708
2709 pRect->left = left;
2710 pRect->right = right;
2711 pRect->top = top;
2712 pRect->bottom = bottom;
2713}
2714
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