DevVGA-SVGA.cpp revision 51163b26ef6e81898acf6db392f1ca751335f71b
/* $Id$ */
/** @file
* VMWare SVGA device.
*
* Logging levels guidelines for this and related files:
* - Log() for normal bits.
* - LogFlow() for more info.
* - Log2 for hex dump of cursor data.
* - Log3 for hex dump of shader code.
* - Log4 for hex dumps of 3D data.
*/
/*
* Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
#define VMSVGA_USE_EMT_HALT_CODE
#ifdef VMSVGA_USE_EMT_HALT_CODE
#endif
#include <iprt/semaphore.h>
#ifdef IN_RING3
#endif
#include <VBox/VBoxVideo.h>
#include <VBox/bioslogo.h>
/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
#include "DevVGA.h"
#ifdef DEBUG
/* Enable to log FIFO register accesses. */
//# define DEBUG_FIFO_ACCESS
/* Enable to log GMR page accesses. */
//# define DEBUG_GMR_ACCESS
#endif
#include "DevVGA-SVGA.h"
#include "vmsvga/svga_reg.h"
#include "vmsvga/svga_escape.h"
#include "vmsvga/svga_overlay.h"
#include "vmsvga/svga3d_reg.h"
#include "vmsvga/svga3d_caps.h"
#ifdef VBOX_WITH_VMSVGA3D
# include "DevVGA-SVGA3d.h"
#endif
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/**
* Macro for checking if a fixed FIFO register is valid according to the
* current FIFO configuration.
*
* @returns true / false.
* @param a_iIndex The fifo register index (like SVGA_FIFO_CAPABILITIES).
* @param a_offFifoMin A valid SVGA_FIFO_MIN value.
*/
#define VMSVGA_IS_VALID_FIFO_REG(a_iIndex, a_offFifoMin) ( ((a_iIndex) + 1) * sizeof(uint32_t) <= (a_offFifoMin) )
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/* 64-bit GMR descriptor */
typedef struct
{
/* GMR slot */
typedef struct
{
/* Internal SVGA state. */
typedef struct
{
struct
{
} GMRFB;
struct
{
bool fActive;
void *pData;
} Cursor;
#ifdef VMSVGA_USE_EMT_HALT_CODE
/** Number of EMTs in BusyDelayedEmts (quicker than scanning the set). */
uint32_t volatile cBusyDelayedEmts;
/** Set of EMTs that are */
#else
/** Number of EMTs waiting on hBusyDelayedEmts. */
uint32_t volatile cBusyDelayedEmts;
/** Semaphore that EMTs wait on when reading SVGA_REG_BUSY and the FIFO is
* busy (ugly). */
#endif
/** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */
} VMSVGASTATE, *PVMSVGASTATE;
#ifdef IN_RING3
/**
* SSM descriptor table for the VMSVGAGMRDESCRIPTOR structure.
*/
static SSMFIELD const g_aVMSVGAGMRDESCRIPTORFields[] =
{
};
/**
* SSM descriptor table for the GMR structure.
*/
static SSMFIELD const g_aGMRFields[] =
{
};
/**
* SSM descriptor table for the VMSVGASTATE structure.
*/
static SSMFIELD const g_aVMSVGASTATEFields[] =
{
#ifdef VMSVGA_USE_EMT_HALT_CODE
#else
#endif
};
/**
* SSM descriptor table for the VGAState.svga structure.
*/
static SSMFIELD const g_aVGAStateSVGAFields[] =
{
};
#endif /* IN_RING3 */
#ifdef LOG_ENABLED
/**
* Index register string name lookup
*
* @returns Index register string or "UNKNOWN"
* @param pThis VMSVGA State
*/
{
{
case SVGA_REG_ID:
return "SVGA_REG_ID";
case SVGA_REG_ENABLE:
return "SVGA_REG_ENABLE";
case SVGA_REG_WIDTH:
return "SVGA_REG_WIDTH";
case SVGA_REG_HEIGHT:
return "SVGA_REG_HEIGHT";
case SVGA_REG_MAX_WIDTH:
return "SVGA_REG_MAX_WIDTH";
case SVGA_REG_MAX_HEIGHT:
return "SVGA_REG_MAX_HEIGHT";
case SVGA_REG_DEPTH:
return "SVGA_REG_DEPTH";
case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
return "SVGA_REG_BITS_PER_PIXEL";
case SVGA_REG_HOST_BITS_PER_PIXEL: /* (Deprecated) */
return "SVGA_REG_HOST_BITS_PER_PIXEL";
case SVGA_REG_PSEUDOCOLOR:
return "SVGA_REG_PSEUDOCOLOR";
case SVGA_REG_RED_MASK:
return "SVGA_REG_RED_MASK";
case SVGA_REG_GREEN_MASK:
return "SVGA_REG_GREEN_MASK";
case SVGA_REG_BLUE_MASK:
return "SVGA_REG_BLUE_MASK";
case SVGA_REG_BYTES_PER_LINE:
return "SVGA_REG_BYTES_PER_LINE";
case SVGA_REG_VRAM_SIZE: /* VRAM size */
return "SVGA_REG_VRAM_SIZE";
case SVGA_REG_FB_START: /* Frame buffer physical address. */
return "SVGA_REG_FB_START";
case SVGA_REG_FB_OFFSET: /* Offset of the frame buffer in VRAM */
return "SVGA_REG_FB_OFFSET";
case SVGA_REG_FB_SIZE: /* Frame buffer size */
return "SVGA_REG_FB_SIZE";
case SVGA_REG_CAPABILITIES:
return "SVGA_REG_CAPABILITIES";
case SVGA_REG_MEM_START: /* FIFO start */
return "SVGA_REG_MEM_START";
case SVGA_REG_MEM_SIZE: /* FIFO size */
return "SVGA_REG_MEM_SIZE";
case SVGA_REG_CONFIG_DONE: /* Set when memory area configured */
return "SVGA_REG_CONFIG_DONE";
case SVGA_REG_SYNC: /* See "FIFO Synchronization Registers" */
return "SVGA_REG_SYNC";
case SVGA_REG_BUSY: /* See "FIFO Synchronization Registers" */
return "SVGA_REG_BUSY";
case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
return "SVGA_REG_GUEST_ID";
case SVGA_REG_SCRATCH_SIZE: /* Number of scratch registers */
return "SVGA_REG_SCRATCH_SIZE";
case SVGA_REG_MEM_REGS: /* Number of FIFO registers */
return "SVGA_REG_MEM_REGS";
case SVGA_REG_PITCHLOCK: /* Fixed pitch for all modes */
return "SVGA_REG_PITCHLOCK";
case SVGA_REG_IRQMASK: /* Interrupt mask */
return "SVGA_REG_IRQMASK";
case SVGA_REG_GMR_ID:
return "SVGA_REG_GMR_ID";
case SVGA_REG_GMR_DESCRIPTOR:
return "SVGA_REG_GMR_DESCRIPTOR";
case SVGA_REG_GMR_MAX_IDS:
return "SVGA_REG_GMR_MAX_IDS";
return "SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH";
case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
return "SVGA_REG_TRACES";
case SVGA_REG_GMRS_MAX_PAGES: /* Maximum number of 4KB pages for all GMRs */
return "SVGA_REG_GMRS_MAX_PAGES";
case SVGA_REG_MEMORY_SIZE: /* Total dedicated device memory excluding FIFO */
return "SVGA_REG_MEMORY_SIZE";
case SVGA_REG_TOP: /* Must be 1 more than the last register */
return "SVGA_REG_TOP";
case SVGA_PALETTE_BASE: /* Base of SVGA color map */
return "SVGA_PALETTE_BASE";
case SVGA_REG_CURSOR_ID:
return "SVGA_REG_CURSOR_ID";
case SVGA_REG_CURSOR_X:
return "SVGA_REG_CURSOR_X";
case SVGA_REG_CURSOR_Y:
return "SVGA_REG_CURSOR_Y";
case SVGA_REG_CURSOR_ON:
return "SVGA_REG_CURSOR_ON";
case SVGA_REG_NUM_GUEST_DISPLAYS:/* Number of guest displays in X/Y direction */
return "SVGA_REG_NUM_GUEST_DISPLAYS";
case SVGA_REG_DISPLAY_ID: /* Display ID for the following display attributes */
return "SVGA_REG_DISPLAY_ID";
case SVGA_REG_DISPLAY_IS_PRIMARY:/* Whether this is a primary display */
return "SVGA_REG_DISPLAY_IS_PRIMARY";
case SVGA_REG_DISPLAY_POSITION_X:/* The display position x */
return "SVGA_REG_DISPLAY_POSITION_X";
case SVGA_REG_DISPLAY_POSITION_Y:/* The display position y */
return "SVGA_REG_DISPLAY_POSITION_Y";
case SVGA_REG_DISPLAY_WIDTH: /* The display's width */
return "SVGA_REG_DISPLAY_WIDTH";
case SVGA_REG_DISPLAY_HEIGHT: /* The display's height */
return "SVGA_REG_DISPLAY_HEIGHT";
case SVGA_REG_NUM_DISPLAYS: /* (Deprecated) */
return "SVGA_REG_NUM_DISPLAYS";
default:
return "SVGA_SCRATCH_BASE reg";
return "SVGA_PALETTE_BASE reg";
return "UNKNOWN";
}
}
/**
* FIFO command name lookup
*
* @returns FIFO command string or "UNKNOWN"
* @param u32Cmd FIFO command
*/
{
switch (u32Cmd)
{
case SVGA_CMD_INVALID_CMD:
return "SVGA_CMD_INVALID_CMD";
case SVGA_CMD_UPDATE:
return "SVGA_CMD_UPDATE";
case SVGA_CMD_RECT_COPY:
return "SVGA_CMD_RECT_COPY";
case SVGA_CMD_DEFINE_CURSOR:
return "SVGA_CMD_DEFINE_CURSOR";
return "SVGA_CMD_DEFINE_ALPHA_CURSOR";
case SVGA_CMD_UPDATE_VERBOSE:
return "SVGA_CMD_UPDATE_VERBOSE";
case SVGA_CMD_FRONT_ROP_FILL:
return "SVGA_CMD_FRONT_ROP_FILL";
case SVGA_CMD_FENCE:
return "SVGA_CMD_FENCE";
case SVGA_CMD_ESCAPE:
return "SVGA_CMD_ESCAPE";
case SVGA_CMD_DEFINE_SCREEN:
return "SVGA_CMD_DEFINE_SCREEN";
case SVGA_CMD_DESTROY_SCREEN:
return "SVGA_CMD_DESTROY_SCREEN";
case SVGA_CMD_DEFINE_GMRFB:
return "SVGA_CMD_DEFINE_GMRFB";
return "SVGA_CMD_BLIT_GMRFB_TO_SCREEN";
return "SVGA_CMD_BLIT_SCREEN_TO_GMRFB";
case SVGA_CMD_ANNOTATION_FILL:
return "SVGA_CMD_ANNOTATION_FILL";
case SVGA_CMD_ANNOTATION_COPY:
return "SVGA_CMD_ANNOTATION_COPY";
case SVGA_CMD_DEFINE_GMR2:
return "SVGA_CMD_DEFINE_GMR2";
case SVGA_CMD_REMAP_GMR2:
return "SVGA_CMD_REMAP_GMR2";
return "SVGA_3D_CMD_SURFACE_DEFINE";
return "SVGA_3D_CMD_SURFACE_DESTROY";
case SVGA_3D_CMD_SURFACE_COPY:
return "SVGA_3D_CMD_SURFACE_COPY";
return "SVGA_3D_CMD_SURFACE_STRETCHBLT";
case SVGA_3D_CMD_SURFACE_DMA:
return "SVGA_3D_CMD_SURFACE_DMA";
return "SVGA_3D_CMD_CONTEXT_DEFINE";
return "SVGA_3D_CMD_CONTEXT_DESTROY";
case SVGA_3D_CMD_SETTRANSFORM:
return "SVGA_3D_CMD_SETTRANSFORM";
case SVGA_3D_CMD_SETZRANGE:
return "SVGA_3D_CMD_SETZRANGE";
return "SVGA_3D_CMD_SETRENDERSTATE";
return "SVGA_3D_CMD_SETRENDERTARGET";
return "SVGA_3D_CMD_SETTEXTURESTATE";
case SVGA_3D_CMD_SETMATERIAL:
return "SVGA_3D_CMD_SETMATERIAL";
case SVGA_3D_CMD_SETLIGHTDATA:
return "SVGA_3D_CMD_SETLIGHTDATA";
return "SVGA_3D_CMD_SETLIGHTENABLED";
case SVGA_3D_CMD_SETVIEWPORT:
return "SVGA_3D_CMD_SETVIEWPORT";
case SVGA_3D_CMD_SETCLIPPLANE:
return "SVGA_3D_CMD_SETCLIPPLANE";
case SVGA_3D_CMD_CLEAR:
return "SVGA_3D_CMD_CLEAR";
case SVGA_3D_CMD_PRESENT:
return "SVGA_3D_CMD_PRESENT";
return "SVGA_3D_CMD_SHADER_DEFINE";
return "SVGA_3D_CMD_SHADER_DESTROY";
case SVGA_3D_CMD_SET_SHADER:
return "SVGA_3D_CMD_SET_SHADER";
return "SVGA_3D_CMD_SET_SHADER_CONST";
return "SVGA_3D_CMD_DRAW_PRIMITIVES";
return "SVGA_3D_CMD_SETSCISSORRECT";
case SVGA_3D_CMD_BEGIN_QUERY:
return "SVGA_3D_CMD_BEGIN_QUERY";
case SVGA_3D_CMD_END_QUERY:
return "SVGA_3D_CMD_END_QUERY";
return "SVGA_3D_CMD_WAIT_FOR_QUERY";
return "SVGA_3D_CMD_PRESENT_READBACK";
return "SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN";
return "SVGA_3D_CMD_SURFACE_DEFINE_V2";
return "SVGA_3D_CMD_GENERATE_MIPMAPS";
return "SVGA_3D_CMD_ACTIVATE_SURFACE";
return "SVGA_3D_CMD_DEACTIVATE_SURFACE";
default:
return "UNKNOWN";
}
}
#endif
/**
* Inform the VGA device of viewport changes (as a result of e.g. scrolling)
*
* @param pInterface Pointer to this interface.
* @param
* @param uScreenId The screen updates are for.
* @param x The upper left corner x coordinate of the new viewport rectangle
* @param y The upper left corner y coordinate of the new viewport rectangle
* @param cx The width of the new viewport rectangle
* @param cy The height of the new viewport rectangle
* @thread The emulation thread.
*/
DECLCALLBACK(void) vmsvgaPortSetViewPort(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
{
return;
}
/**
* Read port register
*
* @returns VBox status code.
* @param pThis VMSVGA State
* @param pu32 Where to store the read value
*/
{
int rc = VINF_SUCCESS;
*pu32 = 0;
{
case SVGA_REG_ID:
break;
case SVGA_REG_ENABLE:
break;
case SVGA_REG_WIDTH:
{
{
}
else
{
#ifndef IN_RING3
#else
#endif
}
break;
}
case SVGA_REG_HEIGHT:
{
{
}
else
{
#ifndef IN_RING3
#else
#endif
}
break;
}
case SVGA_REG_MAX_WIDTH:
break;
case SVGA_REG_MAX_HEIGHT:
break;
case SVGA_REG_DEPTH:
/* This returns the color depth of the current mode. */
{
case 15:
case 16:
case 24:
break;
default:
case 32:
break;
}
break;
case SVGA_REG_HOST_BITS_PER_PIXEL: /* (Deprecated) */
{
}
else
{
#ifndef IN_RING3
#else
#endif
}
break;
case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
{
}
else
{
#ifndef IN_RING3
#else
#endif
}
break;
case SVGA_REG_PSEUDOCOLOR:
*pu32 = 0;
break;
case SVGA_REG_RED_MASK:
case SVGA_REG_GREEN_MASK:
case SVGA_REG_BLUE_MASK:
{
{
}
else
{
#ifndef IN_RING3
break;
#else
#endif
}
switch (uBpp)
{
case 8:
u32RedMask = 0x07;
u32GreenMask = 0x38;
u32BlueMask = 0xc0;
break;
case 15:
u32RedMask = 0x0000001f;
u32GreenMask = 0x000003e0;
u32BlueMask = 0x00007c00;
break;
case 16:
u32RedMask = 0x0000001f;
u32GreenMask = 0x000007e0;
u32BlueMask = 0x0000f800;
break;
case 24:
case 32:
default:
u32RedMask = 0x00ff0000;
u32GreenMask = 0x0000ff00;
u32BlueMask = 0x000000ff;
break;
}
{
case SVGA_REG_RED_MASK:
*pu32 = u32RedMask;
break;
case SVGA_REG_GREEN_MASK:
*pu32 = u32GreenMask;
break;
case SVGA_REG_BLUE_MASK:
*pu32 = u32BlueMask;
break;
}
break;
}
case SVGA_REG_BYTES_PER_LINE:
{
{
}
else
{
#ifndef IN_RING3
#else
#endif
}
break;
}
case SVGA_REG_VRAM_SIZE: /* VRAM size */
break;
case SVGA_REG_FB_START: /* Frame buffer physical address. */
break;
case SVGA_REG_FB_OFFSET: /* Offset of the frame buffer in VRAM */
/* Always zero in our case. */
*pu32 = 0;
break;
case SVGA_REG_FB_SIZE: /* Frame buffer size */
{
#ifndef IN_RING3
#else
/* VMWare testcases want at least 4 MB in case the hardware is disabled. */
{
/* Hardware enabled; return real framebuffer size .*/
}
else
#endif
break;
}
case SVGA_REG_CAPABILITIES:
break;
case SVGA_REG_MEM_START: /* FIFO start */
break;
case SVGA_REG_MEM_SIZE: /* FIFO size */
break;
case SVGA_REG_CONFIG_DONE: /* Set when memory area configured */
break;
case SVGA_REG_SYNC: /* See "FIFO Synchronization Registers" */
*pu32 = 0;
break;
case SVGA_REG_BUSY: /* See "FIFO Synchronization Registers" */
{
#ifndef IN_RING3
/* Go to ring-3 and halt the CPU. */
break;
#elif defined(VMSVGA_USE_EMT_HALT_CODE)
/* The guest is basically doing a HLT via the device here, but with
a special wake up condition on FIFO completion. */
VMCPUID idCpu = PDMDevHlpGetVMCPU(pThis->pDevInsR3)->idCpu; /** @todo add a separate dev helper for this. */
#else
/* Delay the EMT a bit so the FIFO and others can get some work done.
This used to be a crude 50 ms sleep. The current code tries to be
more efficient, but the consept is still very crude. */
{
{
* code in VMEmt.cpp here, otherwise all kind of EMT interaction will
* suffer when the guest is polling on a busy FIFO. */
if (cNsMaxWait >= RT_NS_100US)
}
}
#endif
}
else
*pu32 = false;
break;
case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
break;
case SVGA_REG_SCRATCH_SIZE: /* Number of scratch registers */
break;
case SVGA_REG_MEM_REGS: /* Number of FIFO registers */
break;
case SVGA_REG_PITCHLOCK: /* Fixed pitch for all modes */
break;
case SVGA_REG_IRQMASK: /* Interrupt mask */
break;
/* See "Guest memory regions" below. */
case SVGA_REG_GMR_ID:
break;
case SVGA_REG_GMR_DESCRIPTOR:
/* Write only */
*pu32 = 0;
break;
case SVGA_REG_GMR_MAX_IDS:
break;
break;
case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
break;
case SVGA_REG_GMRS_MAX_PAGES: /* Maximum number of 4KB pages for all GMRs */
break;
case SVGA_REG_MEMORY_SIZE: /* Total dedicated device memory excluding FIFO */
break;
case SVGA_REG_TOP: /* Must be 1 more than the last register */
break;
case SVGA_PALETTE_BASE: /* Base of SVGA color map */
break;
/* Next 768 (== 256*3) registers exist for colormap */
/* Mouse cursor support. */
case SVGA_REG_CURSOR_ID:
case SVGA_REG_CURSOR_X:
case SVGA_REG_CURSOR_Y:
case SVGA_REG_CURSOR_ON:
break;
/* Legacy multi-monitor support */
case SVGA_REG_NUM_GUEST_DISPLAYS:/* Number of guest displays in X/Y direction */
*pu32 = 1;
break;
case SVGA_REG_DISPLAY_ID: /* Display ID for the following display attributes */
case SVGA_REG_DISPLAY_IS_PRIMARY:/* Whether this is a primary display */
case SVGA_REG_DISPLAY_POSITION_X:/* The display position x */
case SVGA_REG_DISPLAY_POSITION_Y:/* The display position y */
*pu32 = 0;
break;
case SVGA_REG_DISPLAY_WIDTH: /* The display's width */
break;
case SVGA_REG_DISPLAY_HEIGHT: /* The display's height */
break;
case SVGA_REG_NUM_DISPLAYS: /* (Deprecated) */
*pu32 = 1; /* Must return something sensible here otherwise the Linux driver will take a legacy code path without 3d support. */
break;
default:
{
}
break;
}
Log(("vmsvgaReadPort index=%s (%d) val=%#x rc=%x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, *pu32, rc));
return rc;
}
#ifdef IN_RING3
/**
* Apply the current resolution settings to change the video mode.
*
* @returns VBox status code.
* @param pThis VMSVGA State
*/
{
int rc;
{
/* Mode change in progress; wait for all values to be set. */
Log(("vmsvgaChangeMode: BOGUS sEnable LFB mode and resize to (%d,%d) bpp=%d\n", pThis->svga.uWidth, pThis->svga.uHeight, pThis->svga.uBpp));
return VINF_SUCCESS;
}
{
/* Invalid mode change. */
Log(("vmsvgaChangeMode: BOGUS sEnable LFB mode and resize to (%d,%d) bpp=%d\n", pThis->svga.uWidth, pThis->svga.uHeight, pThis->svga.uBpp));
return VINF_SUCCESS;
}
)
{
/* Nothing to do. */
Log(("vmsvgaChangeMode: nothing changed; ignore\n"));
return VINF_SUCCESS;
}
Log(("vmsvgaChangeMode: sEnable LFB mode and resize to (%d,%d) bpp=%d\n", pThis->svga.uWidth, pThis->svga.uHeight, pThis->svga.uBpp));
rc = pThis->pDrv->pfnResize(pThis->pDrv, pThis->svga.uBpp, pThis->CTX_SUFF(vram_ptr), pThis->svga.cbScanline, pThis->svga.uWidth, pThis->svga.uHeight);
/* last stuff */
/* vmsvgaPortSetViewPort not called after state load; set sensible defaults. */
{
}
return VINF_SUCCESS;
}
#endif /* IN_RING3 */
/**
* Safely updates the SVGA_FIFO_BUSY register (in shared memory).
*
* @param pThis The VMSVGA state.
* @param fState The busy state.
*/
{
{
/* Race / unfortunately scheduling. Highly unlikly. */
do
{
ASMNopPause();
}
}
#endif
/**
* Write port register
*
* @returns VBox status code.
* @param pThis VMSVGA State
* @param u32 Value to write
*/
{
int rc = VINF_SUCCESS;
Log(("vmsvgaWritePort index=%s (%d) val=%#x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, u32));
{
case SVGA_REG_ID:
break;
case SVGA_REG_ENABLE:
)
/* Nothing to do. */
break;
#ifdef IN_RING3
if ( u32 == 1
{
/* Make a backup copy of the first 32k in order to save font data etc. */
}
{
{
/* Keep the current mode. */
}
{
}
/* Disable or enable dirty page tracking according to the current fTraces value. */
}
else
{
/* Restore the text mode backup. */
/* pThis->svga.uHeight = -1;
pThis->svga.uWidth = -1;
pThis->svga.uBpp = -1;
pThis->svga.cbScanline = 0; */
/* Enable dirty page tracking again when going into legacy mode. */
vmsvgaSetTraces(pThis, true);
}
#else
#endif
break;
case SVGA_REG_WIDTH:
{
{
#ifdef IN_RING3
#else
#endif
}
else
}
/* else: nop */
break;
case SVGA_REG_HEIGHT:
{
{
#ifdef IN_RING3
#else
#endif
}
else
}
/* else: nop */
break;
case SVGA_REG_DEPTH:
/** @todo read-only?? */
break;
case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
{
{
#ifdef IN_RING3
#else
#endif
}
else
}
/* else: nop */
break;
case SVGA_REG_PSEUDOCOLOR:
break;
case SVGA_REG_CONFIG_DONE: /* Set when memory area configured */
#ifdef IN_RING3
/* Disabling the FIFO enables tracing (dirty page detection) by default. */
{
}
#else
#endif
break;
case SVGA_REG_SYNC: /* See "FIFO Synchronization Registers" */
{
vmsvgaSafeFifoBusyRegUpdate(pThis, true);
/* Kick the FIFO thread to start processing commands again. */
#else
#endif
}
/* else nothing to do. */
else
break;
case SVGA_REG_BUSY: /* See "FIFO Synchronization Registers" (read-only) */
break;
case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
break;
case SVGA_REG_PITCHLOCK: /* Fixed pitch for all modes */
break;
case SVGA_REG_IRQMASK: /* Interrupt mask */
/* Irq pending after the above change? */
{
}
else
break;
/* Mouse cursor support */
case SVGA_REG_CURSOR_ID:
case SVGA_REG_CURSOR_X:
case SVGA_REG_CURSOR_Y:
case SVGA_REG_CURSOR_ON:
break;
/* Legacy multi-monitor support */
case SVGA_REG_NUM_GUEST_DISPLAYS:/* Number of guest displays in X/Y direction */
break;
case SVGA_REG_DISPLAY_ID: /* Display ID for the following display attributes */
break;
case SVGA_REG_DISPLAY_IS_PRIMARY:/* Whether this is a primary display */
break;
case SVGA_REG_DISPLAY_POSITION_X:/* The display position x */
break;
case SVGA_REG_DISPLAY_POSITION_Y:/* The display position y */
break;
case SVGA_REG_DISPLAY_WIDTH: /* The display's width */
break;
case SVGA_REG_DISPLAY_HEIGHT: /* The display's height */
break;
#ifdef VBOX_WITH_VMSVGA3D
/* See "Guest memory regions" below. */
case SVGA_REG_GMR_ID:
break;
case SVGA_REG_GMR_DESCRIPTOR:
# ifndef IN_RING3
break;
# else /* IN_RING3 */
{
uint32_t iDescriptor = 0;
/* Validate current GMR id. */
/* Free the old GMR if present. */
/* Just undefine the GMR? */
if (GCPhys == 0)
break;
pSVGAState->aGMR[idGMR].paDesc = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ(cDescriptorsAllocated * sizeof(VMSVGAGMRDESCRIPTOR));
/* Never cross a page boundary automatically. */
{
/* Read descriptor. */
break; /* terminator */
{
/* Pointer to the next physical page of descriptors. */
}
else
{
if (iDescriptor == cDescriptorsAllocated)
{
cDescriptorsAllocated += 16;
pSVGAState->aGMR[idGMR].paDesc = (PVMSVGAGMRDESCRIPTOR)RTMemRealloc(pSVGAState->aGMR[idGMR].paDesc, cDescriptorsAllocated * sizeof(VMSVGAGMRDESCRIPTOR));
}
/* Continue with the next descriptor. */
}
}
Log(("Defined new gmr %x numDescriptors=%d cbTotal=%x\n", idGMR, iDescriptor, pSVGAState->aGMR[idGMR].cbTotal));
{
AssertFailed();
}
break;
}
# endif /* IN_RING3 */
#endif // VBOX_WITH_VMSVGA3D
case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
break; /* nothing to do */
#ifdef IN_RING3
#else
#endif
break;
case SVGA_REG_TOP: /* Must be 1 more than the last register */
break;
case SVGA_PALETTE_BASE: /* Base of SVGA color map */
break;
/* Next 768 (== 256*3) registers exist for colormap */
case SVGA_REG_NUM_DISPLAYS: /* (Deprecated) */
break;
case SVGA_REG_FB_START:
case SVGA_REG_MEM_START:
case SVGA_REG_MAX_WIDTH:
case SVGA_REG_MAX_HEIGHT:
case SVGA_REG_VRAM_SIZE:
case SVGA_REG_FB_SIZE:
case SVGA_REG_CAPABILITIES:
case SVGA_REG_MEM_SIZE:
case SVGA_REG_SCRATCH_SIZE: /* Number of scratch registers */
case SVGA_REG_MEM_REGS: /* Number of FIFO registers */
case SVGA_REG_BYTES_PER_LINE:
case SVGA_REG_FB_OFFSET:
case SVGA_REG_RED_MASK:
case SVGA_REG_GREEN_MASK:
case SVGA_REG_BLUE_MASK:
case SVGA_REG_GMRS_MAX_PAGES: /* Maximum number of 4KB pages for all GMRs */
case SVGA_REG_MEMORY_SIZE: /* Total dedicated device memory excluding FIFO */
case SVGA_REG_GMR_MAX_IDS:
/* Read only - ignore. */
break;
default:
{
}
break;
}
return rc;
}
/**
* Port I/O Handler for IN operations.
*
* @returns VINF_SUCCESS or VINF_EM_*.
* @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
*
* @param pDevIns The device instance.
* @param pvUser User argument.
* @param uPort Port number used for the IN operation.
* @param pu32 Where to store the result. This is always a 32-bit
* variable regardless of what @a cb might say.
* @param cb Number of bytes read.
*/
PDMBOTHCBDECL(int) vmsvgaIORead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
int rc = VINF_SUCCESS;
/* Ignore non-dword accesses. */
if (cb != 4)
{
*pu32 = ~0;
return VINF_SUCCESS;
}
{
case SVGA_INDEX_PORT:
break;
case SVGA_VALUE_PORT:
case SVGA_BIOS_PORT:
Log(("Ignoring BIOS port read\n"));
*pu32 = 0;
break;
case SVGA_IRQSTATUS_PORT:
break;
}
return rc;
}
/**
* Port I/O Handler for OUT operations.
*
* @returns VINF_SUCCESS or VINF_EM_*.
*
* @param pDevIns The device instance.
* @param pvUser User argument.
* @param uPort Port number used for the OUT operation.
* @param u32 The value to output.
* @param cb The value size in bytes.
*/
PDMBOTHCBDECL(int) vmsvgaIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
int rc = VINF_SUCCESS;
/* Ignore non-dword accesses. */
if (cb != 4)
{
return VINF_SUCCESS;
}
{
case SVGA_INDEX_PORT:
break;
case SVGA_VALUE_PORT:
case SVGA_BIOS_PORT:
break;
case SVGA_IRQSTATUS_PORT:
Log(("vmsvgaIOWrite SVGA_IRQSTATUS_PORT %x: status %x -> %x\n", u32, pThis->svga.u32IrqStatus, pThis->svga.u32IrqStatus & ~u32));
/* Clear the irq in case all events have been cleared. */
PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
break;
}
return rc;
}
#ifdef DEBUG_FIFO_ACCESS
# ifdef IN_RING3
/**
* Handle LFB access.
* @returns VBox status code.
* @param pVM VM handle.
* @param pThis VGA device instance data.
* @param GCPhys The access physical address.
* @param fWriteAccess Read or write access
*/
{
switch (GCPhysOffset >> 2)
{
case SVGA_FIFO_MIN:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_MIN = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_MAX:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_MAX = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_NEXT_CMD:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_NEXT_CMD = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_STOP:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_STOP = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_CAPABILITIES:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CAPABILITIES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_FLAGS:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_FLAGS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_FENCE:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_FENCE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_3D_HWVERSION:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_HWVERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_PITCHLOCK:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_PITCHLOCK = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_CURSOR_ON:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_ON = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_CURSOR_X:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_X = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_CURSOR_Y:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_Y = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_CURSOR_COUNT:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_COUNT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_LAST_UPDATED = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_RESERVED:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_RESERVED = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_CURSOR_SCREEN_ID = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_DEAD:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_DEAD = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_HWVERSION_REVISED = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_3D_CAPS + SVGA3D_DEVCAP_3D:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_3D = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_LIGHTS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_CLIP_PLANES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_VERTEX_SHADER_VERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_VERTEX_SHADER = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_FRAGMENT_SHADER = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_RENDER_TARGETS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_S23E8_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_S10E5_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_D16_BUFFER_FORMAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_QUERY_TYPES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_POINT_SIZE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_SHADER_TEXTURES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VOLUME_EXTENT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
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]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_VERTEX_INDEX = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
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]));
break;
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]));
break;
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]));
break;
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]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_TEXTURE_OPS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT1 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT2 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT3 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT4 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_DXT5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
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]));
break;
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]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_V16U16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_G16R16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_UYVY = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_YUY2 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_ALPHATOCOVERAGE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SUPERSAMPLE = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_AUTOGENMIPMAPS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_NV12 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_AYUV = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_CONTEXT_IDS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_MAX_SURFACE_IDS = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
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]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_3D_CAPS_LAST:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_3D_CAPS_LAST = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_GUEST_3D_HWVERSION = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_FENCE_GOAL:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_FENCE_GOAL = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
case SVGA_FIFO_BUSY:
Log(("vmsvgaFIFOAccess [0x%x]: %s SVGA_FIFO_BUSY = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", pFIFO[GCPhysOffset >> 2]));
break;
default:
Log(("vmsvgaFIFOAccess [0x%x]: %s access at offset %x = %x\n", GCPhysOffset >> 2, (fWriteAccess) ? "WRITE" : "READ", GCPhysOffset, pFIFO[GCPhysOffset >> 2]));
break;
}
return VINF_EM_RAW_EMULATE_INSTR;
}
/**
* HC access handler for the FIFO.
*
* @returns VINF_SUCCESS if the handler have carried out the operation.
* @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
* @param pVM VM Handle.
* @param GCPhys The physical address the guest is writing to.
* @param pvPhys The HC mapping of that address.
* @param enmAccessType The access type.
* @param pvUser User argument.
*/
static DECLCALLBACK(int) vmsvgaR3FIFOAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
{
int rc;
if (RT_SUCCESS(rc))
return VINF_PGM_HANDLER_DO_DEFAULT;
return rc;
}
# endif /* IN_RING3 */
#endif /* DEBUG_FIFO_ACCESS */
#ifdef DEBUG_GMR_ACCESS
/**
* HC access handler for the FIFO.
*
* @returns VINF_SUCCESS if the handler have carried out the operation.
* @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
* @param pVM VM Handle.
* @param GCPhys The physical address the guest is writing to.
* @param pvPhys The HC mapping of that address.
* @param enmAccessType The access type.
* @param pvUser User argument.
*/
static DECLCALLBACK(int) vmsvgaR3GMRAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
{
{
if (pGMR->numDescriptors)
{
{
{
/*
* Turn off the write handler for this particular page and make it R/W.
* Then return telling the caller to restart the guest instruction.
*/
goto end;
}
}
}
}
end:
return VINF_PGM_HANDLER_DO_DEFAULT;
}
# ifdef IN_RING3
/* Callback handler for VMR3ReqCallWait */
{
int rc;
{
"VMSVGA GMR");
}
return VINF_SUCCESS;
}
/* Callback handler for VMR3ReqCallWait */
{
{
}
return VINF_SUCCESS;
}
/* Callback handler for VMR3ReqCallWait */
{
{
if (pGMR->numDescriptors)
{
{
}
}
}
return VINF_SUCCESS;
}
# endif /* IN_RING3 */
#endif /* DEBUG_GMR_ACCESS */
/* -=-=-=-=-=- Ring 3 -=-=-=-=-=- */
#ifdef IN_RING3
/**
* Marks the FIFO non-busy, notifying any waiting EMTs.
*
* @param pThis The VGA state.
* @param pSVGAState Pointer to the ring-3 only SVGA state data.
* @param offFifoMin The start byte offset of the command FIFO.
*/
{
/* Wake up any waiting EMTs. */
if (pSVGAState->cBusyDelayedEmts > 0)
{
#ifdef VMSVGA_USE_EMT_HALT_CODE
if (idCpu != NIL_VMCPUID)
{
while (idCpu-- > 0)
}
#else
#endif
}
}
/**
* Reads (more) payload into the command buffer.
*
* @returns pbBounceBuf on success
* @retval (void *)1 if the thread was requested to stop.
* @retval NULL on FIFO error.
*
* @param cbPayloadReq The number of bytes of payload requested.
* @param pFIFO The FIFO.
* @param offCurrentCmd The FIFO byte offset of the current command.
* @param offFifoMin The start byte offset of the command FIFO.
* @param offFifoMax The end byte offset of the command FIFO.
* @param pbBounceBuf The bounch buffer. Same size as the entire FIFO, so
* always sufficient size.
* @param pcbAlreadyRead How much payload we've already read into the bounce
* buffer. (We will NEVER re-read anything.)
* @param pThread The calling PDM thread handle.
* @param pThis The VGA state.
* @param pSVGAState Pointer to the ring-3 only SVGA state data. For
* statistics collection.
*/
{
/*
* Check if the requested payload size has already been satisfied .
* .
* When called to read more, the caller is responsible for making sure the .
* new command size (cbRequsted) never is smaller than what has already .
* been read.
*/
if (cbPayloadReq <= cbAlreadyRead)
{
return pbBounceBuf;
}
/*
* Commands bigger than the fifo buffer are invalid.
*/
AssertMsgReturnStmt(cbPayloadReq <= cbFifoCmd, ("cbPayloadReq=%#x cbFifoCmd=%#x\n", cbPayloadReq, cbFifoCmd),
NULL);
/*
* Move offCurrentCmd past the command dword.
*/
offCurrentCmd += sizeof(uint32_t);
if (offCurrentCmd >= offFifoMax)
/*
* Do we have sufficient payload data available already?
*/
if (offNextCmd > offCurrentCmd)
{
else
{
/** @todo release counter. */
}
cbBefore = 0;
}
else
{
if (offNextCmd >= offFifoMin)
else
{
/** @todo release counter. */
cbBefore = 0;
}
}
{
/*
* Insufficient, must wait for it to arrive.
*/
for (uint32_t i = 0;; i++)
{
{
return (void *)(uintptr_t)1;
}
Log(("Guest still copying (%x vs %x) current %x next %x stop %x loop %u; sleep a bit\n",
if (offNextCmd > offCurrentCmd)
{
cbBefore = 0;
}
else
{
}
break;
}
}
/*
* Copy out the memory and update what pcbAlreadyRead points to.
*/
if (cbAfter >= cbPayloadReq)
else
{
if (cbAlreadyRead < cbAfter)
{
cbAfter - cbAlreadyRead);
}
}
return pbBounceBuf;
}
/* The async FIFO handling thread. */
{
int rc;
return VINF_SUCCESS;
/*
* Signal the semaphore to make sure we don't wait for 250 after a
* suspend & resume scenario (see vmsvgaFIFOGetCmdPayload).
*/
/*
* Allocate a bounce buffer for command we get from the FIFO.
* (All code must return via the end of the function to free this buffer.)
*/
LogFlow(("vmsvgaFIFOLoop: started loop\n"));
{
/*
* Wait for at most 250 ms to start polling.
*/
{
break;
}
if (rc == VERR_TIMEOUT)
{
continue;
Log(("vmsvgaFIFOLoop: timeout\n"));
}
Log(("vmsvgaFIFOLoop: enabled=%d configured=%d busy=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured, pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
/*
* Handle external commands.
*/
{
{
case VMSVGA_FIFO_EXTCMD_RESET:
Log(("vmsvgaFIFOLoop: reset the fifo thread.\n"));
# ifdef VBOX_WITH_VMSVGA3D
{
/* The 3d subsystem must be reset from the fifo thread. */
}
# endif
break;
Log(("vmsvgaFIFOLoop: terminate the fifo thread.\n"));
# ifdef VBOX_WITH_VMSVGA3D
{
/* The 3d subsystem must be shut down from the fifo thread. */
}
# endif
break;
Log(("vmsvgaFIFOLoop: VMSVGA_FIFO_EXTCMD_SAVESTATE.\n"));
# ifdef VBOX_WITH_VMSVGA3D
# endif
break;
{
Log(("vmsvgaFIFOLoop: VMSVGA_FIFO_EXTCMD_LOADSTATE.\n"));
# ifdef VBOX_WITH_VMSVGA3D
# endif
break;
}
}
/* Signal the end of the external command. */
continue;
}
{
continue; /* device not enabled. */
}
/*
* unchanged while we process requests. A further ASSUMPTION is that
* the guest won't mess with SVGA_FIFO_NEXT_CMD while we're busy, so
* we don't read it back while in the loop.
*/
|| offFifoMax <= offFifoMin
|| (offFifoMax & 3) != 0
|| (offFifoMin & 3) != 0
|| offCurrentCmd < offFifoMin
|| offCurrentCmd > offFifoMax))
{
LogRelMax(8, ("vmsvgaFIFOLoop: Bad fifo: min=%#x stop=%#x max=%#x\n", offFifoMin, offCurrentCmd, offFifoMax));
continue;
}
{
}
/**
* Macro for shortening calls to vmsvgaFIFOGetCmdPayload.
*
* Will break out of the switch on failure.
* Will restart and quit the loop if the thread was requested to stop.
*
* @param a_cbPayloadReq How much payload to fetch.
* @remarks Access a bunch of variables in the current scope!
*/
if (1) { \
(a_PtrVar) = (a_Type *)vmsvgaFIFOGetCmdPayload((a_cbPayloadReq), pFIFO, offCurrentCmd, offFifoMin, offFifoMax, \
} else do {} while (0)
/**
* Macro for shortening calls to vmsvgaFIFOGetCmdPayload for refetching the
* buffer after figuring out the actual command size.
* Will break out of the switch on failure.
* @param a_cbPayloadReq How much payload to fetch.
* @remarks Access a bunch of variables in the current scope!
*/
if (1) { \
} else do {} while (0)
/*
* Mark the FIFO as busy.
*/
/*
* Execute all queued FIFO commands.
* Quit if pending external command or changes in the thread state.
*/
bool fDone = false;
{
uint32_t u32IrqStatus = 0;
bool fTriggerIrq = false;
/* First check any pending actions. */
# ifdef VBOX_WITH_VMSVGA3D
# else
{/*nothing*/}
# endif
/* Check for pending external commands. */
break;
/*
* Process the command.
*/
LogFlow(("vmsvgaFIFOLoop: FIFO command (iCmd=0x%x) %s 0x%x\n",
switch (enmCmdId)
{
case SVGA_CMD_INVALID_CMD:
/* Nothing to do. */
break;
case SVGA_CMD_FENCE:
{
{
{
Log(("vmsvgaFIFOLoop: any fence irq\n"));
}
else
{
}
}
else
break;
}
case SVGA_CMD_UPDATE:
case SVGA_CMD_UPDATE_VERBOSE:
{
Log(("vmsvgaFIFOLoop: UPDATE (%d,%d)(%d,%d)\n", pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height));
break;
}
case SVGA_CMD_DEFINE_CURSOR:
{
/* Followed by bitmap data. */
AssertFailed(); /** @todo implement when necessary. */
break;
}
{
/* Followed by bitmap data. */
Log(("vmsvgaFIFOLoop: ALPHA_CURSOR id=%d size (%d,%d) hotspot (%d,%d)\n", pCursor->id, pCursor->width, pCursor->height, pCursor->hotspotX, pCursor->hotspotY));
/* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */
/* Refetch the bitmap data as well. */
cbCmd = sizeof(SVGAFifoCmdDefineAlphaCursor) + pCursor->width * pCursor->height * sizeof(uint32_t) /* 32-bit BRGA format */;
/** @todo Would be more efficient to copy the data straight into pCursorCopy (memcpy below). */
/* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */
cbCursorShape = cbAndMask + pCursor->width * sizeof(uint32_t) * pCursor->height; /* + size of the XOR mask (32-bit BRGA format) */
/* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */
/* Colour data */
memcpy(pCursorCopy + cbAndMask, (pCursor + 1), pCursor->width * pCursor->height * sizeof(uint32_t));
true,
true,
break;
}
case SVGA_CMD_ESCAPE:
{
/* Followed by nsize bytes of data. */
/* Refetch the command buffer with the variable data; undo size increase (ugly) */
{
switch (cmd)
{
{
{
Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: reg %x val %x\n", pVideoCmd->items[iReg].registerId, pVideoCmd->items[iReg].value));
}
break;
}
break;
}
}
else
break;
}
# ifdef VBOX_WITH_VMSVGA3D
case SVGA_CMD_DEFINE_GMR2:
{
/* Validate current GMR id. */
{
}
else
{
}
/* everything done in remap */
break;
}
case SVGA_CMD_REMAP_GMR2:
{
/* Followed by page descriptors or guest ptr. */
Log(("vmsvgaFIFOLoop: SVGA_CMD_REMAP_GMR2 id=%x flags=%x offset=%x npages=%x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));
/* Calculate the size of what comes after next and fetch it. */
cbCmd = sizeof(SVGAFifoCmdRemapGMR2);
cbCmd += sizeof(SVGAGuestPtr);
else
{
cbCmd += cbPageDesc;
}
else
{
}
/* Validate current GMR id. */
/* Save the old page descriptors as an array of page addresses (>> PAGE_SHIFT) */
{
{
{
}
}
}
/* Free the old GMR if present. */
/* Allocate the maximum amount possible (everything non-continuous) */
{
/** @todo */
AssertFailed();
}
else
{
uint32_t iDescriptor = 0;
if (paNewPage64)
{
/* Overwrite the old page array with the new page values. */
{
else
}
/* Use the updated page array instead of the command data. */
fGCPhys64 = true;
}
if (fGCPhys64)
GCPhys = (pPage64[0] << PAGE_SHIFT) & 0x00000FFFFFFFFFFFULL; /* seeing rubbish in the top bits with certain linux guests*/
else
{
GCPhys = (pPage64[i] << PAGE_SHIFT) & 0x00000FFFFFFFFFFFULL; /* seeing rubbish in the top bits with certain linux guests*/
else
/* Continuous physical memory? */
{
}
else
{
iDescriptor++;
}
}
}
if (paNewPage64)
# ifdef DEBUG_GMR_ACCESS
VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaRegisterGMR, 2, pThis->pDevInsR3, pCmd->gmrId);
# endif
break;
}
# endif // VBOX_WITH_VMSVGA3D
case SVGA_CMD_DEFINE_SCREEN:
{
/* Note! The size of this command is specified by the guest and depends on capabilities. */
RT_BZERO(&pCmd->screen.id, sizeof(*pCmd) - RT_OFFSETOF(SVGAFifoCmdDefineScreen, screen.structSize));
VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineScreen, RT_MAX(sizeof(pCmd->screen.structSize), pCmd->screen.structSize));
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));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_HAS_ROOT\n"));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_IS_PRIMARY\n"));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_FULLSCREEN_HINT\n"));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_DEACTIVATE \n"));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_BLANKING\n"));
/** @todo multi monitor support and screen object capabilities. */
break;
}
case SVGA_CMD_DESTROY_SCREEN:
{
break;
}
# ifdef VBOX_WITH_VMSVGA3D
case SVGA_CMD_DEFINE_GMRFB:
{
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));
break;
}
{
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));
/** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp */
if ( width == 0
|| height == 0)
break; /* Nothing to do. */
/* Clip to screen dimensions. */
unsigned offsetSource = (pCmd->srcOrigin.x * pSVGAState->GMRFB.format.s.bitsPerPixel) / 8 + pSVGAState->GMRFB.bytesPerLine * pCmd->srcOrigin.y;
unsigned offsetDest = (pCmd->destRect.left * RT_ALIGN(pThis->svga.uBpp, 8)) / 8 + pThis->svga.cbScanline * pCmd->destRect.top;
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);
vgaR3UpdateDisplay(pThis, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right - pCmd->destRect.left, pCmd->destRect.bottom - pCmd->destRect.top);
break;
}
{
/* Note! This can fetch 3d render results as well!! */
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));
AssertFailed();
break;
}
# endif // VBOX_WITH_VMSVGA3D
case SVGA_CMD_ANNOTATION_FILL:
{
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));
break;
}
case SVGA_CMD_ANNOTATION_COPY:
{
Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_COPY\n"));
AssertFailed();
break;
}
/** @todo SVGA_CMD_RECT_COPY - see with ubuntu */
default:
# ifdef VBOX_WITH_VMSVGA3D
if ( enmCmdId >= SVGA_3D_CMD_BASE
&& enmCmdId < SVGA_3D_CMD_MAX)
{
/* All 3d commands start with a common header, which defines the size of the command. */
/**
* Check that the 3D command has at least a_cbMin of payload bytes after the
* header. Will break out of the switch if it doesn't.
*/
# define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \
switch ((int)enmCmdId)
{
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceDefine(pThis, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0, SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1));
# ifdef DEBUG_GMR_ACCESS
VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaResetGMRHandlers, 1, pThis);
# endif
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceDefine(pThis, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face, pCmd->multisampleCount, pCmd->autogenFilter, cMipLevels, (SVGA3dSize *)(pCmd + 1));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SURFACE_COPY:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceStretchBlt(pThis, pCmd->dest, pCmd->boxDest, pCmd->src, pCmd->boxSrc, pCmd->mode);
break;
}
case SVGA_3D_CMD_SURFACE_DMA:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceDMA(pThis, pCmd->guest, pCmd->host, pCmd->transfer, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceBlitToScreen(pThis, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage, pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SETTRANSFORM:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SETZRANGE:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SETMATERIAL:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SETLIGHTDATA:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SETVIEWPORT:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SETCLIPPLANE:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_CLEAR:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dCommandClear(pThis, pCmd->cid, pCmd->clearFlag, pCmd->color, pCmd->depth, pCmd->stencil, cRects, (SVGA3dRect *)(pCmd + 1));
break;
}
case SVGA_3D_CMD_PRESENT:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dShaderDefine(pThis, pCmd->cid, pCmd->shid, pCmd->type, cbData, (uint32_t *)(pCmd + 1));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_SET_SHADER:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dShaderSetConst(pThis, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values);
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cVertexDivisor = (pHdr->size - sizeof(*pCmd) - sizeof(SVGA3dVertexDecl) * pCmd->numVertexDecls - sizeof(SVGA3dPrimitiveRange) * pCmd->numRanges);
SVGA3dVertexDivisor *pVertexDivisor = (cVertexDivisor) ? (SVGA3dVertexDivisor *)(&pNumRange[pCmd->numRanges]) : NULL;
rc = vmsvga3dDrawPrimitives(pThis, pCmd->cid, pCmd->numVertexDecls, pVertexDecl, pCmd->numRanges, pNumRange, cVertexDivisor, pVertexDivisor);
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_BEGIN_QUERY:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
case SVGA_3D_CMD_END_QUERY:
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
{
VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
break;
}
/* context id + surface id? */
break;
default:
AssertFailed();
break;
}
}
else
# endif // VBOX_WITH_VMSVGA3D
{
AssertFailed();
}
}
/* Go to the next slot */
if (offCurrentCmd >= offFifoMax)
{
}
/* FIFO progress might trigger an interrupt. */
{
Log(("vmsvgaFIFOLoop: fifo progress irq\n"));
}
/* Irq pending? */
{
}
}
/* If really done, clear the busy flag. */
if (fDone)
{
Log(("vmsvgaFIFOLoop: emptied the FIFO next=%x stop=%x\n", pFIFO[SVGA_FIFO_NEXT_CMD], offCurrentCmd));
}
}
/*
* Free the bounce buffer. (There are no returns above!)
*/
return VINF_SUCCESS;
}
/**
* Free the specified GMR
*
* @param pThis VGA device instance data.
* @param idGMR GMR id
*/
{
/* Free the old descriptor if present. */
{
# ifdef DEBUG_GMR_ACCESS
VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaUnregisterGMR, 2, pThis->pDevInsR3, idGMR);
# endif
pGMR->numDescriptors = 0;
}
}
/**
* Copy from a GMR to host memory or vice versa
*
* @returns VBox status code.
* @param pThis VGA device instance data.
* @param pbDst Host destination pointer
* @param cbDestPitch Destination buffer pitch
* @param src GMR description
* @param offSrc Source buffer offset
* @param cbSrcPitch Source buffer pitch
* @param cbWidth Source width in bytes
* @param cHeight Source height
*/
int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pbDst, int32_t cbDestPitch,
{
int rc;
unsigned offDesc = 0;
Log(("vmsvgaGMRTransfer: gmr=%x offset=%x pitch=%d cbWidth=%d cHeight=%d; src offset=%d src pitch=%d\n",
/* Shortcut for the framebuffer. */
{
("src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x vram_size=%#x\n",
("src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x vram_size=%#x\n",
if (enmTransferType == SVGA3D_READ_HOST_VRAM)
{
/* switch src & dest */
}
&& cbSrcPitch == cbDestPitch)
{
}
else
{
{
pbDst += cbDestPitch;
pSrc += cbSrcPitch;
}
}
return VINF_SUCCESS;
}
("src.gmrId=%#x src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x\n",
("src.gmrId=%#x src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x\n",
{
/* Find the right descriptor */
{
pDesc++;
}
while (cbCurrentWidth)
{
{
}
else
{
}
LogFlow(("vmsvgaGMRTransfer: %s phys=%RGp\n", (enmTransferType == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", pDesc->GCPhys + offCurrent - offDesc));
rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + offCurrent - offDesc, pCurrentDest, cbToCopy);
else
rc = PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + offCurrent - offDesc, pCurrentDest, cbToCopy);
offCurrent += cbToCopy;
pCurrentDest += cbToCopy;
/* Go to the next descriptor if there's anything left. */
if (cbCurrentWidth)
{
pDesc++;
}
}
offSrc += cbSrcPitch;
pbDst += cbDestPitch;
}
return VINF_SUCCESS;
}
/**
* Unblock the FIFO I/O thread so it can respond to a state change.
*
* @returns VBox status code.
* @param pDevIns The VGA device instance.
* @param pThread The send thread.
*/
{
Log(("vmsvgaFIFOLoopWakeUp\n"));
}
/**
* Enables or disables dirty page tracking for the framebuffer
*
* @param pThis VGA device instance data.
*/
{
&& !fTraces)
{
//Assert(pThis->svga.fTraces);
Log(("vmsvgaSetTraces: *not* allowed to disable dirty page tracking when the device is in legacy mode.\n"));
return;
}
{
Log(("vmsvgaSetTraces: enable dirty page handling for the frame buffer only (%x bytes)\n", 0));
{
/* Hardware enabled; return real framebuffer size .*/
}
{
Log(("vmsvgaSetTraces: enable frame buffer dirty page tracking. (%x bytes; vram %x)\n", cbFrameBuffer, pThis->vram_size));
}
}
else
{
{
Log(("vmsvgaSetTraces: disable frame buffer dirty page tracking\n"));
}
}
}
/**
* Callback function for mapping a PCI I/O region.
*
* @return VBox status code.
* @param pPciDev Pointer to PCI device.
* Use pPciDev->pDevIns to get the device instance.
* @param iRegion The region number.
* @param GCPhysAddress Physical address of the region.
* If iType is PCI_ADDRESS_SPACE_IO, this is an
* I/O port, else it's a physical address.
* This address is *NOT* relative
* to pci_mem_base like earlier!
* @param enmType One of the PCI_ADDRESS_SPACE_* values.
*/
DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
{
int rc;
Log(("vgasvgaR3IORegionMap: iRegion=%d GCPhysAddress=%RGp cb=%#x enmType=%d\n", iRegion, GCPhysAddress, cb, enmType));
if (enmType == PCI_ADDRESS_SPACE_IO)
{
if (RT_FAILURE(rc))
return rc;
if (pThis->fR0Enabled)
{
if (RT_FAILURE(rc))
return rc;
}
if (pThis->fGCEnabled)
{
if (RT_FAILURE(rc))
return rc;
}
}
else
{
if (GCPhysAddress != NIL_RTGCPHYS)
{
/*
* Mapping the FIFO RAM.
*/
# ifdef DEBUG_FIFO_ACCESS
if (RT_SUCCESS(rc))
{
"VMSVGA FIFO");
}
# endif
if (RT_SUCCESS(rc))
{
}
}
else
{
# ifdef DEBUG_FIFO_ACCESS
# endif
}
}
return VINF_SUCCESS;
}
/**
* @copydoc FNSSMDEVLOADEXEC
*/
{
int rc;
/* Load our part of the VGAState */
/* Load the framebuffer backup. */
/* Load the VMSVGA state. */
/* Load the active cursor bitmaps. */
{
}
/* Load the GMR state */
{
if (pGMR->numDescriptors)
{
/* Allocate the maximum amount possible (everything non-continuous) */
pGMR->paDesc = (PVMSVGAGMRDESCRIPTOR)RTMemAllocZ((pGMR->cMaxPages) ? pGMR->cMaxPages : (pGMR->cbTotal >> PAGE_SHIFT) * sizeof(VMSVGAGMRDESCRIPTOR));
{
rc = SSMR3GetStructEx(pSSM, &pGMR->paDesc[j], sizeof(pGMR->paDesc[j]), 0, g_aVMSVGAGMRDESCRIPTORFields, NULL);
}
}
}
# ifdef VBOX_WITH_VMSVGA3D
{
/* Save the 3d state in the FIFO thread. */
/* Hack alert: resume the IO thread as it has been suspended before the destruct callback.
* The PowerOff notification isn't working, so not an option in this case.
*/
/* Wait for the end of the command. */
}
# endif
return VINF_SUCCESS;
}
/**
* Reinit the video mode after the state has been loaded.
*/
{
/* Set the active cursor. */
{
int rc;
true,
true,
}
return VINF_SUCCESS;
}
/**
* @copydoc FNSSMDEVSAVEEXEC
*/
{
int rc;
/* Save our part of the VGAState */
/* Save the framebuffer backup. */
/* Save the VMSVGA state. */
/* Save the active cursor bitmaps. */
{
}
/* Save the GMR state */
{
rc = SSMR3PutStructEx(pSSM, &pSVGAState->aGMR[i], sizeof(pSVGAState->aGMR[i]), 0, g_aGMRFields, NULL);
{
rc = SSMR3PutStructEx(pSSM, &pSVGAState->aGMR[i].paDesc[j], sizeof(pSVGAState->aGMR[i].paDesc[j]), 0, g_aVMSVGAGMRDESCRIPTORFields, NULL);
}
}
# ifdef VBOX_WITH_VMSVGA3D
{
/* Save the 3d state in the FIFO thread. */
/* Hack alert: resume the IO thread as it has been suspended before the destruct callback.
* The PowerOff notification isn't working, so not an option in this case.
*/
/* Wait for the end of the external command. */
}
# endif
return VINF_SUCCESS;
}
/**
* Resets the SVGA hardware state
*
* @returns VBox status code.
* @param pDevIns The device instance.
*/
{
/* Reset before init? */
if (!pSVGAState)
return VINF_SUCCESS;
Log(("vmsvgaReset\n"));
/* Reset the FIFO thread. */
/* Wait for the end of the termination sequence. */
/* Register caps. */
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 | SVGA_CAP_ALPHA_CURSOR;
# ifdef VBOX_WITH_VMSVGA3D
# endif
/* Setup FIFO capabilities. */
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;
/* Valid with SVGA_FIFO_CAP_SCREEN_OBJECT_2 */
/* VRAM tracking is enabled by default during bootup. */
/* Invalidate current settings. */
return rc;
}
/**
* Cleans up the SVGA hardware state
*
* @returns VBox status code.
* @param pDevIns The device instance.
*/
{
int rc;
/* Stop the FIFO thread. */
/* Hack alert: resume the IO thread as it has been suspended before the destruct callback.
* The PowerOff notification isn't working, so not an option in this case.
*/
/* Wait for the end of the termination sequence. */
if (pSVGAState)
{
# ifndef VMSVGA_USE_EMT_HALT_CODE
{
}
# endif
{
}
}
{
}
{
}
return VINF_SUCCESS;
}
/**
* Initialize the SVGA hardware state
*
* @returns VBox status code.
* @param pDevIns The device instance.
*/
{
int rc;
/* Necessary for creating a backup of the text mode frame buffer when switching into svga mode. */
/* Create event semaphore. */
if (RT_FAILURE(rc))
{
return rc;
}
/* Create event semaphore. */
if (RT_FAILURE(rc))
{
return rc;
}
# ifndef VMSVGA_USE_EMT_HALT_CODE
/* Create semaphore for delaying EMTs wait for the FIFO to stop being busy. */
# endif
/* Register caps. */
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 | SVGA_CAP_ALPHA_CURSOR;
# ifdef VBOX_WITH_VMSVGA3D
# endif
/* Setup FIFO capabilities. */
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;
/* Valid with SVGA_FIFO_CAP_SCREEN_OBJECT_2 */
pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION] = pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION_REVISED] = 0; /* no 3d available. */
# ifdef VBOX_WITH_VMSVGA3D
{
if (RT_FAILURE(rc))
{
}
}
# endif
/* VRAM tracking is enabled by default during bootup. */
/* Invalidate current settings. */
{
}
/* Create the async IO thread. */
rc = PDMDevHlpThreadCreate(pDevIns, &pThis->svga.pFIFOIOThread, pThis, vmsvgaFIFOLoop, vmsvgaFIFOLoopWakeUp, 0,
RTTHREADTYPE_IO, "VMSVGA FIFO");
if (RT_FAILURE(rc))
{
AssertMsgFailed(("%s: Async IO Thread creation for FIFO handling failed rc=%d\n", __FUNCTION__, rc));
return rc;
}
/*
* Statistics.
*/
STAM_REG(pVM, &pSVGAState->StatR3CmdPresent, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/Present", STAMUNIT_TICKS_PER_CALL, "Profiling of Present.");
STAM_REG(pVM, &pSVGAState->StatR3CmdDrawPrimitive, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/DrawPrimitive", STAMUNIT_TICKS_PER_CALL, "Profiling of DrawPrimitive.");
STAM_REG(pVM, &pSVGAState->StatR3CmdSurfaceDMA, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/SurfaceDMA", STAMUNIT_TICKS_PER_CALL, "Profiling of SurfaceDMA.");
STAM_REL_REG(pVM, &pSVGAState->StatBusyDelayEmts, STAMTYPE_PROFILE, "/Devices/VMSVGA/EmtDelayOnBusyFifo", STAMUNIT_TICKS_PER_CALL, "Time we've delayed EMTs because of busy FIFO thread.");
STAM_REL_REG(pVM, &pSVGAState->StatFifoCommands, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCommands", STAMUNIT_OCCURENCES, "FIFO command counter.");
STAM_REL_REG(pVM, &pSVGAState->StatFifoErrors, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoErrors", STAMUNIT_OCCURENCES, "FIFO error counter.");
STAM_REL_REG(pVM, &pSVGAState->StatFifoUnkCmds, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoUnknownCommands", STAMUNIT_OCCURENCES, "FIFO unknown command counter.");
STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoTimeout, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoTimeout", STAMUNIT_OCCURENCES, "Number of times we discovered pending work after a wait timeout.");
STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoWoken, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoWoken", STAMUNIT_OCCURENCES, "Number of times we discovered pending work after being woken up.");
STAM_REL_REG(pVM, &pSVGAState->StatFifoStalls, STAMTYPE_PROFILE, "/Devices/VMSVGA/FifoStalls", STAMUNIT_TICKS_PER_CALL, "Profiling of FIFO stalls (waiting for guest to finish copying data).");
return VINF_SUCCESS;
}
/**
* Power On notification.
*
* @returns VBox status.
* @param pDevIns The device instance data.
*
* @remarks Caller enters the device critical section.
*/
{
int rc;
# ifdef VBOX_WITH_VMSVGA3D
{
if (RT_SUCCESS(rc))
{
/* 3d hardware version; latest and greatest */
/* Fill out all 3d capabilities. */
for (unsigned i = 0; i < SVGA3D_DEVCAP_MAX; i++)
{
if (RT_SUCCESS(rc))
{
idxCap++;
}
}
/* Mark end of record array. */
}
}
# endif // VBOX_WITH_VMSVGA3D
}
#endif /* IN_RING3 */