VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h@ 77193

Last change on this file since 77193 was 77193, checked in by vboxsync, 6 years ago

Devices/DevVGA-SVGA: make FIFO polling thread sleep when idle.
bugref:9376: Complete hardware cursor implementation in VMSVGA.
This change adds an access handler for VMSVGA FIFO accesses (the first page
only, which starts with lots of register-type locations before the actual
FIFO begins) which is enabled when we have not seen any activity on the FIFO
for one second or changes to the cursor location registers. This extends
the old polling on the FIFO with increasing intervals by switching to the
handler when the interval increase reaches a maximum. After a single access
intercept the handler is disabled again and the polling interval reset to
minimum. The code contains debug assertions intended to test that we really
do switch correctly in both ways at the right time.
The change also fixes two FIFO access tests to also check the cursor
registers. Testing was done with DEBUG_FIFO_ACCESS enabled as well, which
also creates a FIFO access handler, to ensure that the changes to not break
that mode.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.2 KB
Line 
1/* $Id: DevVGA-SVGA.h 77193 2019-02-07 10:06:19Z vboxsync $ */
2/** @file
3 * VMware SVGA device
4 */
5/*
6 * Copyright (C) 2013-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#ifndef VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA_h
18#define VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA_h
19#ifndef RT_WITHOUT_PRAGMA_ONCE
20# pragma once
21#endif
22
23#ifndef VBOX_WITH_VMSVGA
24# error "VBOX_WITH_VMSVGA is not defined"
25#endif
26
27#include <VBox/vmm/pdmthread.h>
28
29#include "vmsvga/svga3d_reg.h"
30
31/** Default FIFO size. */
32#define VMSVGA_FIFO_SIZE _2M
33/** The old FIFO size. */
34#define VMSVGA_FIFO_SIZE_OLD _128K
35
36/** Default scratch region size. */
37#define VMSVGA_SCRATCH_SIZE 0x100
38/** Surface memory available to the guest. */
39#define VMSVGA_SURFACE_SIZE (512*1024*1024)
40/** Maximum GMR pages. */
41#define VMSVGA_MAX_GMR_PAGES 0x100000
42/** Maximum nr of GMR ids. */
43#define VMSVGA_MAX_GMR_IDS _8K
44/** Maximum number of GMR descriptors. */
45#define VMSVGA_MAX_GMR_DESC_LOOP_COUNT VMSVGA_MAX_GMR_PAGES
46
47#define VMSVGA_VAL_UNINITIALIZED (unsigned)-1
48
49/** For validating X and width values.
50 * The code assumes it's at least an order of magnitude less than UINT32_MAX. */
51#define VMSVGA_MAX_X _1M
52/** For validating Y and height values.
53 * The code assumes it's at least an order of magnitude less than UINT32_MAX. */
54#define VMSVGA_MAX_Y _1M
55
56/* u32ActionFlags */
57#define VMSVGA_ACTION_CHANGEMODE_BIT 0
58#define VMSVGA_ACTION_CHANGEMODE RT_BIT(VMSVGA_ACTION_CHANGEMODE_BIT)
59
60
61#ifdef DEBUG
62/* Enable to log FIFO register accesses. */
63//# define DEBUG_FIFO_ACCESS
64/* Enable to log GMR page accesses. */
65//# define DEBUG_GMR_ACCESS
66#endif
67
68#define VMSVGA_FIFO_EXTCMD_NONE 0
69#define VMSVGA_FIFO_EXTCMD_TERMINATE 1
70#define VMSVGA_FIFO_EXTCMD_SAVESTATE 2
71#define VMSVGA_FIFO_EXTCMD_LOADSTATE 3
72#define VMSVGA_FIFO_EXTCMD_RESET 4
73#define VMSVGA_FIFO_EXTCMD_UPDATE_SURFACE_HEAP_BUFFERS 5
74
75/** Size of the region to backup when switching into svga mode. */
76#define VMSVGA_VGA_FB_BACKUP_SIZE _512K
77
78/** @def VMSVGA_WITH_VGA_FB_BACKUP
79 * Enables correct VGA MMIO read/write handling when VMSVGA is enabled. It
80 * is SLOW and probably not entirely right, but it helps with getting 3dmark
81 * output and other stuff. */
82#define VMSVGA_WITH_VGA_FB_BACKUP 1
83
84/** @def VMSVGA_WITH_VGA_FB_BACKUP_AND_IN_RING3
85 * defined(VMSVGA_WITH_VGA_FB_BACKUP) && defined(IN_RING3) */
86#if (defined(VMSVGA_WITH_VGA_FB_BACKUP) && defined(IN_RING3)) || defined(DOXYGEN_RUNNING)
87# define VMSVGA_WITH_VGA_FB_BACKUP_AND_IN_RING3 1
88#else
89# undef VMSVGA_WITH_VGA_FB_BACKUP_AND_IN_RING3
90#endif
91
92/** @def VMSVGA_WITH_VGA_FB_BACKUP_AND_IN_RZ
93 * defined(VMSVGA_WITH_VGA_FB_BACKUP) && !defined(IN_RING3) */
94#if (defined(VMSVGA_WITH_VGA_FB_BACKUP) && !defined(IN_RING3)) || defined(DOXYGEN_RUNNING)
95# define VMSVGA_WITH_VGA_FB_BACKUP_AND_IN_RZ 1
96#else
97# undef VMSVGA_WITH_VGA_FB_BACKUP_AND_IN_RZ
98#endif
99
100
101typedef struct
102{
103 PSSMHANDLE pSSM;
104 uint32_t uVersion;
105 uint32_t uPass;
106} VMSVGA_STATE_LOAD;
107typedef VMSVGA_STATE_LOAD *PVMSVGA_STATE_LOAD;
108
109/** Host screen viewport.
110 * (4th quadrant with negated Y values - usual Windows and X11 world view.) */
111typedef struct VMSVGAVIEWPORT
112{
113 uint32_t x; /**< x coordinate (left). */
114 uint32_t y; /**< y coordinate (top). */
115 uint32_t cx; /**< width. */
116 uint32_t cy; /**< height. */
117 /** Right side coordinate (exclusive). Same as x + cx. */
118 uint32_t xRight;
119 /** First quadrant low y coordinate.
120 * Same as y + cy - 1 in window coordinates. */
121 uint32_t yLowWC;
122 /** First quadrant high y coordinate (exclusive) - yLowWC + cy.
123 * Same as y - 1 in window coordinates. */
124 uint32_t yHighWC;
125 /** Alignment padding. */
126 uint32_t uAlignment;
127} VMSVGAVIEWPORT;
128
129/**
130 * Screen object state.
131 */
132typedef struct VMSVGASCREENOBJECT
133{
134 /** SVGA_SCREEN_* flags. */
135 uint32_t fuScreen;
136 /** The screen object id. */
137 uint32_t idScreen;
138 /** The screen dimensions. */
139 int32_t xOrigin;
140 int32_t yOrigin;
141 uint32_t cWidth;
142 uint32_t cHeight;
143 /** Offset of the screen buffer in the guest VRAM. */
144 uint32_t offVRAM;
145 /** Scanline pitch. */
146 uint32_t cbPitch;
147 /** Bits per pixel. */
148 uint32_t cBpp;
149 bool fDefined;
150 bool fModified;
151} VMSVGASCREENOBJECT;
152
153/** Pointer to the private VMSVGA ring-3 state structure.
154 * @todo Still not entirely satisfired with the type name, but better than
155 * the previous lower/upper case only distinction. */
156typedef struct VMSVGAR3STATE *PVMSVGAR3STATE;
157/** Pointer to the private (implementation specific) VMSVGA3d state. */
158typedef struct VMSVGA3DSTATE *PVMSVGA3DSTATE;
159
160
161/**
162 * The VMSVGA device state.
163 *
164 * This instantatiated as VGASTATE::svga.
165 */
166typedef struct VMSVGAState
167{
168 /** The R3 FIFO pointer. */
169 R3PTRTYPE(uint32_t *) pFIFOR3;
170 /** The R0 FIFO pointer. */
171 R0PTRTYPE(uint32_t *) pFIFOR0;
172 /** R3 Opaque pointer to svga state. */
173 R3PTRTYPE(PVMSVGAR3STATE) pSvgaR3State;
174 /** R3 Opaque pointer to 3d state. */
175 R3PTRTYPE(PVMSVGA3DSTATE) p3dState;
176 /** The separate VGA frame buffer in svga mode.
177 * Unlike the the boch-based VGA device implementation, VMSVGA seems to have a
178 * separate frame buffer for VGA and allows concurrent use of both. The SVGA
179 * SDK is making use of this to do VGA text output while testing other things in
180 * SVGA mode, displaying the result by switching back to VGA text mode. So,
181 * when entering SVGA mode we copy the first part of the frame buffer here and
182 * direct VGA accesses here instead. It is copied back when leaving SVGA mode. */
183 R3PTRTYPE(uint8_t *) pbVgaFrameBufferR3;
184 /** R3 Opaque pointer to an external fifo cmd parameter. */
185 R3PTRTYPE(void * volatile) pvFIFOExtCmdParam;
186
187 /** Guest physical address of the FIFO memory range. */
188 RTGCPHYS GCPhysFIFO;
189 /** Size in bytes of the FIFO memory range.
190 * This may be smaller than cbFIFOConfig after restoring an old VM state. */
191 uint32_t cbFIFO;
192 /** The configured FIFO size. */
193 uint32_t cbFIFOConfig;
194 /** SVGA id. */
195 uint32_t u32SVGAId;
196 /** SVGA extensions enabled or not. */
197 uint32_t fEnabled;
198 /** SVGA memory area configured status. */
199 uint32_t fConfigured;
200 /** Device is busy handling FIFO requests (VMSVGA_BUSY_F_FIFO,
201 * VMSVGA_BUSY_F_EMT_FORCE). */
202 uint32_t volatile fBusy;
203#define VMSVGA_BUSY_F_FIFO RT_BIT_32(0) /**< The normal true/false busy FIFO bit. */
204#define VMSVGA_BUSY_F_EMT_FORCE RT_BIT_32(1) /**< Bit preventing race status flickering when EMT kicks the FIFO thread. */
205 /** Traces (dirty page detection) enabled or not. */
206 uint32_t fTraces;
207 /** Guest OS identifier. */
208 uint32_t u32GuestId;
209 /** Scratch region size (VMSVGAState::au32ScratchRegion). */
210 uint32_t cScratchRegion;
211 /** Irq status. */
212 uint32_t u32IrqStatus;
213 /** Irq mask. */
214 uint32_t u32IrqMask;
215 /** Pitch lock. */
216 uint32_t u32PitchLock;
217 /** Current GMR id. (SVGA_REG_GMR_ID) */
218 uint32_t u32CurrentGMRId;
219 /** Register caps. */
220 uint32_t u32RegCaps;
221 /** Physical address of command mmio range. */
222 RTIOPORT BasePort;
223 RTIOPORT Padding0;
224 /** Port io index register. */
225 uint32_t u32IndexReg;
226 /** The support driver session handle for use with FIFORequestSem. */
227 R3R0PTRTYPE(PSUPDRVSESSION) pSupDrvSession;
228 /** FIFO request semaphore. */
229 SUPSEMEVENT FIFORequestSem;
230 /** FIFO external command semaphore. */
231 R3PTRTYPE(RTSEMEVENT) FIFOExtCmdSem;
232 /** FIFO IO Thread. */
233 R3PTRTYPE(PPDMTHREAD) pFIFOIOThread;
234 /** The legacy GFB mode registers. If used, they correspond to screen 0. */
235 /** True when the guest modifies the GFB mode registers. */
236 bool fGFBRegisters;
237 bool afPadding[7];
238 uint32_t uWidth;
239 uint32_t uHeight;
240 uint32_t uBpp;
241 uint32_t cbScanline;
242 /** Maximum width supported. */
243 uint32_t u32MaxWidth;
244 /** Maximum height supported. */
245 uint32_t u32MaxHeight;
246 /** Viewport rectangle, i.e. what's currently visible of the target host
247 * window. This is usually (0,0)(uWidth,uHeight), but if the window is
248 * shrunk and scrolling applied, both the origin and size may differ. */
249 VMSVGAVIEWPORT viewport;
250 /** Action flags */
251 uint32_t u32ActionFlags;
252 /** SVGA 3d extensions enabled or not. */
253 bool f3DEnabled;
254 /** VRAM page monitoring enabled or not. */
255 bool fVRAMTracking;
256 /** External command to be executed in the FIFO thread. */
257 uint8_t volatile u8FIFOExtCommand;
258 /** Set by vmsvgaR3RunExtCmdOnFifoThread when it temporarily resumes the FIFO
259 * thread and does not want it do anything but the command. */
260 bool volatile fFifoExtCommandWakeup;
261// #if defined(DEBUG_GMR_ACCESS) /* Needed for alignment. */
262 /** GMR debug access handler type handle. */
263 PGMPHYSHANDLERTYPE hGmrAccessHandlerType;
264// #endif
265 /** FIFO debug access handler type handle. */
266 PGMPHYSHANDLERTYPE hFifoAccessHandlerType;
267 /** Number of GMRs. */
268 uint32_t cGMR;
269 uint32_t uScreenOffset; /* Used only for loading older saved states. */
270
271 /** Scratch array.
272 * Putting this at the end since it's big it probably not . */
273 uint32_t au32ScratchRegion[VMSVGA_SCRATCH_SIZE];
274
275 STAMCOUNTER StatRegBitsPerPixelWr;
276 STAMCOUNTER StatRegBusyWr;
277 STAMCOUNTER StatRegCursorXxxxWr;
278 STAMCOUNTER StatRegDepthWr;
279 STAMCOUNTER StatRegDisplayHeightWr;
280 STAMCOUNTER StatRegDisplayIdWr;
281 STAMCOUNTER StatRegDisplayIsPrimaryWr;
282 STAMCOUNTER StatRegDisplayPositionXWr;
283 STAMCOUNTER StatRegDisplayPositionYWr;
284 STAMCOUNTER StatRegDisplayWidthWr;
285 STAMCOUNTER StatRegEnableWr;
286 STAMCOUNTER StatRegGmrIdWr;
287 STAMCOUNTER StatRegGuestIdWr;
288 STAMCOUNTER StatRegHeightWr;
289 STAMCOUNTER StatRegIdWr;
290 STAMCOUNTER StatRegIrqMaskWr;
291 STAMCOUNTER StatRegNumDisplaysWr;
292 STAMCOUNTER StatRegNumGuestDisplaysWr;
293 STAMCOUNTER StatRegPaletteWr;
294 STAMCOUNTER StatRegPitchLockWr;
295 STAMCOUNTER StatRegPseudoColorWr;
296 STAMCOUNTER StatRegReadOnlyWr;
297 STAMCOUNTER StatRegScratchWr;
298 STAMCOUNTER StatRegSyncWr;
299 STAMCOUNTER StatRegTopWr;
300 STAMCOUNTER StatRegTracesWr;
301 STAMCOUNTER StatRegUnknownWr;
302 STAMCOUNTER StatRegWidthWr;
303
304 STAMCOUNTER StatRegBitsPerPixelRd;
305 STAMCOUNTER StatRegBlueMaskRd;
306 STAMCOUNTER StatRegBusyRd;
307 STAMCOUNTER StatRegBytesPerLineRd;
308 STAMCOUNTER StatRegCapabilitesRd;
309 STAMCOUNTER StatRegConfigDoneRd;
310 STAMCOUNTER StatRegCursorXxxxRd;
311 STAMCOUNTER StatRegDepthRd;
312 STAMCOUNTER StatRegDisplayHeightRd;
313 STAMCOUNTER StatRegDisplayIdRd;
314 STAMCOUNTER StatRegDisplayIsPrimaryRd;
315 STAMCOUNTER StatRegDisplayPositionXRd;
316 STAMCOUNTER StatRegDisplayPositionYRd;
317 STAMCOUNTER StatRegDisplayWidthRd;
318 STAMCOUNTER StatRegEnableRd;
319 STAMCOUNTER StatRegFbOffsetRd;
320 STAMCOUNTER StatRegFbSizeRd;
321 STAMCOUNTER StatRegFbStartRd;
322 STAMCOUNTER StatRegGmrIdRd;
323 STAMCOUNTER StatRegGmrMaxDescriptorLengthRd;
324 STAMCOUNTER StatRegGmrMaxIdsRd;
325 STAMCOUNTER StatRegGmrsMaxPagesRd;
326 STAMCOUNTER StatRegGreenMaskRd;
327 STAMCOUNTER StatRegGuestIdRd;
328 STAMCOUNTER StatRegHeightRd;
329 STAMCOUNTER StatRegHostBitsPerPixelRd;
330 STAMCOUNTER StatRegIdRd;
331 STAMCOUNTER StatRegIrqMaskRd;
332 STAMCOUNTER StatRegMaxHeightRd;
333 STAMCOUNTER StatRegMaxWidthRd;
334 STAMCOUNTER StatRegMemorySizeRd;
335 STAMCOUNTER StatRegMemRegsRd;
336 STAMCOUNTER StatRegMemSizeRd;
337 STAMCOUNTER StatRegMemStartRd;
338 STAMCOUNTER StatRegNumDisplaysRd;
339 STAMCOUNTER StatRegNumGuestDisplaysRd;
340 STAMCOUNTER StatRegPaletteRd;
341 STAMCOUNTER StatRegPitchLockRd;
342 STAMCOUNTER StatRegPsuedoColorRd;
343 STAMCOUNTER StatRegRedMaskRd;
344 STAMCOUNTER StatRegScratchRd;
345 STAMCOUNTER StatRegScratchSizeRd;
346 STAMCOUNTER StatRegSyncRd;
347 STAMCOUNTER StatRegTopRd;
348 STAMCOUNTER StatRegTracesRd;
349 STAMCOUNTER StatRegUnknownRd;
350 STAMCOUNTER StatRegVramSizeRd;
351 STAMCOUNTER StatRegWidthRd;
352 STAMCOUNTER StatRegWriteOnlyRd;
353} VMSVGAState;
354
355
356DECLCALLBACK(int) vmsvgaR3IORegionMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
357 RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType);
358
359DECLCALLBACK(void) vmsvgaPortSetViewport(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId,
360 uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
361
362int vmsvgaInit(PPDMDEVINS pDevIns);
363int vmsvgaReset(PPDMDEVINS pDevIns);
364int vmsvgaDestruct(PPDMDEVINS pDevIns);
365int vmsvgaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
366int vmsvgaLoadDone(PPDMDEVINS pDevIns);
367int vmsvgaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
368DECLCALLBACK(void) vmsvgaR3PowerOn(PPDMDEVINS pDevIns);
369DECLCALLBACK(void) vmsvgaR3PowerOff(PPDMDEVINS pDevIns);
370
371typedef struct VGAState *PVGASTATE;
372
373#ifdef IN_RING3
374VMSVGASCREENOBJECT *vmsvgaGetScreenObject(PVGASTATE pThis, uint32_t idScreen);
375int vmsvgaUpdateScreen(PVGASTATE pThis, VMSVGASCREENOBJECT *pScreen, int x, int y, int w, int h);
376#endif
377
378void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR);
379int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType,
380 uint8_t *pbHstBuf, uint32_t cbHstBuf, uint32_t offHst, int32_t cbHstPitch,
381 SVGAGuestPtr gstPtr, uint32_t offGst, int32_t cbGstPitch,
382 uint32_t cbWidth, uint32_t cHeight);
383
384void vmsvgaClipCopyBox(const SVGA3dSize *pSizeSrc,
385 const SVGA3dSize *pSizeDest,
386 SVGA3dCopyBox *pBox);
387void vmsvgaClipBox(const SVGA3dSize *pSize,
388 SVGA3dBox *pBox);
389void vmsvgaClipRect(SVGASignedRect const *pBound,
390 SVGASignedRect *pRect);
391
392#endif /* !VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA_h */
393
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