VirtualBox

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

Last change on this file since 50079 was 49983, checked in by vboxsync, 11 years ago

Devices/Graphics: VMware SVGA II compatible graphics emulation (2D only), including the associated small API and VBoxManage changes, contributed by trivirt AG.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 131.2 KB
Line 
1/** @file
2 * VMWare SVGA device
3 */
4/*
5 * Copyright (C) 2013 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15
16
17/*******************************************************************************
18* Header Files *
19*******************************************************************************/
20#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
21#include <VBox/vmm/pdmdev.h>
22#include <VBox/version.h>
23#include <VBox/err.h>
24#include <VBox/log.h>
25#include <VBox/vmm/pgm.h>
26
27#include <iprt/assert.h>
28#include <iprt/semaphore.h>
29#include <iprt/uuid.h>
30#ifdef IN_RING3
31#include <iprt/mem.h>
32#endif
33
34#include <VBox/VMMDev.h>
35#include <VBox/VBoxVideo.h>
36#include <VBox/bioslogo.h>
37
38/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
39#include "DevVGA.h"
40
41#ifdef DEBUG
42/* Enable to log FIFO register accesses. */
43//#define DEBUG_FIFO_ACCESS
44/* Enable to log GMR page accesses. */
45//#define DEBUG_GMR_ACCESS
46#endif
47
48#include "DevVGA-SVGA.h"
49#include "vmsvga/svga_reg.h"
50#include "vmsvga/svga_escape.h"
51#include "vmsvga/svga_overlay.h"
52#include "vmsvga/svga3d_reg.h"
53#include "vmsvga/svga3d_caps.h"
54#ifdef VBOX_WITH_VMSVGA3D
55#include "DevVGA-SVGA3d.h"
56#endif
57
58/*******************************************************************************
59* Structures and Typedefs *
60*******************************************************************************/
61/* 64-bit GMR descriptor */
62typedef struct
63{
64 RTGCPHYS GCPhys;
65 uint64_t numPages;
66} VMSVGAGMRDESCRIPTOR, *PVMSVGAGMRDESCRIPTOR;
67
68/* GMR slot */
69typedef struct
70{
71 uint32_t cbTotal;
72 uint32_t numDescriptors;
73 PVMSVGAGMRDESCRIPTOR paDesc;
74} GMR, *PGMR;
75
76/* Internal SVGA state. */
77typedef struct
78{
79 GMR aGMR[VMSVGA_MAX_GMR_IDS];
80 struct
81 {
82 SVGAGuestPtr ptr;
83 uint32_t bytesPerLine;
84 SVGAGMRImageFormat format;
85 } GMRFB;
86 SVGAColorBGRX colorAnnotation;
87 STAMPROFILE StatR3CmdPresent;
88 STAMPROFILE StatR3CmdDrawPrimitive;
89 STAMPROFILE StatR3CmdSurfaceDMA;
90} VMSVGASTATE, *PVMSVGASTATE;
91
92#ifdef IN_RING3
93
94/**
95 * SSM descriptor table for the VMSVGAGMRDESCRIPTOR structure.
96 */
97static SSMFIELD const g_aVMSVGAGMRDESCRIPTORFields[] =
98{
99 SSMFIELD_ENTRY_GCPHYS( VMSVGAGMRDESCRIPTOR, GCPhys),
100 SSMFIELD_ENTRY( VMSVGAGMRDESCRIPTOR, numPages),
101 SSMFIELD_ENTRY_TERM()
102};
103
104/**
105 * SSM descriptor table for the GMR structure.
106 */
107static SSMFIELD const g_aGMRFields[] =
108{
109 SSMFIELD_ENTRY( GMR, cbTotal),
110 SSMFIELD_ENTRY( GMR, numDescriptors),
111 SSMFIELD_ENTRY_IGN_HCPTR( GMR, paDesc),
112 SSMFIELD_ENTRY_TERM()
113};
114
115/**
116 * SSM descriptor table for the VMSVGASTATE structure.
117 */
118static SSMFIELD const g_aVMSVGASTATEFields[] =
119{
120 SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, aGMR),
121 SSMFIELD_ENTRY( VMSVGASTATE, GMRFB),
122 SSMFIELD_ENTRY( VMSVGASTATE, colorAnnotation),
123 SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatR3CmdPresent),
124 SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatR3CmdDrawPrimitive),
125 SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatR3CmdSurfaceDMA),
126 SSMFIELD_ENTRY_TERM()
127};
128
129/**
130 * SSM descriptor table for the VGAState.svga structure.
131 */
132static SSMFIELD const g_aVGAStateSVGAFields[] =
133{
134 SSMFIELD_ENTRY_IGNORE( VGAState, svga.u64HostWindowId),
135 SSMFIELD_ENTRY_IGN_HCPTR( VGAState, svga.pFIFOR3),
136 SSMFIELD_ENTRY_IGN_HCPTR( VGAState, svga.pFIFOR0),
137 SSMFIELD_ENTRY_IGN_HCPTR( VGAState, svga.pSVGAState),
138 SSMFIELD_ENTRY_IGN_HCPTR( VGAState, svga.p3dState),
139 SSMFIELD_ENTRY_IGNORE( VGAState, svga.pFrameBufferBackup),
140 SSMFIELD_ENTRY_IGN_GCPHYS( VGAState, svga.GCPhysFIFO),
141 SSMFIELD_ENTRY_IGNORE( VGAState, svga.cbFIFO),
142 SSMFIELD_ENTRY( VGAState, svga.u32SVGAId),
143 SSMFIELD_ENTRY( VGAState, svga.fEnabled),
144 SSMFIELD_ENTRY( VGAState, svga.fConfigured),
145 SSMFIELD_ENTRY( VGAState, svga.fBusy),
146 SSMFIELD_ENTRY( VGAState, svga.fTraces),
147 SSMFIELD_ENTRY( VGAState, svga.u32GuestId),
148 SSMFIELD_ENTRY( VGAState, svga.cScratchRegion),
149 SSMFIELD_ENTRY( VGAState, svga.au32ScratchRegion),
150 SSMFIELD_ENTRY( VGAState, svga.u32IrqStatus),
151 SSMFIELD_ENTRY( VGAState, svga.u32IrqMask),
152 SSMFIELD_ENTRY( VGAState, svga.u32PitchLock),
153 SSMFIELD_ENTRY( VGAState, svga.u32CurrentGMRId),
154 SSMFIELD_ENTRY( VGAState, svga.u32RegCaps),
155 SSMFIELD_ENTRY_IGNORE( VGAState, svga.BasePort),
156 SSMFIELD_ENTRY( VGAState, svga.u32IndexReg),
157 SSMFIELD_ENTRY_IGNORE( VGAState, svga.FIFORequestSem),
158 SSMFIELD_ENTRY_IGN_HCPTR( VGAState, svga.pFIFOIOThread),
159 SSMFIELD_ENTRY( VGAState, svga.iWidth),
160 SSMFIELD_ENTRY( VGAState, svga.iHeight),
161 SSMFIELD_ENTRY( VGAState, svga.iBpp),
162 SSMFIELD_ENTRY( VGAState, svga.cbScanline),
163 SSMFIELD_ENTRY( VGAState, svga.u32MaxWidth),
164 SSMFIELD_ENTRY( VGAState, svga.u32MaxHeight),
165 SSMFIELD_ENTRY( VGAState, svga.u32ActionFlags),
166 SSMFIELD_ENTRY( VGAState, svga.f3DEnabled),
167 SSMFIELD_ENTRY( VGAState, svga.fVRAMTracking),
168 SSMFIELD_ENTRY( VGAState, svga.Padding6),
169 SSMFIELD_ENTRY_TERM()
170};
171#endif /* IN_RING3 */
172
173RT_C_DECLS_BEGIN
174
175#ifdef IN_RING3
176static void vmsvgaSetTraces(PVGASTATE pThis, bool fTraces);
177#endif
178
179RT_C_DECLS_END
180
181
182#ifdef LOG_ENABLED
183/**
184 * Index register string name lookup
185 *
186 * @returns Index register string or "UNKNOWN"
187 * @param pThis VMSVGA State
188 */
189static const char *vmsvgaIndexToString(PVGASTATE pThis)
190{
191 switch (pThis->svga.u32IndexReg)
192 {
193 case SVGA_REG_ID:
194 return "SVGA_REG_ID";
195 case SVGA_REG_ENABLE:
196 return "SVGA_REG_ENABLE";
197 case SVGA_REG_WIDTH:
198 return "SVGA_REG_WIDTH";
199 case SVGA_REG_HEIGHT:
200 return "SVGA_REG_HEIGHT";
201 case SVGA_REG_MAX_WIDTH:
202 return "SVGA_REG_MAX_WIDTH";
203 case SVGA_REG_MAX_HEIGHT:
204 return "SVGA_REG_MAX_HEIGHT";
205 case SVGA_REG_DEPTH:
206 return "SVGA_REG_DEPTH";
207 case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
208 return "SVGA_REG_BITS_PER_PIXEL";
209 case SVGA_REG_HOST_BITS_PER_PIXEL: /* (Deprecated) */
210 return "SVGA_REG_HOST_BITS_PER_PIXEL";
211 case SVGA_REG_PSEUDOCOLOR:
212 return "SVGA_REG_PSEUDOCOLOR";
213 case SVGA_REG_RED_MASK:
214 return "SVGA_REG_RED_MASK";
215 case SVGA_REG_GREEN_MASK:
216 return "SVGA_REG_GREEN_MASK";
217 case SVGA_REG_BLUE_MASK:
218 return "SVGA_REG_BLUE_MASK";
219 case SVGA_REG_BYTES_PER_LINE:
220 return "SVGA_REG_BYTES_PER_LINE";
221 case SVGA_REG_VRAM_SIZE: /* VRAM size */
222 return "SVGA_REG_VRAM_SIZE";
223 case SVGA_REG_FB_START: /* Frame buffer physical address. */
224 return "SVGA_REG_FB_START";
225 case SVGA_REG_FB_OFFSET: /* Offset of the frame buffer in VRAM */
226 return "SVGA_REG_FB_OFFSET";
227 case SVGA_REG_FB_SIZE: /* Frame buffer size */
228 return "SVGA_REG_FB_SIZE";
229 case SVGA_REG_CAPABILITIES:
230 return "SVGA_REG_CAPABILITIES";
231 case SVGA_REG_MEM_START: /* FIFO start */
232 return "SVGA_REG_MEM_START";
233 case SVGA_REG_MEM_SIZE: /* FIFO size */
234 return "SVGA_REG_MEM_SIZE";
235 case SVGA_REG_CONFIG_DONE: /* Set when memory area configured */
236 return "SVGA_REG_CONFIG_DONE";
237 case SVGA_REG_SYNC: /* See "FIFO Synchronization Registers" */
238 return "SVGA_REG_SYNC";
239 case SVGA_REG_BUSY: /* See "FIFO Synchronization Registers" */
240 return "SVGA_REG_BUSY";
241 case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
242 return "SVGA_REG_GUEST_ID";
243 case SVGA_REG_SCRATCH_SIZE: /* Number of scratch registers */
244 return "SVGA_REG_SCRATCH_SIZE";
245 case SVGA_REG_MEM_REGS: /* Number of FIFO registers */
246 return "SVGA_REG_MEM_REGS";
247 case SVGA_REG_PITCHLOCK: /* Fixed pitch for all modes */
248 return "SVGA_REG_PITCHLOCK";
249 case SVGA_REG_IRQMASK: /* Interrupt mask */
250 return "SVGA_REG_IRQMASK";
251 case SVGA_REG_GMR_ID:
252 return "SVGA_REG_GMR_ID";
253 case SVGA_REG_GMR_DESCRIPTOR:
254 return "SVGA_REG_GMR_DESCRIPTOR";
255 case SVGA_REG_GMR_MAX_IDS:
256 return "SVGA_REG_GMR_MAX_IDS";
257 case SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH:
258 return "SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH";
259 case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
260 return "SVGA_REG_TRACES";
261 case SVGA_REG_GMRS_MAX_PAGES: /* Maximum number of 4KB pages for all GMRs */
262 return "SVGA_REG_GMRS_MAX_PAGES";
263 case SVGA_REG_MEMORY_SIZE: /* Total dedicated device memory excluding FIFO */
264 return "SVGA_REG_MEMORY_SIZE";
265 case SVGA_REG_TOP: /* Must be 1 more than the last register */
266 return "SVGA_REG_TOP";
267 case SVGA_PALETTE_BASE: /* Base of SVGA color map */
268 return "SVGA_PALETTE_BASE";
269 case SVGA_REG_CURSOR_ID:
270 return "SVGA_REG_CURSOR_ID";
271 case SVGA_REG_CURSOR_X:
272 return "SVGA_REG_CURSOR_X";
273 case SVGA_REG_CURSOR_Y:
274 return "SVGA_REG_CURSOR_Y";
275 case SVGA_REG_CURSOR_ON:
276 return "SVGA_REG_CURSOR_ON";
277 case SVGA_REG_NUM_GUEST_DISPLAYS:/* Number of guest displays in X/Y direction */
278 return "SVGA_REG_NUM_GUEST_DISPLAYS";
279 case SVGA_REG_DISPLAY_ID: /* Display ID for the following display attributes */
280 return "SVGA_REG_DISPLAY_ID";
281 case SVGA_REG_DISPLAY_IS_PRIMARY:/* Whether this is a primary display */
282 return "SVGA_REG_DISPLAY_IS_PRIMARY";
283 case SVGA_REG_DISPLAY_POSITION_X:/* The display position x */
284 return "SVGA_REG_DISPLAY_POSITION_X";
285 case SVGA_REG_DISPLAY_POSITION_Y:/* The display position y */
286 return "SVGA_REG_DISPLAY_POSITION_Y";
287 case SVGA_REG_DISPLAY_WIDTH: /* The display's width */
288 return "SVGA_REG_DISPLAY_WIDTH";
289 case SVGA_REG_DISPLAY_HEIGHT: /* The display's height */
290 return "SVGA_REG_DISPLAY_HEIGHT";
291 case SVGA_REG_NUM_DISPLAYS: /* (Deprecated) */
292 return "SVGA_REG_NUM_DISPLAYS";
293
294 default:
295 if ( pThis->svga.u32IndexReg >= SVGA_SCRATCH_BASE
296 && pThis->svga.u32IndexReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion)
297 {
298 return "SVGA_SCRATCH_BASE reg";
299 }
300 return "UNKNOWN";
301 }
302}
303
304/**
305 * FIFO command name lookup
306 *
307 * @returns FIFO command string or "UNKNOWN"
308 * @param u32Cmd FIFO command
309 */
310static const char *vmsvgaFIFOCmdToString(uint32_t u32Cmd)
311{
312 switch (u32Cmd)
313 {
314 case SVGA_CMD_INVALID_CMD:
315 return "SVGA_CMD_INVALID_CMD";
316 case SVGA_CMD_UPDATE:
317 return "SVGA_CMD_UPDATE";
318 case SVGA_CMD_RECT_COPY:
319 return "SVGA_CMD_RECT_COPY";
320 case SVGA_CMD_DEFINE_CURSOR:
321 return "SVGA_CMD_DEFINE_CURSOR";
322 case SVGA_CMD_DEFINE_ALPHA_CURSOR:
323 return "SVGA_CMD_DEFINE_ALPHA_CURSOR";
324 case SVGA_CMD_UPDATE_VERBOSE:
325 return "SVGA_CMD_UPDATE_VERBOSE";
326 case SVGA_CMD_FRONT_ROP_FILL:
327 return "SVGA_CMD_FRONT_ROP_FILL";
328 case SVGA_CMD_FENCE:
329 return "SVGA_CMD_FENCE";
330 case SVGA_CMD_ESCAPE:
331 return "SVGA_CMD_ESCAPE";
332 case SVGA_CMD_DEFINE_SCREEN:
333 return "SVGA_CMD_DEFINE_SCREEN";
334 case SVGA_CMD_DESTROY_SCREEN:
335 return "SVGA_CMD_DESTROY_SCREEN";
336 case SVGA_CMD_DEFINE_GMRFB:
337 return "SVGA_CMD_DEFINE_GMRFB";
338 case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
339 return "SVGA_CMD_BLIT_GMRFB_TO_SCREEN";
340 case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
341 return "SVGA_CMD_BLIT_SCREEN_TO_GMRFB";
342 case SVGA_CMD_ANNOTATION_FILL:
343 return "SVGA_CMD_ANNOTATION_FILL";
344 case SVGA_CMD_ANNOTATION_COPY:
345 return "SVGA_CMD_ANNOTATION_COPY";
346 case SVGA_CMD_DEFINE_GMR2:
347 return "SVGA_CMD_DEFINE_GMR2";
348 case SVGA_CMD_REMAP_GMR2:
349 return "SVGA_CMD_REMAP_GMR2";
350 case SVGA_3D_CMD_SURFACE_DEFINE:
351 return "SVGA_3D_CMD_SURFACE_DEFINE";
352 case SVGA_3D_CMD_SURFACE_DESTROY:
353 return "SVGA_3D_CMD_SURFACE_DESTROY";
354 case SVGA_3D_CMD_SURFACE_COPY:
355 return "SVGA_3D_CMD_SURFACE_COPY";
356 case SVGA_3D_CMD_SURFACE_STRETCHBLT:
357 return "SVGA_3D_CMD_SURFACE_STRETCHBLT";
358 case SVGA_3D_CMD_SURFACE_DMA:
359 return "SVGA_3D_CMD_SURFACE_DMA";
360 case SVGA_3D_CMD_CONTEXT_DEFINE:
361 return "SVGA_3D_CMD_CONTEXT_DEFINE";
362 case SVGA_3D_CMD_CONTEXT_DESTROY:
363 return "SVGA_3D_CMD_CONTEXT_DESTROY";
364 case SVGA_3D_CMD_SETTRANSFORM:
365 return "SVGA_3D_CMD_SETTRANSFORM";
366 case SVGA_3D_CMD_SETZRANGE:
367 return "SVGA_3D_CMD_SETZRANGE";
368 case SVGA_3D_CMD_SETRENDERSTATE:
369 return "SVGA_3D_CMD_SETRENDERSTATE";
370 case SVGA_3D_CMD_SETRENDERTARGET:
371 return "SVGA_3D_CMD_SETRENDERTARGET";
372 case SVGA_3D_CMD_SETTEXTURESTATE:
373 return "SVGA_3D_CMD_SETTEXTURESTATE";
374 case SVGA_3D_CMD_SETMATERIAL:
375 return "SVGA_3D_CMD_SETMATERIAL";
376 case SVGA_3D_CMD_SETLIGHTDATA:
377 return "SVGA_3D_CMD_SETLIGHTDATA";
378 case SVGA_3D_CMD_SETLIGHTENABLED:
379 return "SVGA_3D_CMD_SETLIGHTENABLED";
380 case SVGA_3D_CMD_SETVIEWPORT:
381 return "SVGA_3D_CMD_SETVIEWPORT";
382 case SVGA_3D_CMD_SETCLIPPLANE:
383 return "SVGA_3D_CMD_SETCLIPPLANE";
384 case SVGA_3D_CMD_CLEAR:
385 return "SVGA_3D_CMD_CLEAR";
386 case SVGA_3D_CMD_PRESENT:
387 return "SVGA_3D_CMD_PRESENT";
388 case SVGA_3D_CMD_SHADER_DEFINE:
389 return "SVGA_3D_CMD_SHADER_DEFINE";
390 case SVGA_3D_CMD_SHADER_DESTROY:
391 return "SVGA_3D_CMD_SHADER_DESTROY";
392 case SVGA_3D_CMD_SET_SHADER:
393 return "SVGA_3D_CMD_SET_SHADER";
394 case SVGA_3D_CMD_SET_SHADER_CONST:
395 return "SVGA_3D_CMD_SET_SHADER_CONST";
396 case SVGA_3D_CMD_DRAW_PRIMITIVES:
397 return "SVGA_3D_CMD_DRAW_PRIMITIVES";
398 case SVGA_3D_CMD_SETSCISSORRECT:
399 return "SVGA_3D_CMD_SETSCISSORRECT";
400 case SVGA_3D_CMD_BEGIN_QUERY:
401 return "SVGA_3D_CMD_BEGIN_QUERY";
402 case SVGA_3D_CMD_END_QUERY:
403 return "SVGA_3D_CMD_END_QUERY";
404 case SVGA_3D_CMD_WAIT_FOR_QUERY:
405 return "SVGA_3D_CMD_WAIT_FOR_QUERY";
406 case SVGA_3D_CMD_PRESENT_READBACK:
407 return "SVGA_3D_CMD_PRESENT_READBACK";
408 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
409 return "SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN";
410 case SVGA_3D_CMD_SURFACE_DEFINE_V2:
411 return "SVGA_3D_CMD_SURFACE_DEFINE_V2";
412 case SVGA_3D_CMD_GENERATE_MIPMAPS:
413 return "SVGA_3D_CMD_GENERATE_MIPMAPS";
414 case SVGA_3D_CMD_ACTIVATE_SURFACE:
415 return "SVGA_3D_CMD_ACTIVATE_SURFACE";
416 case SVGA_3D_CMD_DEACTIVATE_SURFACE:
417 return "SVGA_3D_CMD_DEACTIVATE_SURFACE";
418 default:
419 return "UNKNOWN";
420 }
421}
422#endif
423
424/**
425 * Read port register
426 *
427 * @returns VBox status code.
428 * @param pThis VMSVGA State
429 * @param pu32 Where to store the read value
430 */
431PDMBOTHCBDECL(int) vmsvgaReadPort(PVGASTATE pThis, uint32_t *pu32)
432{
433 int rc = VINF_SUCCESS;
434
435 *pu32 = 0;
436 switch (pThis->svga.u32IndexReg)
437 {
438 case SVGA_REG_ID:
439 *pu32 = pThis->svga.u32SVGAId;
440 break;
441
442 case SVGA_REG_ENABLE:
443 *pu32 = pThis->svga.fEnabled;
444 break;
445
446 case SVGA_REG_WIDTH:
447 {
448 if ( pThis->svga.fEnabled
449 && pThis->svga.iWidth != -1)
450 {
451 *pu32 = pThis->svga.iWidth;
452 }
453 else
454 {
455#ifndef IN_RING3
456 rc = VINF_IOM_R3_IOPORT_READ;
457#else
458 *pu32 = pThis->pDrv->cx;
459#endif
460 }
461 break;
462 }
463
464 case SVGA_REG_HEIGHT:
465 {
466 if ( pThis->svga.fEnabled
467 && pThis->svga.iHeight != -1)
468 {
469 *pu32 = pThis->svga.iHeight;
470 }
471 else
472 {
473#ifndef IN_RING3
474 rc = VINF_IOM_R3_IOPORT_READ;
475#else
476 *pu32 = pThis->pDrv->cy;
477#endif
478 }
479 break;
480 }
481
482 case SVGA_REG_MAX_WIDTH:
483 *pu32 = pThis->svga.u32MaxWidth;
484 break;
485
486 case SVGA_REG_MAX_HEIGHT:
487 *pu32 = pThis->svga.u32MaxHeight;
488 break;
489
490 case SVGA_REG_DEPTH:
491 /* This returns the color depth of the current mode. */
492 switch (pThis->svga.iBpp)
493 {
494 case 15:
495 case 16:
496 case 24:
497 *pu32 = pThis->svga.iBpp;
498 break;
499
500 default:
501 case 32:
502 *pu32 = 24; /* The upper 8 bits are either alpha bits or not used. */
503 break;
504 }
505 break;
506
507 case SVGA_REG_HOST_BITS_PER_PIXEL: /* (Deprecated) */
508 if ( pThis->svga.fEnabled
509 && pThis->svga.iBpp != (unsigned)-1)
510 {
511 *pu32 = pThis->svga.iBpp;
512 }
513 else
514 {
515#ifndef IN_RING3
516 rc = VINF_IOM_R3_IOPORT_READ;
517#else
518 *pu32 = pThis->pDrv->cBits;
519#endif
520 }
521 break;
522
523 case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
524 if ( pThis->svga.fEnabled
525 && pThis->svga.iBpp != (unsigned)-1)
526 {
527 *pu32 = (pThis->svga.iBpp + 7) & ~7;
528 }
529 else
530 {
531#ifndef IN_RING3
532 rc = VINF_IOM_R3_IOPORT_READ;
533#else
534 *pu32 = (pThis->pDrv->cBits + 7) & ~7;
535#endif
536 }
537 break;
538
539 case SVGA_REG_PSEUDOCOLOR:
540 *pu32 = 0;
541 break;
542
543 case SVGA_REG_RED_MASK:
544 case SVGA_REG_GREEN_MASK:
545 case SVGA_REG_BLUE_MASK:
546 {
547 uint32_t iBpp;
548
549 if ( pThis->svga.fEnabled
550 && pThis->svga.iBpp != (unsigned)-1)
551 {
552 iBpp = pThis->svga.iBpp;
553 }
554 else
555 {
556#ifndef IN_RING3
557 rc = VINF_IOM_R3_IOPORT_READ;
558 break;
559#else
560 iBpp = pThis->pDrv->cBits;
561#endif
562 }
563 uint32_t u32RedMask, u32GreenMask, u32BlueMask;
564 switch (iBpp)
565 {
566 case 8:
567 u32RedMask = 0x07;
568 u32GreenMask = 0x38;
569 u32BlueMask = 0xc0;
570 break;
571
572 case 15:
573 u32RedMask = 0x0000001f;
574 u32GreenMask = 0x000003e0;
575 u32BlueMask = 0x00007c00;
576 break;
577
578 case 16:
579 u32RedMask = 0x0000001f;
580 u32GreenMask = 0x000007e0;
581 u32BlueMask = 0x0000f800;
582 break;
583
584 case 24:
585 case 32:
586 default:
587 u32RedMask = 0x00ff0000;
588 u32GreenMask = 0x0000ff00;
589 u32BlueMask = 0x000000ff;
590 break;
591 }
592 switch (pThis->svga.u32IndexReg)
593 {
594 case SVGA_REG_RED_MASK:
595 *pu32 = u32RedMask;
596 break;
597
598 case SVGA_REG_GREEN_MASK:
599 *pu32 = u32GreenMask;
600 break;
601
602 case SVGA_REG_BLUE_MASK:
603 *pu32 = u32BlueMask;
604 break;
605 }
606 break;
607 }
608
609 case SVGA_REG_BYTES_PER_LINE:
610 {
611 if ( pThis->svga.fEnabled
612 && pThis->svga.cbScanline)
613 {
614 *pu32 = pThis->svga.cbScanline;
615 }
616 else
617 {
618#ifndef IN_RING3
619 rc = VINF_IOM_R3_IOPORT_READ;
620#else
621 *pu32 = pThis->pDrv->cbScanline;
622#endif
623 }
624 break;
625 }
626
627 case SVGA_REG_VRAM_SIZE: /* VRAM size */
628 *pu32 = pThis->vram_size;
629 break;
630
631 case SVGA_REG_FB_START: /* Frame buffer physical address. */
632 Assert(pThis->GCPhysVRAM <= 0xffffffff);
633 *pu32 = pThis->GCPhysVRAM;
634 break;
635
636 case SVGA_REG_FB_OFFSET: /* Offset of the frame buffer in VRAM */
637 /* Always zero in our case. */
638 *pu32 = 0;
639 break;
640
641 case SVGA_REG_FB_SIZE: /* Frame buffer size */
642 {
643#ifndef IN_RING3
644 rc = VINF_IOM_R3_IOPORT_READ;
645#else
646 /* VMWare testcases want at least 4 MB in case the hardware is disabled. */
647 if ( pThis->svga.fEnabled
648 && pThis->svga.iHeight != -1)
649 {
650 /* Hardware enabled; return real framebuffer size .*/
651 *pu32 = (uint32_t)pThis->svga.iHeight * pThis->svga.cbScanline;
652 }
653 else
654 *pu32 = RT_MAX(0x100000, (uint32_t)pThis->pDrv->cy * pThis->pDrv->cbScanline);
655
656 *pu32 = RT_MIN(pThis->vram_size, *pu32);
657 Log(("h=%d w=%d bpp=%d\n", pThis->pDrv->cy, pThis->pDrv->cx, pThis->pDrv->cBits));
658#endif
659 break;
660 }
661
662 case SVGA_REG_CAPABILITIES:
663 *pu32 = pThis->svga.u32RegCaps;
664 break;
665
666 case SVGA_REG_MEM_START: /* FIFO start */
667 Assert(pThis->svga.GCPhysFIFO <= 0xffffffff);
668 *pu32 = pThis->svga.GCPhysFIFO;
669 break;
670
671 case SVGA_REG_MEM_SIZE: /* FIFO size */
672 *pu32 = pThis->svga.cbFIFO;
673 break;
674
675 case SVGA_REG_CONFIG_DONE: /* Set when memory area configured */
676 *pu32 = pThis->svga.fConfigured;
677 break;
678
679 case SVGA_REG_SYNC: /* See "FIFO Synchronization Registers" */
680 *pu32 = 0;
681 break;
682
683 case SVGA_REG_BUSY: /* See "FIFO Synchronization Registers" */
684 if (pThis->svga.fBusy)
685 {
686#ifndef IN_RING3
687 rc = VINF_IOM_R3_IOPORT_READ;
688 break;
689#else
690 /* @todo bit crude */
691 RTThreadSleep(50);
692#endif
693 }
694 *pu32 = pThis->svga.fBusy;
695 break;
696
697 case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
698 *pu32 = pThis->svga.u32GuestId;
699 break;
700
701 case SVGA_REG_SCRATCH_SIZE: /* Number of scratch registers */
702 *pu32 = pThis->svga.cScratchRegion;
703 break;
704
705 case SVGA_REG_MEM_REGS: /* Number of FIFO registers */
706 *pu32 = SVGA_FIFO_NUM_REGS;
707 break;
708
709 case SVGA_REG_PITCHLOCK: /* Fixed pitch for all modes */
710 *pu32 = pThis->svga.u32PitchLock;
711 break;
712
713 case SVGA_REG_IRQMASK: /* Interrupt mask */
714 *pu32 = pThis->svga.u32IrqMask;
715 break;
716
717 /* See "Guest memory regions" below. */
718 case SVGA_REG_GMR_ID:
719 *pu32 = pThis->svga.u32CurrentGMRId;
720 break;
721
722 case SVGA_REG_GMR_DESCRIPTOR:
723 /* Write only */
724 *pu32 = 0;
725 break;
726
727 case SVGA_REG_GMR_MAX_IDS:
728 *pu32 = VMSVGA_MAX_GMR_IDS;
729 break;
730
731 case SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH:
732 *pu32 = VMSVGA_MAX_GMR_PAGES;
733 break;
734
735 case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
736 *pu32 = pThis->svga.fTraces;
737 break;
738
739 case SVGA_REG_GMRS_MAX_PAGES: /* Maximum number of 4KB pages for all GMRs */
740 *pu32 = VMSVGA_MAX_GMR_PAGES;
741 break;
742
743 case SVGA_REG_MEMORY_SIZE: /* Total dedicated device memory excluding FIFO */
744 *pu32 = VMSVGA_SURFACE_SIZE;
745 break;
746
747 case SVGA_REG_TOP: /* Must be 1 more than the last register */
748 break;
749
750 case SVGA_PALETTE_BASE: /* Base of SVGA color map */
751 break;
752 /* Next 768 (== 256*3) registers exist for colormap */
753
754 /* Mouse cursor support. */
755 case SVGA_REG_CURSOR_ID:
756 case SVGA_REG_CURSOR_X:
757 case SVGA_REG_CURSOR_Y:
758 case SVGA_REG_CURSOR_ON:
759 break;
760
761 /* Legacy multi-monitor support */
762 case SVGA_REG_NUM_GUEST_DISPLAYS:/* Number of guest displays in X/Y direction */
763 *pu32 = 1;
764 break;
765
766 case SVGA_REG_DISPLAY_ID: /* Display ID for the following display attributes */
767 case SVGA_REG_DISPLAY_IS_PRIMARY:/* Whether this is a primary display */
768 case SVGA_REG_DISPLAY_POSITION_X:/* The display position x */
769 case SVGA_REG_DISPLAY_POSITION_Y:/* The display position y */
770 *pu32 = 0;
771 break;
772
773 case SVGA_REG_DISPLAY_WIDTH: /* The display's width */
774 *pu32 = pThis->svga.iWidth;
775 break;
776
777 case SVGA_REG_DISPLAY_HEIGHT: /* The display's height */
778 *pu32 = pThis->svga.iHeight;
779 break;
780
781 case SVGA_REG_NUM_DISPLAYS: /* (Deprecated) */
782 *pu32 = 1; /* Must return something sensible here otherwise the Linux driver will take a legacy code path without 3d support. */
783 break;
784
785 default:
786 if ( pThis->svga.u32IndexReg >= SVGA_SCRATCH_BASE
787 && pThis->svga.u32IndexReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion)
788 {
789 *pu32 = pThis->svga.au32ScratchRegion[pThis->svga.u32IndexReg - SVGA_SCRATCH_BASE];
790 }
791 break;
792 }
793 Log(("vmsvgaReadPort index=%s (%d) val=%x rc=%x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, *pu32, rc));
794 return rc;
795}
796
797#ifdef IN_RING3
798/**
799 * Apply the current resolution settings to change the video mode.
800 *
801 * @returns VBox status code.
802 * @param pThis VMSVGA State
803 */
804int vmsvgaChangeMode(PVGASTATE pThis)
805{
806 int rc;
807
808 if ( pThis->svga.iWidth == -1
809 || pThis->svga.iHeight == -1
810 || pThis->svga.iBpp == (unsigned)-1)
811 {
812 /* Mode change in progress; wait for all values to be set. */
813 Log(("vmsvgaChangeMode: BOGUS sEnable LFB mode and resize to (%d,%d) bpp=%d\n", pThis->svga.iWidth, pThis->svga.iHeight, pThis->svga.iBpp));
814 return VINF_SUCCESS;
815 }
816
817 if ( pThis->last_bpp == (unsigned)pThis->svga.iBpp
818 && pThis->last_scr_width == (unsigned)pThis->svga.iWidth
819 && pThis->last_scr_height == (unsigned)pThis->svga.iHeight
820 && pThis->last_width == (unsigned)pThis->svga.iWidth
821 && pThis->last_height == (unsigned)pThis->svga.iHeight
822 )
823 {
824 /* Nothing to do. */
825 Log(("vmsvgaChangeMode: nothing changed; ignore\n"));
826 return VINF_SUCCESS;
827 }
828
829 Log(("vmsvgaChangeMode: sEnable LFB mode and resize to (%d,%d) bpp=%d\n", pThis->svga.iWidth, pThis->svga.iHeight, pThis->svga.iBpp));
830 pThis->svga.cbScanline = ((pThis->svga.iWidth * pThis->svga.iBpp + 7) & ~7) / 8;
831
832 pThis->pDrv->pfnLFBModeChange(pThis->pDrv, true);
833 rc = pThis->pDrv->pfnResize(pThis->pDrv, pThis->svga.iBpp, pThis->CTX_SUFF(vram_ptr), pThis->svga.cbScanline, pThis->svga.iWidth, pThis->svga.iHeight);
834 AssertRC(rc);
835 AssertReturn(rc == VINF_SUCCESS || rc == VINF_VGA_RESIZE_IN_PROGRESS, rc);
836
837 /* last stuff */
838 pThis->last_bpp = pThis->svga.iBpp;
839 pThis->last_scr_width = pThis->svga.iWidth;
840 pThis->last_scr_height = pThis->svga.iHeight;
841 pThis->last_width = pThis->svga.iWidth;
842 pThis->last_height = pThis->svga.iHeight;
843
844 ASMAtomicOrU32(&pThis->svga.u32ActionFlags, VMSVGA_ACTION_CHANGEMODE);
845
846 return VINF_SUCCESS;
847}
848#endif /* IN_RING3 */
849
850/**
851 * Write port register
852 *
853 * @returns VBox status code.
854 * @param pThis VMSVGA State
855 * @param u32 Value to write
856 */
857PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
858{
859 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
860 int rc = VINF_SUCCESS;
861
862 Log(("vmsvgaWritePort index=%s (%d) val=%x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, u32));
863 switch (pThis->svga.u32IndexReg)
864 {
865 case SVGA_REG_ID:
866 if ( u32 == SVGA_ID_0
867 || u32 == SVGA_ID_1
868 || u32 == SVGA_ID_2)
869 pThis->svga.u32SVGAId = u32;
870 break;
871
872 case SVGA_REG_ENABLE:
873 if ( pThis->svga.fEnabled == u32
874 && pThis->last_bpp == (unsigned)pThis->svga.iBpp
875 && pThis->last_scr_width == (unsigned)pThis->svga.iWidth
876 && pThis->last_scr_height == (unsigned)pThis->svga.iHeight
877 && pThis->last_width == (unsigned)pThis->svga.iWidth
878 && pThis->last_height == (unsigned)pThis->svga.iHeight
879 )
880 /* Nothing to do. */
881 break;
882
883#ifdef IN_RING3
884 if ( u32 == 1
885 && pThis->svga.fEnabled == false)
886 {
887 /* Make a backup copy of the first 32k in order to save font data etc. */
888 memcpy(pThis->svga.pFrameBufferBackup, pThis->vram_ptrR3, VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
889 }
890
891 pThis->svga.fEnabled = u32;
892 if (pThis->svga.fEnabled)
893 {
894 if ( pThis->svga.iWidth == -1
895 && pThis->svga.iHeight == -1
896 && pThis->svga.iBpp == (unsigned)-1)
897 {
898 /* Keep the current mode. */
899 pThis->svga.iWidth = pThis->pDrv->cx;
900 pThis->svga.iHeight = pThis->pDrv->cy;
901 pThis->svga.iBpp = (pThis->pDrv->cBits + 7) & ~7;
902 }
903
904 if ( pThis->svga.iWidth != -1
905 && pThis->svga.iHeight != -1
906 && pThis->svga.iBpp != (unsigned)-1)
907 {
908 rc = vmsvgaChangeMode(pThis);
909 AssertRCReturn(rc, rc);
910 }
911 Log(("configured=%d busy=%d\n", pThis->svga.fConfigured, pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
912 uint32_t *pFIFO = pThis->svga.pFIFOR3;
913 Log(("next %x stop %x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
914
915 /* Disable or enable dirty page tracking according to the current fTraces value. */
916 vmsvgaSetTraces(pThis, !!pThis->svga.fTraces);
917 }
918 else
919 {
920 /* Restore the text mode backup. */
921 memcpy(pThis->vram_ptrR3, pThis->svga.pFrameBufferBackup, VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
922
923/* pThis->svga.iHeight = -1;
924 pThis->svga.iWidth = -1;
925 pThis->svga.iBpp = -1;
926 pThis->svga.cbScanline = 0; */
927 pThis->pDrv->pfnLFBModeChange(pThis->pDrv, false);
928
929 /* Enable dirty page tracking again when going into legacy mode. */
930 vmsvgaSetTraces(pThis, true);
931 }
932#else
933 rc = VINF_IOM_R3_IOPORT_WRITE;
934#endif
935 break;
936
937 case SVGA_REG_WIDTH:
938 if (pThis->svga.iWidth == (int) u32)
939 break; /* nop */
940
941 pThis->svga.iWidth = (int) u32;
942 if (pThis->svga.fEnabled)
943 {
944#ifdef IN_RING3
945 rc = vmsvgaChangeMode(pThis);
946 AssertRCReturn(rc, rc);
947#else
948 rc = VINF_IOM_R3_IOPORT_WRITE;
949 break;
950#endif
951 }
952 break;
953
954 case SVGA_REG_HEIGHT:
955 if (pThis->svga.iHeight == (int) u32)
956 break; /* nop */
957
958 pThis->svga.iHeight = (int) u32;
959 if (pThis->svga.fEnabled)
960 {
961#ifdef IN_RING3
962 rc = vmsvgaChangeMode(pThis);
963 AssertRCReturn(rc, rc);
964#else
965 rc = VINF_IOM_R3_IOPORT_WRITE;
966 break;
967#endif
968 }
969 break;
970
971 case SVGA_REG_DEPTH:
972 /* @todo read-only?? */
973 break;
974
975 case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
976 if (pThis->svga.iBpp == u32)
977 break; /* nop */
978
979 pThis->svga.iBpp = u32;
980 if (pThis->svga.fEnabled)
981 {
982#ifdef IN_RING3
983 rc = vmsvgaChangeMode(pThis);
984 AssertRCReturn(rc, rc);
985#else
986 rc = VINF_IOM_R3_IOPORT_WRITE;
987 break;
988#endif
989 }
990 break;
991
992 case SVGA_REG_PSEUDOCOLOR:
993 break;
994
995 case SVGA_REG_CONFIG_DONE: /* Set when memory area configured */
996#ifdef IN_RING3
997 pThis->svga.fConfigured = u32;
998 /* Disabling the FIFO enables tracing (dirty page detection) by default. */
999 if (!pThis->svga.fConfigured)
1000 {
1001 pThis->svga.fTraces = true;
1002 }
1003 vmsvgaSetTraces(pThis, !!pThis->svga.fTraces);
1004#else
1005 rc = VINF_IOM_R3_IOPORT_WRITE;
1006#endif
1007 break;
1008
1009 case SVGA_REG_SYNC: /* See "FIFO Synchronization Registers" */
1010 if ( pThis->svga.fEnabled
1011 && pThis->svga.fConfigured)
1012 {
1013#ifdef IN_RING3
1014 Log(("SVGA_REG_SYNC: SVGA_FIFO_BUSY=%d\n", pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
1015 pThis->svga.fBusy = true;
1016 pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
1017
1018 /* Kick the FIFO thread to start processing commands again. */
1019 RTSemEventSignal(pThis->svga.FIFORequestSem);
1020#else
1021 rc = VINF_IOM_R3_IOPORT_WRITE;
1022#endif
1023 }
1024 /* else nothing to do. */
1025 else
1026 Log(("Sync ignored enabled=%d configured=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured));
1027
1028 break;
1029
1030 case SVGA_REG_BUSY: /* See "FIFO Synchronization Registers" (read-only) */
1031 break;
1032
1033 case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
1034 pThis->svga.u32GuestId = u32;
1035 break;
1036
1037 case SVGA_REG_PITCHLOCK: /* Fixed pitch for all modes */
1038 pThis->svga.u32PitchLock = u32;
1039 break;
1040
1041 case SVGA_REG_IRQMASK: /* Interrupt mask */
1042 pThis->svga.u32IrqMask = u32;
1043
1044 /* Irq pending after the above change? */
1045 if (pThis->svga.u32IrqMask & pThis->svga.u32IrqStatus)
1046 {
1047 Log(("SVGA_REG_IRQMASK: Trigger interrupt with status %x\n", pThis->svga.u32IrqStatus));
1048 PDMDevHlpPCISetIrqNoWait(pThis->CTX_SUFF(pDevIns), 0, 1);
1049 }
1050 else
1051 PDMDevHlpPCISetIrqNoWait(pThis->CTX_SUFF(pDevIns), 0, 0);
1052 break;
1053
1054 /* Mouse cursor support */
1055 case SVGA_REG_CURSOR_ID:
1056 case SVGA_REG_CURSOR_X:
1057 case SVGA_REG_CURSOR_Y:
1058 case SVGA_REG_CURSOR_ON:
1059 break;
1060
1061 /* Legacy multi-monitor support */
1062 case SVGA_REG_NUM_GUEST_DISPLAYS:/* Number of guest displays in X/Y direction */
1063 break;
1064 case SVGA_REG_DISPLAY_ID: /* Display ID for the following display attributes */
1065 break;
1066 case SVGA_REG_DISPLAY_IS_PRIMARY:/* Whether this is a primary display */
1067 break;
1068 case SVGA_REG_DISPLAY_POSITION_X:/* The display position x */
1069 break;
1070 case SVGA_REG_DISPLAY_POSITION_Y:/* The display position y */
1071 break;
1072 case SVGA_REG_DISPLAY_WIDTH: /* The display's width */
1073 break;
1074 case SVGA_REG_DISPLAY_HEIGHT: /* The display's height */
1075 break;
1076#ifdef VBOX_WITH_VMSVGA3D
1077 /* See "Guest memory regions" below. */
1078 case SVGA_REG_GMR_ID:
1079 pThis->svga.u32CurrentGMRId = u32;
1080 break;
1081
1082 case SVGA_REG_GMR_DESCRIPTOR:
1083#ifndef IN_RING3
1084 rc = VINF_IOM_R3_IOPORT_WRITE;
1085 break;
1086#else
1087 {
1088 SVGAGuestMemDescriptor desc;
1089 RTGCPHYS GCPhys = (RTGCPHYS)u32 << PAGE_SHIFT;
1090 RTGCPHYS GCPhysBase = GCPhys;
1091 uint32_t idGMR = pThis->svga.u32CurrentGMRId;
1092 uint32_t cDescriptorsAllocated = 16;
1093 uint32_t iDescriptor = 0;
1094
1095 /* Validate current GMR id. */
1096 AssertBreak(idGMR < VMSVGA_MAX_GMR_IDS);
1097
1098 /* Free the old GMR if present. */
1099 vmsvgaGMRFree(pThis, idGMR);
1100
1101 /* Just undefine the GMR? */
1102 if (GCPhys == 0)
1103 break;
1104
1105 pSVGAState->aGMR[idGMR].paDesc = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(cDescriptorsAllocated * sizeof(VMSVGAGMRDESCRIPTOR));
1106 AssertReturn(pSVGAState->aGMR[idGMR].paDesc, VERR_NO_MEMORY);
1107
1108 /* Never cross a page boundary automatically. */
1109 while (PHYS_PAGE_ADDRESS(GCPhys) == PHYS_PAGE_ADDRESS(GCPhysBase))
1110 {
1111 /* Read descriptor. */
1112 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), GCPhys, &desc, sizeof(desc));
1113 AssertRCBreak(rc);
1114
1115 if ( desc.ppn == 0
1116 && desc.numPages == 0)
1117 break; /* terminator */
1118
1119 if ( desc.ppn != 0
1120 && desc.numPages == 0)
1121 {
1122 /* Pointer to the next physical page of descriptors. */
1123 GCPhys = GCPhysBase = desc.ppn << PAGE_SHIFT;
1124 }
1125 else
1126 {
1127 if (iDescriptor == cDescriptorsAllocated)
1128 {
1129 cDescriptorsAllocated += 16;
1130 pSVGAState->aGMR[idGMR].paDesc = (PVMSVGAGMRDESCRIPTOR)RTMemRealloc(pSVGAState->aGMR[idGMR].paDesc, cDescriptorsAllocated * sizeof(VMSVGAGMRDESCRIPTOR));
1131 AssertReturn(pSVGAState->aGMR[idGMR].paDesc, VERR_NO_MEMORY);
1132 }
1133
1134 pSVGAState->aGMR[idGMR].paDesc[iDescriptor].GCPhys = desc.ppn << PAGE_SHIFT;
1135 pSVGAState->aGMR[idGMR].paDesc[iDescriptor++].numPages = desc.numPages;
1136 pSVGAState->aGMR[idGMR].cbTotal += desc.numPages * PAGE_SIZE;
1137
1138 /* Continue with the next descriptor. */
1139 GCPhys += sizeof(desc);
1140 }
1141 }
1142 pSVGAState->aGMR[idGMR].numDescriptors = iDescriptor;
1143 Log(("Defined new gmr %x numDescriptors=%d cbTotal=%x\n", idGMR, iDescriptor, pSVGAState->aGMR[idGMR].cbTotal));
1144
1145 if (!pSVGAState->aGMR[idGMR].numDescriptors)
1146 {
1147 AssertFailed();
1148 RTMemFree(pSVGAState->aGMR[idGMR].paDesc);
1149 pSVGAState->aGMR[idGMR].paDesc = NULL;
1150 }
1151 AssertRC(rc);
1152 break;
1153 }
1154#endif
1155#endif // VBOX_WITH_VMSVGA3D
1156
1157 case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
1158 if (pThis->svga.fTraces == u32)
1159 break; /* nothing to do */
1160
1161#ifdef IN_RING3
1162 vmsvgaSetTraces(pThis, !!u32);
1163#else
1164 rc = VINF_IOM_R3_IOPORT_WRITE;
1165#endif
1166 break;
1167
1168 case SVGA_REG_TOP: /* Must be 1 more than the last register */
1169 break;
1170
1171 case SVGA_PALETTE_BASE: /* Base of SVGA color map */
1172 break;
1173 /* Next 768 (== 256*3) registers exist for colormap */
1174
1175 case SVGA_REG_NUM_DISPLAYS: /* (Deprecated) */
1176 Log(("Write to deprecated register %x - val %x ignored\n", pThis->svga.u32IndexReg, u32));
1177 break;
1178
1179 case SVGA_REG_FB_START:
1180 case SVGA_REG_MEM_START:
1181 case SVGA_REG_HOST_BITS_PER_PIXEL:
1182 case SVGA_REG_MAX_WIDTH:
1183 case SVGA_REG_MAX_HEIGHT:
1184 case SVGA_REG_VRAM_SIZE:
1185 case SVGA_REG_FB_SIZE:
1186 case SVGA_REG_CAPABILITIES:
1187 case SVGA_REG_MEM_SIZE:
1188 case SVGA_REG_SCRATCH_SIZE: /* Number of scratch registers */
1189 case SVGA_REG_MEM_REGS: /* Number of FIFO registers */
1190 case SVGA_REG_BYTES_PER_LINE:
1191 case SVGA_REG_FB_OFFSET:
1192 case SVGA_REG_RED_MASK:
1193 case SVGA_REG_GREEN_MASK:
1194 case SVGA_REG_BLUE_MASK:
1195 case SVGA_REG_GMRS_MAX_PAGES: /* Maximum number of 4KB pages for all GMRs */
1196 case SVGA_REG_MEMORY_SIZE: /* Total dedicated device memory excluding FIFO */
1197 case SVGA_REG_GMR_MAX_IDS:
1198 case SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH:
1199 /* Read only - ignore. */
1200 Log(("Write to R/O register %x - val %x ignored\n", pThis->svga.u32IndexReg, u32));
1201 break;
1202
1203 default:
1204 if ( pThis->svga.u32IndexReg >= SVGA_SCRATCH_BASE
1205 && pThis->svga.u32IndexReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion)
1206 {
1207 pThis->svga.au32ScratchRegion[pThis->svga.u32IndexReg - SVGA_SCRATCH_BASE] = u32;
1208 }
1209 break;
1210 }
1211 return rc;
1212}
1213
1214/**
1215 * Port I/O Handler for IN operations.
1216 *
1217 * @returns VINF_SUCCESS or VINF_EM_*.
1218 * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
1219 *
1220 * @param pDevIns The device instance.
1221 * @param pvUser User argument.
1222 * @param uPort Port number used for the IN operation.
1223 * @param pu32 Where to store the result. This is always a 32-bit
1224 * variable regardless of what @a cb might say.
1225 * @param cb Number of bytes read.
1226 */
1227PDMBOTHCBDECL(int) vmsvgaIORead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
1228{
1229 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
1230 int rc = VINF_SUCCESS;
1231
1232 /* Ignore non-dword accesses. */
1233 if (cb != 4)
1234 {
1235 Log(("Ignoring non-dword read at %x cb=%d\n", Port, cb));
1236 *pu32 = ~0;
1237 return VINF_SUCCESS;
1238 }
1239
1240 switch (Port - pThis->svga.BasePort)
1241 {
1242 case SVGA_INDEX_PORT:
1243 *pu32 = pThis->svga.u32IndexReg;
1244 break;
1245
1246 case SVGA_VALUE_PORT:
1247 return vmsvgaReadPort(pThis, pu32);
1248
1249 case SVGA_BIOS_PORT:
1250 Log(("Ignoring BIOS port read\n"));
1251 *pu32 = 0;
1252 break;
1253
1254 case SVGA_IRQSTATUS_PORT:
1255 Log(("vmsvgaIORead: SVGA_IRQSTATUS_PORT %x\n", pThis->svga.u32IrqStatus));
1256 *pu32 = pThis->svga.u32IrqStatus;
1257 break;
1258 }
1259 return rc;
1260}
1261
1262/**
1263 * Port I/O Handler for OUT operations.
1264 *
1265 * @returns VINF_SUCCESS or VINF_EM_*.
1266 *
1267 * @param pDevIns The device instance.
1268 * @param pvUser User argument.
1269 * @param uPort Port number used for the OUT operation.
1270 * @param u32 The value to output.
1271 * @param cb The value size in bytes.
1272 */
1273PDMBOTHCBDECL(int) vmsvgaIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
1274{
1275 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
1276 int rc = VINF_SUCCESS;
1277
1278 /* Ignore non-dword accesses. */
1279 if (cb != 4)
1280 {
1281 Log(("Ignoring non-dword write at %x val=%x cb=%d\n", Port, u32, cb));
1282 return VINF_SUCCESS;
1283 }
1284
1285 switch (Port - pThis->svga.BasePort)
1286 {
1287 case SVGA_INDEX_PORT:
1288 pThis->svga.u32IndexReg = u32;
1289 break;
1290
1291 case SVGA_VALUE_PORT:
1292 return vmsvgaWritePort(pThis, u32);
1293
1294 case SVGA_BIOS_PORT:
1295 Log(("Ignoring BIOS port write (val=%x)\n", u32));
1296 break;
1297
1298 case SVGA_IRQSTATUS_PORT:
1299 Log(("vmsvgaIOWrite SVGA_IRQSTATUS_PORT %x: status %x -> %x\n", u32, pThis->svga.u32IrqStatus, pThis->svga.u32IrqStatus & ~u32));
1300 ASMAtomicAndU32(&pThis->svga.u32IrqStatus, ~u32);
1301 /* Clear the irq in case all events have been cleared. */
1302 if (!(pThis->svga.u32IrqStatus & pThis->svga.u32IrqMask))
1303 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
1304 break;
1305 }
1306 return rc;
1307}
1308
1309#ifdef DEBUG_FIFO_ACCESS
1310
1311# ifdef IN_RING3
1312/**
1313 * Handle LFB access.
1314 * @returns VBox status code.
1315 * @param pVM VM handle.
1316 * @param pThis VGA device instance data.
1317 * @param GCPhys The access physical address.
1318 * @param fWriteAccess Read or write access
1319 */
1320static int vmsvgaFIFOAccess(PVM pVM, PVGASTATE pThis, RTGCPHYS GCPhys, bool fWriteAccess)
1321{
1322 RTGCPHYS GCPhysOffset = GCPhys - pThis->svga.GCPhysFIFO;
1323 uint32_t *pFIFO = pThis->svga.pFIFOR3;
1324
1325 switch (GCPhysOffset >> 2)
1326 {
1327 case SVGA_FIFO_MIN:
1328 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_MIN = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1329 break;
1330 case SVGA_FIFO_MAX:
1331 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_MAX = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1332 break;
1333 case SVGA_FIFO_NEXT_CMD:
1334 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_NEXT_CMD = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1335 break;
1336 case SVGA_FIFO_STOP:
1337 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_STOP = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1338 break;
1339 case SVGA_FIFO_CAPABILITIES:
1340 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CAPABILITIES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1341 break;
1342 case SVGA_FIFO_FLAGS:
1343 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_FLAGS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1344 break;
1345 case SVGA_FIFO_FENCE:
1346 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_FENCE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1347 break;
1348 case SVGA_FIFO_3D_HWVERSION:
1349 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_HWVERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1350 break;
1351 case SVGA_FIFO_PITCHLOCK:
1352 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_PITCHLOCK = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1353 break;
1354 case SVGA_FIFO_CURSOR_ON:
1355 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_ON = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1356 break;
1357 case SVGA_FIFO_CURSOR_X:
1358 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_X = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1359 break;
1360 case SVGA_FIFO_CURSOR_Y:
1361 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_Y = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1362 break;
1363 case SVGA_FIFO_CURSOR_COUNT:
1364 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_COUNT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1365 break;
1366 case SVGA_FIFO_CURSOR_LAST_UPDATED:
1367 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_LAST_UPDATED = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1368 break;
1369 case SVGA_FIFO_RESERVED:
1370 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_RESERVED = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1371 break;
1372 case SVGA_FIFO_CURSOR_SCREEN_ID:
1373 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_SCREEN_ID = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1374 break;
1375 case SVGA_FIFO_DEAD:
1376 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_DEAD = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1377 break;
1378 case SVGA_FIFO_3D_HWVERSION_REVISED:
1379 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_HWVERSION_REVISED = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1380 break;
1381 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_3D:
1382 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_3D = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1383 break;
1384 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_LIGHTS:
1385 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_LIGHTS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1386 break;
1387 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_TEXTURES:
1388 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1389 break;
1390 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_CLIP_PLANES:
1391 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_CLIP_PLANES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1392 break;
1393 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
1394 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_VERTEX_SHADER_VERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1395 break;
1396 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_VERTEX_SHADER:
1397 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_VERTEX_SHADER = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1398 break;
1399 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
1400 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1401 break;
1402 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_FRAGMENT_SHADER:
1403 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_FRAGMENT_SHADER = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1404 break;
1405 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_RENDER_TARGETS:
1406 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_RENDER_TARGETS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1407 break;
1408 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_S23E8_TEXTURES:
1409 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_S23E8_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1410 break;
1411 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_S10E5_TEXTURES:
1412 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_S10E5_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1413 break;
1414 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
1415 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1416 break;
1417 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
1418 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_D16_BUFFER_FORMAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1419 break;
1420 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
1421 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1422 break;
1423 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
1424 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1425 break;
1426 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_QUERY_TYPES:
1427 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_QUERY_TYPES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1428 break;
1429 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
1430 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1431 break;
1432 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_POINT_SIZE:
1433 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_POINT_SIZE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1434 break;
1435 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
1436 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_SHADER_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1437 break;
1438 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
1439 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1440 break;
1441 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
1442 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1443 break;
1444 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
1445 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VOLUME_EXTENT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1446 break;
1447 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
1448 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1449 break;
1450 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
1451 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1452 break;
1453 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
1454 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1455 break;
1456 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
1457 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1458 break;
1459 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
1460 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VERTEX_INDEX = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1461 break;
1462 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
1463 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1464 break;
1465 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
1466 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1467 break;
1468 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
1469 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1470 break;
1471 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
1472 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1473 break;
1474 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_TEXTURE_OPS:
1475 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_TEXTURE_OPS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1476 break;
1477 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
1478 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1479 break;
1480 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
1481 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1482 break;
1483 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
1484 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1485 break;
1486 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
1487 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1488 break;
1489 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
1490 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1491 break;
1492 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
1493 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1494 break;
1495 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
1496 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1497 break;
1498 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
1499 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1500 break;
1501 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
1502 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1503 break;
1504 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
1505 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1506 break;
1507 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
1508 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1509 break;
1510 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
1511 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1512 break;
1513 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
1514 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1515 break;
1516 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
1517 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1518 break;
1519 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_DXT1:
1520 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT1 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1521 break;
1522 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_DXT2:
1523 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT2 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1524 break;
1525 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_DXT3:
1526 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT3 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1527 break;
1528 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_DXT4:
1529 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT4 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1530 break;
1531 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_DXT5:
1532 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1533 break;
1534 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
1535 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1536 break;
1537 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
1538 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1539 break;
1540 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
1541 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1542 break;
1543 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
1544 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1545 break;
1546 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
1547 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1548 break;
1549 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
1550 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1551 break;
1552 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
1553 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1554 break;
1555 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
1556 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1557 break;
1558 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
1559 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1560 break;
1561 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
1562 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1563 break;
1564 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
1565 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1566 break;
1567 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
1568 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1569 break;
1570 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
1571 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1572 break;
1573 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_V16U16:
1574 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_V16U16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1575 break;
1576 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_G16R16:
1577 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_G16R16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1578 break;
1579 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
1580 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1581 break;
1582 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_UYVY:
1583 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_UYVY = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1584 break;
1585 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_YUY2:
1586 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_YUY2 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1587 break;
1588 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES:
1589 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1590 break;
1591 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES:
1592 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1593 break;
1594 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_ALPHATOCOVERAGE:
1595 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_ALPHATOCOVERAGE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1596 break;
1597 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SUPERSAMPLE:
1598 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SUPERSAMPLE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1599 break;
1600 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_AUTOGENMIPMAPS:
1601 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_AUTOGENMIPMAPS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1602 break;
1603 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_NV12:
1604 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_NV12 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1605 break;
1606 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_AYUV:
1607 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_AYUV = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1608 break;
1609 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
1610 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_CONTEXT_IDS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1611 break;
1612 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_MAX_SURFACE_IDS:
1613 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_SURFACE_IDS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1614 break;
1615 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
1616 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1617 break;
1618 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
1619 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1620 break;
1621 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
1622 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1623 break;
1624 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM:
1625 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1626 break;
1627 case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM:
1628 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1629 break;
1630 case SVGA_FIFO_3D_CAPS_LAST:
1631 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS_LAST = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1632 break;
1633 case SVGA_FIFO_GUEST_3D_HWVERSION:
1634 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_GUEST_3D_HWVERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1635 break;
1636 case SVGA_FIFO_FENCE_GOAL:
1637 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_FENCE_GOAL = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1638 break;
1639 case SVGA_FIFO_BUSY:
1640 Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_BUSY = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
1641 break;
1642 default:
1643 Log(("vmsvgaFIFOAccess [0x%x]: %s access at offset %x = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", GCPhysOffset, pFIFO[GCPhysOffset >> 2]));
1644 break;
1645 }
1646
1647 return VINF_EM_RAW_EMULATE_INSTR;
1648}
1649
1650/**
1651 * HC access handler for the FIFO.
1652 *
1653 * @returns VINF_SUCCESS if the handler have carried out the operation.
1654 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
1655 * @param pVM VM Handle.
1656 * @param GCPhys The physical address the guest is writing to.
1657 * @param pvPhys The HC mapping of that address.
1658 * @param pvBuf What the guest is reading/writing.
1659 * @param cbBuf How much it's reading/writing.
1660 * @param enmAccessType The access type.
1661 * @param pvUser User argument.
1662 */
1663static DECLCALLBACK(int) vmsvgaR3FIFOAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
1664{
1665 PVGASTATE pThis = (PVGASTATE)pvUser;
1666 int rc;
1667 Assert(pThis);
1668 Assert(GCPhys >= pThis->GCPhysVRAM);
1669 NOREF(pvPhys); NOREF(pvBuf); NOREF(cbBuf);
1670
1671 rc = vmsvgaFIFOAccess(pVM, pThis, GCPhys, enmAccessType == PGMACCESSTYPE_WRITE);
1672 if (RT_SUCCESS(rc))
1673 return VINF_PGM_HANDLER_DO_DEFAULT;
1674 AssertMsg(rc <= VINF_SUCCESS, ("rc=%Rrc\n", rc));
1675 return rc;
1676}
1677# endif /* IN_RING3 */
1678#endif /* DEBUG */
1679
1680#ifdef DEBUG_GMR_ACCESS
1681/**
1682 * HC access handler for the FIFO.
1683 *
1684 * @returns VINF_SUCCESS if the handler have carried out the operation.
1685 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
1686 * @param pVM VM Handle.
1687 * @param GCPhys The physical address the guest is writing to.
1688 * @param pvPhys The HC mapping of that address.
1689 * @param pvBuf What the guest is reading/writing.
1690 * @param cbBuf How much it's reading/writing.
1691 * @param enmAccessType The access type.
1692 * @param pvUser User argument.
1693 */
1694static DECLCALLBACK(int) vmsvgaR3GMRAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
1695{
1696 PVGASTATE pThis = (PVGASTATE)pvUser;
1697 Assert(pThis);
1698 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
1699 NOREF(pvPhys); NOREF(pvBuf); NOREF(cbBuf);
1700
1701 Log(("vmsvgaR3GMRAccessHandler: GMR access to page %RGp\n", GCPhys));
1702
1703 for (uint32_t i = 0; i < RT_ELEMENTS(pSVGAState->aGMR); i++)
1704 {
1705 PGMR pGMR = &pSVGAState->aGMR[i];
1706
1707 if (pGMR->numDescriptors)
1708 {
1709 for (uint32_t j = 0; j < pGMR->numDescriptors; j++)
1710 {
1711 if ( GCPhys >= pGMR->paDesc[j].GCPhys
1712 && GCPhys < pGMR->paDesc[j].GCPhys + pGMR->paDesc[j].numPages * PAGE_SIZE)
1713 {
1714 /*
1715 * Turn off the write handler for this particular page and make it R/W.
1716 * Then return telling the caller to restart the guest instruction.
1717 */
1718 int rc = PGMHandlerPhysicalPageTempOff(pVM, pGMR->paDesc[j].GCPhys, GCPhys);
1719 goto end;
1720 }
1721 }
1722 }
1723 }
1724end:
1725 return VINF_PGM_HANDLER_DO_DEFAULT;
1726}
1727
1728#ifdef IN_RING3
1729/* Callback handler for VMR3ReqCallWait */
1730static DECLCALLBACK(int) vmsvgaRegisterGMR(PPDMDEVINS pDevIns, uint32_t gmrId)
1731{
1732 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
1733 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
1734 PGMR pGMR = &pSVGAState->aGMR[gmrId];
1735 int rc;
1736
1737 for (uint32_t i = 0; i < pGMR->numDescriptors; i++)
1738 {
1739 rc = PGMR3HandlerPhysicalRegister(PDMDevHlpGetVM(pThis->pDevInsR3),
1740 PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
1741 pGMR->paDesc[i].GCPhys, pGMR->paDesc[i].GCPhys + pGMR->paDesc[i].numPages * PAGE_SIZE - 1,
1742 vmsvgaR3GMRAccessHandler, pThis,
1743 NULL, NULL, NULL,
1744 NULL, NULL, NULL,
1745 "VMSVGA GMR");
1746 AssertRC(rc);
1747 }
1748 return VINF_SUCCESS;
1749}
1750
1751/* Callback handler for VMR3ReqCallWait */
1752static DECLCALLBACK(int) vmsvgaUnregisterGMR(PPDMDEVINS pDevIns, uint32_t gmrId)
1753{
1754 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
1755 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
1756 PGMR pGMR = &pSVGAState->aGMR[gmrId];
1757
1758 for (uint32_t i = 0; i < pGMR->numDescriptors; i++)
1759 {
1760 int rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pThis->pDevInsR3), pGMR->paDesc[i].GCPhys);
1761 AssertRC(rc);
1762 }
1763 return VINF_SUCCESS;
1764}
1765
1766/* Callback handler for VMR3ReqCallWait */
1767static DECLCALLBACK(int) vmsvgaResetGMRHandlers(PVGASTATE pThis)
1768{
1769 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
1770
1771 for (uint32_t i = 0; i < RT_ELEMENTS(pSVGAState->aGMR); i++)
1772 {
1773 PGMR pGMR = &pSVGAState->aGMR[i];
1774
1775 if (pGMR->numDescriptors)
1776 {
1777 for (uint32_t j = 0; j < pGMR->numDescriptors; j++)
1778 {
1779 int rc = PGMHandlerPhysicalReset(PDMDevHlpGetVM(pThis->pDevInsR3), pGMR->paDesc[j].GCPhys);
1780 AssertRC(rc);
1781 }
1782 }
1783 }
1784 return VINF_SUCCESS;
1785}
1786#endif /* IN_RING3 */
1787
1788
1789#endif /* DEBUG_GMR_ACCESS */
1790
1791/* -=-=-=-=-=- Ring 3 -=-=-=-=-=- */
1792
1793#ifdef IN_RING3
1794
1795#include <iprt/mem.h>
1796
1797static void *vmsvgaFIFOGetCmdBuffer(uint32_t *pFIFO, uint32_t cbCmd, uint32_t *pSize, void **ppfBounceBuffer)
1798{
1799 uint32_t cbLeft;
1800 uint32_t cbFIFOCmd = pFIFO[SVGA_FIFO_MAX] - pFIFO[SVGA_FIFO_MIN];
1801 uint32_t u32Current = pFIFO[SVGA_FIFO_STOP] + sizeof(uint32_t); /* skip command dword */
1802 uint8_t *pCmdBuffer;
1803
1804 Assert(ppfBounceBuffer);
1805
1806 *pSize += cbCmd;
1807 *ppfBounceBuffer = NULL;
1808
1809 while (true)
1810 {
1811 Assert(pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP]);
1812
1813 if (pFIFO[SVGA_FIFO_NEXT_CMD] >= u32Current)
1814 cbLeft = pFIFO[SVGA_FIFO_NEXT_CMD] - u32Current;
1815 else
1816 cbLeft = cbFIFOCmd - (u32Current - pFIFO[SVGA_FIFO_NEXT_CMD]);
1817
1818 if (cbCmd <= cbLeft)
1819 break;
1820
1821 /* Guest still busy copying into the FIFO; wait a bit. */
1822 Log(("Guest still copying (%x vs %x) current %x next %x stop %x; sleep a bit\n", cbCmd, cbLeft, u32Current, pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
1823 RTThreadSleep(2);
1824 }
1825
1826 if (u32Current + cbCmd <= pFIFO[SVGA_FIFO_MAX])
1827 {
1828 pCmdBuffer = (uint8_t *)pFIFO + u32Current;
1829 }
1830 else
1831 {
1832 /* command data split; allocate memory and copy. */
1833 uint8_t *pFIFOMin = (uint8_t *)pFIFO + pFIFO[SVGA_FIFO_MIN];
1834 uint32_t cbPart1 = pFIFO[SVGA_FIFO_MAX] - u32Current;
1835 uint32_t cbPart2 = cbCmd - cbPart1;
1836
1837 LogFlow(("Split data buffer at %x (%d-%d)\n", u32Current, cbPart1, cbPart2));
1838 pCmdBuffer = (uint8_t *)RTMemAlloc(cbCmd);
1839 AssertReturn(pCmdBuffer, NULL);
1840 *ppfBounceBuffer = (void *)pCmdBuffer;
1841
1842 memcpy(pCmdBuffer, (uint8_t *)pFIFO + u32Current, cbPart1);
1843 memcpy(pCmdBuffer + cbPart1, pFIFOMin, cbPart2);
1844 }
1845
1846 return pCmdBuffer;
1847}
1848
1849
1850/* The async FIFO handling thread. */
1851static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
1852{
1853 PVGASTATE pThis = (PVGASTATE)pThread->pvUser;
1854 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
1855 int rc;
1856
1857 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
1858 return VINF_SUCCESS;
1859
1860 LogFlow(("vmsvgaFIFOLoop: started loop\n"));
1861 while (pThread->enmState == PDMTHREADSTATE_RUNNING)
1862 {
1863 uint32_t *pFIFO = pThis->svga.pFIFOR3;
1864
1865 /* Wait for at most 250 ms to start polling. */
1866 rc = RTSemEventWait(pThis->svga.FIFORequestSem, 250);
1867 AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);
1868 if (pThread->enmState != PDMTHREADSTATE_RUNNING)
1869 {
1870 LogFlow(("vmsvgaFIFOLoop: thread state %x\n", pThread->enmState));
1871 return VINF_SUCCESS;
1872 }
1873 if (rc == VERR_TIMEOUT)
1874 {
1875 if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
1876 continue;
1877
1878 Log(("vmsvgaFIFOLoop: timeout\n"));
1879 }
1880 Log(("vmsvgaFIFOLoop: enabled=%d configured=%d busy=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured, pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
1881 Log(("vmsvgaFIFOLoop: min %x max %x\n", pFIFO[SVGA_FIFO_MIN], pFIFO[SVGA_FIFO_MAX]));
1882 Log(("vmsvgaFIFOLoop: next %x stop %x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
1883
1884 if ( !pThis->svga.fEnabled
1885 || !pThis->svga.fConfigured)
1886 {
1887 pThis->svga.fBusy = false;
1888 pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
1889 continue; /* device not enabled. */
1890 }
1891
1892 if (pFIFO[SVGA_FIFO_STOP] >= pFIFO[SVGA_FIFO_MAX])
1893 {
1894 Log(("vmsvgaFIFOLoop: Invalid stop %x max=%x\n", pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MAX]));
1895 continue; /* invalid. */
1896 }
1897
1898 if (pFIFO[SVGA_FIFO_MAX] < VMSVGA_FIFO_SIZE)
1899 {
1900 Log(("vmsvgaFIFOLoop: Invalid max %x fifo max=%x\n", pFIFO[SVGA_FIFO_MAX], VMSVGA_FIFO_SIZE));
1901 continue; /* invalid. */
1902 }
1903
1904 if (pFIFO[SVGA_FIFO_STOP] < pFIFO[SVGA_FIFO_MIN])
1905 {
1906 Log(("vmsvgaFIFOLoop: Invalid stop %x min=%x\n", pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MIN]));
1907 continue; /* invalid. */
1908 }
1909 pThis->svga.fBusy = true;
1910 pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
1911
1912 /* Execute all queued FIFO commands. */
1913 while ( pThread->enmState == PDMTHREADSTATE_RUNNING
1914 && pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
1915 {
1916 uint32_t u32Cmd;
1917 uint32_t u32Current, size;
1918 uint32_t u32IrqStatus = 0;
1919 bool fTriggerIrq = false;
1920 void *pBounceBuffer = NULL;
1921
1922 /* First check any pending actions. */
1923 if (ASMBitTestAndClear(&pThis->svga.u32ActionFlags, VMSVGA_ACTION_CHANGEMODE_BIT))
1924#ifdef VBOX_WITH_VMSVGA3D
1925 vmsvga3dChangeMode(pThis);
1926#else
1927 {}
1928#endif
1929 u32Current = pFIFO[SVGA_FIFO_STOP];
1930
1931 u32Cmd = u32Current / sizeof(uint32_t);
1932 LogFlow(("vmsvgaFIFOLoop: FIFO command (iCmd=0x%x) %s 0x%x\n", u32Cmd, vmsvgaFIFOCmdToString(pFIFO[u32Cmd]), pFIFO[u32Cmd]));
1933 size = sizeof(uint32_t); /* command dword */
1934
1935 switch (pFIFO[u32Cmd])
1936 {
1937 case SVGA_CMD_INVALID_CMD:
1938 /* Nothing to do. */
1939 break;
1940
1941 case SVGA_CMD_FENCE:
1942 {
1943 SVGAFifoCmdFence *pCmdFence = (SVGAFifoCmdFence *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdFence), &size, &pBounceBuffer);
1944
1945 Log(("vmsvgaFIFOLoop: SVGA_CMD_FENCE %x\n", pCmdFence->fence));
1946 pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence;
1947 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
1948 {
1949 Log(("vmsvgaFIFOLoop: any fence irq\n"));
1950 u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
1951 }
1952 else
1953 if ( (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL)
1954 && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence)
1955 {
1956 Log(("vmsvgaFIFOLoop: fence goal reached irq (fence=%x)\n", pCmdFence->fence));
1957 u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
1958 }
1959 break;
1960 }
1961 case SVGA_CMD_UPDATE:
1962 case SVGA_CMD_UPDATE_VERBOSE:
1963 {
1964 SVGAFifoCmdUpdate *pUpdate = (SVGAFifoCmdUpdate *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdUpdate), &size, &pBounceBuffer);
1965
1966 Log(("vmsvgaFIFOLoop: UPDATE (%d,%d)(%d,%d)\n", pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height));
1967 vgaR3UpdateDisplay(pThis, pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height);
1968 break;
1969 }
1970
1971 case SVGA_CMD_DEFINE_CURSOR:
1972 {
1973 /* Followed by bitmap data. */
1974 SVGAFifoCmdDefineCursor *pCursor = (SVGAFifoCmdDefineCursor *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdDefineCursor), &size, &pBounceBuffer);
1975
1976 AssertFailed();
1977 break;
1978 }
1979
1980 case SVGA_CMD_DEFINE_ALPHA_CURSOR:
1981 {
1982 /* Followed by bitmap data. */
1983 SVGAFifoCmdDefineAlphaCursor *pCursor = (SVGAFifoCmdDefineAlphaCursor *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdDefineAlphaCursor), &size, &pBounceBuffer);
1984 uint32_t cbCursorShape, cbAndMask;
1985 uint8_t *pCursorCopy;
1986 uint32_t cbCmd;
1987
1988 Log(("vmsvgaFIFOLoop: ALPHA_CURSOR id=%d size (%d,%d) hotspot (%d,%d)\n", pCursor->id, pCursor->width, pCursor->height, pCursor->hotspotX, pCursor->hotspotY));
1989
1990 /* Refetch the command buffer with the added bitmap data; undo size increase (ugly) */
1991 cbCmd = sizeof(SVGAFifoCmdDefineAlphaCursor) + pCursor->width * pCursor->height * sizeof(uint32_t) /* 32-bit BRGA format */;
1992 size = sizeof(uint32_t); /* command dword */
1993 if (pBounceBuffer)
1994 RTMemFree(pBounceBuffer);
1995 pCursor = (SVGAFifoCmdDefineAlphaCursor *)vmsvgaFIFOGetCmdBuffer(pFIFO, cbCmd, &size, &pBounceBuffer);
1996
1997 /* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */
1998 cbAndMask = (pCursor->width + 7) / 8 * pCursor->height; /* size of the AND mask */
1999 cbAndMask = ((cbAndMask + 3) & ~3); /* + gap for alignment */
2000 cbCursorShape = cbAndMask + pCursor->width * sizeof(uint32_t) * pCursor->height; /* + size of the XOR mask (32-bit BRGA format) */
2001
2002 pCursorCopy = (uint8_t *)RTMemAlloc(cbCursorShape);
2003 AssertBreak(pCursorCopy);
2004
2005 LogFlow(("Cursor data:\n%.*Rhxd\n", pCursor->width * pCursor->height * sizeof(uint32_t), pCursor+1));
2006
2007 /* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */
2008 memset(pCursorCopy, 0xff, cbAndMask);
2009 /* Colour data */
2010 memcpy(pCursorCopy + cbAndMask, (pCursor + 1), pCursor->width * pCursor->height * sizeof(uint32_t));
2011
2012 rc = pThis->pDrv->pfnVBVAMousePointerShape (pThis->pDrv,
2013 true,
2014 true,
2015 pCursor->hotspotX,
2016 pCursor->hotspotY,
2017 pCursor->width,
2018 pCursor->height,
2019 pCursorCopy);
2020 AssertRC(rc);
2021 RTMemFree(pCursorCopy);
2022
2023 break;
2024 }
2025
2026 case SVGA_CMD_ESCAPE:
2027 {
2028 /* Followed by nsize bytes of data. */
2029 SVGAFifoCmdEscape *pEscape = (SVGAFifoCmdEscape *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdEscape), &size, &pBounceBuffer);
2030 uint32_t cbCmd;
2031
2032 /* Refetch the command buffer with the variable data; undo size increase (ugly) */
2033 cbCmd = sizeof(SVGAFifoCmdEscape) + pEscape->size;
2034 size = sizeof(uint32_t); /* command dword */
2035 if (pBounceBuffer)
2036 RTMemFree(pBounceBuffer);
2037 pEscape = (SVGAFifoCmdEscape *)vmsvgaFIFOGetCmdBuffer(pFIFO, cbCmd, &size, &pBounceBuffer);
2038
2039 if (pEscape->nsid == SVGA_ESCAPE_NSID_VMWARE)
2040 {
2041 Assert(pEscape->size >= sizeof(uint32_t));
2042 uint32_t cmd = *(uint32_t *)(pEscape + 1);
2043 Log(("vmsvgaFIFOLoop: ESCAPE (%x %x) VMWARE cmd=%x\n", pEscape->nsid, pEscape->size, cmd));
2044
2045 switch (cmd)
2046 {
2047 case SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS:
2048 {
2049 SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pEscape + 1);
2050 uint32_t cRegs = (pEscape->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]);
2051
2052 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: stream %x\n", pVideoCmd->header.streamId));
2053 for (uint32_t iReg = 0; iReg < cRegs; iReg++)
2054 {
2055 Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: reg %x val %x\n", pVideoCmd->items[iReg].registerId, pVideoCmd->items[iReg].value));
2056 }
2057 break;
2058 }
2059
2060 case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH:
2061 SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pEscape + 1);
2062 Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %x\n", pVideoCmd->streamId));
2063 break;
2064 }
2065 }
2066 else
2067 Log(("vmsvgaFIFOLoop: ESCAPE %x %x\n", pEscape->nsid, pEscape->size));
2068
2069 break;
2070 }
2071#ifdef VBOX_WITH_VMSVGA3D
2072 case SVGA_CMD_DEFINE_GMR2:
2073 {
2074 SVGAFifoCmdDefineGMR2 *pCmd = (SVGAFifoCmdDefineGMR2 *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdDefineGMR2), &size, &pBounceBuffer);
2075 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_GMR2 id=%x %x pages\n", pCmd->gmrId, pCmd->numPages));
2076
2077 /* Validate current GMR id. */
2078 AssertBreak(pCmd->gmrId < VMSVGA_MAX_GMR_IDS);
2079 AssertBreak(pCmd->numPages <= VMSVGA_MAX_GMR_PAGES);
2080
2081 if (!pCmd->numPages)
2082 vmsvgaGMRFree(pThis, pCmd->gmrId);
2083 /* else everything done in remap */
2084
2085 break;
2086 }
2087
2088 case SVGA_CMD_REMAP_GMR2:
2089 {
2090 /* Followed by page descriptors. */
2091 SVGAFifoCmdRemapGMR2 *pCmd = (SVGAFifoCmdRemapGMR2 *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdRemapGMR2), &size, &pBounceBuffer);
2092 uint32_t cbPageDesc = (pCmd->flags & SVGA_REMAP_GMR2_PPN64) ? sizeof(uint64_t) : sizeof(uint32_t);
2093 uint32_t cbCmd;
2094
2095 Log(("vmsvgaFIFOLoop: SVGA_CMD_REMAP_GMR2 id=%x flags=%x offset=%x npages=%x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));
2096
2097 /* @todo */
2098 AssertBreak(pCmd->offsetPages == 0);
2099
2100 /* Refetch the command buffer with the variable data; undo size increase (ugly) */
2101 cbCmd = sizeof(SVGAFifoCmdRemapGMR2);
2102 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
2103 cbCmd += sizeof(SVGAGuestPtr);
2104 else
2105 if (pCmd->flags & SVGA_REMAP_GMR2_SINGLE_PPN)
2106 {
2107 cbCmd += cbPageDesc;
2108 pCmd->numPages = 1;
2109 }
2110 else
2111 cbCmd += cbPageDesc * pCmd->numPages;
2112 size = sizeof(uint32_t); /* command dword */
2113
2114 if (pBounceBuffer)
2115 RTMemFree(pBounceBuffer);
2116 pCmd = (SVGAFifoCmdRemapGMR2 *)vmsvgaFIFOGetCmdBuffer(pFIFO, cbCmd, &size, &pBounceBuffer);
2117 AssertReturn(pCmd, VERR_INTERNAL_ERROR);
2118
2119 PGMR pGMR = &pSVGAState->aGMR[pCmd->gmrId];
2120
2121 /* Validate current GMR id. */
2122 AssertBreak(pCmd->gmrId < VMSVGA_MAX_GMR_IDS);
2123 AssertBreak(pCmd->numPages <= VMSVGA_MAX_GMR_PAGES);
2124
2125 /* Free the old GMR if present. */
2126 vmsvgaGMRFree(pThis, pCmd->gmrId);
2127
2128 pGMR->paDesc = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(pCmd->numPages * sizeof(VMSVGAGMRDESCRIPTOR));
2129 AssertBreak(pGMR->paDesc);
2130
2131 if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
2132 {
2133 /* @todo */
2134 AssertFailed();
2135 }
2136 else
2137 {
2138 uint32_t *pPage32 = (uint32_t *)(pCmd + 1);
2139 uint64_t *pPage64 = (uint64_t *)(pCmd + 1);
2140 uint32_t iDescriptor = 0;
2141 RTGCPHYS GCPhys;
2142
2143 if (pCmd->flags & SVGA_REMAP_GMR2_PPN64)
2144 GCPhys = (pPage64[0] << PAGE_SHIFT) & 0x00000FFFFFFFFFFFULL; /* seeing rubbish in the top bits with certain linux guests*/
2145 else
2146 GCPhys = pPage32[0] << PAGE_SHIFT;
2147
2148 pGMR->paDesc[0].GCPhys = GCPhys;
2149 pGMR->paDesc[0].numPages = 1;
2150 pGMR->cbTotal = PAGE_SIZE;
2151
2152 for (uint32_t i = 1; i < pCmd->numPages; i++)
2153 {
2154 if (pCmd->flags & SVGA_REMAP_GMR2_PPN64)
2155 GCPhys = (pPage64[i] << PAGE_SHIFT) & 0x00000FFFFFFFFFFFULL; /* seeing rubbish in the top bits with certain linux guests*/
2156 else
2157 GCPhys = pPage32[i] << PAGE_SHIFT;
2158
2159 /* Continuous physical memory? */
2160 if (GCPhys == pGMR->paDesc[iDescriptor].GCPhys + pGMR->paDesc[iDescriptor].numPages * PAGE_SIZE)
2161 {
2162 Assert(pGMR->paDesc[iDescriptor].numPages);
2163 pGMR->paDesc[iDescriptor].numPages++;
2164 LogFlow(("Page %x GCPhys=%RGp successor\n", i, GCPhys));
2165 }
2166 else
2167 {
2168 iDescriptor++;
2169 pGMR->paDesc[iDescriptor].GCPhys = GCPhys;
2170 pGMR->paDesc[iDescriptor].numPages = 1;
2171 LogFlow(("Page %x GCPhys=%RGp\n", i, pGMR->paDesc[iDescriptor].GCPhys));
2172 }
2173
2174 pGMR->cbTotal += PAGE_SIZE;
2175 }
2176 LogFlow(("Nr of descriptors %x\n", iDescriptor + 1));
2177 pGMR->numDescriptors = iDescriptor + 1;
2178 }
2179
2180#ifdef DEBUG_GMR_ACCESS
2181 VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaRegisterGMR, 2, pThis->pDevInsR3, pCmd->gmrId);
2182#endif
2183 break;
2184 }
2185#endif // VBOX_WITH_VMSVGA3D
2186 case SVGA_CMD_DEFINE_SCREEN:
2187 {
2188 /* @note optional size depending on the capabilities */
2189 Assert(!(pThis->svga.pFIFOR3[SVGA_FIFO_CAPABILITIES] & SVGA_FIFO_CAP_SCREEN_OBJECT));
2190 SVGAFifoCmdDefineScreen *pCmd = (SVGAFifoCmdDefineScreen *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdDefineScreen), &size, &pBounceBuffer);
2191
2192 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d)\n", pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y));
2193 if (pCmd->screen.flags & SVGA_SCREEN_HAS_ROOT)
2194 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_HAS_ROOT\n"));
2195 if (pCmd->screen.flags & SVGA_SCREEN_IS_PRIMARY)
2196 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_IS_PRIMARY\n"));
2197 if (pCmd->screen.flags & SVGA_SCREEN_FULLSCREEN_HINT)
2198 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_FULLSCREEN_HINT\n"));
2199 if (pCmd->screen.flags & SVGA_SCREEN_DEACTIVATE )
2200 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_DEACTIVATE \n"));
2201 if (pCmd->screen.flags & SVGA_SCREEN_BLANKING)
2202 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_BLANKING\n"));
2203
2204 pThis->svga.iWidth = pCmd->screen.size.width;
2205 pThis->svga.iHeight = pCmd->screen.size.height;
2206 vmsvgaChangeMode(pThis);
2207 break;
2208 }
2209
2210 case SVGA_CMD_DESTROY_SCREEN:
2211 {
2212 SVGAFifoCmdDestroyScreen *pCmd = (SVGAFifoCmdDestroyScreen *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdDestroyScreen), &size, &pBounceBuffer);
2213
2214 Log(("vmsvgaFIFOLoop: SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId));
2215 break;
2216 }
2217#ifdef VBOX_WITH_VMSVGA3D
2218 case SVGA_CMD_DEFINE_GMRFB:
2219 {
2220 SVGAFifoCmdDefineGMRFB *pCmd = (SVGAFifoCmdDefineGMRFB *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdDefineGMRFB), &size, &pBounceBuffer);
2221
2222 Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n", pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.s.bitsPerPixel, pCmd->format.s.colorDepth));
2223 pSVGAState->GMRFB.ptr = pCmd->ptr;
2224 pSVGAState->GMRFB.bytesPerLine = pCmd->bytesPerLine;
2225 pSVGAState->GMRFB.format = pCmd->format;
2226 break;
2227 }
2228
2229 case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
2230 {
2231 SVGAFifoCmdBlitGMRFBToScreen *pCmd = (SVGAFifoCmdBlitGMRFBToScreen *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdBlitGMRFBToScreen), &size, &pBounceBuffer);
2232 int32_t width, height;
2233
2234 Log(("vmsvgaFIFOLoop: SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n", pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom));
2235
2236 /* @todo */
2237 AssertBreak(pSVGAState->GMRFB.format.s.bitsPerPixel == pThis->svga.iBpp);
2238 AssertBreak(pCmd->destScreenId == 0);
2239
2240 if (pCmd->destRect.left < 0)
2241 pCmd->destRect.left = 0;
2242 if (pCmd->destRect.top < 0)
2243 pCmd->destRect.top = 0;
2244 if (pCmd->destRect.right < 0)
2245 pCmd->destRect.right = 0;
2246 if (pCmd->destRect.bottom < 0)
2247 pCmd->destRect.bottom = 0;
2248
2249 width = pCmd->destRect.right - pCmd->destRect.left;
2250 height = pCmd->destRect.bottom - pCmd->destRect.top;
2251
2252 if ( width == 0
2253 || height == 0)
2254 break; /* Nothing to do. */
2255
2256 /* Clip to screen dimensions. */
2257 if (width > pThis->svga.iWidth)
2258 width = pThis->svga.iWidth;
2259 if (height > pThis->svga.iHeight)
2260 height = pThis->svga.iHeight;
2261
2262 unsigned offsetSource = (pCmd->srcOrigin.x * pSVGAState->GMRFB.format.s.bitsPerPixel) / 8 + pSVGAState->GMRFB.bytesPerLine * pCmd->srcOrigin.y;
2263 unsigned offsetDest = (pCmd->destRect.left * RT_ALIGN(pThis->svga.iBpp, 8)) / 8 + pThis->svga.cbScanline * pCmd->destRect.top;
2264 unsigned cbCopyWidth = (width * RT_ALIGN(pThis->svga.iBpp, 8)) / 8;
2265
2266 rc = vmsvgaGMRTransfer(pThis, SVGA3D_WRITE_HOST_VRAM, pThis->CTX_SUFF(vram_ptr) + offsetDest, pThis->svga.cbScanline, pSVGAState->GMRFB.ptr, offsetSource, pSVGAState->GMRFB.bytesPerLine, cbCopyWidth, height);
2267 AssertRC(rc);
2268
2269 vgaR3UpdateDisplay(pThis, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right - pCmd->destRect.left, pCmd->destRect.bottom - pCmd->destRect.top);
2270 break;
2271 }
2272
2273 case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
2274 {
2275 SVGAFifoCmdBlitScreenToGMRFB *pCmd = (SVGAFifoCmdBlitScreenToGMRFB *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdBlitScreenToGMRFB), &size, &pBounceBuffer);
2276
2277 /* @note this can fetch 3d render results as well!! */
2278 Log(("vmsvgaFIFOLoop: SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n", pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom));
2279 AssertFailed();
2280 break;
2281 }
2282#endif // VBOX_WITH_VMSVGA3D
2283 case SVGA_CMD_ANNOTATION_FILL:
2284 {
2285 SVGAFifoCmdAnnotationFill *pCmd = (SVGAFifoCmdAnnotationFill *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdAnnotationFill), &size, &pBounceBuffer);
2286
2287 Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.s.r, pCmd->color.s.g, pCmd->color.s.b));
2288 pSVGAState->colorAnnotation = pCmd->color;
2289 break;
2290 }
2291
2292 case SVGA_CMD_ANNOTATION_COPY:
2293 {
2294 SVGAFifoCmdAnnotationCopy *pCmd = (SVGAFifoCmdAnnotationCopy*)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGAFifoCmdAnnotationCopy), &size, &pBounceBuffer);
2295
2296 Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_COPY\n"));
2297 AssertFailed();
2298 break;
2299 }
2300
2301 default:
2302#ifdef VBOX_WITH_VMSVGA3D
2303 if ( pFIFO[u32Cmd] >= SVGA_3D_CMD_BASE
2304 && pFIFO[u32Cmd] < SVGA_3D_CMD_MAX)
2305 {
2306 /* All 3d commands start with a common header, which defines the size of the command. */
2307 SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)vmsvgaFIFOGetCmdBuffer(pFIFO, sizeof(SVGA3dCmdHeader), &size, &pBounceBuffer);
2308 uint32_t cbCmd;
2309
2310 /* Refetch the command buffer with the variable data; undo size increase (ugly) */
2311 cbCmd = sizeof(SVGA3dCmdHeader) + pHdr->size;
2312 size = sizeof(uint32_t); /* command dword */
2313 if (pBounceBuffer)
2314 RTMemFree(pBounceBuffer);
2315 pHdr = (SVGA3dCmdHeader *)vmsvgaFIFOGetCmdBuffer(pFIFO, cbCmd, &size, &pBounceBuffer);
2316
2317 switch (pFIFO[u32Cmd])
2318 {
2319 case SVGA_3D_CMD_SURFACE_DEFINE:
2320 {
2321 SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)(pHdr + 1);
2322 uint32_t cMipLevels;
2323
2324 cMipLevels = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dSize);
2325 rc = vmsvga3dSurfaceDefine(pThis, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0, SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1));
2326#ifdef DEBUG_GMR_ACCESS
2327 VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaResetGMRHandlers, 1, pThis);
2328#endif
2329 break;
2330 }
2331
2332 case SVGA_3D_CMD_SURFACE_DEFINE_V2:
2333 {
2334 SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)(pHdr + 1);
2335 uint32_t cMipLevels;
2336
2337 cMipLevels = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dSize);
2338 rc = vmsvga3dSurfaceDefine(pThis, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face, pCmd->multisampleCount, pCmd->autogenFilter, cMipLevels, (SVGA3dSize *)(pCmd + 1));
2339 break;
2340 }
2341
2342 case SVGA_3D_CMD_SURFACE_DESTROY:
2343 {
2344 SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)(pHdr + 1);
2345 rc = vmsvga3dSurfaceDestroy(pThis, pCmd->sid);
2346 break;
2347 }
2348
2349 case SVGA_3D_CMD_SURFACE_COPY:
2350 {
2351 SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)(pHdr + 1);
2352 uint32_t cCopyBoxes;
2353
2354 cCopyBoxes = (pHdr->size - sizeof(pCmd)) / sizeof(SVGA3dCopyBox);
2355 rc = vmsvga3dSurfaceCopy(pThis, pCmd->dest, pCmd->src, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
2356 break;
2357 }
2358
2359 case SVGA_3D_CMD_SURFACE_STRETCHBLT:
2360 {
2361 SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)(pHdr + 1);
2362
2363 rc = vmsvga3dSurfaceStretchBlt(pThis, pCmd->dest, pCmd->boxDest, pCmd->src, pCmd->boxSrc, pCmd->mode);
2364 break;
2365 }
2366
2367 case SVGA_3D_CMD_SURFACE_DMA:
2368 {
2369 SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)(pHdr + 1);
2370 uint32_t cCopyBoxes;
2371
2372 cCopyBoxes = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox);
2373 STAM_PROFILE_START(&pSVGAState->StatR3CmdSurfaceDMA, a);
2374 rc = vmsvga3dSurfaceDMA(pThis, pCmd->guest, pCmd->host, pCmd->transfer, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
2375 STAM_PROFILE_STOP(&pSVGAState->StatR3CmdSurfaceDMA, a);
2376 break;
2377 }
2378
2379 case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
2380 {
2381 SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)(pHdr + 1);
2382 uint32_t cRects;
2383
2384 cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGASignedRect);
2385 rc = vmsvga3dSurfaceBlitToScreen(pThis, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage, pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1));
2386 break;
2387 }
2388
2389 case SVGA_3D_CMD_CONTEXT_DEFINE:
2390 {
2391 SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)(pHdr + 1);
2392
2393 rc = vmsvga3dContextDefine(pThis, pCmd->cid);
2394 break;
2395 }
2396
2397 case SVGA_3D_CMD_CONTEXT_DESTROY:
2398 {
2399 SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)(pHdr + 1);
2400
2401 rc = vmsvga3dContextDestroy(pThis, pCmd->cid);
2402 break;
2403 }
2404
2405 case SVGA_3D_CMD_SETTRANSFORM:
2406 {
2407 SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)(pHdr + 1);
2408
2409 rc = vmsvga3dSetTransform(pThis, pCmd->cid, pCmd->type, pCmd->matrix);
2410 break;
2411 }
2412
2413 case SVGA_3D_CMD_SETZRANGE:
2414 {
2415 SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)(pHdr + 1);
2416
2417 rc = vmsvga3dSetZRange(pThis, pCmd->cid, pCmd->zRange);
2418 break;
2419 }
2420
2421 case SVGA_3D_CMD_SETRENDERSTATE:
2422 {
2423 SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)(pHdr + 1);
2424 uint32_t cRenderStates;
2425
2426 cRenderStates = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dRenderState);
2427 rc = vmsvga3dSetRenderState(pThis, pCmd->cid, cRenderStates, (SVGA3dRenderState *)(pCmd + 1));
2428 break;
2429 }
2430
2431 case SVGA_3D_CMD_SETRENDERTARGET:
2432 {
2433 SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)(pHdr + 1);
2434
2435 rc = vmsvga3dSetRenderTarget(pThis, pCmd->cid, pCmd->type, pCmd->target);
2436 break;
2437 }
2438
2439 case SVGA_3D_CMD_SETTEXTURESTATE:
2440 {
2441 SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)(pHdr + 1);
2442 uint32_t cTextureStates;
2443
2444 cTextureStates = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dTextureState);
2445 rc = vmsvga3dSetTextureState(pThis, pCmd->cid, cTextureStates, (SVGA3dTextureState *)(pCmd + 1));
2446 break;
2447 }
2448
2449 case SVGA_3D_CMD_SETMATERIAL:
2450 {
2451 SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)(pHdr + 1);
2452
2453 rc = vmsvga3dSetMaterial(pThis, pCmd->cid, pCmd->face, &pCmd->material);
2454 break;
2455 }
2456
2457 case SVGA_3D_CMD_SETLIGHTDATA:
2458 {
2459 SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)(pHdr + 1);
2460
2461 rc = vmsvga3dSetLightData(pThis, pCmd->cid, pCmd->index, &pCmd->data);
2462 break;
2463 }
2464
2465 case SVGA_3D_CMD_SETLIGHTENABLED:
2466 {
2467 SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)(pHdr + 1);
2468
2469 rc = vmsvga3dSetLightEnabled(pThis, pCmd->cid, pCmd->index, pCmd->enabled);
2470 break;
2471 }
2472
2473 case SVGA_3D_CMD_SETVIEWPORT:
2474 {
2475 SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)(pHdr + 1);
2476
2477 rc = vmsvga3dSetViewPort(pThis, pCmd->cid, &pCmd->rect);
2478 break;
2479 }
2480
2481 case SVGA_3D_CMD_SETCLIPPLANE:
2482 {
2483 SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)(pHdr + 1);
2484
2485 rc = vmsvga3dSetClipPlane(pThis, pCmd->cid, pCmd->index, pCmd->plane);
2486 break;
2487 }
2488
2489 case SVGA_3D_CMD_CLEAR:
2490 {
2491 SVGA3dCmdClear *pCmd = (SVGA3dCmdClear *)(pHdr + 1);
2492 uint32_t cRects;
2493
2494 cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dRect);
2495 rc = vmsvga3dCommandClear(pThis, pCmd->cid, pCmd->clearFlag, pCmd->color, pCmd->depth, pCmd->stencil, cRects, (SVGA3dRect *)(pCmd + 1));
2496 break;
2497 }
2498
2499 case SVGA_3D_CMD_PRESENT:
2500 {
2501 SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)(pHdr + 1);
2502 uint32_t cRects;
2503
2504 cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dCopyRect);
2505
2506 STAM_PROFILE_START(&pSVGAState->StatR3CmdPresent, a);
2507 rc = vmsvga3dCommandPresent(pThis, pCmd->sid, cRects, (SVGA3dCopyRect *)(pCmd + 1));
2508 STAM_PROFILE_STOP(&pSVGAState->StatR3CmdPresent, a);
2509 break;
2510 }
2511
2512 case SVGA_3D_CMD_SHADER_DEFINE:
2513 {
2514 SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)(pHdr + 1);
2515 uint32_t cbData;
2516
2517 cbData = (pHdr->size - sizeof(*pCmd));
2518 rc = vmsvga3dShaderDefine(pThis, pCmd->cid, pCmd->shid, pCmd->type, cbData, (uint32_t *)(pCmd + 1));
2519 break;
2520 }
2521
2522 case SVGA_3D_CMD_SHADER_DESTROY:
2523 {
2524 SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)(pHdr + 1);
2525
2526 rc = vmsvga3dShaderDestroy(pThis, pCmd->cid, pCmd->shid, pCmd->type);
2527 break;
2528 }
2529
2530 case SVGA_3D_CMD_SET_SHADER:
2531 {
2532 SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)(pHdr + 1);
2533
2534 rc = vmsvga3dShaderSet(pThis, pCmd->cid, pCmd->type, pCmd->shid);
2535 break;
2536 }
2537
2538 case SVGA_3D_CMD_SET_SHADER_CONST:
2539 {
2540 SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)(pHdr + 1);
2541
2542 uint32_t cRegisters = (pHdr->size - sizeof(*pCmd)) / sizeof(pCmd->values) + 1;
2543 rc = vmsvga3dShaderSetConst(pThis, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values);
2544 break;
2545 }
2546
2547 case SVGA_3D_CMD_DRAW_PRIMITIVES:
2548 {
2549 SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)(pHdr + 1);
2550 uint32_t cVertexDivisor;
2551
2552 cVertexDivisor = (pHdr->size - sizeof(*pCmd) - sizeof(SVGA3dVertexDecl) * pCmd->numVertexDecls - sizeof(SVGA3dPrimitiveRange) * pCmd->numRanges);
2553 Assert(pCmd->numRanges <= SVGA3D_MAX_DRAW_PRIMITIVE_RANGES);
2554 Assert(pCmd->numVertexDecls <= SVGA3D_MAX_VERTEX_ARRAYS);
2555 Assert(!cVertexDivisor || cVertexDivisor == pCmd->numVertexDecls);
2556
2557 SVGA3dVertexDecl *pVertexDecl = (SVGA3dVertexDecl *)(pCmd + 1);
2558 SVGA3dPrimitiveRange *pNumRange = (SVGA3dPrimitiveRange *) (&pVertexDecl[pCmd->numVertexDecls]);
2559 SVGA3dVertexDivisor *pVertexDivisor = (cVertexDivisor) ? (SVGA3dVertexDivisor *)(&pNumRange[pCmd->numRanges]) : NULL;
2560
2561 STAM_PROFILE_START(&pSVGAState->StatR3CmdDrawPrimitive, a);
2562 rc = vmsvga3dDrawPrimitives(pThis, pCmd->cid, pCmd->numVertexDecls, pVertexDecl, pCmd->numRanges, pNumRange, cVertexDivisor, pVertexDivisor);
2563 STAM_PROFILE_STOP(&pSVGAState->StatR3CmdDrawPrimitive, a);
2564 break;
2565 }
2566
2567 case SVGA_3D_CMD_SETSCISSORRECT:
2568 {
2569 SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)(pHdr + 1);
2570
2571 rc = vmsvga3dSetScissorRect(pThis, pCmd->cid, &pCmd->rect);
2572 break;
2573 }
2574
2575 case SVGA_3D_CMD_BEGIN_QUERY:
2576 {
2577 SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)(pHdr + 1);
2578
2579 rc = vmsvga3dQueryBegin(pThis, pCmd->cid, pCmd->type);
2580 break;
2581 }
2582
2583 case SVGA_3D_CMD_END_QUERY:
2584 {
2585 SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)(pHdr + 1);
2586
2587 rc = vmsvga3dQueryEnd(pThis, pCmd->cid, pCmd->type, pCmd->guestResult);
2588 break;
2589 }
2590
2591 case SVGA_3D_CMD_WAIT_FOR_QUERY:
2592 {
2593 SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)(pHdr + 1);
2594
2595 rc = vmsvga3dQueryWait(pThis, pCmd->cid, pCmd->type, pCmd->guestResult);
2596 break;
2597 }
2598
2599 case SVGA_3D_CMD_GENERATE_MIPMAPS:
2600 {
2601 SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)(pHdr + 1);
2602
2603 rc = vmsvga3dGenerateMipmaps(pThis, pCmd->sid, pCmd->filter);
2604 break;
2605 }
2606
2607 case SVGA_3D_CMD_ACTIVATE_SURFACE:
2608 case SVGA_3D_CMD_DEACTIVATE_SURFACE:
2609 /* context id + surface id? */
2610 break;
2611 }
2612 }
2613 else
2614#endif // VBOX_WITH_VMSVGA3D
2615 AssertFailed();
2616 }
2617 if (pBounceBuffer)
2618 RTMemFree(pBounceBuffer);
2619
2620 /* Go to the next slot */
2621 if (u32Current + size >= pFIFO[SVGA_FIFO_MAX])
2622 ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MIN] + u32Current + size - pFIFO[SVGA_FIFO_MAX]);
2623 else
2624 ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], u32Current + size);
2625
2626 /* FIFO progress might trigger an interrupt. */
2627 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FIFO_PROGRESS)
2628 {
2629 Log(("vmsvgaFIFOLoop: fifo progress irq\n"));
2630 u32IrqStatus |= SVGA_IRQFLAG_FIFO_PROGRESS;
2631 }
2632
2633 /* Irq pending? */
2634 if (pThis->svga.u32IrqMask & u32IrqStatus)
2635 {
2636 Log(("vmsvgaFIFOLoop: Trigger interrupt with status %x\n", u32IrqStatus));
2637 ASMAtomicOrU32(&pThis->svga.u32IrqStatus, u32IrqStatus);
2638 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
2639 }
2640 }
2641 /* Done? */
2642 if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
2643 {
2644 Log(("vmsvgaFIFOLoop: emptied the FIFO next=%x stop=%x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
2645 pThis->svga.fBusy = false;
2646 pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
2647 }
2648 }
2649 return VINF_SUCCESS;
2650}
2651
2652/**
2653 * Free the specified GMR
2654 *
2655 * @param pThis VGA device instance data.
2656 * @param idGMR GMR id
2657 */
2658void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR)
2659{
2660 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
2661
2662 /* Free the old descriptor if present. */
2663 if (pSVGAState->aGMR[idGMR].numDescriptors)
2664 {
2665#ifdef DEBUG_GMR_ACCESS
2666 VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaUnregisterGMR, 2, pThis->pDevInsR3, idGMR);
2667#endif
2668
2669 Assert(pSVGAState->aGMR[idGMR].paDesc);
2670 RTMemFree(pSVGAState->aGMR[idGMR].paDesc);
2671 pSVGAState->aGMR[idGMR].paDesc = NULL;
2672 pSVGAState->aGMR[idGMR].numDescriptors = 0;
2673 pSVGAState->aGMR[idGMR].cbTotal = 0;
2674 }
2675 Assert(!pSVGAState->aGMR[idGMR].cbTotal);
2676}
2677
2678/**
2679 * Copy from a GMR to host memory or vice versa
2680 *
2681 * @returns VBox status code.
2682 * @param pThis VGA device instance data.
2683 * @param transfer Transfer type (read/write)
2684 * @param pDest Host destination pointer
2685 * @param cbDestPitch Destination buffer pitch
2686 * @param src GMR description
2687 * @param cbSrcOffset Source buffer offset
2688 * @param cbSrcPitch Source buffer pitch
2689 * @param cbWidth Source width in bytes
2690 * @param cHeight Source height
2691 */
2692int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType transfer, uint8_t *pDest, uint32_t cbDestPitch, SVGAGuestPtr src, uint32_t cbSrcOffset, uint32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight)
2693{
2694 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
2695 PGMR pGMR;
2696 int rc;
2697 PVMSVGAGMRDESCRIPTOR pDesc;
2698 unsigned uDescOffset = 0;
2699
2700 Log(("vmsvgaGMRTransfer: gmr=%x offset=%x pitch=%d cbWidth=%d cHeight=%d; src offset=%d src pitch=%d\n", src.gmrId, src.offset, cbDestPitch, cbWidth, cHeight, cbSrcOffset, cbSrcPitch));
2701 Assert(cbWidth && cHeight);
2702
2703 /* Shortcut for the framebuffer. */
2704 if (src.gmrId == SVGA_GMR_FRAMEBUFFER)
2705 {
2706 cbSrcOffset += src.offset;
2707 AssertReturn(cbSrcOffset + cbSrcPitch * (cHeight - 1) + cbWidth <= pThis->vram_size, VERR_INVALID_PARAMETER);
2708
2709 uint8_t *pSrc = pThis->CTX_SUFF(vram_ptr) + cbSrcOffset;
2710
2711 if (transfer == SVGA3D_READ_HOST_VRAM)
2712 {
2713 /* switch src & dest */
2714 uint8_t *pTemp = pDest;
2715 uint32_t cbTempPitch = cbDestPitch;
2716
2717 pDest = pSrc;
2718 pSrc = pTemp;
2719
2720 cbDestPitch = cbSrcPitch;
2721 cbSrcPitch = cbTempPitch;
2722 }
2723
2724 if ( pThis->svga.cbScanline == cbDestPitch
2725 && cbWidth == cbDestPitch)
2726 {
2727 memcpy(pDest, pSrc, cbWidth * cHeight);
2728 }
2729 else
2730 {
2731 for(uint32_t i = 0; i < cHeight; i++)
2732 {
2733 memcpy(pDest, pSrc, cbWidth);
2734
2735 pDest += cbDestPitch;
2736 pSrc += cbSrcPitch;
2737 }
2738 }
2739 return VINF_SUCCESS;
2740 }
2741
2742 AssertReturn(src.gmrId < VMSVGA_MAX_GMR_IDS, VERR_INVALID_PARAMETER);
2743 pGMR = &pSVGAState->aGMR[src.gmrId];
2744 pDesc = pGMR->paDesc;
2745
2746 cbSrcOffset += src.offset;
2747 AssertReturn(cbSrcOffset + cbSrcPitch * (cHeight - 1) + cbWidth <= pGMR->cbTotal, VERR_INVALID_PARAMETER);
2748
2749 for (unsigned i = 0; i < cHeight; i++)
2750 {
2751 unsigned cbCurrentWidth = cbWidth;
2752 unsigned uCurrentOffset = cbSrcOffset;
2753 uint8_t *pCurrentDest = pDest;
2754
2755 /* Find the right descriptor */
2756 while (uDescOffset + pDesc->numPages * PAGE_SIZE <= uCurrentOffset)
2757 {
2758 uDescOffset += pDesc->numPages * PAGE_SIZE;
2759 AssertReturn(uDescOffset < pGMR->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
2760 pDesc++;
2761 }
2762
2763 while (cbCurrentWidth)
2764 {
2765 unsigned cbToCopy;
2766
2767 if (uCurrentOffset + cbCurrentWidth <= uDescOffset + pDesc->numPages * PAGE_SIZE)
2768 cbToCopy = cbCurrentWidth;
2769 else
2770 cbToCopy = (uDescOffset + pDesc->numPages * PAGE_SIZE - uCurrentOffset);
2771
2772 LogFlow(("vmsvgaGMRTransfer: %s phys=%RGp\n", (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", pDesc->GCPhys + uCurrentOffset - uDescOffset));
2773
2774 if (transfer == SVGA3D_WRITE_HOST_VRAM)
2775 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + uCurrentOffset - uDescOffset, pCurrentDest, cbToCopy);
2776 else
2777 rc = PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + uCurrentOffset - uDescOffset, pCurrentDest, cbToCopy);
2778 AssertRCBreak(rc);
2779
2780 cbCurrentWidth -= cbToCopy;
2781 uCurrentOffset += cbToCopy;
2782 pCurrentDest += cbToCopy;
2783
2784 /* Go to the next descriptor if there's anything left. */
2785 if (cbCurrentWidth)
2786 {
2787 uDescOffset += pDesc->numPages * PAGE_SIZE;
2788 pDesc++;
2789 }
2790 }
2791
2792 cbSrcOffset += cbSrcPitch;
2793 pDest += cbDestPitch;
2794 }
2795
2796 return VINF_SUCCESS;
2797}
2798
2799/**
2800 * Unblock the FIFO I/O thread so it can respond to a state change.
2801 *
2802 * @returns VBox status code.
2803 * @param pDevIns The VGA device instance.
2804 * @param pThread The send thread.
2805 */
2806static DECLCALLBACK(int) vmsvgaFIFOLoopWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
2807{
2808 PVGASTATE pThis = (PVGASTATE)pThread->pvUser;
2809 Log(("vmsvgaFIFOLoopWakeUp\n"));
2810 return RTSemEventSignal(pThis->svga.FIFORequestSem);
2811}
2812
2813/**
2814 * Enables or disables dirty page tracking for the framebuffer
2815 *
2816 * @param pThis VGA device instance data.
2817 * @param fTraces Enable/disable traces
2818 */
2819static void vmsvgaSetTraces(PVGASTATE pThis, bool fTraces)
2820{
2821 if ( (!pThis->svga.fConfigured || !pThis->svga.fEnabled)
2822 && !fTraces)
2823 {
2824 //Assert(pThis->svga.fTraces);
2825 Log(("vmsvgaSetTraces: *not* allowed to disable dirty page tracking when the device is in legacy mode.\n"));
2826 return;
2827 }
2828
2829 pThis->svga.fTraces = fTraces;
2830 if (pThis->svga.fTraces)
2831 {
2832 unsigned cbFrameBuffer = pThis->vram_size;
2833
2834 Log(("vmsvgaSetTraces: enable dirty page handling for the frame buffer only (%x bytes)\n", 0));
2835 if (pThis->svga.iHeight != -1)
2836 {
2837 Assert(pThis->svga.cbScanline);
2838 /* Hardware enabled; return real framebuffer size .*/
2839 cbFrameBuffer = (uint32_t)pThis->svga.iHeight * pThis->svga.cbScanline;
2840 cbFrameBuffer = RT_ALIGN(cbFrameBuffer, PAGE_SIZE);
2841 }
2842
2843 if (!pThis->svga.fVRAMTracking)
2844 {
2845 Log(("vmsvgaSetTraces: enable frame buffer dirty page tracking. (%x bytes; vram %x)\n", cbFrameBuffer, pThis->vram_size));
2846 vgaR3RegisterVRAMHandler(pThis, cbFrameBuffer);
2847 pThis->svga.fVRAMTracking = true;
2848 }
2849 }
2850 else
2851 {
2852 if (pThis->svga.fVRAMTracking)
2853 {
2854 Log(("vmsvgaSetTraces: disable frame buffer dirty page tracking\n"));
2855 vgaR3UnregisterVRAMHandler(pThis);
2856 pThis->svga.fVRAMTracking = false;
2857 }
2858 }
2859}
2860
2861/**
2862 * Callback function for mapping a PCI I/O region.
2863 *
2864 * @return VBox status code.
2865 * @param pPciDev Pointer to PCI device.
2866 * Use pPciDev->pDevIns to get the device instance.
2867 * @param iRegion The region number.
2868 * @param GCPhysAddress Physical address of the region.
2869 * If iType is PCI_ADDRESS_SPACE_IO, this is an
2870 * I/O port, else it's a physical address.
2871 * This address is *NOT* relative
2872 * to pci_mem_base like earlier!
2873 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
2874 */
2875DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
2876{
2877 int rc;
2878 PPDMDEVINS pDevIns = pPciDev->pDevIns;
2879 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
2880
2881 if (enmType == PCI_ADDRESS_SPACE_IO)
2882 {
2883 AssertReturn(iRegion == 0, VERR_INTERNAL_ERROR);
2884 rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0, vmsvgaIOWrite, vmsvgaIORead, NULL /* OutStr */, NULL /* InStr */, "VMSVGA");
2885 if (RT_FAILURE(rc))
2886 return rc;
2887
2888 pThis->svga.BasePort = GCPhysAddress;
2889 Log(("vmsvgaR3IORegionMap: base port = %x\n", pThis->svga.BasePort));
2890 }
2891 else
2892 {
2893 AssertReturn(iRegion == 2 && enmType == PCI_ADDRESS_SPACE_MEM, VERR_INTERNAL_ERROR);
2894 if (GCPhysAddress != NIL_RTGCPHYS)
2895 {
2896 /*
2897 * Mapping the FIFO RAM.
2898 */
2899 rc = PDMDevHlpMMIO2Map(pDevIns, iRegion, GCPhysAddress);
2900 AssertRC(rc);
2901
2902#ifdef DEBUG_FIFO_ACCESS
2903 if (RT_SUCCESS(rc))
2904 {
2905 rc = PGMR3HandlerPhysicalRegister(PDMDevHlpGetVM(pDevIns),
2906 PGMPHYSHANDLERTYPE_PHYSICAL_ALL,
2907 GCPhysAddress, GCPhysAddress + (VMSVGA_FIFO_SIZE - 1),
2908 vmsvgaR3FIFOAccessHandler, pThis,
2909 NULL, NULL, NULL,
2910 NULL, NULL, NULL,
2911 "VMSVGA FIFO");
2912 AssertRC(rc);
2913 }
2914#endif
2915 if (RT_SUCCESS(rc))
2916 {
2917 pThis->svga.GCPhysFIFO = GCPhysAddress;
2918 Log(("vmsvgaR3IORegionMap: FIFO address = %RGp\n", GCPhysAddress));
2919 }
2920 }
2921 else
2922 {
2923 Assert(pThis->svga.GCPhysFIFO);
2924#ifdef DEBUG_FIFO_ACCESS
2925 rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pDevIns), pThis->svga.GCPhysFIFO);
2926 AssertRC(rc);
2927#endif
2928 pThis->svga.GCPhysFIFO = 0;
2929 }
2930
2931 }
2932 return VINF_SUCCESS;
2933}
2934
2935
2936/**
2937 * @copydoc FNSSMDEVLOADEXEC
2938 */
2939int vmsvgaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
2940{
2941 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
2942 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
2943 int rc;
2944
2945 /* Load our part of the VGAState */
2946 rc = SSMR3GetStruct(pSSM, &pThis->svga, g_aVGAStateSVGAFields);
2947 AssertReturn(rc, rc);
2948
2949 /* Load the framebuffer backup. */
2950 rc = SSMR3GetMem(pSSM, pThis->svga.pFrameBufferBackup, VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
2951 AssertReturn(rc, rc);
2952
2953 /* Load the VMSVGA state. */
2954 rc = SSMR3GetStruct(pSSM, pSVGAState, g_aVMSVGASTATEFields);
2955 AssertReturn(rc, rc);
2956
2957 /* Save the GMR state */
2958 for (uint32_t i = 0; i < RT_ELEMENTS(pSVGAState->aGMR); i++)
2959 {
2960 rc = SSMR3GetStruct(pSSM, &pSVGAState->aGMR[i], g_aGMRFields);
2961 AssertReturn(rc, rc);
2962
2963 for (uint32_t j = 0; j < pSVGAState->aGMR[i].numDescriptors; j++)
2964 {
2965 rc = SSMR3GetStruct(pSSM, &pSVGAState->aGMR[i].paDesc[j], g_aVMSVGAGMRDESCRIPTORFields);
2966 AssertReturn(rc, rc);
2967 }
2968 }
2969
2970#ifdef VBOX_WITH_VMSVGA3D
2971 if ( uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA
2972 && pThis->svga.f3DEnabled)
2973 vmsvga3dLoadExec(pThis, pSSM, uVersion, uPass);
2974#endif
2975
2976 return VINF_SUCCESS;
2977}
2978
2979
2980/**
2981 * @copydoc FNSSMDEVSAVEEXEC
2982 */
2983int vmsvgaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
2984{
2985 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
2986 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
2987 int rc;
2988
2989 /* Save our part of the VGAState */
2990 rc = SSMR3PutStruct(pSSM, &pThis->svga, g_aVGAStateSVGAFields);
2991 AssertReturn(rc, rc);
2992
2993 /* Save the framebuffer backup. */
2994 rc = SSMR3PutMem(pSSM, pThis->svga.pFrameBufferBackup, VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
2995 AssertReturn(rc, rc);
2996
2997 /* Save the VMSVGA state. */
2998 rc = SSMR3PutStruct(pSSM, pSVGAState, g_aVMSVGASTATEFields);
2999 AssertReturn(rc, rc);
3000
3001 /* Save the GMR state */
3002 for (uint32_t i = 0; i < RT_ELEMENTS(pSVGAState->aGMR); i++)
3003 {
3004 rc = SSMR3PutStruct(pSSM, &pSVGAState->aGMR[i], g_aGMRFields);
3005 AssertReturn(rc, rc);
3006
3007 for (uint32_t j = 0; j < pSVGAState->aGMR[i].numDescriptors; j++)
3008 {
3009 rc = SSMR3PutStruct(pSSM, &pSVGAState->aGMR[i].paDesc[j], g_aVMSVGAGMRDESCRIPTORFields);
3010 AssertReturn(rc, rc);
3011 }
3012 }
3013
3014#ifdef VBOX_WITH_VMSVGA3D
3015 if (pThis->svga.f3DEnabled)
3016 vmsvga3dSaveExec(pThis, pSSM);
3017#endif
3018 return VINF_SUCCESS;
3019}
3020
3021/**
3022 * Cleans up the SVGA hardware state
3023 *
3024 * @returns VBox status code.
3025 * @param pDevIns The device instance.
3026 */
3027int vmsvgaDestruct(PPDMDEVINS pDevIns)
3028{
3029 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
3030 PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
3031
3032 if (pSVGAState)
3033 {
3034 for (unsigned i = 0; i < RT_ELEMENTS(pSVGAState->aGMR); i++)
3035 {
3036 if (pSVGAState->aGMR[i].paDesc)
3037 RTMemFree(pSVGAState->aGMR[i].paDesc);
3038 }
3039 RTMemFree(pSVGAState);
3040 }
3041
3042#ifdef VBOX_WITH_VMSVGA3D
3043 /** @todo */
3044 if (pThis->svga.f3DEnabled)
3045 vmsvga3dTerminate(pThis);
3046#endif
3047 return VINF_SUCCESS;
3048}
3049
3050/**
3051 * Initialize the SVGA hardware state
3052 *
3053 * @returns VBox status code.
3054 * @param pDevIns The device instance.
3055 */
3056int vmsvgaInit(PPDMDEVINS pDevIns)
3057{
3058 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
3059 PVMSVGASTATE pSVGAState;
3060 PVM pVM = PDMDevHlpGetVM(pDevIns);
3061 int rc;
3062
3063 pThis->svga.cScratchRegion = VMSVGA_SCRATCH_SIZE;
3064 memset(pThis->svga.au32ScratchRegion, 0, sizeof(pThis->svga.au32ScratchRegion));
3065
3066 pThis->svga.pSVGAState = RTMemAllocZ(sizeof(VMSVGASTATE));
3067 AssertReturn(pThis->svga.pSVGAState, VERR_NO_MEMORY);
3068 pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
3069
3070 /* Necessary for creating a backup of the text mode frame buffer when switching into svga mode. */
3071 pThis->svga.pFrameBufferBackup = RTMemAllocZ(VMSVGA_FRAMEBUFFER_BACKUP_SIZE);
3072 AssertReturn(pThis->svga.pFrameBufferBackup, VERR_NO_MEMORY);
3073
3074 /* Create event semaphore. */
3075 rc = RTSemEventCreate(&pThis->svga.FIFORequestSem);
3076 if (RT_FAILURE(rc))
3077 {
3078 Log(("%s: Failed to create event semaphore for FIFO handling.\n", __FUNCTION__));
3079 return rc;
3080 }
3081
3082 /* Register caps. */
3083 pThis->svga.u32RegCaps = SVGA_CAP_GMR | SVGA_CAP_GMR2 | SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 | SVGA_CAP_EXTENDED_FIFO | SVGA_CAP_IRQMASK | SVGA_CAP_PITCHLOCK | SVGA_CAP_TRACES | SVGA_CAP_SCREEN_OBJECT_2;
3084#ifdef VBOX_WITH_VMSVGA3D
3085 pThis->svga.u32RegCaps |= SVGA_CAP_3D;
3086#endif
3087
3088 /* Setup FIFO capabilities. */
3089 pThis->svga.pFIFOR3[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE | SVGA_FIFO_CAP_CURSOR_BYPASS_3 | SVGA_FIFO_CAP_GMR2 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED | SVGA_FIFO_CAP_SCREEN_OBJECT_2;
3090
3091 /* Valid with SVGA_FIFO_CAP_SCREEN_OBJECT_2 */
3092 pThis->svga.pFIFOR3[SVGA_FIFO_CURSOR_SCREEN_ID] = SVGA_ID_INVALID;
3093
3094 pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION] = pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION_REVISED] = 0; /* no 3d available. */
3095#ifdef VBOX_WITH_VMSVGA3D
3096 if (pThis->svga.f3DEnabled)
3097 {
3098 rc = vmsvga3dInit(pThis);
3099 if (RT_FAILURE(rc))
3100 pThis->svga.f3DEnabled = false;
3101 }
3102#endif
3103 /* VRAM tracking is enabled by default during bootup. */
3104 pThis->svga.fVRAMTracking = true;
3105
3106 /* Invalidate current settings. */
3107 pThis->svga.iWidth = -1;
3108 pThis->svga.iHeight = -1;
3109 pThis->svga.iBpp = -1;
3110 pThis->svga.cbScanline = 0;
3111
3112 pThis->svga.u32MaxWidth = VBE_DISPI_MAX_YRES;
3113 pThis->svga.u32MaxHeight = VBE_DISPI_MAX_XRES;
3114 while (pThis->svga.u32MaxWidth * pThis->svga.u32MaxHeight * 4 /* 32 bpp */ > pThis->vram_size)
3115 {
3116 pThis->svga.u32MaxWidth -= 256;
3117 pThis->svga.u32MaxHeight -= 256;
3118 }
3119 Log(("VMSVGA: Maximum size (%d,%d)\n", pThis->svga.u32MaxWidth, pThis->svga.u32MaxHeight));
3120
3121 /* Create the async IO thread. */
3122 rc = PDMDevHlpThreadCreate(pDevIns, &pThis->svga.pFIFOIOThread, pThis, vmsvgaFIFOLoop, vmsvgaFIFOLoopWakeUp, 0,
3123 RTTHREADTYPE_IO, "VMSVGA FIFO");
3124 if (RT_FAILURE(rc))
3125 {
3126 AssertMsgFailed(("%s: Async IO Thread creation for FIFO handling failed rc=%d\n", __FUNCTION__, rc));
3127 return rc;
3128 }
3129
3130 /*
3131 * Statistics.
3132 */
3133 STAM_REG(pVM, &pSVGAState->StatR3CmdPresent, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/Present", STAMUNIT_TICKS_PER_CALL, "Profiling of Present.");
3134 STAM_REG(pVM, &pSVGAState->StatR3CmdDrawPrimitive, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/DrawPrimitive", STAMUNIT_TICKS_PER_CALL, "Profiling of DrawPrimitive.");
3135 STAM_REG(pVM, &pSVGAState->StatR3CmdSurfaceDMA, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/SurfaceDMA", STAMUNIT_TICKS_PER_CALL, "Profiling of SurfaceDMA.");
3136
3137 return VINF_SUCCESS;
3138}
3139
3140
3141/**
3142 * Power On notification.
3143 *
3144 * @returns VBox status.
3145 * @param pDevIns The device instance data.
3146 *
3147 * @remarks Caller enters the device critical section.
3148 */
3149DECLCALLBACK(void) vmsvgaR3PowerOn(PPDMDEVINS pDevIns)
3150{
3151 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
3152 int rc;
3153#ifdef VBOX_WITH_VMSVGA3D
3154 if (pThis->svga.f3DEnabled)
3155 {
3156 rc = vmsvga3dPowerOn(pThis);
3157
3158 if (RT_SUCCESS(rc))
3159 {
3160 SVGA3dCapsRecord *pCaps;
3161 SVGA3dCapPair *pData;
3162 uint32_t idxCap = 0;
3163
3164 /* 3d hardware version; latest and greatest */
3165 pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION_REVISED] = SVGA3D_HWVERSION_CURRENT;
3166 pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION] = SVGA3D_HWVERSION_CURRENT;
3167
3168 pCaps = (SVGA3dCapsRecord *)&pThis->svga.pFIFOR3[SVGA_FIFO_3D_CAPS];
3169 pCaps->header.type = SVGA3DCAPS_RECORD_DEVCAPS;
3170 pData = (SVGA3dCapPair *)&pCaps->data;
3171
3172 /* Fill out all 3d capabilities. */
3173 for (unsigned i = 0; i < SVGA3D_DEVCAP_MAX; i++)
3174 {
3175 uint32_t val = 0;
3176
3177 rc = vmsvga3dQueryCaps(pThis, i, &val);
3178 if (RT_SUCCESS(rc))
3179 {
3180 pData[idxCap][0] = i;
3181 pData[idxCap][1] = val;
3182 idxCap++;
3183 }
3184 }
3185 pCaps->header.length = (sizeof(pCaps->header) + idxCap * sizeof(SVGA3dCapPair)) / sizeof(uint32_t);
3186 pCaps = (SVGA3dCapsRecord *)((uint32_t *)pCaps + pCaps->header.length);
3187
3188 /* Mark end of record array. */
3189 pCaps->header.length = 0;
3190 }
3191 }
3192#endif // VBOX_WITH_VMSVGA3D
3193}
3194
3195#endif /* IN_RING3 */
3196
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