aboutsummaryrefslogtreecommitdiffstats
path: root/vmware
diff options
context:
space:
mode:
authorJaroslav Hensl <emulator@emulace.cz>2023-04-10 14:53:37 +0200
committerJaroslav Hensl <emulator@emulace.cz>2023-04-10 14:53:37 +0200
commit503e91046f60a86823629d43e64e2d0fcc006549 (patch)
tree7f4815da1ae1a94ede4d35aeb32b7ec2b32427e2 /vmware
downloadvmdisp9x-503e91046f60a86823629d43e64e2d0fcc006549.tar.gz
public release
Diffstat (limited to 'vmware')
-rw-r--r--vmware/pci.c277
-rw-r--r--vmware/pci.h101
-rw-r--r--vmware/pci32.c2
-rw-r--r--vmware/svga.c1971
-rw-r--r--vmware/svga.h153
-rw-r--r--vmware/svga32.c2
-rw-r--r--vmware/svga3d.c1222
-rw-r--r--vmware/svga3d.h149
-rw-r--r--vmware/svga3d_caps.h140
-rw-r--r--vmware/svga3d_reg.h3189
-rw-r--r--vmware/svga_all.h13
-rw-r--r--vmware/svga_escape.h89
-rw-r--r--vmware/svga_overlay.h201
-rw-r--r--vmware/svga_reg.h1610
14 files changed, 9119 insertions, 0 deletions
diff --git a/vmware/pci.c b/vmware/pci.c
new file mode 100644
index 0000000..93647b4
--- /dev/null
+++ b/vmware/pci.c
@@ -0,0 +1,277 @@
+/* -*- Mode: C; c-basic-offset: 3 -*-
+ *
+ * pci.c - Simple PCI configuration interface. This implementation
+ * only supports type 1 accesses to configuration space,
+ * and it ignores the PCI BIOS.
+ *
+ * This file is part of Metalkit, a simple collection of modules for
+ * writing software that runs on the bare metal. Get the latest code
+ * at http://svn.navi.cx/misc/trunk/metalkit/
+ *
+ * Copyright (c) 2008-2009 Micah Dowty
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <stdlib.h>
+#include "svga_all.h"
+
+#ifdef VXD32
+#define IO_IN32
+#define IO_OUT32
+#define IO_OUT16
+#define IO_IN16
+#define IO_IN8
+#include "io32.h"
+#else
+#include "io.h"
+#endif
+
+/*
+ * There can be up to 256 PCI busses, but it takes a noticeable
+ * amount of time to scan that whole space. Limit the number of
+ * supported busses to something more reasonable...
+ */
+#define PCI_MAX_BUSSES 0x20
+
+#define PCI_REG_CONFIG_ADDRESS 0xCF8
+#define PCI_REG_CONFIG_DATA 0xCFC
+
+#ifndef VXD32
+#pragma code_seg( _INIT )
+#else
+#include "code32.h"
+#endif
+
+/*
+ * PCIConfigPackAddress --
+ *
+ * Pack a 32-bit CONFIG_ADDRESS value.
+ */
+
+static uint32
+PCIConfigPackAddress(const PCIAddress __far *addr, uint16 offset)
+{
+ const uint32 enableBit = 0x80000000UL;
+
+ return (((uint32)addr->bus << 16) |
+ ((uint32)addr->device << 11) |
+ ((uint32)addr->function << 8) |
+ offset | enableBit);
+}
+
+
+/*
+ * PCI_ConfigRead32 --
+ * PCI_ConfigRead16 --
+ * PCI_ConfigRead8 --
+ * PCI_ConfigWrite32 --
+ * PCI_ConfigWrite16 --
+ * PCI_ConfigWrite8 --
+ *
+ * Access a device's PCI configuration space, using configuration
+ * mechanism #1. All new machines should use method #1, method #2
+ * is for legacy compatibility.
+ *
+ * See http://www.osdev.org/wiki/PCI
+ */
+
+uint32
+PCI_ConfigRead32(const PCIAddress __far *addr, uint16 offset)
+{
+ outpd(PCI_REG_CONFIG_ADDRESS, PCIConfigPackAddress(addr, offset));
+ return inpd(PCI_REG_CONFIG_DATA);
+}
+
+uint16
+PCI_ConfigRead16(const PCIAddress __far *addr, uint16 offset)
+{
+ outpd(PCI_REG_CONFIG_ADDRESS, PCIConfigPackAddress(addr, offset));
+ return inpw(PCI_REG_CONFIG_DATA);
+}
+
+uint8
+PCI_ConfigRead8(const PCIAddress __far *addr, uint16 offset)
+{
+ outpd(PCI_REG_CONFIG_ADDRESS, PCIConfigPackAddress(addr, offset));
+ return inp(PCI_REG_CONFIG_DATA);
+}
+
+void
+PCI_ConfigWrite32(const PCIAddress __far *addr, uint16 offset, uint32 data)
+{
+ outpd(PCI_REG_CONFIG_ADDRESS, PCIConfigPackAddress(addr, offset));
+ outpd(PCI_REG_CONFIG_DATA, data);
+}
+
+void
+PCI_ConfigWrite16(const PCIAddress __far *addr, uint16 offset, uint16 data)
+{
+ outpd(PCI_REG_CONFIG_ADDRESS, PCIConfigPackAddress(addr, offset));
+ outpw(PCI_REG_CONFIG_DATA, data);
+}
+
+void
+PCI_ConfigWrite8(const PCIAddress __far *addr, uint16 offset, uint8 data)
+{
+ outpd(PCI_REG_CONFIG_ADDRESS, PCIConfigPackAddress(addr, offset));
+ outpd(PCI_REG_CONFIG_DATA, data);
+}
+
+
+/*
+ * PCI_ScanBus --
+ *
+ * Scan the PCI bus for devices. Before starting a scan,
+ * the caller should zero the PCIScanState structure.
+ * Every time this function is called, it returns the next
+ * device in sequence.
+ *
+ * Returns TRUE if a device was found, leaving that device's
+ * vendorId, productId, and address in 'state'.
+ *
+ * Returns FALSE if there are no more devices.
+ */
+
+Bool
+PCI_ScanBus(PCIScanState __far *state)
+{
+ PCIConfigSpace config;
+
+ for (;;) {
+ config.words[0] = PCI_ConfigRead32(&state->nextAddr, 0);
+
+ state->addr = state->nextAddr;
+
+ if (++state->nextAddr.function == 0x8) {
+ state->nextAddr.function = 0;
+ if (++state->nextAddr.device == 0x20) {
+ state->nextAddr.device = 0;
+ if (++state->nextAddr.bus == PCI_MAX_BUSSES) {
+ return FALSE;
+ }
+ }
+ }
+
+ if (config.words[0] != 0xFFFFFFFFUL) {
+ state->vendorId = config.vendorId;
+ state->deviceId = config.deviceId;
+ return TRUE;
+ }
+ }
+}
+
+
+/*
+ * PCI_FindDevice --
+ *
+ * Scan the PCI bus for a device with a specific vendor and device ID.
+ *
+ * On success, returns TRUE and puts the device address into 'addrOut'.
+ * If the device was not found, returns FALSE.
+ */
+
+Bool
+PCI_FindDevice(uint16 vendorId, uint16 deviceId, PCIAddress __far *addrOut)
+{
+ PCIScanState busScan = {0};
+
+ while (PCI_ScanBus(&busScan)) {
+ if (busScan.vendorId == vendorId && busScan.deviceId == deviceId) {
+ *addrOut = busScan.addr;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * PCI_SetBAR --
+ *
+ * Set one of a device's Base Address Registers to the provided value.
+ */
+
+void
+PCI_SetBAR(const PCIAddress __far *addr, int index, uint32 value)
+{
+ // PCI_ConfigWrite32(addr, offsetof(PCIConfigSpace, BAR[index]), value);
+ PCI_ConfigWrite32(addr, 16+4*index, value);
+}
+
+
+/*
+ * PCI_GetBARAddr --
+ *
+ * Get the current address set in one of the device's Base Address Registers.
+ * We mask off the lower bits that are not part of the address. IO bars are
+ * 4 byte aligned so we mask lower 2 bits, and memory bars are 16-byte aligned
+ * so we mask the lower 4 bits.
+ */
+
+uint32
+PCI_GetBARAddr(const PCIAddress __far *addr, int index)
+{
+ // uint32 bar = PCI_ConfigRead32(addr, offsetof(PCIConfigSpace, BAR[index]));
+ uint32 bar = PCI_ConfigRead32(addr, 16+4*index);
+ uint32 mask = (bar & PCI_CONF_BAR_IO) ? 0x3 : 0xf;
+
+ return bar & ~mask;
+}
+
+uint32
+PCI_GetSubsystem(const PCIAddress __far *addr)
+{
+ uint32 subsys = PCI_ConfigRead32(addr, 44);
+
+ return subsys;
+}
+
+
+/*
+ * PCI_SetMemEnable --
+ *
+ * Enable or disable a device's memory and IO space. This must be
+ * called to enable a device's resources after setting all
+ * applicable BARs. Also enables/disables bus mastering.
+ */
+
+void
+PCI_SetMemEnable(const PCIAddress __far *addr, Bool enable)
+{
+ //uint16 command = PCI_ConfigRead16(addr, offsetof(PCIConfigSpace, command));
+ uint16 command = PCI_ConfigRead16(addr, 4);
+
+ /* Mem space enable, IO space enable, bus mastering. */
+ const uint16 flags = 0x0007;
+
+ if (enable) {
+ command |= flags;
+ } else {
+ command &= ~flags;
+ }
+
+ //PCI_ConfigWrite16(addr, offsetof(PCIConfigSpace, command), command);
+ PCI_ConfigWrite16(addr, 4, command);
+
+}
+
diff --git a/vmware/pci.h b/vmware/pci.h
new file mode 100644
index 0000000..080fc86
--- /dev/null
+++ b/vmware/pci.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C; c-basic-offset: 3 -*-
+ *
+ * pci.h - Simple PCI configuration interface. This implementation
+ * only supports type 1 accesses to configuration space,
+ * and it ignores the PCI BIOS.
+ *
+ * This file is part of Metalkit, a simple collection of modules for
+ * writing software that runs on the bare metal. Get the latest code
+ * at http://svn.navi.cx/misc/trunk/metalkit/
+ *
+ * Copyright (c) 2008-2009 Micah Dowty
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __PCI_H__
+#define __PCI_H__
+
+#include "types16.h"
+
+#pragma pack(push)
+#pragma pack(1)
+typedef union PCIConfigSpace {
+ uint32 words[16];
+ struct { // offset
+ uint16 vendorId; // 0
+ uint16 deviceId; // 2
+ uint16 command; // 4
+ uint16 status; // 6
+ uint16 revisionId; // 8
+ uint8 subclass; // 10
+ uint8 classCode; // 11
+ uint8 cacheLineSize; // 12
+ uint8 latTimer; // 13
+ uint8 headerType; // 14
+ uint8 BIST; // 15
+ uint32 BAR[6]; // 16
+ uint32 cardbusCIS; // 40
+ uint16 subsysVendorId; // 44
+ uint16 subsysId; // 46
+ uint32 expansionRomAddr; // 48
+ uint32 reserved0; // 52
+ uint32 reserved1; // 56
+ uint8 intrLine; // 60
+ uint8 intrPin; // 61
+ uint8 minGrant; // 62
+ uint8 maxLatency; // 63
+ };
+} PCIConfigSpace;
+#pragma pack(pop)
+
+typedef struct PCIAddress {
+ uint8 bus, device, function, padding;
+} PCIAddress;
+
+typedef struct PCIScanState {
+ uint16 vendorId;
+ uint16 deviceId;
+ PCIAddress nextAddr;
+ PCIAddress addr;
+} PCIScanState;
+
+// BAR bits
+#define PCI_CONF_BAR_IO 0x01
+#define PCI_CONF_BAR_64BIT 0x04
+#define PCI_CONF_BAR_PREFETCH 0x08
+
+uint32 PCI_ConfigRead32(const PCIAddress __far *addr, uint16 offset);
+uint16 PCI_ConfigRead16(const PCIAddress __far *addr, uint16 offset);
+uint8 PCI_ConfigRead8(const PCIAddress __far *addr, uint16 offset);
+void PCI_ConfigWrite32(const PCIAddress __far *addr, uint16 offset, uint32 data);
+void PCI_ConfigWrite16(const PCIAddress __far *addr, uint16 offset, uint16 data);
+void PCI_ConfigWrite8(const PCIAddress __far *addr, uint16 offset, uint8 data);
+
+Bool PCI_ScanBus(PCIScanState __far *state);
+Bool PCI_FindDevice(uint16 vendorId, uint16 deviceId, PCIAddress __far *addrOut);
+void PCI_SetBAR(const PCIAddress __far *addr, int index, uint32 value);
+uint32 PCI_GetBARAddr(const PCIAddress __far *addr, int index);
+void PCI_SetMemEnable(const PCIAddress __far *addr, Bool enable);
+uint32 PCI_GetSubsystem(const PCIAddress __far *addr);
+
+#endif /* __PCI_H__ */
diff --git a/vmware/pci32.c b/vmware/pci32.c
new file mode 100644
index 0000000..cd00f19
--- /dev/null
+++ b/vmware/pci32.c
@@ -0,0 +1,2 @@
+#define VXD32
+#include "pci.c"
diff --git a/vmware/svga.c b/vmware/svga.c
new file mode 100644
index 0000000..76d69fb
--- /dev/null
+++ b/vmware/svga.c
@@ -0,0 +1,1971 @@
+/**********************************************************
+ * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga.c --
+ *
+ * This is a simple example driver for the VMware SVGA device.
+ * It handles initialization, register accesses, low-level
+ * command FIFO writes, and host/guest synchronization.
+ */
+
+//#include <string.h> /* include some basics like NULL */
+#include "winhack.h"
+
+#include "svga_all.h"
+#include "pci.h"
+
+#ifdef VXD32
+#define IO_IN32
+#define IO_OUT32
+#include "io32.h"
+#else
+#include "io.h"
+#endif
+
+#include "drvlib.h"
+
+#ifndef VXD32
+#include "dpmi.h"
+#endif
+
+#ifdef DBGPRINT
+void dbg_printf( const char *s, ... );
+#else
+#define dbg_printf(...)
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (((a) > (b)) ? (b) : (a))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((b) > (a)) ? (b) : (a))
+#endif
+
+#ifdef VXD32
+#include "code32.h"
+#endif
+
+
+SVGADevice gSVGA;
+
+static void SVGAFIFOFull(void);
+
+#ifndef REALLY_TINY
+static void SVGAInterruptHandler(int vector);
+#endif
+
+#ifdef REALLY_TINY
+# ifdef VXD32
+# define Console_Panic(x)
+# define SVGA_Panic(x)
+# else
+# define Console_Panic(x) dbg_printf("PANIC: %s\n", x)
+# define SVGA_Panic(x) dbg_printf("PANIC: %s\n", x)
+# endif
+#endif
+
+#ifndef VXD32
+#pragma code_seg( _INIT )
+#endif
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Init --
+ *
+ * Initialize the global SVGA device. This locates it on the PCI bus,
+ * negotiates device version, and maps the command FIFO and framebuffer
+ * memory.
+ *
+ * Intr_Init() must have already been called. If the SVGA device
+ * supports interrupts, this will initalize them.
+ *
+ * Does not switch video modes.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * Steals various IOspace and memory regions.
+ * In this example code they're constant addresses, but in reality
+ * you'll need to negotiate these with the operating system.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+SVGA_Init(Bool enableFIFO)
+{
+ int vga_found = 0;
+
+ if (PCI_FindDevice(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA2,
+ &gSVGA.pciAddr)) {
+ gSVGA.vendorId = PCI_VENDOR_ID_VMWARE;
+ gSVGA.deviceId = PCI_DEVICE_ID_VMWARE_SVGA2;
+#ifndef VXD32
+ dbg_printf("PCI VMWare SVGA-II: %X:%X\n", gSVGA.vendorId, gSVGA.deviceId);
+#endif
+
+ vga_found = 1;
+ }
+
+ if (PCI_FindDevice(PCI_VENDOR_ID_INNOTEK, PCI_DEVICE_ID_VBOX_VGA, &gSVGA.pciAddr)) {
+ uint32 subsys = PCI_GetSubsystem(&gSVGA.pciAddr);
+ if(subsys == PCI_SUBCLASS_ID_SVGA2)
+ {
+ gSVGA.vendorId = PCI_VENDOR_ID_INNOTEK;
+ gSVGA.deviceId = PCI_DEVICE_ID_VBOX_VGA;
+#ifndef VXD32
+ dbg_printf("PCI VBox SVGA: %X:%X\n", gSVGA.vendorId, gSVGA.deviceId);
+#endif
+ vga_found = 1;
+ }
+ else
+ {
+#ifndef VXD32
+ dbg_printf("PCI VBox VGA, subclass %lX = this driver is not for it!\n", subsys);
+#endif
+ }
+ }
+
+ if(vga_found == 0)
+ {
+ Console_Panic("No VMware SVGA device found.");
+ return 1;
+ }
+
+ /*
+ * Use the default base address for each memory region.
+ * We must map at least ioBase before using ReadReg/WriteReg.
+ */
+
+ PCI_SetMemEnable(&gSVGA.pciAddr, TRUE);
+ if(gSVGA.deviceId == PCI_DEVICE_ID_VBOX_VGA) {
+ /* VBox SVGA have swapped IO and VRAM in PCI BAR */
+ gSVGA.fbMem = (void __far*) PCI_GetBARAddr(&gSVGA.pciAddr, 0);
+ gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 1);
+ } else {
+ gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
+ gSVGA.fbMem = (void __far*) PCI_GetBARAddr(&gSVGA.pciAddr, 1);
+ }
+ gSVGA.fifoMem = (void __far*) PCI_GetBARAddr(&gSVGA.pciAddr, 2);
+
+#ifndef VXD32 /* version negotiation is done in PM16 driver, only get addresses here */
+ /*
+ * Version negotiation:
+ *
+ * 1. Write to SVGA_REG_ID the maximum ID supported by this driver.
+ * 2. Read from SVGA_REG_ID
+ * a. If we read back the same value, this ID is supported. We're done.
+ * b. If not, decrement the ID and repeat.
+ */
+
+ gSVGA.deviceVersionId = SVGA_ID_2;
+ do {
+ SVGA_WriteReg(SVGA_REG_ID, gSVGA.deviceVersionId);
+ if (SVGA_ReadReg(SVGA_REG_ID) == gSVGA.deviceVersionId) {
+ break;
+ } else {
+ gSVGA.deviceVersionId--;
+ }
+ } while (gSVGA.deviceVersionId >= SVGA_ID_0);
+
+ if (gSVGA.deviceVersionId < SVGA_ID_0) {
+ Console_Panic("Error negotiating SVGA device version.");
+ }
+#endif
+
+ /*
+ * We must determine the FIFO and FB size after version
+ * negotiation, since the default version (SVGA_ID_0)
+ * does not support the FIFO buffer at all.
+ */
+
+ gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
+ gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE);
+ gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE);
+
+ /*
+ * Sanity-check the FIFO and framebuffer sizes.
+ * These are arbitrary values.
+ */
+
+ if (gSVGA.fbSize < 0x100000) {
+ SVGA_Panic("FB size very small, probably incorrect.");
+ }
+ if (gSVGA.fifoSize < 0x20000) {
+ SVGA_Panic("FIFO size very small, probably incorrect.");
+ }
+
+ /*
+ * If the device is new enough to support capability flags, get the
+ * capabilities register.
+ */
+
+ if (gSVGA.deviceVersionId >= SVGA_ID_1) {
+ gSVGA.capabilities = SVGA_ReadReg(SVGA_REG_CAPABILITIES);
+ }
+
+ /*
+ * Optional interrupt initialization.
+ *
+ * This uses the default IRQ that was assigned to our
+ * device by the BIOS.
+ */
+
+#ifndef REALLY_TINY
+ if (gSVGA.capabilities & SVGA_CAP_IRQMASK) {
+ uint8 irq = PCI_ConfigRead8(&gSVGA.pciAddr, offsetof(PCIConfigSpace, intrLine));
+
+ /* Start out with all SVGA IRQs masked */
+ SVGA_WriteReg(SVGA_REG_IRQMASK, 0);
+
+ /* Clear all pending IRQs stored by the device */
+ IO_Out32(gSVGA.ioBase + SVGA_IRQSTATUS_PORT, 0xFF);
+
+ /* Clear all pending IRQs stored by us */
+ SVGA_ClearIRQ();
+
+ /* Enable the IRQ */
+ Intr_SetHandler(IRQ_VECTOR(irq), SVGAInterruptHandler);
+ Intr_SetMask(irq, TRUE);
+ }
+#endif
+ gSVGA.fifoLinear = 0;
+ gSVGA.fifoSel = 0;
+ gSVGA.fifoAct = 0;
+
+ if(enableFIFO)
+ {
+ SVGA_Enable();
+ }
+
+ return 0;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Enable --
+ *
+ * Enable the SVGA device along with the SVGA FIFO.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * Initializes the command FIFO.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_Enable(void)
+{
+ /*
+ * Initialize the command FIFO. The beginning of FIFO memory is
+ * used for an additional set of registers, the "FIFO registers".
+ * These are higher-performance memory mapped registers which
+ * happen to live in the same space as the FIFO. The driver is
+ * responsible for allocating space for these registers, according
+ * to the maximum number of registers supported by this driver
+ * release.
+ */
+
+ gSVGA.fifoMem[SVGA_FIFO_MIN] = SVGA_FIFO_NUM_REGS * sizeof(uint32);
+ gSVGA.fifoMem[SVGA_FIFO_MAX] = gSVGA.fifoSize;
+ //gSVGA.fifoMem[SVGA_FIFO_MAX] = 0xFFFCUL - gSVGA.fifoMem[SVGA_FIFO_MIN];
+ gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD] = gSVGA.fifoMem[SVGA_FIFO_MIN];
+ gSVGA.fifoMem[SVGA_FIFO_STOP] = gSVGA.fifoMem[SVGA_FIFO_MIN];
+
+ /*
+ * Prep work for 3D version negotiation. See SVGA3D_Init for
+ * details, but we have to give the host our 3D protocol version
+ * before enabling the FIFO.
+ */
+
+ if (SVGA_HasFIFOCap(SVGA_CAP_EXTENDED_FIFO) &&
+ SVGA_IsFIFORegValid(SVGA_FIFO_GUEST_3D_HWVERSION)) {
+
+ gSVGA.fifoMem[SVGA_FIFO_GUEST_3D_HWVERSION] = SVGA3D_HWVERSION_CURRENT;
+ }
+
+ /*
+ * Enable the SVGA device and FIFO.
+ */
+
+ SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
+ SVGA_WriteReg(SVGA_REG_CONFIG_DONE, TRUE);
+
+ /*
+ * Now that the FIFO is initialized, we can do an IRQ sanity check.
+ * This makes sure that the VM's chipset and our own IRQ code
+ * works. Better to find out now if something's wrong, than to
+ * deadlock later.
+ *
+ * This inserts a FIFO fence, does a legacy sync to drain the FIFO,
+ * then ensures that we received all applicable interrupts.
+ */
+
+#ifndef REALLY_TINY
+ if (gSVGA.capabilities & SVGA_CAP_IRQMASK) {
+
+ SVGA_WriteReg(SVGA_REG_IRQMASK, SVGA_IRQFLAG_ANY_FENCE);
+ SVGA_ClearIRQ();
+
+ SVGA_InsertFence();
+
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
+
+ SVGA_WriteReg(SVGA_REG_IRQMASK, 0);
+
+ /* Check whether the interrupt occurred without blocking. */
+ if ((gSVGA.irq.pending & SVGA_IRQFLAG_ANY_FENCE) == 0) {
+ SVGA_Panic("SVGA IRQ appears to be present but broken.");
+ }
+
+ SVGA_WaitForIRQ();
+ }
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Disable --
+ *
+ * Disable the SVGA portion of the video adapter, switching back
+ * to VGA mode.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * Switches modes. Disables the command FIFO, without flushing it.
+ * (Any commands still in the FIFO will be lost.)
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_Disable(void)
+{
+ SVGA_WriteReg(SVGA_REG_ENABLE, FALSE);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_SetMode --
+ *
+ * This switches the SVGA video mode and enables SVGA device.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * Transitions to SVGA mode if SVGA device currently disabled.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_SetMode(uint32 width, // IN
+ uint32 height, // IN
+ uint32 bpp) // IN
+{
+ gSVGA.width = width;
+ gSVGA.height = height;
+ gSVGA.bpp = bpp;
+
+ SVGA_WriteReg(SVGA_REG_WIDTH, width);
+ SVGA_WriteReg(SVGA_REG_HEIGHT, height);
+ SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, bpp);
+ SVGA_ReadReg(SVGA_REG_FB_OFFSET);
+ SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
+ gSVGA.pitch = SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Panic --
+ *
+ * This is a Panic handler which works in SVGA mode. It disables SVGA,
+ * then executes the Console's panic handler.
+ *
+ * Results:
+ * Never returns.
+ *
+ * Side effects:
+ * Disables SVGA mode, initializes VGA text mode.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#ifndef REALLY_TINY
+void
+SVGA_Panic(const char *msg) // IN
+{
+ SVGA_Disable();
+ ConsoleVGA_Init();
+ Console_Panic(msg);
+}
+#endif
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_DefaultFaultHandler --
+ *
+ * This is a default fault handler which works in SVGA mode. It
+ * disables SVGA, then executes the Console's default fault
+ * handler.
+ *
+ * Results:
+ * Never returns.
+ *
+ * Side effects:
+ * Disables SVGA mode, initializes VGA text mode.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_DefaultFaultHandler(int vector) // IN
+{
+#ifndef REALLY_TINY
+ SVGA_Disable();
+ Console_UnhandledFault(vector);
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_ReadReg --
+ *
+ * Read an SVGA device register (SVGA_REG_*).
+ * This must be called after the PCI device's IOspace has been mapped.
+ *
+ * Results:
+ * 32-bit register value.
+ *
+ * Side effects:
+ * Depends on the register value. Some special registers
+ * like SVGA_REG_BUSY have significant side-effects.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+uint32
+SVGA_ReadReg(uint32 index) // IN
+{
+ outpd(gSVGA.ioBase + SVGA_INDEX_PORT, index);
+ return inpd(gSVGA.ioBase + SVGA_VALUE_PORT);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_WriteReg --
+ *
+ * Write an SVGA device register (SVGA_REG_*).
+ * This must be called after the PCI device's IOspace has been mapped.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * Depends on the register value.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_WriteReg(uint32 index, // IN
+ uint32 value) // IN
+{
+ outpd(gSVGA.ioBase + SVGA_INDEX_PORT, index);
+ outpd(gSVGA.ioBase + SVGA_VALUE_PORT, value);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_IsFIFORegValid --
+ *
+ * Check whether space has been allocated for a particular FIFO register.
+ *
+ * This isn't particularly useful for our simple examples, since the
+ * same binary is responsible for both allocating and using the FIFO,
+ * but a real driver may need to check this if the module which handles
+ * initialization and mode switches is separate from the module which
+ * actually writes to the FIFO.
+ *
+ * Results:
+ * TRUE if the register has been allocated, FALSE if the register
+ * does not exist.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+SVGA_IsFIFORegValid(int reg)
+{
+ return gSVGA.fifoMem[SVGA_FIFO_MIN] > (reg << 2);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_HasFIFOCap --
+ *
+ * Check whether the SVGA device has a particular FIFO capability bit.
+ *
+ * Results:
+ * TRUE if the capability is present, FALSE if it's absent.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+SVGA_HasFIFOCap(unsigned long cap)
+{
+ return (gSVGA.fifoMem[SVGA_FIFO_CAPABILITIES] & cap) != 0;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_FIFOReserve --
+ *
+ * Begin writing a command to the FIFO buffer. There are several
+ * examples floating around which show how to write to the FIFO
+ * buffer, but this is the preferred method: write directly to
+ * FIFO memory in the common case, but if the command would not
+ * be contiguous, use a bounce buffer.
+ *
+ * This method is easy to use, and quite fast. The X.org driver
+ * does not yet use this method, but recent Windows drivers use
+ * it.
+ *
+ * The main principles here are:
+ *
+ * - There are multiple code paths. In the best case, we write
+ * directly to the FIFO. In the next-best case, we use a
+ * static bounce buffer. If you need to support arbitrarily
+ * large commands, you can have a worst case in which you use
+ * a dynamically sized bounce buffer.
+ *
+ * - We must tell the host that we're reserving FIFO
+ * space. This is important because the device doesn't
+ * guarantee it will preserve the contents of FIFO memory
+ * which hasn't been reserved. If we write to a totally
+ * unused portion of the FIFO and the VM is suspended, on
+ * resume that data will no longer exist.
+ *
+ * This function is not re-entrant. If your driver is
+ * multithreaded or may be used from multiple processes
+ * concurrently, you must make sure to serialize all FIFO
+ * commands.
+ *
+ * The caller must pair this command with SVGA_FIFOCommit or
+ * SVGA_FIFOCommitAll.
+ *
+ * Results:
+ * Returns a pointer to the location where the FIFO command can
+ * be written. There will be room for at least 'bytes' bytes of
+ * data.
+ *
+ * Side effects:
+ * Begins a FIFO command, reserves space in the FIFO.
+ * May block (in SVGAFIFOFull) if the FIFO is full.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void __far *
+SVGA_FIFOReserve(uint32 bytes) // IN
+{
+ volatile uint32 __far *fifo = gSVGA.fifoMem;
+ uint32 max = fifo[SVGA_FIFO_MAX];
+ uint32 min = fifo[SVGA_FIFO_MIN];
+#if 0
+ uint32 nextCmd = fifo[SVGA_FIFO_NEXT_CMD];
+ Bool reserveable = SVGA_HasFIFOCap(SVGA_FIFO_CAP_RESERVE);
+#endif
+
+ /*
+ * This example implementation uses only a statically allocated
+ * buffer. If you want to support arbitrarily large commands,
+ * dynamically allocate a buffer if and only if it's necessary.
+ */
+
+ if (bytes > sizeof gSVGA.fifo.bounceBuffer ||
+ bytes > (max - min)) {
+ SVGA_Panic("FIFO command too large");
+ }
+
+ if (bytes % sizeof(uint32)) {
+ SVGA_Panic("FIFO command length not 32-bit aligned");
+ }
+
+ if (gSVGA.fifo.reservedSize != 0) {
+ SVGA_Panic("FIFOReserve before FIFOCommit");
+ }
+
+ gSVGA.fifo.reservedSize = bytes;
+
+#if 0
+ while (1) {
+ uint32 stop = fifo[SVGA_FIFO_STOP];
+ Bool reserveInPlace = FALSE;
+ Bool needBounce = FALSE;
+
+ /*
+ * Find a strategy for dealing with "bytes" of data:
+ * - reserve in place, if there's room and the FIFO supports it
+ * - reserve in bounce buffer, if there's room in FIFO but not
+ * contiguous or FIFO can't safely handle reservations
+ * - otherwise, sync the FIFO and try again.
+ */
+
+ if (nextCmd >= stop) {
+ /* There is no valid FIFO data between nextCmd and max */
+
+ if (nextCmd + bytes < max ||
+ (nextCmd + bytes == max && stop > min)) {
+ /*
+ * Fastest path 1: There is already enough contiguous space
+ * between nextCmd and max (the end of the buffer).
+ *
+ * Note the edge case: If the "<" path succeeds, we can
+ * quickly return without performing any other tests. If
+ * we end up on the "==" path, we're writing exactly up to
+ * the top of the FIFO and we still need to make sure that
+ * there is at least one unused DWORD at the bottom, in
+ * order to be sure we don't fill the FIFO entirely.
+ *
+ * If the "==" test succeeds, but stop <= min (the FIFO
+ * would be completely full if we were to reserve this
+ * much space) we'll end up hitting the FIFOFull path below.
+ */
+ reserveInPlace = TRUE;
+ } else if ((max - nextCmd) + (stop - min) <= bytes) {
+ /*
+ * We have to split the FIFO command into two pieces,
+ * but there still isn't enough total free space in
+ * the FIFO to store it.
+ *
+ * Note the "<=". We need to keep at least one DWORD
+ * of the FIFO free at all times, or we won't be able
+ * to tell the difference between full and empty.
+ */
+ SVGAFIFOFull();
+ } else {
+ /*
+ * Data fits in FIFO but only if we split it.
+ * Need to bounce to guarantee contiguous buffer.
+ */
+ needBounce = TRUE;
+ }
+
+ } else {
+ /* There is FIFO data between nextCmd and max */
+
+ if (nextCmd + bytes < stop) {
+ /*
+ * Fastest path 2: There is already enough contiguous space
+ * between nextCmd and stop.
+ */
+ reserveInPlace = TRUE;
+ } else {
+ /*
+ * There isn't enough room between nextCmd and stop.
+ * The FIFO is too full to accept this command.
+ */
+ SVGAFIFOFull();
+ }
+ }
+
+ /*
+ * If we decided we can write directly to the FIFO, make sure
+ * the VMX can safely support this.
+ */
+ if (reserveInPlace) {
+ if (reserveable || bytes <= sizeof(uint32)) {
+ gSVGA.fifo.usingBounceBuffer = FALSE;
+ if (reserveable) {
+ fifo[SVGA_FIFO_RESERVED] = bytes;
+ }
+ return nextCmd + (uint8 __far*) fifo;
+ } else {
+ /*
+ * Need to bounce because we can't trust the VMX to safely
+ * handle uncommitted data in FIFO.
+ */
+ needBounce = TRUE;
+ }
+ }
+
+ /*
+ * If we reach here, either we found a full FIFO, called
+ * SVGAFIFOFull to make more room, and want to try again, or we
+ * decided to use a bounce buffer instead.
+ */
+ if (needBounce) {
+ gSVGA.fifo.usingBounceBuffer = TRUE;
+ return (void __far *)(&gSVGA.fifo.bounceBuffer[0]);
+ }
+ } /* while (1) */
+#else
+ gSVGA.fifo.usingBounceBuffer = TRUE;
+ return (void __far *)(&gSVGA.fifo.bounceBuffer[0]);
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_FIFOCommit --
+ *
+ * Commit a block of FIFO data which was placed in the buffer
+ * returned by SVGA_FIFOReserve. Every Reserve must be paired
+ * with exactly one Commit, but the sizes don't have to match.
+ * The caller is free to commit less space than they
+ * reserved. This can be used if the command size isn't known in
+ * advance, but it is reasonable to make a worst-case estimate.
+ *
+ * The commit size does not have to match the size of a single
+ * FIFO command. This can be used to write a partial command, or
+ * to write multiple commands at once.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+
+#ifndef VXD32
+static void WriteFifo(uint32 pos, uint32 dw)
+{
+ uint32 act = pos >> 16;
+ uint16 off = pos & 0xFFFF;
+
+ uint32 __far *ptr;
+
+ if(act != gSVGA.fifoAct)
+ {
+ DPMI_SetSegBase(gSVGA.fifoSel, gSVGA.fifoLinear + (act << 16));
+ gSVGA.fifoAct = act;
+ }
+
+ //dbg_printf("Fifo: %ld (%X:%X)\n", pos, gSVGA.fifoAct, off);
+
+ ptr = (uint32 __far *)(gSVGA.fifoSel :> off);
+
+ *ptr = dw;
+}
+#endif
+
+void
+SVGA_FIFOCommit(uint32 bytes) // IN
+{
+ volatile uint32 __far *fifo = gSVGA.fifoMem;
+ uint32 nextCmd = fifo[SVGA_FIFO_NEXT_CMD];
+ uint32 max = fifo[SVGA_FIFO_MAX];
+ uint32 min = fifo[SVGA_FIFO_MIN];
+ Bool reserveable = 0; //SVGA_HasFIFOCap(SVGA_FIFO_CAP_RESERVE);
+
+ if (gSVGA.fifo.reservedSize == 0) {
+ SVGA_Panic("FIFOCommit before FIFOReserve");
+ }
+ gSVGA.fifo.reservedSize = 0;
+
+ if (gSVGA.fifo.usingBounceBuffer) {
+ /*
+ * Slow paths: copy out of a bounce buffer.
+ */
+ uint8 __far *buffer = gSVGA.fifo.bounceBuffer;
+
+ if (reserveable) {
+ /*
+ * Slow path: bulk copy out of a bounce buffer in two chunks.
+ *
+ * Note that the second chunk may be zero-length if the reserved
+ * size was large enough to wrap around but the commit size was
+ * small enough that everything fit contiguously into the FIFO.
+ *
+ * Note also that we didn't need to tell the FIFO about the
+ * reservation in the bounce buffer, but we do need to tell it
+ * about the data we're bouncing from there into the FIFO.
+ */
+
+ uint32 chunkSize = MIN(bytes, max - nextCmd);
+ fifo[SVGA_FIFO_RESERVED] = bytes;
+ drv_memcpy(nextCmd + (uint8 __far*) fifo, buffer, chunkSize);
+ drv_memcpy(min + (uint8 __far*) fifo, buffer + chunkSize, bytes - chunkSize);
+
+ } else {
+ /*
+ * Slowest path: copy one dword at a time, updating NEXT_CMD as
+ * we go, so that we bound how much data the guest has written
+ * and the host doesn't know to checkpoint.
+ */
+
+ uint32 *dword = (uint32 *)buffer;
+
+ while (bytes > 0) {
+ //fifo[nextCmd / sizeof(uint32)] = *dword++;
+
+#ifndef VXD32
+ WriteFifo(nextCmd, *dword);
+#else
+ fifo[nextCmd / sizeof(uint32)] = *dword;
+#endif
+ dword++;
+
+ nextCmd += sizeof(uint32);
+ if (nextCmd >= max) {
+ nextCmd = min;
+ }
+ fifo[SVGA_FIFO_NEXT_CMD] = nextCmd;
+ bytes -= sizeof *dword;
+ }
+ }
+ }
+
+ /*
+ * Atomically update NEXT_CMD, if we didn't already
+ */
+ if (!gSVGA.fifo.usingBounceBuffer || reserveable) {
+ nextCmd += bytes;
+ if (nextCmd >= max) {
+ nextCmd -= max - min;
+ }
+ fifo[SVGA_FIFO_NEXT_CMD] = nextCmd;
+ }
+
+ /*
+ * Clear the reservation in the FIFO.
+ */
+ if (reserveable) {
+ fifo[SVGA_FIFO_RESERVED] = 0;
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_FIFOCommitAll --
+ *
+ * This is a convenience wrapper for SVGA_FIFOCommit(), which
+ * always commits the last reserved block in its entirety.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * SVGA_FIFOCommit.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_FIFOCommitAll(void)
+{
+ SVGA_FIFOCommit(gSVGA.fifo.reservedSize);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_FIFOReserveCmd --
+ *
+ * This is a convenience wrapper around SVGA_FIFOReserve, which
+ * prefixes the reserved memory block with a uint32 that
+ * indicates the command type.
+ *
+ * Results:
+ * Always returns a pointer to 'bytes' bytes of reserved space in the FIFO.
+ *
+ * Side effects:
+ * Begins a FIFO command, reserves space in the FIFO. Writes a
+ * 1-word header into the FIFO. May block (in SVGAFIFOFull) if
+ * the FIFO is full.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void __far *
+SVGA_FIFOReserveCmd(uint32 type, // IN
+ uint32 bytes) // IN
+{
+ uint32 __far *cmd = SVGA_FIFOReserve(bytes + sizeof type);
+ cmd[0] = type;
+ return cmd + 1;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_FIFOReserveEscape --
+ *
+ * This is a convenience wrapper around SVGA_FIFOReserve, which
+ * prefixes the reserved memory block with an ESCAPE command header.
+ *
+ * ESCAPE commands are a way of encoding extensible and
+ * variable-length packets within the basic FIFO protocol
+ * itself. ESCAPEs are used for some SVGA device functionality,
+ * like video overlays, for VMware's internal debugging tools,
+ * and for communicating with third party code that can load into
+ * the SVGA device.
+ *
+ * Results:
+ * Always returns a pointer to 'bytes' bytes of reserved space in the FIFO.
+ *
+ * Side effects:
+ * Begins a FIFO command, reserves space in the FIFO. Writes a
+ * 3-word header into the FIFO. May block (in SVGAFIFOFull) if
+ * the FIFO is full.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void __far *
+SVGA_FIFOReserveEscape(uint32 nsid, // IN
+ uint32 bytes) // IN
+{
+ uint32 paddedBytes = (bytes + 3) & ~3UL;
+#pragma pack(push)
+#pragma pack(1)
+ struct {
+ uint32 cmd;
+ uint32 nsid;
+ uint32 size;
+ } __far *header;
+#pragma pack(pop)
+
+ header = SVGA_FIFOReserve(paddedBytes + sizeof(*header));
+
+ header->cmd = SVGA_CMD_ESCAPE;
+ header->nsid = nsid;
+ header->size = bytes;
+
+ return header + 1;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGAFIFOFull --
+ *
+ * This function is called repeatedly as long as the FIFO has too
+ * little free space for us to continue.
+ *
+ * The simplest implementation of this function is a no-op. This
+ * will just burn guest CPU until space is available. (That's a
+ * bad idea, since the host probably needs that CPU in order to
+ * make progress on emptying the FIFO.)
+ *
+ * A better implementation would sleep until a FIFO progress
+ * interrupt occurs. Depending on the OS you're writing drivers
+ * for, this may deschedule the calling task or it may simply put
+ * the CPU to sleep.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#if 0
+void
+SVGAFIFOFull(void)
+{
+#ifndef REALLY_TINY
+ if (SVGA_IsFIFORegValid(SVGA_FIFO_FENCE_GOAL) &&
+ (gSVGA.capabilities & SVGA_CAP_IRQMASK)) {
+
+ /*
+ * On hosts which support interrupts, we can sleep until the
+ * FIFO_PROGRESS interrupt occurs. This is the most efficient
+ * thing to do when the FIFO fills up.
+ *
+ * As with the IRQ-based SVGA_SyncToFence(), this will only work
+ * on Workstation 6.5 virtual machines and later.
+ */
+
+ SVGA_WriteReg(SVGA_REG_IRQMASK, SVGA_IRQFLAG_FIFO_PROGRESS);
+ SVGA_ClearIRQ();
+ SVGA_RingDoorbell();
+ SVGA_WaitForIRQ();
+ SVGA_WriteReg(SVGA_REG_IRQMASK, 0);
+
+ } else {
+
+ /*
+ * Fallback implementation: Perform one iteration of the
+ * legacy-style sync. This synchronously processes FIFO commands
+ * for an arbitrary amount of time, then returns control back to
+ * the guest CPU.
+ */
+
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ SVGA_ReadReg(SVGA_REG_BUSY);
+ }
+#endif
+}
+#endif
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_InsertFence --
+ *
+ * Write a new fence value to the FIFO.
+ *
+ * Fences are the basis of the SVGA device's synchronization
+ * model. A fence is a marker inserted into the FIFO by the
+ * guest. The host processes all FIFO commands in order. Once the
+ * fence is reached, the host does two things:
+ *
+ * - The fence value is written to the SVGA_FIFO_FENCE register.
+ * - Optionally, an interrupt is raised.
+ *
+ * There are multiple ways to use fences for synchronization. See
+ * SVGA_SyncToFence and SVGA_HasFencePassed.
+ *
+ * Results:
+ *
+ * Returns the value of the fence we inserted. Fence values
+ * increment, wrapping around at 32 bits. Fence value zero is
+ * reserved to mean "no fence". This function never returns zero.
+ *
+ * Certain very old versions of the VMware SVGA device do not
+ * support fences. On these devices, we always return 1. On these
+ * devices, SyncToFence will always do a full Sync and
+ * SyncToFence will always return FALSE, so the actual fence
+ * value we use is unimportant. Code written to use fences will
+ * run inefficiently, but it will still be correct.
+ *
+ * Side effects:
+ * Writes to the FIFO. Increments our nextFence.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+uint32
+SVGA_InsertFence(void)
+{
+ uint32 fence;
+
+#pragma pack(push)
+#pragma pack(1)
+ struct {
+ uint32 id;
+ uint32 fence;
+ } __far *cmd;
+#pragma pack(pop)
+
+ if (!SVGA_HasFIFOCap(SVGA_FIFO_CAP_FENCE)) {
+ return 1;
+ }
+
+ if (gSVGA.fifo.nextFence == 0) {
+ gSVGA.fifo.nextFence = 1;
+ }
+ fence = gSVGA.fifo.nextFence++;
+
+ cmd = SVGA_FIFOReserve(sizeof *cmd);
+ cmd->id = SVGA_CMD_FENCE;
+ cmd->fence = fence;
+ SVGA_FIFOCommitAll();
+
+ return fence;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_SyncToFence --
+ *
+ * Sleep until the SVGA device has processed all FIFO commands
+ * prior to the insertion point of the specified fence.
+ *
+ * This is the most important way to maintain synchronization
+ * between the driver and the SVGA3D device itself. It can be
+ * used to provide flow control between the host and the guest,
+ * or to ensure that DMA operations have completed before reusing
+ * guest memory.
+ *
+ * If the provided fence is zero or it has already passed,
+ * this is a no-op.
+ *
+ * If the SVGA device and virtual machine hardware version are
+ * both new enough (Workstation 6.5 or later), this will use an
+ * efficient interrupt-driven mechanism to sleep until just after
+ * the host processes the fence.
+ *
+ * If not, this will use a less efficient synchronization
+ * mechanism which may require the host to process significantly
+ * more of the FIFO than is necessary.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_SyncToFence(uint32 fence) // IN
+{
+ if (!fence) {
+ return;
+ }
+
+ if (!SVGA_HasFIFOCap(SVGA_FIFO_CAP_FENCE)) {
+ /*
+ * Fall back on the legacy sync if the host does not support
+ * fences. This is the old sync mechanism that has been
+ * supported in the SVGA device pretty much since the dawn of
+ * time: write to the SYNC register, then read from BUSY until
+ * it's nonzero. This will drain the entire FIFO.
+ *
+ * The parameter we write to SVGA_REG_SYNC is an arbitrary
+ * nonzero value which can be used for debugging, but which is
+ * ignored by release builds of VMware products.
+ */
+
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
+ return;
+ }
+
+ if (SVGA_HasFencePassed(fence)) {
+ /*
+ * Nothing to do
+ */
+
+ return;
+ }
+
+#ifndef REALLY_TINY
+ if (SVGA_IsFIFORegValid(SVGA_FIFO_FENCE_GOAL) &&
+ (gSVGA.capabilities & SVGA_CAP_IRQMASK)) {
+
+ /*
+ * On hosts which support interrupts and which support the
+ * FENCE_GOAL interrupt, we can use our preferred
+ * synchronization mechanism.
+ *
+ * This provides low latency notification both from guest to
+ * host and from host to guest, and it doesn't block the guest
+ * while we're waiting.
+ *
+ * This will only work on Workstation 6.5 virtual machines
+ * or later. Older virtual machines did not allocate an IRQ
+ * for the SVGA device, and the IRQMASK capability will be
+ * unset.
+ */
+
+ /*
+ * Set the fence goal. This asks the host to send an interrupt
+ * when this specific fence has been reached.
+ */
+
+ gSVGA.fifoMem[SVGA_FIFO_FENCE_GOAL] = fence;
+ SVGA_WriteReg(SVGA_REG_IRQMASK, SVGA_IRQFLAG_FENCE_GOAL);
+
+ SVGA_ClearIRQ();
+
+ /*
+ * Must check again, in case we reached the fence between the
+ * first HasFencePassed and when we set up the IRQ.
+ *
+ * As a small performance optimization, we check yet again after
+ * RingDoorbell, since there's a chance that RingDoorbell will
+ * deschedule this VM and process some SVGA FIFO commands in a
+ * way that appears synchronous from the VM's point of view.
+ */
+
+ if (!SVGA_HasFencePassed(fence)) {
+ /*
+ * We're about to go to sleep. Make sure the host is awake.
+ */
+ SVGA_RingDoorbell();
+
+ if (!SVGA_HasFencePassed(fence)) {
+ SVGA_WaitForIRQ();
+ }
+ }
+
+ SVGA_WriteReg(SVGA_REG_IRQMASK, 0);
+
+ } else
+#endif // REALLY_TINY
+ {
+ /*
+ * Sync-to-fence mechanism for older hosts. Wake up the host,
+ * and spin on BUSY until we've reached the fence. This
+ * processes FIFO commands synchronously, blocking the VM's
+ * execution entirely until it's done.
+ */
+
+ Bool busy = TRUE;
+
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+
+ while (!SVGA_HasFencePassed(fence) && busy) {
+ busy = (SVGA_ReadReg(SVGA_REG_BUSY) != 0);
+ }
+ }
+
+#ifndef REALLY_TINY
+ if (!SVGA_HasFencePassed(fence)) {
+ /*
+ * This shouldn't happen. If it does, there might be a bug in
+ * the SVGA device.
+ */
+ SVGA_Panic("SyncToFence failed!");
+ }
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_HasFencePassed --
+ *
+ * Test whether the host has processed all FIFO commands prior to
+ * the insertion point of the specified fence.
+ *
+ * This function tolerates fence wrap-around, but it will return
+ * the wrong result if 'fence' is more than 2^31 fences old. It
+ * is recommended that callers don't allow fence values to
+ * persist indefinitely. Once we notice that a fence has been
+ * passed, that fence variable should be set to zero so we don't
+ * test it in the future.
+ *
+ * Results:
+ * TRUE if the fence has been passed,
+ * TRUE if fence==0 (no fence),
+ * FALSE if the fence has not been passed,
+ * FALSE if the SVGA device does not support fences.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+SVGA_HasFencePassed(uint32 fence) // IN
+{
+ if (!fence) {
+ return TRUE;
+ }
+
+ if (!SVGA_HasFIFOCap(SVGA_FIFO_CAP_FENCE)) {
+ return FALSE;
+ }
+
+ return ((int32)(gSVGA.fifoMem[SVGA_FIFO_FENCE] - fence)) >= 0;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_RingDoorbell --
+ *
+ * FIFO fences are fundamentally a host-to-guest notification
+ * mechanism. This is the opposite: we can explicitly wake up
+ * the host when we know there is work for it to do.
+ *
+ * Background: The host processes the SVGA command FIFO in a
+ * separate thread which runs asynchronously with the virtual
+ * machine's CPU and other I/O devices. When the SVGA device is
+ * idle, this thread is sleeping. It periodically wakes up to
+ * poll for new commands. This polling must occur for various
+ * reasons, but it's mostly related to the historical way in
+ * which the SVGA device processes 2D updates.
+ *
+ * This polling introduces significant latency between when the
+ * first new command is placed in an empty FIFO, and when the
+ * host begins processing it. Normally this isn't a huge problem
+ * since the host and guest run fairly asynchronously, but in
+ * a synchronization-heavy workload this can be a bottleneck.
+ *
+ * For example, imagine an application with a worst-case
+ * synchronization bottleneck: The guest enqueues a single FIFO
+ * command, then waits for that command to finish using
+ * SyncToFence, then the guest spends a little time doing
+ * CPU-intensive processing before the cycle repeats. The
+ * workload may be latency-bound if the host-to-guest or
+ * guest-to-host notifications ever block.
+ *
+ * One solution would be for the guest to explicitly wake up the
+ * SVGA3D device any time a command is enqueued. This would solve
+ * the latency bottleneck above, but it would be inefficient on
+ * single-CPU host machines. One could easily imagine a situation
+ * in which we wake up the host after enqueueing one FIFO
+ * command, the physical CPU context switches to the SVGA
+ * device's thread, the single command is processed, then we
+ * context switch back to running guest code.
+ *
+ * Our recommended solution is to wake up the host only either:
+ *
+ * - After a "significant" amount of work has been enqueued into
+ * the FIFO. For example, at least one 3D drawing command.
+ *
+ * - After a complete frame has been rendered.
+ *
+ * - Just before the guest sleeps for any reason.
+ *
+ * This function implements the above guest wakeups. It uses the
+ * SVGA_FIFO_BUSY register to quickly assess whether the SVGA
+ * device may be idle. If so, it asynchronously wakes up the host
+ * by writing to SVGA_REG_SYNC.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May wake up the SVGA3D device.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_RingDoorbell(void)
+{
+ if (SVGA_IsFIFORegValid(SVGA_FIFO_BUSY) &&
+ gSVGA.fifoMem[SVGA_FIFO_BUSY] == FALSE) {
+
+ /* Remember that we already rang the doorbell. */
+ gSVGA.fifoMem[SVGA_FIFO_BUSY] = TRUE;
+
+ /*
+ * Asynchronously wake up the SVGA3D device. The second
+ * parameter is an arbitrary nonzero 'sync reason' which can be
+ * used for debugging, but which isn't part of the SVGA3D
+ * protocol proper and which isn't used by release builds of
+ * VMware products.
+ */
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Flush --
+ *
+ * Force to apply all register changes. Useful if registry changes
+ * needs be applyed immediately
+ *
+ *-----------------------------------------------------------------------------
+ */
+void SVGA_Flush(void)
+{
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_ClearIRQ --
+ *
+ * Clear all pending IRQs. Any IRQs which occurred prior to this
+ * function call will be ignored by the next SVGA_WaitForIRQ()
+ * call.
+ *
+ * Does not affect the current IRQ mask. This function is not
+ * useful unless the SVGA device has IRQ support.
+ *
+ * Results:
+ * Returns a mask of all the interrupt flags that were set prior
+ * to the clear.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+#ifndef REALLY_TINY
+/*
+uint32
+SVGA_ClearIRQ(void)
+{
+ uint32 flags = 0;
+ Atomic_Exchange(gSVGA.irq.pending, flags);
+
+ return flags;
+}*/
+
+uint32 SVGA_ClearIRQ(void);
+#pragma aux SVGA_ClearIRQ = \
+ ".386" \
+ "push eax" \
+ "xor eax, eax" \
+ "xchg ptr gSVGA.irq.pending, eax" \
+ "mov dx, ax" \
+ "shr eax, 16" \
+ "xchg dx, ax" \
+ "xchg bx, ax" \
+ "pop eax" \
+ "xchg bx, ax" \
+ value [dx ax] modify [bx];
+
+#endif
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_WaitForIRQ --
+ *
+ * Sleep until an SVGA interrupt occurs. When we wake up, return
+ * a mask of all SVGA IRQs which occurred while we were asleep.
+ *
+ * The design of this function will be different for every OS,
+ * but it is imperative that you ensure it will work properly
+ * no matter when the interrupt actually occurs. The IRQ could have
+ * already happened (any time since the last ClearIRQ, it could
+ * happen while this function is running, or it could happen
+ * after we decide to sleep.
+ *
+ * In this example:
+ *
+ * 1. If the IRQ occurred before this function was called,
+ * the bit will already be set in irq.pending. We can return.
+ *
+ * 2. If the IRQ occurs while this function is executing, we
+ * ask our IRQ handler to do a light-weight context switch
+ * back to the beginning of this function, so we can
+ * re-examine irq.pending before sleeping.
+ *
+ * 3. If the IRQ occurs while we're sleeping, we wake up
+ * from the HLT instruction and re-test irq.pending.
+ *
+ * Results:
+ * Returns a mask of all the interrupt flags that were set prior
+ * to the clear. This will always be nonzero.
+ *
+ * Side effects:
+ * Clears the irq.pending flags for exactly the set of IRQs we return.
+ *
+ *-----------------------------------------------------------------------------
+ */
+#ifndef REALLY_TINY
+static __attribute__ ((noinline)) uint32
+SVGAWaitForIRQInternal(void *arg, ...)
+{
+ uint32 flags = 0;
+
+ /*
+ * switchContext must be set to TRUE before we halt, or we'll deadlock.
+ * This variable is marked as volatile, plus we use a compiler memory barrier.
+ */
+ gSVGA.irq.switchContext = TRUE;
+ asm volatile ("" ::: "memory");
+
+ Atomic_Exchange(gSVGA.irq.pending, flags);
+
+ if (!flags) {
+ Intr_Halt();
+ }
+
+ /*
+ * Must set switchContext to FALSE before this stack frame is deallocated.
+ */
+ gSVGA.irq.switchContext = FALSE;
+ asm volatile ("" ::: "memory");
+
+ return flags;
+}
+
+uint32
+SVGA_WaitForIRQ(void)
+{
+ uint32 flags;
+
+ /*
+ * Store this CPU context, and tell the IRQ handler to return
+ * here if an IRQ occurs. We use IntrContext here just like a
+ * setjmp/longjmp that works in ISRs.
+ *
+ * This must be above the irq.pending check, so that we re-test
+ * irq.pending if an IRQ occurs after testing irq.pending but
+ * before we halt. Without this, we could deadlock if an IRQ
+ * comes in before we actually halt but after we've decided to
+ * halt.
+ */
+
+ Intr_SaveContext((IntrContext*) &gSVGA.irq.newContext);
+
+ do {
+ /*
+ * XXX: The arguments here are a kludge to prevent the interrupt
+ * stack frame from overlapping the stack frame referenced
+ * by Intr_SaveContext().
+ *
+ * Be sure to look at the generated assembly and compare the
+ * size of this argument list to the amount of stack space
+ * allocated for Intr_SaveContext.
+ */
+ flags = SVGAWaitForIRQInternal(NULL, NULL, NULL, NULL, NULL, NULL);
+
+ } while (flags == 0);
+
+ return flags;
+}
+
+#endif
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGAInterruptHandler --
+ *
+ * This is the ISR for the SVGA device's interrupt. We ask the
+ * SVGA device which interrupt occurred, and clear its flag.
+ *
+ * To report this IRQ to the rest of the driver, we:
+ *
+ * 1. Atomically remember the IRQ in the irq.pending bitmask.
+ *
+ * 2. Optionally switch to a different light-weight thread
+ * or a different place in this thread upon returning.
+ * This is analogous to waking up a sleeping thread in
+ * a driver for a real operating system. See SVGA_WaitForIRQ
+ * for details.
+ *
+ * Results:
+ * void.
+ *
+ * Side effects:
+ * Sets bits in pendingIRQs. Reads and clears the device's IRQ flags.
+ * May switch execution contexts.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#ifndef REALLY_TINY
+void
+SVGAInterruptHandler(int vector) // IN (unused)
+{
+ IntrContext *context = Intr_GetContext(vector);
+
+ /*
+ * The SVGA_IRQSTATUS_PORT is a separate I/O port, not a register.
+ * Reading from it gives us the set of IRQ flags which are
+ * set. Writing a '1' to any bit in this register will clear the
+ * corresponding flag.
+ *
+ * Here, we read then clear all flags.
+ */
+
+ uint16 port = gSVGA.ioBase + SVGA_IRQSTATUS_PORT;
+ uint32 irqFlags = IO_In32(port);
+ IO_Out32(port, irqFlags);
+
+ gSVGA.irq.count++;
+
+ if (!irqFlags) {
+ SVGA_Panic("Spurious SVGA IRQ");
+ }
+
+ Atomic_Or(gSVGA.irq.pending, irqFlags);
+
+ if (gSVGA.irq.switchContext) {
+ drv_memcpy((void*) &gSVGA.irq.oldContext, context, sizeof *context);
+ drv_memcpy(context, (void*) &gSVGA.irq.newContext, sizeof *context);
+ gSVGA.irq.switchContext = FALSE;
+ }
+}
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA_AllocGMR --
+ *
+ * Allocate a buffer from the framebuffer GMR for screen/DMA operations.
+ * Returns both a pointer (for us to use) and an SVGAGuestPtr (for the
+ * SVGA device to use).
+ *
+ * XXX: This is a trivial implementation which just returns
+ * consecutive addresses in the framebuffer.
+ *
+ * Results:
+ * Returns a local pointer and an SVGAGuestPtr to unused memory.
+ *
+ * Side effects:
+ * Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void __far *
+SVGA_AllocGMR(uint32 size, // IN
+ SVGAGuestPtr __far *ptr) // OUT
+{
+ static SVGAGuestPtr nextPtr = { SVGA_GMR_FRAMEBUFFER, 0 };
+ *ptr = nextPtr;
+ nextPtr.offset += size;
+ return gSVGA.fbMem + ptr->offset;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Update --
+ *
+ * Send a 2D update rectangle through the FIFO.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_Update(uint32 x, // IN
+ uint32 y, // IN
+ uint32 width, // IN
+ uint32 height) // IN
+{
+ SVGAFifoCmdUpdate __far *cmd = SVGA_FIFOReserveCmd(SVGA_CMD_UPDATE, sizeof *cmd);
+ cmd->x = x;
+ cmd->y = y;
+ cmd->width = width;
+ cmd->height = height;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_BeginDefineCursor --
+ *
+ * Begin an SVGA_CMD_DEFINE_CURSOR command. This copies the command header
+ * into the FIFO, and reserves enough space for the cursor image itself.
+ * We return pointers to FIFO memory where the AND/XOR masks can be written.
+ * When finished, the caller must invoke SVGA_FIFOCommitAll().
+ *
+ * Results:
+ * Returns pointers to memory where the caller can store the AND/XOR masks.
+ *
+ * Side effects:
+ * Reserves space in the FIFO.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_BeginDefineCursor(const SVGAFifoCmdDefineCursor __far *cursorInfo, // IN
+ void __far * __far *andMask, // OUT
+ void __far * __far *xorMask) // OUT
+{
+ uint32 andPitch = ((cursorInfo->andMaskDepth * cursorInfo->width + 31) >> 5) << 2;
+ uint32 andSize = andPitch * cursorInfo->height;
+ uint32 xorPitch = ((cursorInfo->xorMaskDepth * cursorInfo->width + 31) >> 5) << 2;
+ uint32 xorSize = xorPitch * cursorInfo->height;
+
+ SVGAFifoCmdDefineCursor __far *cmd = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_CURSOR,
+ sizeof *cmd + andSize + xorSize);
+ *cmd = *cursorInfo;
+ *andMask = (void*) (cmd + 1);
+ *xorMask = (void*) (andSize + (uint8 __far*) *andMask);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_BeginDefineAlphaCursor --
+ *
+ * Begin an SVGA_CMD_DEFINE_ALPHA_CURSOR command. This copies the
+ * command header into the FIFO, and reserves enough space for
+ * the cursor image itself. We return a pointer to the FIFO
+ * memory where the caller should write a pre-multiplied BGRA
+ * image. When finished, the caller must invoke SVGA_FIFOCommitAll().
+ *
+ * Results:
+ * Returns pointers to memory where the caller can store the image.
+ *
+ * Side effects:
+ * Reserves space in the FIFO.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_BeginDefineAlphaCursor(const SVGAFifoCmdDefineAlphaCursor __far *cursorInfo, // IN
+ void __far * __far * data) // OUT
+{
+ uint32 imageSize = cursorInfo->width * cursorInfo->height * sizeof(uint32);
+ SVGAFifoCmdDefineAlphaCursor __far *cmd = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_ALPHA_CURSOR,
+ sizeof *cmd + imageSize);
+ *cmd = *cursorInfo;
+ *data = (void*) (cmd + 1);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_MoveCursor --
+ *
+ * Change the position or visibility of the hardware cursor, using
+ * the Cursor Bypass 3 protocol.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Modifies FIFO registers.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_MoveCursor(uint32 visible, // IN
+ uint32 x, // IN
+ uint32 y, // IN
+ uint32 screenId) // IN
+{
+ if (SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT)) {
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_SCREEN_ID] = screenId;
+ }
+
+ if (SVGA_HasFIFOCap(SVGA_FIFO_CAP_CURSOR_BYPASS_3)) {
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_ON] = visible;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_X] = x;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_Y] = y;
+ gSVGA.fifoMem[SVGA_FIFO_CURSOR_COUNT]++;
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_BeginVideoSetRegs --
+ *
+ * Begin an SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS command. This can be
+ * used to set an arbitrary number of video registers atomically.
+ *
+ * Results:
+ * Returns a pointer to the command. The caller must fill in (*setRegs)->items.
+ *
+ * Side effects:
+ * Reserves space in the FIFO.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_BeginVideoSetRegs(uint32 streamId, // IN
+ uint32 numItems, // IN
+ SVGAEscapeVideoSetRegs __far * __far * setRegs) // OUT
+{
+ SVGAEscapeVideoSetRegs __far *cmd;
+ uint32 cmdSize = (sizeof *cmd
+ - sizeof cmd->items
+ + numItems * sizeof cmd->items[0]);
+
+ cmd = SVGA_FIFOReserveEscape(SVGA_ESCAPE_NSID_VMWARE, cmdSize);
+ cmd->header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
+ cmd->header.streamId = streamId;
+
+ *setRegs = cmd;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_VideoSetReg --
+ *
+ * Atomically set all registers in a video overlay unit.
+ *
+ * 'maxReg' should be the highest video overlay register that the
+ * caller understands. We will not set any registers with IDs
+ * higher than maxReg. This prevents older applications compiled
+ * with newer headers from sending improper values to new overlay
+ * registers.
+ *
+ * Each video overlay unit (specified by streamId) has a collection
+ * of 32-bit registers which control the operation of that overlay.
+ * Changes to these registers take effect at the next Flush.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Writes a FIFO command.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_VideoSetAllRegs(uint32 streamId, // IN
+ SVGAOverlayUnit __far *regs, // IN
+ uint32 maxReg) // IN
+{
+ uint32 __far *regArray = (uint32 __far*) regs;
+ const uint32 numRegs = maxReg + 1;
+ SVGAEscapeVideoSetRegs __far *setRegs;
+ uint32 i;
+
+ SVGA_BeginVideoSetRegs(streamId, numRegs, &setRegs);
+
+ for (i = 0; i < numRegs; i++) {
+ setRegs->items[i].registerId = i;
+ setRegs->items[i].value = regArray[i];
+ }
+
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_VideoSetReg --
+ *
+ * Set a single video overlay register.
+ *
+ * Each video overlay unit (specified by streamId) has a collection
+ * of 32-bit registers which control the operation of that overlay.
+ * Changes to these registers take effect at the next Flush.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Writes a FIFO command.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_VideoSetReg(uint32 streamId, // IN
+ uint32 registerId, // IN
+ uint32 value) // IN
+{
+ SVGAEscapeVideoSetRegs __far *setRegs;
+
+ SVGA_BeginVideoSetRegs(streamId, 1, &setRegs);
+ setRegs->items[0].registerId = registerId;
+ setRegs->items[0].value = value;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_VideoFlush --
+ *
+ * Update a video overlay. On a VideoFlush, all register changes
+ * take effect, and the device will perform a DMA transfer to
+ * copy the next frame of video from guest memory.
+ *
+ * The SVGA device will generally perform a DMA transfer from
+ * overlay memory only during a VideoFlush. The DMA operation
+ * will usually be completed before the host moves to the next
+ * FIFO command. However, this is not guaranteed. In unusual
+ * conditions, the device may re-perform the DMA operation at any
+ * time. This means that, as long as an overlay is enabled, its
+ * corresponding guest memory must be valid.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Writes a FIFO command. May cause an asynchronous DMA transfer.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_VideoFlush(uint32 streamId) // IN
+{
+ SVGAEscapeVideoFlush __far *cmd;
+
+ cmd = SVGA_FIFOReserveEscape(SVGA_ESCAPE_NSID_VMWARE, sizeof *cmd);
+ cmd->cmdType = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
+ cmd->streamId = streamId;
+ SVGA_FIFOCommitAll();
+}
diff --git a/vmware/svga.h b/vmware/svga.h
new file mode 100644
index 0000000..6095045
--- /dev/null
+++ b/vmware/svga.h
@@ -0,0 +1,153 @@
+/**********************************************************
+ * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga.h --
+ *
+ * This is a simple example driver for the VMware SVGA device.
+ * It handles initialization, register accesses, low-level
+ * command FIFO writes, and host/guest synchronization.
+ */
+
+#ifndef __SVGA_H__
+#define __SVGA_H__
+
+#include "types16.h"
+#include "pci.h"
+//#include "intr.h"
+
+#define REALLY_TINY
+
+// XXX: Shouldn't have to do this here.
+//#define INLINE __inline__
+#define INLINE inline
+
+#include "svga_reg.h"
+#include "svga_escape.h"
+#include "svga_overlay.h"
+#include "svga3d_reg.h"
+
+typedef struct SVGADevice {
+ PCIAddress pciAddr; // 0
+ uint32 ioBase; // 4
+ uint32 __far *fifoMem; // 8
+ uint8 __far *fbMem; // 16
+ uint32 fifoSize; // 20
+
+ uint32 fifoLinear; // 24
+ uint16 fifoSel; // 28
+ uint16 fifoAct; // 32
+
+ uint32 fifoPhy;
+
+ uint32 fbSize;
+ uint32 fbLinear;
+ uint32 fbPhy;
+ uint32 vramSize;
+
+ uint32 deviceVersionId;
+ uint32 capabilities;
+
+ uint32 width;
+ uint32 height;
+ uint32 bpp;
+ uint32 pitch;
+
+ struct {
+ uint32 reservedSize;
+ Bool usingBounceBuffer;
+ uint8 bounceBuffer[16 * 1024];
+ uint32 nextFence;
+ } fifo;
+
+ /* VMWare SVGAII and VBox SVGA is same device with different PCI ID */
+ uint16 vendorId;
+ uint16 deviceId;
+
+#ifndef REALLY_TINY
+ volatile struct {
+ uint32 pending;
+ uint32 switchContext;
+ IntrContext oldContext;
+ IntrContext newContext;
+ uint32 count;
+ } irq;
+#endif
+
+} SVGADevice;
+
+extern SVGADevice gSVGA;
+
+#ifndef VXD32
+int __loadds SVGA_Init(Bool enableFIFO);
+#else
+int SVGA_Init(Bool enableFIFO);
+#endif
+void SVGA_Enable(void);
+void SVGA_SetMode(uint32 width, uint32 height, uint32 bpp);
+void SVGA_Disable(void);
+void SVGA_Panic(const char *err);
+void SVGA_DefaultFaultHandler(int vector);
+
+void SVGA_Flush(void);
+
+uint32 SVGA_ReadReg(uint32 index);
+void SVGA_WriteReg(uint32 index, uint32 value);
+uint32 SVGA_ClearIRQ(void);
+uint32 SVGA_WaitForIRQ();
+
+Bool SVGA_IsFIFORegValid(int reg);
+Bool SVGA_HasFIFOCap(unsigned long cap);
+
+void __far *SVGA_FIFOReserve(uint32 bytes);
+void __far *SVGA_FIFOReserveCmd(uint32 type, uint32 bytes);
+void __far *SVGA_FIFOReserveEscape(uint32 nsid, uint32 bytes);
+void SVGA_FIFOCommit(uint32 bytes);
+void SVGA_FIFOCommitAll(void);
+
+uint32 SVGA_InsertFence(void);
+void SVGA_SyncToFence(uint32 fence);
+Bool SVGA_HasFencePassed(uint32 fence);
+void SVGA_RingDoorbell(void);
+
+void __far *SVGA_AllocGMR(uint32 size, SVGAGuestPtr __far *ptr);
+
+/* 2D commands */
+
+void SVGA_Update(uint32 x, uint32 y, uint32 width, uint32 height);
+void SVGA_BeginDefineCursor(const SVGAFifoCmdDefineCursor __far *cursorInfo,
+ void __far * __far *andMask, void __far * __far *xorMask);
+void SVGA_BeginDefineAlphaCursor(const SVGAFifoCmdDefineAlphaCursor __far *cursorInfo,
+ void __far * __far *data);
+void SVGA_MoveCursor(uint32 visible, uint32 x, uint32 y, uint32 screenId);
+
+void SVGA_BeginVideoSetRegs(uint32 streamId, uint32 numItems,
+ SVGAEscapeVideoSetRegs __far * __far *setRegs);
+void SVGA_VideoSetAllRegs(uint32 streamId, SVGAOverlayUnit __far *regs, uint32 maxReg);
+void SVGA_VideoSetReg(uint32 streamId, uint32 registerId, uint32 value);
+void SVGA_VideoFlush(uint32 streamId);
+
+
+#endif /* __SVGA_H__ */
diff --git a/vmware/svga32.c b/vmware/svga32.c
new file mode 100644
index 0000000..1091735
--- /dev/null
+++ b/vmware/svga32.c
@@ -0,0 +1,2 @@
+#define VXD32
+#include "svga.c"
diff --git a/vmware/svga3d.c b/vmware/svga3d.c
new file mode 100644
index 0000000..bd48035
--- /dev/null
+++ b/vmware/svga3d.c
@@ -0,0 +1,1222 @@
+/**********************************************************
+ * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga3d.c --
+ *
+ * FIFO command level interface to the SVGA3D protocol used by
+ * the VMware SVGA device.
+ */
+
+#include <string.h>
+#include "svga_all.h"
+
+#ifdef DBGPRINT
+void dbg_printf( const char *s, ... );
+#else
+#define dbg_printf(...)
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_Init --
+ *
+ * Perform 3D-only initialization for the SVGA device. This
+ * function negotiates SVGA3D protocol versions between the host
+ * and the guest.
+ *
+ * The 3D protocol negotiation works as follows:
+ *
+ * 1. Before enabling the FIFO, the guest writes its 3D protocol
+ * version to the SVGA_FIFO_GUEST_3D_HWVERSION register.
+ * We do this step in SVGA_Init().
+ *
+ * 2. When the FIFO is enabled, the host checks our 3D version
+ * for compatibility. If the host can support our protocol,
+ * the host puts its protocol version in SVGA_FIFO_3D_HWVERSION.
+ * If the host cannot support our protocol, it leaves the
+ * version set to zero.
+ *
+ * This function must be called after the FIFO is enabled.
+ * (After SVGA_SetMode.)
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Panic if the host is incompatible with 3D.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+SVGA3D_Init(void)
+{
+ SVGA3dHardwareVersion hwVersion;
+
+ if (!(gSVGA.capabilities & SVGA_CAP_EXTENDED_FIFO)) {
+ dbg_printf("3D requires the Extended FIFO capability.");
+ }
+
+ if (SVGA_HasFIFOCap(SVGA_FIFO_CAP_3D_HWVERSION_REVISED)) {
+ hwVersion = gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION_REVISED];
+ } else {
+ if (gSVGA.fifoMem[SVGA_FIFO_MIN] <= sizeof(uint32) * SVGA_FIFO_GUEST_3D_HWVERSION) {
+ dbg_printf("GUEST_3D_HWVERSION register not present.");
+ }
+ hwVersion = gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION];
+ }
+
+ /*
+ * Check the host's version, make sure we're binary compatible.
+ */
+
+ if (hwVersion == 0) {
+ dbg_printf("3D disabled by host.");
+ return FALSE;
+ }
+ if (hwVersion < SVGA3D_HWVERSION_WS65_B1) {
+ dbg_printf("Host SVGA3D protocol is too old, not binary compatible.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_FIFOReserve --
+ *
+ * Reserve space for an SVGA3D FIFO command.
+ *
+ * The 2D SVGA commands have been around for a while, so they
+ * have a rather asymmetric structure. The SVGA3D protocol is
+ * more uniform: each command begins with a header containing the
+ * command number and the full size.
+ *
+ * This is a convenience wrapper around SVGA_FIFOReserve. We
+ * reserve space for the whole command, and write the header.
+ *
+ * This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * Results:
+ * Returns a pointer to the space reserved for command-specific
+ * data. It must be 'cmdSize' bytes long.
+ *
+ * Side effects:
+ * Begins a FIFO reservation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+SVGA3D_FIFOReserve(uint32 cmd, // IN
+ uint32 cmdSize) // IN
+{
+ SVGA3dCmdHeader __far *header;
+
+ header = SVGA_FIFOReserve(sizeof *header + cmdSize);
+ header->id = cmd;
+ header->size = cmdSize;
+
+ return &header[1];
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginDefineSurface --
+ *
+ * Begin a SURFACE_DEFINE command. This reserves space for it in
+ * the FIFO, and returns pointers to the command's faces and
+ * mipsizes arrays.
+ *
+ * This function must be paired with SVGA_FIFOCommitAll().
+ * The faces and mipSizes arrays are initialized to zero.
+ *
+ * This creates a "surface" object in the SVGA3D device,
+ * with the provided surface ID (sid). Surfaces are generic
+ * containers for host VRAM objects like textures, vertex
+ * buffers, and depth/stencil buffers.
+ *
+ * Surfaces are hierarchial:
+ *
+ * - Surface may have multiple faces (for cube maps)
+ *
+ * - Each face has a list of mipmap levels
+ *
+ * - Each mipmap image may have multiple volume
+ * slices, if the image is three dimensional.
+ *
+ * - Each slice is a 2D array of 'blocks'
+ *
+ * - Each block may be one or more pixels.
+ * (Usually 1, more for DXT or YUV formats.)
+ *
+ * Surfaces are generic host VRAM objects. The SVGA3D device
+ * may optimize surfaces according to the format they were
+ * created with, but this format does not limit the ways in
+ * which the surface may be used. For example, a depth surface
+ * can be used as a texture, or a floating point image may
+ * be used as a vertex buffer. Some surface usages may be
+ * lower performance, due to software emulation, but any
+ * usage should work with any surface.
+ *
+ * If 'sid' is already defined, the old surface is deleted
+ * and this new surface replaces it.
+ *
+ * Surface IDs are arbitrary small non-negative integers,
+ * global to the entire SVGA device.
+ *
+ * Results:
+ * Returns pointers to arrays allocated in the FIFO for 'faces'
+ * and 'mipSizes'.
+ *
+ * Side effects:
+ * Begins a FIFO reservation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginDefineSurface(uint32 sid, // IN
+ SVGA3dSurfaceFlags flags, // IN
+ SVGA3dSurfaceFormat format, // IN
+ SVGA3dSurfaceFace **faces, // OUT
+ SVGA3dSize **mipSizes, // OUT
+ uint32 numMipSizes) // IN
+{
+ SVGA3dCmdDefineSurface *cmd;
+
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +
+ sizeof **mipSizes * numMipSizes);
+
+ cmd->sid = sid;
+ cmd->surfaceFlags = flags;
+ cmd->format = format;
+
+ *faces = &cmd->face[0];
+ *mipSizes = (SVGA3dSize*) &cmd[1];
+
+ memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);
+ memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DestroySurface --
+ *
+ * Release the host VRAM encapsulated by a particular surface ID.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_DestroySurface(uint32 sid) // IN
+{
+ SVGA3dCmdDestroySurface *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd);
+ cmd->sid = sid;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSurfaceDMA--
+ *
+ * Begin a SURFACE_DMA command. This reserves space for it in
+ * the FIFO, and returns a pointer to the command's box array.
+ * This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * When the SVGA3D device asynchronously processes this FIFO
+ * command, a DMA operation is performed between host VRAM and
+ * a generic SVGAGuestPtr. The guest pointer may refer to guest
+ * VRAM (provided by the SVGA PCI device) or to guest system
+ * memory that has been set up as a Guest Memory Region (GMR)
+ * by the SVGA device.
+ *
+ * The guest's DMA buffer must remain valid (not freed, paged out,
+ * or overwritten) until the host has finished processing this
+ * command. The guest can determine that the host has finished
+ * by using the SVGA device's FIFO Fence mechanism.
+ *
+ * The guest's image buffer can be an arbitrary size and shape.
+ * Guest image data is interpreted according to the SVGA3D surface
+ * format specified when the surface was defined.
+ *
+ * The caller may optionally define the guest image's pitch.
+ * guestImage->pitch can either be zero (assume image is tightly
+ * packed) or it must be the number of bytes between vertically
+ * adjacent image blocks.
+ *
+ * The provided copybox list specifies which regions of the source
+ * image are to be copied, and where they appear on the destination.
+ *
+ * NOTE: srcx/srcy are always on the guest image and x/y are
+ * always on the host image, regardless of the actual transfer
+ * direction!
+ *
+ * For efficiency, the SVGA3D device is free to copy more data
+ * than specified. For example, it may round copy boxes outwards
+ * such that they lie on particular alignment boundaries.
+ *
+ * The box array is initialized with zeroes.
+ *
+ * Results:
+ * Returns pointers to a box array allocated in the FIFO.
+ *
+ * Side effects:
+ * Begins a FIFO reservation.
+ * Begins a FIFO command which will eventually perform DMA.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginSurfaceDMA(SVGA3dGuestImage *guestImage, // IN
+ SVGA3dSurfaceImageId *hostImage, // IN
+ SVGA3dTransferType transfer, // IN
+ SVGA3dCopyBox **boxes, // OUT
+ uint32 numBoxes) // IN
+{
+ SVGA3dCmdSurfaceDMA *cmd;
+ uint32 boxesSize = sizeof **boxes * numBoxes;
+
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SURFACE_DMA, sizeof *cmd + boxesSize);
+
+ cmd->guest = *guestImage;
+ cmd->host = *hostImage;
+ cmd->transfer = transfer;
+ *boxes = (SVGA3dCopyBox*) &cmd[1];
+
+ memset(*boxes, 0, boxesSize);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DefineContext --
+ *
+ * Create a new context, to be referred to with the provided ID.
+ *
+ * Context objects encapsulate all render state, and shader
+ * objects are per-context.
+ *
+ * Surfaces are not per-context. The same surface can be shared
+ * between multiple contexts, and surface operations can occur
+ * without a context.
+ *
+ * If the provided context ID already existed, it is redefined.
+ *
+ * Context IDs are arbitrary small non-negative integers,
+ * global to the entire SVGA device.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_DefineContext(uint32 cid) // IN
+{
+ SVGA3dCmdDefineContext *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd);
+ cmd->cid = cid;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DestroyContext --
+ *
+ * Delete a context created with SVGA3D_DefineContext.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_DestroyContext(uint32 cid) // IN
+{
+ SVGA3dCmdDestroyContext *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd);
+ cmd->cid = cid;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetRenderTarget --
+ *
+ * Bind a surface object to a particular render target attachment
+ * point on the current context. Render target attachment points
+ * exist for color buffers, a depth buffer, and a stencil buffer.
+ *
+ * The SVGA3D device is quite lenient about the types of surfaces
+ * that may be used as render targets. The color buffers must
+ * all be the same size, but the depth and stencil buffers do not
+ * have to be the same size as the color buffer. All attachments
+ * are optional.
+ *
+ * Some combinations of render target formats may require software
+ * emulation, depending on the capabilities of the host graphics
+ * API and graphics hardware.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetRenderTarget(uint32 cid, // IN
+ SVGA3dRenderTargetType type, // IN
+ SVGA3dSurfaceImageId *target) // IN
+{
+ SVGA3dCmdSetRenderTarget *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->type = type;
+ cmd->target = *target;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetTransform --
+ *
+ * Set one of the current context's transform matrices.
+ * The 'type' parameter should be an SVGA3D_TRANSFORM_* constant.
+ *
+ * All transformation matrices follow Direct3D-style coordinate
+ * system semantics.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+
+void
+SVGA3D_SetTransform(uint32 cid, // IN
+ SVGA3dTransformType type, // IN
+ const float *matrix) // IN
+{
+ SVGA3dCmdSetTransform *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETTRANSFORM, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->type = type;
+ memcpy(&cmd->matrix[0], matrix, sizeof(float) * 16);
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetMaterial --
+ *
+ * Set all material data for one SVGA3dFace.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetMaterial(uint32 cid, // IN
+ SVGA3dFace face, // IN
+ const SVGA3dMaterial *material) // IN
+{
+ SVGA3dCmdSetMaterial *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETMATERIAL, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->face = face;
+ memcpy(&cmd->material, material, sizeof *material);
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetLightEnabled --
+ *
+ * Enable or disable one fixed-function light.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetLightEnabled(uint32 cid, // IN
+ uint32 index, // IN
+ Bool enabled) // IN
+{
+ SVGA3dCmdSetLightEnabled *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETLIGHTENABLED, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->index = index;
+ cmd->enabled = enabled;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetLightData --
+ *
+ * Set all state for one fixed-function light.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetLightData(uint32 cid, // IN
+ uint32 index, // IN
+ const SVGA3dLightData *data) // IN
+{
+ SVGA3dCmdSetLightData *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETLIGHTDATA, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->index = index;
+ memcpy(&cmd->data, data, sizeof *data);
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DefineShader --
+ *
+ * Upload the bytecode for a new shader. The bytecode is "SVGA3D
+ * format", which is theoretically a binary-compatible superset
+ * of Microsoft's DirectX shader bytecode. In practice, the
+ * SVGA3D bytecode doesn't yet have any extensions to DirectX's
+ * bytecode format.
+ *
+ * The SVGA3D device supports shader models 1.1 through 2.0.
+ *
+ * The caller chooses a shader ID (small positive integer) by
+ * which this shader will be identified in future commands. This
+ * ID is in a namespace which is per-context and per-shader-type.
+ *
+ * 'bytecodeLen' is specified in bytes. It must be a multiple of 4.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_DefineShader(uint32 cid, // IN
+ uint32 shid, // IN
+ SVGA3dShaderType type, // IN
+ const uint32 *bytecode, // IN
+ uint32 bytecodeLen) // IN
+{
+ SVGA3dCmdDefineShader *cmd;
+
+ if (bytecodeLen & 3) {
+ dbg_printf("Shader bytecode length isn't a multiple of 32 bits!");
+ }
+
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen);
+ cmd->cid = cid;
+ cmd->shid = shid;
+ cmd->type = type;
+ memcpy(&cmd[1], bytecode, bytecodeLen);
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DestroyShader --
+ *
+ * Delete a shader that was created by SVGA3D_DefineShader. If
+ * the shader was the current vertex or pixel shader for its
+ * context, rendering results are undefined until a new shader is
+ * bound.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_DestroyShader(uint32 cid, // IN
+ uint32 shid, // IN
+ SVGA3dShaderType type) // IN
+{
+ SVGA3dCmdDestroyShader *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->shid = shid;
+ cmd->type = type;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetShaderConst --
+ *
+ * Set the value of a shader constant.
+ *
+ * Shader constants are analogous to uniform variables in GLSL,
+ * except that they belong to the render context rather than to
+ * an individual shader.
+ *
+ * Constants may have one of three types: A 4-vector of floats,
+ * a 4-vector of integers, or a single boolean flag.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetShaderConst(uint32 cid, // IN
+ uint32 reg, // IN
+ SVGA3dShaderType type, // IN
+ SVGA3dShaderConstType ctype, // IN
+ const void *value) // IN
+{
+ SVGA3dCmdSetShaderConst *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->reg = reg;
+ cmd->type = type;
+ cmd->ctype = ctype;
+
+ switch (ctype) {
+
+ case SVGA3D_CONST_TYPE_FLOAT:
+ case SVGA3D_CONST_TYPE_INT:
+ memcpy(&cmd->values, value, sizeof cmd->values);
+ break;
+
+ case SVGA3D_CONST_TYPE_BOOL:
+ memset(&cmd->values, 0, sizeof cmd->values);
+ cmd->values[0] = *(uint32*)value;
+ break;
+
+ default:
+ dbg_printf("Bad shader constant type.");
+ break;
+
+ }
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetShader --
+ *
+ * Switch active shaders. This binds a new vertex or pixel shader
+ * to the specified context.
+ *
+ * A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
+ * back to the fixed function vertex or pixel pipeline.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetShader(uint32 cid, // IN
+ SVGA3dShaderType type, // IN
+ uint32 shid) // IN
+{
+ SVGA3dCmdSetShader *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SET_SHADER, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->type = type;
+ cmd->shid = shid;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginPresent --
+ *
+ * Begin a PRESENT command. This reserves space for it in the
+ * FIFO, and returns a pointer to the command's rectangle array.
+ * This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * Present is the SVGA3D device's way of transferring fully
+ * rendered images to the 2D portion of the SVGA device. Present
+ * is a hardware accelerated surface-to-screen blit.
+ *
+ * Important caveats:
+ *
+ * - Present may or may not modify the guest-visible 2D
+ * framebuffer. If you need to read back rendering results,
+ * use an surface DMA transfer.
+ *
+ * - Present is a good place to think about flow control
+ * between the host and the guest. If the host and guest
+ * have no other form of synchronization, the FIFO could
+ * fill with many frames worth of rendering commands. The
+ * host will visibly lag the guest. Depending on the
+ * size of the FIFO and the size of the frames, it could
+ * lag by hours! It is advisable to use FIFO fences in order
+ * to guarantee that no more than one or two Presents are
+ * queued in the FIFO at any given time.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May or may not write to the 2D framebuffer.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginPresent(uint32 sid, // IN
+ SVGA3dCopyRect **rects, // OUT
+ uint32 numRects) // IN
+{
+ SVGA3dCmdPresent *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_PRESENT, sizeof *cmd +
+ sizeof **rects * numRects);
+ cmd->sid = sid;
+ *rects = (SVGA3dCopyRect*) &cmd[1];
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginClear --
+ *
+ * Begin a CLEAR command. This reserves space for it in the FIFO,
+ * and returns a pointer to the command's rectangle array. This
+ * function must be paired with SVGA_FIFOCommitAll().
+ *
+ * Clear is a rendering operation which fills a list of
+ * rectangles with constant values on all render target types
+ * indicated by 'flags'.
+ *
+ * Clear is not affected by clipping, depth test, or other
+ * render state which affects the fragment pipeline.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May write to attached render target surfaces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginClear(uint32 cid, // IN
+ SVGA3dClearFlag flags, // IN
+ uint32 color, // IN
+ float depth, // IN
+ uint32 stencil, // IN
+ SVGA3dRect **rects, // OUT
+ uint32 numRects) // IN
+{
+ SVGA3dCmdClear *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_CLEAR, sizeof *cmd +
+ sizeof **rects * numRects);
+ cmd->cid = cid;
+ cmd->clearFlag = flags;
+ cmd->color = color;
+ cmd->depth = depth;
+ cmd->stencil = stencil;
+ *rects = (SVGA3dRect*) &cmd[1];
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginDrawPrimitives --
+ *
+ * Begin a DRAW_PRIMITIVES command. This reserves space for it in
+ * the FIFO, and returns a pointer to the command's arrays.
+ * This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * Drawing commands consist of two variable-length arrays:
+ * SVGA3dVertexDecl elements declare a set of vertex buffers to
+ * use while rendering, and SVGA3dPrimitiveRange elements specify
+ * groups of primitives each with an optional index buffer.
+ *
+ * The decls and ranges arrays are initialized to zero.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May write to attached render target surfaces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginDrawPrimitives(uint32 cid, // IN
+ SVGA3dVertexDecl **decls, // OUT
+ uint32 numVertexDecls, // IN
+ SVGA3dPrimitiveRange **ranges, // OUT
+ uint32 numRanges) // IN
+{
+ SVGA3dCmdDrawPrimitives *cmd;
+ SVGA3dVertexDecl *declArray;
+ SVGA3dPrimitiveRange *rangeArray;
+ uint32 declSize = sizeof **decls * numVertexDecls;
+ uint32 rangeSize = sizeof **ranges * numRanges;
+
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_DRAW_PRIMITIVES, sizeof *cmd +
+ declSize + rangeSize);
+
+ cmd->cid = cid;
+ cmd->numVertexDecls = numVertexDecls;
+ cmd->numRanges = numRanges;
+
+ declArray = (SVGA3dVertexDecl*) &cmd[1];
+ rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
+
+ memset(declArray, 0, declSize);
+ memset(rangeArray, 0, rangeSize);
+
+ *decls = declArray;
+ *ranges = rangeArray;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSurfaceCopy --
+ *
+ * Begin a SURFACE_COPY command. This reserves space for it in
+ * the FIFO, and returns a pointer to the command's arrays. This
+ * function must be paired with SVGA_FIFOCommitAll().
+ *
+ * The box array is initialized with zeroes.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Asynchronously copies a list of boxes from surface to surface.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginSurfaceCopy(SVGA3dSurfaceImageId *src, // IN
+ SVGA3dSurfaceImageId *dest, // IN
+ SVGA3dCopyBox **boxes, // OUT
+ uint32 numBoxes) // IN
+{
+ SVGA3dCmdSurfaceCopy *cmd;
+ uint32 boxesSize = sizeof **boxes * numBoxes;
+
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize);
+
+ cmd->src = *src;
+ cmd->dest = *dest;
+ *boxes = (SVGA3dCopyBox*) &cmd[1];
+
+ memset(*boxes, 0, boxesSize);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SurfaceStretchBlt --
+ *
+ * Issue a SURFACE_STRETCHBLT command: an asynchronous
+ * surface-to-surface blit, with scaling.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Asynchronously copies one box from surface to surface.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SurfaceStretchBlt(SVGA3dSurfaceImageId *src, // IN
+ SVGA3dSurfaceImageId *dest, // IN
+ SVGA3dBox *boxSrc, // IN
+ SVGA3dBox *boxDest, // IN
+ SVGA3dStretchBltMode mode) // IN
+{
+ SVGA3dCmdSurfaceStretchBlt *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd);
+ cmd->src = *src;
+ cmd->dest = *dest;
+ cmd->boxSrc = *boxSrc;
+ cmd->boxDest = *boxDest;
+ cmd->mode = mode;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetViewport --
+ *
+ * Set the current context's viewport rectangle. The viewport
+ * is clipped to the dimensions of the current render target,
+ * then all rendering is clipped to the viewport.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetViewport(uint32 cid, // IN
+ SVGA3dRect *rect) // IN
+{
+ SVGA3dCmdSetViewport *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->rect = *rect;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetZRange --
+ *
+ * Set the range of the depth buffer to use. 'min' and 'max'
+ * are values between 0.0 and 1.0.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_SetZRange(uint32 cid, // IN
+ float zMin, // IN
+ float zMax) // IN
+{
+ SVGA3dCmdSetZRange *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETZRANGE, sizeof *cmd);
+ cmd->cid = cid;
+ cmd->zRange.min = zMin;
+ cmd->zRange.max = zMax;
+ SVGA_FIFOCommitAll();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSetTextureState --
+ *
+ * Begin a SETTEXTURESTATE command. This reserves space for it in
+ * the FIFO, and returns a pointer to the command's texture state
+ * array. This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * This command sets rendering state which is per-texture-unit.
+ *
+ * XXX: Individual texture states need documentation. However,
+ * they are very similar to the texture states defined by
+ * Direct3D. The D3D documentation is a good starting point
+ * for understanding SVGA3D texture states.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginSetTextureState(uint32 cid, // IN
+ SVGA3dTextureState **states, // OUT
+ uint32 numStates) // IN
+{
+ SVGA3dCmdSetTextureState *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETTEXTURESTATE, sizeof *cmd +
+ sizeof **states * numStates);
+ cmd->cid = cid;
+ *states = (SVGA3dTextureState*) &cmd[1];
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSetRenderState --
+ *
+ * Begin a SETRENDERSTATE command. This reserves space for it in
+ * the FIFO, and returns a pointer to the command's texture state
+ * array. This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * This command sets rendering state which is global to the context.
+ *
+ * XXX: Individual render states need documentation. However,
+ * they are very similar to the render states defined by
+ * Direct3D. The D3D documentation is a good starting point
+ * for understanding SVGA3D render states.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginSetRenderState(uint32 cid, // IN
+ SVGA3dRenderState **states, // OUT
+ uint32 numStates) // IN
+{
+ SVGA3dCmdSetRenderState *cmd;
+ cmd = SVGA3D_FIFOReserve(SVGA_3D_CMD_SETRENDERSTATE, sizeof *cmd +
+ sizeof **states * numStates);
+ cmd->cid = cid;
+ *states = (SVGA3dRenderState*) &cmd[1];
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginPresentReadback --
+ *
+ * Begin a PRESENT_READBACK command. This reserves space for it
+ * in the FIFO, and returns a pointer to the command's SVGA3dRect
+ * array. This function must be paired with
+ * SVGA_FIFOCommitAll().
+ *
+ * This command will update the 2D framebuffer with the most
+ * recently presented data in the supplied regions.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginPresentReadback(SVGA3dRect **rects, // OUT
+ uint32 numRects) // IN
+{
+ void *cmd;
+ cmd = (void *) SVGA3D_FIFOReserve(SVGA_3D_CMD_PRESENT_READBACK,
+ sizeof **rects * numRects);
+ *rects = (SVGA3dRect*) cmd;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginBlitSurfaceToScreen --
+ *
+ * Begin a BLIT_SURFACE_TO_SCREEN command. This reserves space
+ * for it in the FIFO, and optionally returns a pointer to the
+ * command's clip rectangle array. This function must be paired
+ * with SVGA_FIFOCommitAll().
+ *
+ * Copy an SVGA3D surface image to a Screen Object. This command
+ * requires the SVGA Screen Object capability to be present.
+ * Copies a rectangular region of a surface image to a
+ * rectangular region of a screen or a portion of the virtual
+ * coordinate space that contains all screens.
+ *
+ * If destScreenId is SVGA_ID_INVALID, the destination rectangle
+ * is in virtual coordinates rather than in screen coordinates.
+ *
+ * If the source and destination rectangle are different sizes,
+ * the image will be scaled using a backend-specific algorithm.
+ *
+ * This command may optionally include a clip rectangle list. If
+ * zero rectangles are specified, there is no clip region. The
+ * entire destination rectangle is drawn. If one or more
+ * rectangles are specified, they describe a destination clipping
+ * region in the same coordinate system as destRect.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Writes to the Screen Object.
+ * Begins a new FIFO command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BeginBlitSurfaceToScreen(const SVGA3dSurfaceImageId *srcImage, // IN
+ const SVGASignedRect *srcRect, // IN
+ uint32 destScreenId, // IN (optional)
+ const SVGASignedRect *destRect, // IN
+ SVGASignedRect **clipRects, // IN (optional)
+ uint32 numClipRects) // IN (optional)
+{
+ SVGA3dCmdBlitSurfaceToScreen *cmd =
+ SVGA3D_FIFOReserve(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
+ sizeof *cmd + numClipRects * sizeof(SVGASignedRect));
+
+ cmd->srcImage = *srcImage;
+ cmd->srcRect = *srcRect;
+ cmd->destScreenId = destScreenId;
+ cmd->destRect = *destRect;
+
+ if (clipRects) {
+ *clipRects = (SVGASignedRect*) &cmd[1];
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BlitSurfaceToScreen --
+ *
+ * This is a convenience wrapper around
+ * SVGA3D_BeginBlitSurfaceToScreen, for callers who do not
+ * require a clip rectangle list.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Writes to the Screen Object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+SVGA3D_BlitSurfaceToScreen(const SVGA3dSurfaceImageId *srcImage, // IN
+ const SVGASignedRect *srcRect, // IN
+ uint32 destScreenId, // IN (optional)
+ const SVGASignedRect *destRect) // IN
+{
+ SVGA3D_BeginBlitSurfaceToScreen(srcImage, srcRect, destScreenId, destRect, NULL, 0);
+ SVGA_FIFOCommitAll();
+}
diff --git a/vmware/svga3d.h b/vmware/svga3d.h
new file mode 100644
index 0000000..1242754
--- /dev/null
+++ b/vmware/svga3d.h
@@ -0,0 +1,149 @@
+/**********************************************************
+ * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga3d.h --
+ *
+ * FIFO command level interface to the SVGA3D protocol used by
+ * the VMware SVGA device.
+ */
+
+#ifndef __SVGA3D_H__
+#define __SVGA3D_H__
+
+#include "svga.h"
+#include "svga3d_reg.h"
+
+
+/*
+ * SVGA Device Interoperability
+ */
+
+Bool SVGA3D_Init(void);
+void SVGA3D_BeginPresent(uint32 sid, SVGA3dCopyRect **rects, uint32 numRects);
+void SVGA3D_BeginPresentReadback(SVGA3dRect **rects, uint32 numRects);
+void SVGA3D_BlitSurfaceToScreen(const SVGA3dSurfaceImageId *srcImage,
+ const SVGASignedRect *srcRect,
+ uint32 destScreenId,
+ const SVGASignedRect *destRect);
+void SVGA3D_BeginBlitSurfaceToScreen(const SVGA3dSurfaceImageId *srcImage,
+ const SVGASignedRect *srcRect,
+ uint32 destScreenId,
+ const SVGASignedRect *destRect,
+ SVGASignedRect **clipRects,
+ uint32 numClipRects);
+
+
+/*
+ * Surface Management
+ */
+
+void SVGA3D_BeginDefineSurface(uint32 sid,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSurfaceFace **faces,
+ SVGA3dSize **mipSizes,
+ uint32 numMipSizes);
+void SVGA3D_DestroySurface(uint32 sid);
+void SVGA3D_BeginSurfaceDMA(SVGA3dGuestImage *guestImage,
+ SVGA3dSurfaceImageId *hostImage,
+ SVGA3dTransferType transfer,
+ SVGA3dCopyBox **boxes,
+ uint32 numBoxes);
+
+
+/*
+ * Context Management
+ */
+
+void SVGA3D_DefineContext(uint32 cid);
+void SVGA3D_DestroyContext(uint32 cid);
+
+
+/*
+ * Drawing Operations
+ */
+
+void SVGA3D_BeginClear(uint32 cid, SVGA3dClearFlag flags,
+ uint32 color, float depth, uint32 stencil,
+ SVGA3dRect **rects, uint32 numRects);
+void SVGA3D_BeginDrawPrimitives(uint32 cid,
+ SVGA3dVertexDecl **decls,
+ uint32 numVertexDecls,
+ SVGA3dPrimitiveRange **ranges,
+ uint32 numRanges);
+
+/*
+ * Blits
+ */
+
+void SVGA3D_BeginSurfaceCopy(SVGA3dSurfaceImageId *src,
+ SVGA3dSurfaceImageId *dest,
+ SVGA3dCopyBox **boxes, uint32 numBoxes);
+
+void SVGA3D_SurfaceStretchBlt(SVGA3dSurfaceImageId *src,
+ SVGA3dSurfaceImageId *dest,
+ SVGA3dBox *boxSrc, SVGA3dBox *boxDest,
+ SVGA3dStretchBltMode mode);
+
+/*
+ * Shared FFP/Shader Render State
+ */
+
+void SVGA3D_SetRenderTarget(uint32 cid, SVGA3dRenderTargetType type,
+ SVGA3dSurfaceImageId *target);
+void SVGA3D_SetZRange(uint32 cid, float zMin, float zMax);
+void SVGA3D_SetViewport(uint32 cid, SVGA3dRect *rect);
+void SVGA3D_SetScissorRect(uint32 cid, SVGA3dRect *rect);
+void SVGA3D_SetClipPlane(uint32 cid, uint32 index, const float *plane);
+void SVGA3D_BeginSetTextureState(uint32 cid, SVGA3dTextureState **states,
+ uint32 numStates);
+void SVGA3D_BeginSetRenderState(uint32 cid, SVGA3dRenderState **states,
+ uint32 numStates);
+
+
+/*
+ * Fixed-function Render State
+ */
+
+void SVGA3D_SetTransform(uint32 cid, SVGA3dTransformType type,
+ const float *matrix);
+void SVGA3D_SetMaterial(uint32 cid, SVGA3dFace face, const SVGA3dMaterial *material);
+void SVGA3D_SetLightData(uint32 cid, uint32 index, const SVGA3dLightData *data);
+void SVGA3D_SetLightEnabled(uint32 cid, uint32 index, Bool enabled);
+
+
+/*
+ * Shaders
+ */
+
+void SVGA3D_DefineShader(uint32 cid, uint32 shid, SVGA3dShaderType type,
+ const uint32 *bytecode, uint32 bytecodeLen);
+void SVGA3D_DestroyShader(uint32 cid, uint32 shid, SVGA3dShaderType type);
+void SVGA3D_SetShaderConst(uint32 cid, uint32 reg, SVGA3dShaderType type,
+ SVGA3dShaderConstType ctype, const void *value);
+void SVGA3D_SetShader(uint32 cid, SVGA3dShaderType type, uint32 shid);
+
+#endif /* __SVGA3D_H__ */
diff --git a/vmware/svga3d_caps.h b/vmware/svga3d_caps.h
new file mode 100644
index 0000000..3eab532
--- /dev/null
+++ b/vmware/svga3d_caps.h
@@ -0,0 +1,140 @@
+/**********************************************************
+ * Copyright 2007-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_caps.h --
+ *
+ * Definitions for SVGA3D hardware capabilities. Capabilities
+ * are used to query for optional rendering features during
+ * driver initialization. The capability data is stored as very
+ * basic key/value dictionary within the "FIFO register" memory
+ * area at the beginning of BAR2.
+ *
+ * Note that these definitions are only for 3D capabilities.
+ * The SVGA device also has "device capabilities" and "FIFO
+ * capabilities", which are non-3D-specific and are stored as
+ * bitfields rather than key/value pairs.
+ */
+
+#ifndef _SVGA3D_CAPS_H_
+#define _SVGA3D_CAPS_H_
+
+#define SVGA_FIFO_3D_CAPS_SIZE (SVGA_FIFO_3D_CAPS_LAST - \
+ SVGA_FIFO_3D_CAPS + 1)
+
+
+/*
+ * SVGA3dCapsRecordType
+ *
+ * Record types that can be found in the caps block.
+ * Related record types are grouped together numerically so that
+ * SVGA3dCaps_FindRecord() can be applied on a range of record
+ * types.
+ */
+
+typedef enum {
+ SVGA3DCAPS_RECORD_UNKNOWN = 0,
+ SVGA3DCAPS_RECORD_DEVCAPS_MIN = 0x100,
+ SVGA3DCAPS_RECORD_DEVCAPS = 0x100,
+ SVGA3DCAPS_RECORD_DEVCAPS_MAX = 0x1ff,
+ SVGA3DCAPS_RECORD_DEVCAPS_FORCE32 = 0xffffffff
+} SVGA3dCapsRecordType;
+
+
+/*
+ * SVGA3dCapsRecordHeader
+ *
+ * Header field leading each caps block record. Contains the offset (in
+ * register words, NOT bytes) to the next caps block record (or the end
+ * of caps block records which will be a zero word) and the record type
+ * as defined above.
+ */
+
+typedef
+struct SVGA3dCapsRecordHeader {
+ uint32 length;
+ SVGA3dCapsRecordType type;
+}
+SVGA3dCapsRecordHeader;
+
+
+/*
+ * SVGA3dCapsRecord
+ *
+ * Caps block record; "data" is a placeholder for the actual data structure
+ * contained within the record; for example a record containing a FOOBAR
+ * structure would be of size "sizeof(SVGA3dCapsRecordHeader) +
+ * sizeof(FOOBAR)".
+ */
+
+typedef
+struct SVGA3dCapsRecord {
+ SVGA3dCapsRecordHeader header;
+ uint32 data[1];
+}
+SVGA3dCapsRecord;
+
+
+typedef uint32 SVGA3dCapPair[2];
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3dCaps_FindRecord
+ *
+ * Finds the record with the highest-valued type within the given range
+ * in the caps block.
+ *
+ * Result: pointer to found record, or NULL if not found.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE SVGA3dCapsRecord *
+SVGA3dCaps_FindRecord(const uint32 *capsBlock,
+ SVGA3dCapsRecordType recordTypeMin,
+ SVGA3dCapsRecordType recordTypeMax)
+{
+ SVGA3dCapsRecord *record, *found = NULL;
+ uint32 offset;
+
+ /*
+ * Search linearly through the caps block records for the specified type.
+ */
+ for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
+ record = (SVGA3dCapsRecord *) (capsBlock + offset);
+ if ((record->header.type >= recordTypeMin) &&
+ (record->header.type <= recordTypeMax) &&
+ (!found || (record->header.type > found->header.type))) {
+ found = record;
+ }
+ }
+
+ return found;
+}
+
+
+#endif // _SVGA3D_CAPS_H_
diff --git a/vmware/svga3d_reg.h b/vmware/svga3d_reg.h
new file mode 100644
index 0000000..9b009d5
--- /dev/null
+++ b/vmware/svga3d_reg.h
@@ -0,0 +1,3189 @@
+/**********************************************************
+ * Copyright 1998-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_reg.h --
+ *
+ * SVGA 3D hardware definitions
+ */
+
+#ifndef _SVGA3D_REG_H_
+#define _SVGA3D_REG_H_
+
+#include "svga_reg.h"
+
+/*
+ * Extra types
+ */
+
+typedef struct uint64 {
+ uint32 low;
+ uint32 hi;
+} uint64;
+
+typedef uint16 SVGA3dLogicOp;
+typedef uint32 SVGA3dSurface1Flags;
+typedef uint32 SVGA3dSurface2Flags;
+typedef uint64 SVGA3dSurfaceAllFlags;
+typedef uint32 SVGAMobId;
+
+#define SVGA3D_INVALID_ID ((uint32)-1)
+
+typedef uint64 PPN64;
+typedef uint32 PPN;
+
+/*
+ * Limits
+ */
+#define SVGA3D_NUM_TEXTURE_UNITS 32
+#define SVGA3D_NUM_LIGHTS 8
+
+/*
+ * 3D Hardware Version
+ *
+ * The hardware version is stored in the SVGA_FIFO_3D_HWVERSION fifo
+ * register. Is set by the host and read by the guest. This lets
+ * us make new guest drivers which are backwards-compatible with old
+ * SVGA hardware revisions. It does not let us support old guest
+ * drivers. Good enough for now.
+ *
+ */
+
+#define SVGA3D_MAKE_HWVERSION(major, minor) (((unsigned long)(major) << 16) | ((unsigned long)(minor) & 0xFF))
+#define SVGA3D_MAJOR_HWVERSION(version) ((unsigned long)(version) >> 16)
+#define SVGA3D_MINOR_HWVERSION(version) ((unsigned long)(version) & 0xFF)
+
+typedef enum {
+ SVGA3D_HWVERSION_WS5_RC1 = SVGA3D_MAKE_HWVERSION(0, 1),
+ SVGA3D_HWVERSION_WS5_RC2 = SVGA3D_MAKE_HWVERSION(0, 2),
+ SVGA3D_HWVERSION_WS51_RC1 = SVGA3D_MAKE_HWVERSION(0, 3),
+ SVGA3D_HWVERSION_WS6_B1 = SVGA3D_MAKE_HWVERSION(1, 1),
+ SVGA3D_HWVERSION_FUSION_11 = SVGA3D_MAKE_HWVERSION(1, 4),
+ SVGA3D_HWVERSION_WS65_B1 = SVGA3D_MAKE_HWVERSION(2, 0),
+ SVGA3D_HWVERSION_WS8_B1 = SVGA3D_MAKE_HWVERSION(2, 1),
+ SVGA3D_HWVERSION_CURRENT = SVGA3D_HWVERSION_WS8_B1,
+} SVGA3dHardwareVersion;
+
+/*
+ * Generic Types
+ */
+
+typedef uint32 SVGA3dBool; /* 32-bit Bool definition */
+#define SVGA3D_NUM_CLIPPLANES 6
+#define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS 8
+#define SVGA3D_MAX_CONTEXT_IDS 256
+#define SVGA3D_MAX_SURFACE_IDS (32 * 1024)
+
+/*
+ * Surface formats.
+ *
+ * If you modify this list, be sure to keep GLUtil.c in sync. It
+ * includes the internal format definition of each surface in
+ * GLUtil_ConvertSurfaceFormat, and it contains a table of
+ * human-readable names in GLUtil_GetFormatName.
+ */
+
+typedef enum SVGA3dSurfaceFormat {
+ SVGA3D_FORMAT_INVALID = 0,
+
+ SVGA3D_X8R8G8B8 = 1,
+ SVGA3D_A8R8G8B8 = 2,
+
+ SVGA3D_R5G6B5 = 3,
+ SVGA3D_X1R5G5B5 = 4,
+ SVGA3D_A1R5G5B5 = 5,
+ SVGA3D_A4R4G4B4 = 6,
+
+ SVGA3D_Z_D32 = 7,
+ SVGA3D_Z_D16 = 8,
+ SVGA3D_Z_D24S8 = 9,
+ SVGA3D_Z_D15S1 = 10,
+
+ SVGA3D_LUMINANCE8 = 11,
+ SVGA3D_LUMINANCE4_ALPHA4 = 12,
+ SVGA3D_LUMINANCE16 = 13,
+ SVGA3D_LUMINANCE8_ALPHA8 = 14,
+
+ SVGA3D_DXT1 = 15,
+ SVGA3D_DXT2 = 16,
+ SVGA3D_DXT3 = 17,
+ SVGA3D_DXT4 = 18,
+ SVGA3D_DXT5 = 19,
+
+ SVGA3D_BUMPU8V8 = 20,
+ SVGA3D_BUMPL6V5U5 = 21,
+ SVGA3D_BUMPX8L8V8U8 = 22,
+ SVGA3D_BUMPL8V8U8 = 23,
+
+ SVGA3D_ARGB_S10E5 = 24, /* 16-bit floating-point ARGB */
+ SVGA3D_ARGB_S23E8 = 25, /* 32-bit floating-point ARGB */
+
+ SVGA3D_A2R10G10B10 = 26,
+
+ /* signed formats */
+ SVGA3D_V8U8 = 27,
+ SVGA3D_Q8W8V8U8 = 28,
+ SVGA3D_CxV8U8 = 29,
+
+ /* mixed formats */
+ SVGA3D_X8L8V8U8 = 30,
+ SVGA3D_A2W10V10U10 = 31,
+
+ SVGA3D_ALPHA8 = 32,
+
+ /* Single- and dual-component floating point formats */
+ SVGA3D_R_S10E5 = 33,
+ SVGA3D_R_S23E8 = 34,
+ SVGA3D_RG_S10E5 = 35,
+ SVGA3D_RG_S23E8 = 36,
+
+ /*
+ * Any surface can be used as a buffer object, but SVGA3D_BUFFER is
+ * the most efficient format to use when creating new surfaces
+ * expressly for index or vertex data.
+ */
+
+ SVGA3D_BUFFER = 37,
+
+ SVGA3D_Z_D24X8 = 38,
+
+ SVGA3D_V16U16 = 39,
+
+ SVGA3D_G16R16 = 40,
+ SVGA3D_A16B16G16R16 = 41,
+
+ /* Packed Video formats */
+ SVGA3D_UYVY = 42,
+ SVGA3D_YUY2 = 43,
+
+ /* Planar video formats */
+ SVGA3D_NV12 = 44,
+
+ /* Video format with alpha */
+ SVGA3D_AYUV = 45,
+
+ SVGA3D_BC4_UNORM = 108,
+ SVGA3D_BC5_UNORM = 111,
+
+ /* Advanced D3D9 depth formats. */
+ SVGA3D_Z_DF16 = 118,
+ SVGA3D_Z_DF24 = 119,
+ SVGA3D_Z_D24S8_INT = 120,
+
+ SVGA3D_FORMAT_MAX
+} SVGA3dSurfaceFormat;
+
+typedef uint32 SVGA3dColor; /* a, r, g, b */
+
+/*
+ * These match the D3DFORMAT_OP definitions used by Direct3D. We need
+ * them so that we can query the host for what the supported surface
+ * operations are (when we're using the D3D backend, in particular),
+ * and so we can send those operations to the guest.
+ */
+typedef enum {
+ SVGA3DFORMAT_OP_TEXTURE = 0x00000001,
+ SVGA3DFORMAT_OP_VOLUMETEXTURE = 0x00000002,
+ SVGA3DFORMAT_OP_CUBETEXTURE = 0x00000004,
+ SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET = 0x00000008,
+ SVGA3DFORMAT_OP_SAME_FORMAT_RENDERTARGET = 0x00000010,
+ SVGA3DFORMAT_OP_ZSTENCIL = 0x00000040,
+ SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH = 0x00000080,
+
+/*
+ * This format can be used as a render target if the current display mode
+ * is the same depth if the alpha channel is ignored. e.g. if the device
+ * can render to A8R8G8B8 when the display mode is X8R8G8B8, then the
+ * format op list entry for A8R8G8B8 should have this cap.
+ */
+ SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET = 0x00000100,
+
+/*
+ * This format contains DirectDraw support (including Flip). This flag
+ * should not to be set on alpha formats.
+ */
+ SVGA3DFORMAT_OP_DISPLAYMODE = 0x00000400,
+
+/*
+ * The rasterizer can support some level of Direct3D support in this format
+ * and implies that the driver can create a Context in this mode (for some
+ * render target format). When this flag is set, the SVGA3DFORMAT_OP_DISPLAYMODE
+ * flag must also be set.
+ */
+ SVGA3DFORMAT_OP_3DACCELERATION = 0x00000800,
+
+/*
+ * This is set for a private format when the driver has put the bpp in
+ * the structure.
+ */
+ SVGA3DFORMAT_OP_PIXELSIZE = 0x00001000,
+
+/*
+ * Indicates that this format can be converted to any RGB format for which
+ * SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB is specified
+ */
+ SVGA3DFORMAT_OP_CONVERT_TO_ARGB = 0x00002000,
+
+/*
+ * Indicates that this format can be used to create offscreen plain surfaces.
+ */
+ SVGA3DFORMAT_OP_OFFSCREENPLAIN = 0x00004000,
+
+/*
+ * Indicated that this format can be read as an SRGB texture (meaning that the
+ * sampler will linearize the looked up data)
+ */
+ SVGA3DFORMAT_OP_SRGBREAD = 0x00008000,
+
+/*
+ * Indicates that this format can be used in the bumpmap instructions
+ */
+ SVGA3DFORMAT_OP_BUMPMAP = 0x00010000,
+
+/*
+ * Indicates that this format can be sampled by the displacement map sampler
+ */
+ SVGA3DFORMAT_OP_DMAP = 0x00020000,
+
+/*
+ * Indicates that this format cannot be used with texture filtering
+ */
+ SVGA3DFORMAT_OP_NOFILTER = 0x00040000,
+
+/*
+ * Indicates that format conversions are supported to this RGB format if
+ * SVGA3DFORMAT_OP_CONVERT_TO_ARGB is specified in the source format.
+ */
+ SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB = 0x00080000,
+
+/*
+ * Indicated that this format can be written as an SRGB target (meaning that the
+ * pixel pipe will DE-linearize data on output to format)
+ */
+ SVGA3DFORMAT_OP_SRGBWRITE = 0x00100000,
+
+/*
+ * Indicates that this format cannot be used with alpha blending
+ */
+ SVGA3DFORMAT_OP_NOALPHABLEND = 0x00200000,
+
+/*
+ * Indicates that the device can auto-generated sublevels for resources
+ * of this format
+ */
+ SVGA3DFORMAT_OP_AUTOGENMIPMAP = 0x00400000,
+
+/*
+ * Indicates that this format can be used by vertex texture sampler
+ */
+ SVGA3DFORMAT_OP_VERTEXTEXTURE = 0x00800000,
+
+/*
+ * Indicates that this format supports neither texture coordinate wrap
+ * modes, nor mipmapping
+ */
+ SVGA3DFORMAT_OP_NOTEXCOORDWRAPNORMIP = 0x01000000
+} SVGA3dFormatOp;
+
+/*
+ * This structure is a conversion of SVGA3DFORMAT_OP_*.
+ * Entries must be located at the same position.
+ */
+typedef union {
+ uint32 value;
+ struct {
+ uint32 texture : 1;
+ uint32 volumeTexture : 1;
+ uint32 cubeTexture : 1;
+ uint32 offscreenRenderTarget : 1;
+ uint32 sameFormatRenderTarget : 1;
+ uint32 unknown1 : 1;
+ uint32 zStencil : 1;
+ uint32 zStencilArbitraryDepth : 1;
+ uint32 sameFormatUpToAlpha : 1;
+ uint32 unknown2 : 1;
+ uint32 displayMode : 1;
+ uint32 acceleration3d : 1;
+ uint32 pixelSize : 1;
+ uint32 convertToARGB : 1;
+ uint32 offscreenPlain : 1;
+ uint32 sRGBRead : 1;
+ uint32 bumpMap : 1;
+ uint32 dmap : 1;
+ uint32 noFilter : 1;
+ uint32 memberOfGroupARGB : 1;
+ uint32 sRGBWrite : 1;
+ uint32 noAlphaBlend : 1;
+ uint32 autoGenMipMap : 1;
+ uint32 vertexTexture : 1;
+ uint32 noTexCoordWrapNorMip : 1;
+ };
+} SVGA3dSurfaceFormatCaps;
+
+/*
+ * SVGA_3D_CMD_SETRENDERSTATE Types. All value types
+ * must fit in a uint32.
+ */
+
+typedef enum {
+ SVGA3D_RS_INVALID = 0,
+ SVGA3D_RS_ZENABLE = 1, /* SVGA3dBool */
+ SVGA3D_RS_ZWRITEENABLE = 2, /* SVGA3dBool */
+ SVGA3D_RS_ALPHATESTENABLE = 3, /* SVGA3dBool */
+ SVGA3D_RS_DITHERENABLE = 4, /* SVGA3dBool */
+ SVGA3D_RS_BLENDENABLE = 5, /* SVGA3dBool */
+ SVGA3D_RS_FOGENABLE = 6, /* SVGA3dBool */
+ SVGA3D_RS_SPECULARENABLE = 7, /* SVGA3dBool */
+ SVGA3D_RS_STENCILENABLE = 8, /* SVGA3dBool */
+ SVGA3D_RS_LIGHTINGENABLE = 9, /* SVGA3dBool */
+ SVGA3D_RS_NORMALIZENORMALS = 10, /* SVGA3dBool */
+ SVGA3D_RS_POINTSPRITEENABLE = 11, /* SVGA3dBool */
+ SVGA3D_RS_POINTSCALEENABLE = 12, /* SVGA3dBool */
+ SVGA3D_RS_STENCILREF = 13, /* uint32 */
+ SVGA3D_RS_STENCILMASK = 14, /* uint32 */
+ SVGA3D_RS_STENCILWRITEMASK = 15, /* uint32 */
+ SVGA3D_RS_FOGSTART = 16, /* float */
+ SVGA3D_RS_FOGEND = 17, /* float */
+ SVGA3D_RS_FOGDENSITY = 18, /* float */
+ SVGA3D_RS_POINTSIZE = 19, /* float */
+ SVGA3D_RS_POINTSIZEMIN = 20, /* float */
+ SVGA3D_RS_POINTSIZEMAX = 21, /* float */
+ SVGA3D_RS_POINTSCALE_A = 22, /* float */
+ SVGA3D_RS_POINTSCALE_B = 23, /* float */
+ SVGA3D_RS_POINTSCALE_C = 24, /* float */
+ SVGA3D_RS_FOGCOLOR = 25, /* SVGA3dColor */
+ SVGA3D_RS_AMBIENT = 26, /* SVGA3dColor */
+ SVGA3D_RS_CLIPPLANEENABLE = 27, /* SVGA3dClipPlanes */
+ SVGA3D_RS_FOGMODE = 28, /* SVGA3dFogMode */
+ SVGA3D_RS_FILLMODE = 29, /* SVGA3dFillMode */
+ SVGA3D_RS_SHADEMODE = 30, /* SVGA3dShadeMode */
+ SVGA3D_RS_LINEPATTERN = 31, /* SVGA3dLinePattern */
+ SVGA3D_RS_SRCBLEND = 32, /* SVGA3dBlendOp */
+ SVGA3D_RS_DSTBLEND = 33, /* SVGA3dBlendOp */
+ SVGA3D_RS_BLENDEQUATION = 34, /* SVGA3dBlendEquation */
+ SVGA3D_RS_CULLMODE = 35, /* SVGA3dFace */
+ SVGA3D_RS_ZFUNC = 36, /* SVGA3dCmpFunc */
+ SVGA3D_RS_ALPHAFUNC = 37, /* SVGA3dCmpFunc */
+ SVGA3D_RS_STENCILFUNC = 38, /* SVGA3dCmpFunc */
+ SVGA3D_RS_STENCILFAIL = 39, /* SVGA3dStencilOp */
+ SVGA3D_RS_STENCILZFAIL = 40, /* SVGA3dStencilOp */
+ SVGA3D_RS_STENCILPASS = 41, /* SVGA3dStencilOp */
+ SVGA3D_RS_ALPHAREF = 42, /* float (0.0 .. 1.0) */
+ SVGA3D_RS_FRONTWINDING = 43, /* SVGA3dFrontWinding */
+ SVGA3D_RS_COORDINATETYPE = 44, /* SVGA3dCoordinateType */
+ SVGA3D_RS_ZBIAS = 45, /* float */
+ SVGA3D_RS_RANGEFOGENABLE = 46, /* SVGA3dBool */
+ SVGA3D_RS_COLORWRITEENABLE = 47, /* SVGA3dColorMask */
+ SVGA3D_RS_VERTEXMATERIALENABLE = 48, /* SVGA3dBool */
+ SVGA3D_RS_DIFFUSEMATERIALSOURCE = 49, /* SVGA3dVertexMaterial */
+ SVGA3D_RS_SPECULARMATERIALSOURCE = 50, /* SVGA3dVertexMaterial */
+ SVGA3D_RS_AMBIENTMATERIALSOURCE = 51, /* SVGA3dVertexMaterial */
+ SVGA3D_RS_EMISSIVEMATERIALSOURCE = 52, /* SVGA3dVertexMaterial */
+ SVGA3D_RS_TEXTUREFACTOR = 53, /* SVGA3dColor */
+ SVGA3D_RS_LOCALVIEWER = 54, /* SVGA3dBool */
+ SVGA3D_RS_SCISSORTESTENABLE = 55, /* SVGA3dBool */
+ SVGA3D_RS_BLENDCOLOR = 56, /* SVGA3dColor */
+ SVGA3D_RS_STENCILENABLE2SIDED = 57, /* SVGA3dBool */
+ SVGA3D_RS_CCWSTENCILFUNC = 58, /* SVGA3dCmpFunc */
+ SVGA3D_RS_CCWSTENCILFAIL = 59, /* SVGA3dStencilOp */
+ SVGA3D_RS_CCWSTENCILZFAIL = 60, /* SVGA3dStencilOp */
+ SVGA3D_RS_CCWSTENCILPASS = 61, /* SVGA3dStencilOp */
+ SVGA3D_RS_VERTEXBLEND = 62, /* SVGA3dVertexBlendFlags */
+ SVGA3D_RS_SLOPESCALEDEPTHBIAS = 63, /* float */
+ SVGA3D_RS_DEPTHBIAS = 64, /* float */
+
+
+ /*
+ * Output Gamma Level
+ *
+ * Output gamma effects the gamma curve of colors that are output from the
+ * rendering pipeline. A value of 1.0 specifies a linear color space. If the
+ * value is <= 0.0, gamma correction is ignored and linear color space is
+ * used.
+ */
+
+ SVGA3D_RS_OUTPUTGAMMA = 65, /* float */
+ SVGA3D_RS_ZVISIBLE = 66, /* SVGA3dBool */
+ SVGA3D_RS_LASTPIXEL = 67, /* SVGA3dBool */
+ SVGA3D_RS_CLIPPING = 68, /* SVGA3dBool */
+ SVGA3D_RS_WRAP0 = 69, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP1 = 70, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP2 = 71, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP3 = 72, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP4 = 73, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP5 = 74, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP6 = 75, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP7 = 76, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP8 = 77, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP9 = 78, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP10 = 79, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP11 = 80, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP12 = 81, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP13 = 82, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP14 = 83, /* SVGA3dWrapFlags */
+ SVGA3D_RS_WRAP15 = 84, /* SVGA3dWrapFlags */
+ SVGA3D_RS_MULTISAMPLEANTIALIAS = 85, /* SVGA3dBool */
+ SVGA3D_RS_MULTISAMPLEMASK = 86, /* uint32 */
+ SVGA3D_RS_INDEXEDVERTEXBLENDENABLE = 87, /* SVGA3dBool */
+ SVGA3D_RS_TWEENFACTOR = 88, /* float */
+ SVGA3D_RS_ANTIALIASEDLINEENABLE = 89, /* SVGA3dBool */
+ SVGA3D_RS_COLORWRITEENABLE1 = 90, /* SVGA3dColorMask */
+ SVGA3D_RS_COLORWRITEENABLE2 = 91, /* SVGA3dColorMask */
+ SVGA3D_RS_COLORWRITEENABLE3 = 92, /* SVGA3dColorMask */
+ SVGA3D_RS_SEPARATEALPHABLENDENABLE = 93, /* SVGA3dBool */
+ SVGA3D_RS_SRCBLENDALPHA = 94, /* SVGA3dBlendOp */
+ SVGA3D_RS_DSTBLENDALPHA = 95, /* SVGA3dBlendOp */
+ SVGA3D_RS_BLENDEQUATIONALPHA = 96, /* SVGA3dBlendEquation */
+ SVGA3D_RS_TRANSPARENCYANTIALIAS = 97, /* SVGA3dTransparencyAntialiasType */
+ SVGA3D_RS_LINEAA = 98, /* SVGA3dBool */
+ SVGA3D_RS_LINEWIDTH = 99, /* float */
+ SVGA3D_RS_MAX
+} SVGA3dRenderStateName;
+
+typedef enum {
+ SVGA3D_TRANSPARENCYANTIALIAS_NORMAL = 0,
+ SVGA3D_TRANSPARENCYANTIALIAS_ALPHATOCOVERAGE = 1,
+ SVGA3D_TRANSPARENCYANTIALIAS_SUPERSAMPLE = 2,
+ SVGA3D_TRANSPARENCYANTIALIAS_MAX
+} SVGA3dTransparencyAntialiasType;
+
+typedef enum {
+ SVGA3D_VERTEXMATERIAL_NONE = 0, /* Use the value in the current material */
+ SVGA3D_VERTEXMATERIAL_DIFFUSE = 1, /* Use the value in the diffuse component */
+ SVGA3D_VERTEXMATERIAL_SPECULAR = 2, /* Use the value in the specular component */
+} SVGA3dVertexMaterial;
+
+typedef enum {
+ SVGA3D_FILLMODE_INVALID = 0,
+ SVGA3D_FILLMODE_POINT = 1,
+ SVGA3D_FILLMODE_LINE = 2,
+ SVGA3D_FILLMODE_FILL = 3,
+ SVGA3D_FILLMODE_MAX
+} SVGA3dFillModeType;
+
+
+typedef
+union {
+ struct {
+ uint16 mode; /* SVGA3dFillModeType */
+ uint16 face; /* SVGA3dFace */
+ };
+ uint32 uintValue;
+} SVGA3dFillMode;
+
+typedef enum {
+ SVGA3D_SHADEMODE_INVALID = 0,
+ SVGA3D_SHADEMODE_FLAT = 1,
+ SVGA3D_SHADEMODE_SMOOTH = 2,
+ SVGA3D_SHADEMODE_PHONG = 3, /* Not supported */
+ SVGA3D_SHADEMODE_MAX
+} SVGA3dShadeMode;
+
+typedef
+union {
+ struct {
+ uint16 repeat;
+ uint16 pattern;
+ };
+ uint32 uintValue;
+} SVGA3dLinePattern;
+
+typedef enum {
+ SVGA3D_BLENDOP_INVALID = 0,
+ SVGA3D_BLENDOP_ZERO = 1,
+ SVGA3D_BLENDOP_ONE = 2,
+ SVGA3D_BLENDOP_SRCCOLOR = 3,
+ SVGA3D_BLENDOP_INVSRCCOLOR = 4,
+ SVGA3D_BLENDOP_SRCALPHA = 5,
+ SVGA3D_BLENDOP_INVSRCALPHA = 6,
+ SVGA3D_BLENDOP_DESTALPHA = 7,
+ SVGA3D_BLENDOP_INVDESTALPHA = 8,
+ SVGA3D_BLENDOP_DESTCOLOR = 9,
+ SVGA3D_BLENDOP_INVDESTCOLOR = 10,
+ SVGA3D_BLENDOP_SRCALPHASAT = 11,
+ SVGA3D_BLENDOP_BLENDFACTOR = 12,
+ SVGA3D_BLENDOP_INVBLENDFACTOR = 13,
+ SVGA3D_BLENDOP_MAX
+} SVGA3dBlendOp;
+
+typedef enum {
+ SVGA3D_BLENDEQ_INVALID = 0,
+ SVGA3D_BLENDEQ_ADD = 1,
+ SVGA3D_BLENDEQ_SUBTRACT = 2,
+ SVGA3D_BLENDEQ_REVSUBTRACT = 3,
+ SVGA3D_BLENDEQ_MINIMUM = 4,
+ SVGA3D_BLENDEQ_MAXIMUM = 5,
+ SVGA3D_BLENDEQ_MAX
+} SVGA3dBlendEquation;
+
+typedef enum {
+ SVGA3D_FRONTWINDING_INVALID = 0,
+ SVGA3D_FRONTWINDING_CW = 1,
+ SVGA3D_FRONTWINDING_CCW = 2,
+ SVGA3D_FRONTWINDING_MAX
+} SVGA3dFrontWinding;
+
+typedef enum {
+ SVGA3D_FACE_INVALID = 0,
+ SVGA3D_FACE_NONE = 1,
+ SVGA3D_FACE_FRONT = 2,
+ SVGA3D_FACE_BACK = 3,
+ SVGA3D_FACE_FRONT_BACK = 4,
+ SVGA3D_FACE_MAX
+} SVGA3dFace;
+
+/*
+ * The order and the values should not be changed
+ */
+
+typedef enum {
+ SVGA3D_CMP_INVALID = 0,
+ SVGA3D_CMP_NEVER = 1,
+ SVGA3D_CMP_LESS = 2,
+ SVGA3D_CMP_EQUAL = 3,
+ SVGA3D_CMP_LESSEQUAL = 4,
+ SVGA3D_CMP_GREATER = 5,
+ SVGA3D_CMP_NOTEQUAL = 6,
+ SVGA3D_CMP_GREATEREQUAL = 7,
+ SVGA3D_CMP_ALWAYS = 8,
+ SVGA3D_CMP_MAX
+} SVGA3dCmpFunc;
+
+/*
+ * SVGA3D_FOGFUNC_* specifies the fog equation, or PER_VERTEX which allows
+ * the fog factor to be specified in the alpha component of the specular
+ * (a.k.a. secondary) vertex color.
+ */
+typedef enum {
+ SVGA3D_FOGFUNC_INVALID = 0,
+ SVGA3D_FOGFUNC_EXP = 1,
+ SVGA3D_FOGFUNC_EXP2 = 2,
+ SVGA3D_FOGFUNC_LINEAR = 3,
+ SVGA3D_FOGFUNC_PER_VERTEX = 4
+} SVGA3dFogFunction;
+
+/*
+ * SVGA3D_FOGTYPE_* specifies if fog factors are computed on a per-vertex
+ * or per-pixel basis.
+ */
+typedef enum {
+ SVGA3D_FOGTYPE_INVALID = 0,
+ SVGA3D_FOGTYPE_VERTEX = 1,
+ SVGA3D_FOGTYPE_PIXEL = 2,
+ SVGA3D_FOGTYPE_MAX = 3
+} SVGA3dFogType;
+
+/*
+ * SVGA3D_FOGBASE_* selects depth or range-based fog. Depth-based fog is
+ * computed using the eye Z value of each pixel (or vertex), whereas range-
+ * based fog is computed using the actual distance (range) to the eye.
+ */
+typedef enum {
+ SVGA3D_FOGBASE_INVALID = 0,
+ SVGA3D_FOGBASE_DEPTHBASED = 1,
+ SVGA3D_FOGBASE_RANGEBASED = 2,
+ SVGA3D_FOGBASE_MAX = 3
+} SVGA3dFogBase;
+
+typedef enum {
+ SVGA3D_STENCILOP_INVALID = 0,
+ SVGA3D_STENCILOP_KEEP = 1,
+ SVGA3D_STENCILOP_ZERO = 2,
+ SVGA3D_STENCILOP_REPLACE = 3,
+ SVGA3D_STENCILOP_INCRSAT = 4,
+ SVGA3D_STENCILOP_DECRSAT = 5,
+ SVGA3D_STENCILOP_INVERT = 6,
+ SVGA3D_STENCILOP_INCR = 7,
+ SVGA3D_STENCILOP_DECR = 8,
+ SVGA3D_STENCILOP_MAX
+} SVGA3dStencilOp;
+
+typedef enum {
+ SVGA3D_CLIPPLANE_0 = (1 << 0),
+ SVGA3D_CLIPPLANE_1 = (1 << 1),
+ SVGA3D_CLIPPLANE_2 = (1 << 2),
+ SVGA3D_CLIPPLANE_3 = (1 << 3),
+ SVGA3D_CLIPPLANE_4 = (1 << 4),
+ SVGA3D_CLIPPLANE_5 = (1 << 5),
+} SVGA3dClipPlanes;
+
+typedef enum {
+ SVGA3D_CLEAR_COLOR = 0x1,
+ SVGA3D_CLEAR_DEPTH = 0x2,
+ SVGA3D_CLEAR_STENCIL = 0x4
+} SVGA3dClearFlag;
+
+typedef enum {
+ SVGA3D_RT_DEPTH = 0,
+ SVGA3D_RT_STENCIL = 1,
+ SVGA3D_RT_COLOR0 = 2,
+ SVGA3D_RT_COLOR1 = 3,
+ SVGA3D_RT_COLOR2 = 4,
+ SVGA3D_RT_COLOR3 = 5,
+ SVGA3D_RT_COLOR4 = 6,
+ SVGA3D_RT_COLOR5 = 7,
+ SVGA3D_RT_COLOR6 = 8,
+ SVGA3D_RT_COLOR7 = 9,
+ SVGA3D_RT_MAX,
+ SVGA3D_RT_INVALID = ((uint32)-1),
+} SVGA3dRenderTargetType;
+
+#define SVGA3D_MAX_RT_COLOR (SVGA3D_RT_COLOR7 - SVGA3D_RT_COLOR0 + 1)
+
+typedef
+union {
+ struct {
+ uint32 red : 1;
+ uint32 green : 1;
+ uint32 blue : 1;
+ uint32 alpha : 1;
+ };
+ uint32 uintValue;
+} SVGA3dColorMask;
+
+typedef enum {
+ SVGA3D_VBLEND_DISABLE = 0,
+ SVGA3D_VBLEND_1WEIGHT = 1,
+ SVGA3D_VBLEND_2WEIGHT = 2,
+ SVGA3D_VBLEND_3WEIGHT = 3,
+} SVGA3dVertexBlendFlags;
+
+typedef enum {
+ SVGA3D_WRAPCOORD_0 = 1 << 0,
+ SVGA3D_WRAPCOORD_1 = 1 << 1,
+ SVGA3D_WRAPCOORD_2 = 1 << 2,
+ SVGA3D_WRAPCOORD_3 = 1 << 3,
+ SVGA3D_WRAPCOORD_ALL = 0xF,
+} SVGA3dWrapFlags;
+
+/*
+ * SVGA_3D_CMD_TEXTURESTATE Types. All value types
+ * must fit in a uint32.
+ */
+
+typedef enum {
+ SVGA3D_TS_INVALID = 0,
+ SVGA3D_TS_MIN = 1,
+ SVGA3D_TS_BIND_TEXTURE = 1, /* SVGA3dSurfaceId */
+ SVGA3D_TS_COLOROP = 2, /* SVGA3dTextureCombiner */
+ SVGA3D_TS_COLORARG1 = 3, /* SVGA3dTextureArgData */
+ SVGA3D_TS_COLORARG2 = 4, /* SVGA3dTextureArgData */
+ SVGA3D_TS_ALPHAOP = 5, /* SVGA3dTextureCombiner */
+ SVGA3D_TS_ALPHAARG1 = 6, /* SVGA3dTextureArgData */
+ SVGA3D_TS_ALPHAARG2 = 7, /* SVGA3dTextureArgData */
+ SVGA3D_TS_ADDRESSU = 8, /* SVGA3dTextureAddress */
+ SVGA3D_TS_ADDRESSV = 9, /* SVGA3dTextureAddress */
+ SVGA3D_TS_MIPFILTER = 10, /* SVGA3dTextureFilter */
+ SVGA3D_TS_MAGFILTER = 11, /* SVGA3dTextureFilter */
+ SVGA3D_TS_MINFILTER = 12, /* SVGA3dTextureFilter */
+ SVGA3D_TS_BORDERCOLOR = 13, /* SVGA3dColor */
+ SVGA3D_TS_TEXCOORDINDEX = 14, /* uint32 */
+ SVGA3D_TS_TEXTURETRANSFORMFLAGS = 15, /* SVGA3dTexTransformFlags */
+ SVGA3D_TS_TEXCOORDGEN = 16, /* SVGA3dTextureCoordGen */
+ SVGA3D_TS_BUMPENVMAT00 = 17, /* float */
+ SVGA3D_TS_BUMPENVMAT01 = 18, /* float */
+ SVGA3D_TS_BUMPENVMAT10 = 19, /* float */
+ SVGA3D_TS_BUMPENVMAT11 = 20, /* float */
+ SVGA3D_TS_TEXTURE_MIPMAP_LEVEL = 21, /* uint32 */
+ SVGA3D_TS_TEXTURE_LOD_BIAS = 22, /* float */
+ SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL = 23, /* uint32 */
+ SVGA3D_TS_ADDRESSW = 24, /* SVGA3dTextureAddress */
+
+
+ /*
+ * Sampler Gamma Level
+ *
+ * Sampler gamma effects the color of samples taken from the sampler. A
+ * value of 1.0 will produce linear samples. If the value is <= 0.0 the
+ * gamma value is ignored and a linear space is used.
+ */
+
+ SVGA3D_TS_GAMMA = 25, /* float */
+ SVGA3D_TS_BUMPENVLSCALE = 26, /* float */
+ SVGA3D_TS_BUMPENVLOFFSET = 27, /* float */
+ SVGA3D_TS_COLORARG0 = 28, /* SVGA3dTextureArgData */
+ SVGA3D_TS_ALPHAARG0 = 29, /* SVGA3dTextureArgData */
+ SVGA3D_TS_PREGB_MAX = 30, /* Max value before GBObjects */
+ SVGA3D_TS_CONSTANT = 30, /* SVGA3dColor */
+ SVGA3D_TS_COLOR_KEY_ENABLE = 31, /* SVGA3dBool */
+ SVGA3D_TS_COLOR_KEY = 32, /* SVGA3dColor */
+ SVGA3D_TS_MAX
+} SVGA3dTextureStateName;
+
+typedef enum {
+ SVGA3D_TC_INVALID = 0,
+ SVGA3D_TC_DISABLE = 1,
+ SVGA3D_TC_SELECTARG1 = 2,
+ SVGA3D_TC_SELECTARG2 = 3,
+ SVGA3D_TC_MODULATE = 4,
+ SVGA3D_TC_ADD = 5,
+ SVGA3D_TC_ADDSIGNED = 6,
+ SVGA3D_TC_SUBTRACT = 7,
+ SVGA3D_TC_BLENDTEXTUREALPHA = 8,
+ SVGA3D_TC_BLENDDIFFUSEALPHA = 9,
+ SVGA3D_TC_BLENDCURRENTALPHA = 10,
+ SVGA3D_TC_BLENDFACTORALPHA = 11,
+ SVGA3D_TC_MODULATE2X = 12,
+ SVGA3D_TC_MODULATE4X = 13,
+ SVGA3D_TC_DSDT = 14,
+ SVGA3D_TC_DOTPRODUCT3 = 15,
+ SVGA3D_TC_BLENDTEXTUREALPHAPM = 16,
+ SVGA3D_TC_ADDSIGNED2X = 17,
+ SVGA3D_TC_ADDSMOOTH = 18,
+ SVGA3D_TC_PREMODULATE = 19,
+ SVGA3D_TC_MODULATEALPHA_ADDCOLOR = 20,
+ SVGA3D_TC_MODULATECOLOR_ADDALPHA = 21,
+ SVGA3D_TC_MODULATEINVALPHA_ADDCOLOR = 22,
+ SVGA3D_TC_MODULATEINVCOLOR_ADDALPHA = 23,
+ SVGA3D_TC_BUMPENVMAPLUMINANCE = 24,
+ SVGA3D_TC_MULTIPLYADD = 25,
+ SVGA3D_TC_LERP = 26,
+ SVGA3D_TC_MAX
+} SVGA3dTextureCombiner;
+
+#define SVGA3D_TC_CAP_BIT(svga3d_tc_op) (svga3d_tc_op ? (1 << (svga3d_tc_op - 1)) : 0)
+
+typedef enum {
+ SVGA3D_TEX_ADDRESS_INVALID = 0,
+ SVGA3D_TEX_ADDRESS_WRAP = 1,
+ SVGA3D_TEX_ADDRESS_MIRROR = 2,
+ SVGA3D_TEX_ADDRESS_CLAMP = 3,
+ SVGA3D_TEX_ADDRESS_BORDER = 4,
+ SVGA3D_TEX_ADDRESS_MIRRORONCE = 5,
+ SVGA3D_TEX_ADDRESS_EDGE = 6,
+ SVGA3D_TEX_ADDRESS_MAX
+} SVGA3dTextureAddress;
+
+/*
+ * SVGA3D_TEX_FILTER_NONE as the minification filter means mipmapping is
+ * disabled, and the rasterizer should use the magnification filter instead.
+ */
+typedef enum {
+ SVGA3D_TEX_FILTER_NONE = 0,
+ SVGA3D_TEX_FILTER_NEAREST = 1,
+ SVGA3D_TEX_FILTER_LINEAR = 2,
+ SVGA3D_TEX_FILTER_ANISOTROPIC = 3,
+ SVGA3D_TEX_FILTER_FLATCUBIC = 4, // Deprecated, not implemented
+ SVGA3D_TEX_FILTER_GAUSSIANCUBIC = 5, // Deprecated, not implemented
+ SVGA3D_TEX_FILTER_PYRAMIDALQUAD = 6, // Not currently implemented
+ SVGA3D_TEX_FILTER_GAUSSIANQUAD = 7, // Not currently implemented
+ SVGA3D_TEX_FILTER_MAX
+} SVGA3dTextureFilter;
+
+typedef enum {
+ SVGA3D_TEX_TRANSFORM_OFF = 0,
+ SVGA3D_TEX_TRANSFORM_S = (1 << 0),
+ SVGA3D_TEX_TRANSFORM_T = (1 << 1),
+ SVGA3D_TEX_TRANSFORM_R = (1 << 2),
+ SVGA3D_TEX_TRANSFORM_Q = (1 << 3),
+ SVGA3D_TEX_PROJECTED = (1 << 15),
+} SVGA3dTexTransformFlags;
+
+typedef enum {
+ SVGA3D_TEXCOORD_GEN_OFF = 0,
+ SVGA3D_TEXCOORD_GEN_EYE_POSITION = 1,
+ SVGA3D_TEXCOORD_GEN_EYE_NORMAL = 2,
+ SVGA3D_TEXCOORD_GEN_REFLECTIONVECTOR = 3,
+ SVGA3D_TEXCOORD_GEN_SPHERE = 4,
+ SVGA3D_TEXCOORD_GEN_MAX
+} SVGA3dTextureCoordGen;
+
+/*
+ * Texture argument constants for texture combiner
+ */
+typedef enum {
+ SVGA3D_TA_INVALID = 0,
+ SVGA3D_TA_CONSTANT = 1,
+ SVGA3D_TA_PREVIOUS = 2,
+ SVGA3D_TA_DIFFUSE = 3,
+ SVGA3D_TA_TEXTURE = 4,
+ SVGA3D_TA_SPECULAR = 5,
+ SVGA3D_TA_MAX
+} SVGA3dTextureArgData;
+
+#define SVGA3D_TM_MASK_LEN 4
+
+/* Modifiers for texture argument constants defined above. */
+typedef enum {
+ SVGA3D_TM_NONE = 0,
+ SVGA3D_TM_ALPHA = (1 << SVGA3D_TM_MASK_LEN),
+ SVGA3D_TM_ONE_MINUS = (2 << SVGA3D_TM_MASK_LEN),
+} SVGA3dTextureArgModifier;
+
+#define SVGA3D_INVALID_ID ((uint32)-1)
+#define SVGA3D_MAX_CLIP_PLANES 6
+
+/*
+ * This is the limit to the number of fixed-function texture
+ * transforms and texture coordinates we can support. It does *not*
+ * correspond to the number of texture image units (samplers) we
+ * support!
+ */
+#define SVGA3D_MAX_TEXTURE_COORDS 8
+
+/*
+ * Vertex declarations
+ *
+ * Notes:
+ *
+ * SVGA3D_DECLUSAGE_POSITIONT is for pre-transformed vertices. If you
+ * draw with any POSITIONT vertex arrays, the programmable vertex
+ * pipeline will be implicitly disabled. Drawing will take place as if
+ * no vertex shader was bound.
+ */
+
+typedef enum {
+ SVGA3D_DECLUSAGE_POSITION = 0,
+ SVGA3D_DECLUSAGE_BLENDWEIGHT, // 1
+ SVGA3D_DECLUSAGE_BLENDINDICES, // 2
+ SVGA3D_DECLUSAGE_NORMAL, // 3
+ SVGA3D_DECLUSAGE_PSIZE, // 4
+ SVGA3D_DECLUSAGE_TEXCOORD, // 5
+ SVGA3D_DECLUSAGE_TANGENT, // 6
+ SVGA3D_DECLUSAGE_BINORMAL, // 7
+ SVGA3D_DECLUSAGE_TESSFACTOR, // 8
+ SVGA3D_DECLUSAGE_POSITIONT, // 9
+ SVGA3D_DECLUSAGE_COLOR, // 10
+ SVGA3D_DECLUSAGE_FOG, // 11
+ SVGA3D_DECLUSAGE_DEPTH, // 12
+ SVGA3D_DECLUSAGE_SAMPLE, // 13
+ SVGA3D_DECLUSAGE_MAX
+} SVGA3dDeclUsage;
+
+typedef enum {
+ SVGA3D_DECLMETHOD_DEFAULT = 0,
+ SVGA3D_DECLMETHOD_PARTIALU,
+ SVGA3D_DECLMETHOD_PARTIALV,
+ SVGA3D_DECLMETHOD_CROSSUV, // Normal
+ SVGA3D_DECLMETHOD_UV,
+ SVGA3D_DECLMETHOD_LOOKUP, // Lookup a displacement map
+ SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map
+} SVGA3dDeclMethod;
+
+typedef enum {
+ SVGA3D_DECLTYPE_FLOAT1 = 0,
+ SVGA3D_DECLTYPE_FLOAT2 = 1,
+ SVGA3D_DECLTYPE_FLOAT3 = 2,
+ SVGA3D_DECLTYPE_FLOAT4 = 3,
+ SVGA3D_DECLTYPE_D3DCOLOR = 4,
+ SVGA3D_DECLTYPE_UBYTE4 = 5,
+ SVGA3D_DECLTYPE_SHORT2 = 6,
+ SVGA3D_DECLTYPE_SHORT4 = 7,
+ SVGA3D_DECLTYPE_UBYTE4N = 8,
+ SVGA3D_DECLTYPE_SHORT2N = 9,
+ SVGA3D_DECLTYPE_SHORT4N = 10,
+ SVGA3D_DECLTYPE_USHORT2N = 11,
+ SVGA3D_DECLTYPE_USHORT4N = 12,
+ SVGA3D_DECLTYPE_UDEC3 = 13,
+ SVGA3D_DECLTYPE_DEC3N = 14,
+ SVGA3D_DECLTYPE_FLOAT16_2 = 15,
+ SVGA3D_DECLTYPE_FLOAT16_4 = 16,
+ SVGA3D_DECLTYPE_MAX,
+} SVGA3dDeclType;
+
+/*
+ * This structure is used for the divisor for geometry instancing;
+ * it's a direct translation of the Direct3D equivalent.
+ */
+typedef union {
+ struct {
+ /*
+ * For index data, this number represents the number of instances to draw.
+ * For instance data, this number represents the number of
+ * instances/vertex in this stream
+ */
+ uint32 count : 30;
+
+ /*
+ * This is 1 if this is supposed to be the data that is repeated for
+ * every instance.
+ */
+ uint32 indexedData : 1;
+
+ /*
+ * This is 1 if this is supposed to be the per-instance data.
+ */
+ uint32 instanceData : 1;
+ };
+
+ uint32 value;
+} SVGA3dVertexDivisor;
+
+typedef enum {
+ SVGA3D_PRIMITIVE_INVALID = 0,
+ SVGA3D_PRIMITIVE_TRIANGLELIST = 1,
+ SVGA3D_PRIMITIVE_POINTLIST = 2,
+ SVGA3D_PRIMITIVE_LINELIST = 3,
+ SVGA3D_PRIMITIVE_LINESTRIP = 4,
+ SVGA3D_PRIMITIVE_TRIANGLESTRIP = 5,
+ SVGA3D_PRIMITIVE_TRIANGLEFAN = 6,
+ SVGA3D_PRIMITIVE_MAX
+} SVGA3dPrimitiveType;
+
+typedef enum {
+ SVGA3D_COORDINATE_INVALID = 0,
+ SVGA3D_COORDINATE_LEFTHANDED = 1,
+ SVGA3D_COORDINATE_RIGHTHANDED = 2,
+ SVGA3D_COORDINATE_MAX
+} SVGA3dCoordinateType;
+
+typedef enum {
+ SVGA3D_TRANSFORM_INVALID = 0,
+ SVGA3D_TRANSFORM_WORLD = 1,
+ SVGA3D_TRANSFORM_VIEW = 2,
+ SVGA3D_TRANSFORM_PROJECTION = 3,
+ SVGA3D_TRANSFORM_TEXTURE0 = 4,
+ SVGA3D_TRANSFORM_TEXTURE1 = 5,
+ SVGA3D_TRANSFORM_TEXTURE2 = 6,
+ SVGA3D_TRANSFORM_TEXTURE3 = 7,
+ SVGA3D_TRANSFORM_TEXTURE4 = 8,
+ SVGA3D_TRANSFORM_TEXTURE5 = 9,
+ SVGA3D_TRANSFORM_TEXTURE6 = 10,
+ SVGA3D_TRANSFORM_TEXTURE7 = 11,
+ SVGA3D_TRANSFORM_WORLD1 = 12,
+ SVGA3D_TRANSFORM_WORLD2 = 13,
+ SVGA3D_TRANSFORM_WORLD3 = 14,
+ SVGA3D_TRANSFORM_MAX
+} SVGA3dTransformType;
+
+typedef enum {
+ SVGA3D_LIGHTTYPE_INVALID = 0,
+ SVGA3D_LIGHTTYPE_POINT = 1,
+ SVGA3D_LIGHTTYPE_SPOT1 = 2, /* 1-cone, in degrees */
+ SVGA3D_LIGHTTYPE_SPOT2 = 3, /* 2-cone, in radians */
+ SVGA3D_LIGHTTYPE_DIRECTIONAL = 4,
+ SVGA3D_LIGHTTYPE_MAX
+} SVGA3dLightType;
+
+typedef enum {
+ SVGA3D_CUBEFACE_POSX = 0,
+ SVGA3D_CUBEFACE_NEGX = 1,
+ SVGA3D_CUBEFACE_POSY = 2,
+ SVGA3D_CUBEFACE_NEGY = 3,
+ SVGA3D_CUBEFACE_POSZ = 4,
+ SVGA3D_CUBEFACE_NEGZ = 5,
+} SVGA3dCubeFace;
+
+typedef enum {
+ SVGA3D_SHADERTYPE_INVALID = 0,
+ SVGA3D_SHADERTYPE_MIN = 1,
+ SVGA3D_SHADERTYPE_VS = 1,
+ SVGA3D_SHADERTYPE_PS = 2,
+ SVGA3D_SHADERTYPE_PREDX_MAX = 3,
+ SVGA3D_SHADERTYPE_GS = 3,
+ SVGA3D_SHADERTYPE_DX10_MAX = 4,
+ SVGA3D_SHADERTYPE_HS = 4,
+ SVGA3D_SHADERTYPE_DS = 5,
+ SVGA3D_SHADERTYPE_CS = 6,
+ SVGA3D_SHADERTYPE_MAX = 7
+} SVGA3dShaderType;
+
+#define SVGA3D_NUM_SHADERTYPE_PREDX \
+ (SVGA3D_SHADERTYPE_PREDX_MAX - SVGA3D_SHADERTYPE_MIN)
+
+#define SVGA3D_NUM_SHADERTYPE_DX10 \
+ (SVGA3D_SHADERTYPE_DX10_MAX - SVGA3D_SHADERTYPE_MIN)
+
+#define SVGA3D_NUM_SHADERTYPE \
+ (SVGA3D_SHADERTYPE_MAX - SVGA3D_SHADERTYPE_MIN)
+
+/*
+ * Register limits for shader consts.
+ */
+#define SVGA3D_CONSTREG_MAX 256
+#define SVGA3D_CONSTINTREG_MAX 16
+#define SVGA3D_CONSTBOOLREG_MAX 16
+
+typedef enum {
+ SVGA3D_CONST_TYPE_FLOAT = 0,
+ SVGA3D_CONST_TYPE_INT = 1,
+ SVGA3D_CONST_TYPE_BOOL = 2,
+} SVGA3dShaderConstType;
+
+#define SVGA3D_MAX_SURFACE_FACES 6
+
+typedef enum {
+ SVGA3D_STRETCH_BLT_POINT = 0,
+ SVGA3D_STRETCH_BLT_LINEAR = 1,
+ SVGA3D_STRETCH_BLT_MAX
+} SVGA3dStretchBltMode;
+
+typedef enum {
+ SVGA3D_QUERYTYPE_OCCLUSION = 0,
+ SVGA3D_QUERYTYPE_MAX
+} SVGA3dQueryType;
+
+typedef enum {
+ SVGA3D_QUERYSTATE_PENDING = 0, /* Waiting on the host (set by guest) */
+ SVGA3D_QUERYSTATE_SUCCEEDED = 1, /* Completed successfully (set by host) */
+ SVGA3D_QUERYSTATE_FAILED = 2, /* Completed unsuccessfully (set by host) */
+ SVGA3D_QUERYSTATE_NEW = 3, /* Never submitted (For guest use only) */
+} SVGA3dQueryState;
+
+typedef enum {
+ SVGA3D_WRITE_HOST_VRAM = 1,
+ SVGA3D_READ_HOST_VRAM = 2,
+} SVGA3dTransferType;
+
+/*
+ * The maximum number of vertex arrays we're guaranteed to support in
+ * SVGA_3D_CMD_DRAWPRIMITIVES.
+ */
+#define SVGA3D_MAX_VERTEX_ARRAYS 32
+
+/*
+ * The maximum number of primitive ranges we're guaranteed to support
+ * in SVGA_3D_CMD_DRAWPRIMITIVES.
+ */
+#define SVGA3D_MAX_DRAW_PRIMITIVE_RANGES 32
+
+/*
+ * Identifiers for commands in the command FIFO.
+ *
+ * IDs between 1000 and 1039 (inclusive) were used by obsolete versions of
+ * the SVGA3D protocol and remain reserved; they should not be used in the
+ * future.
+ *
+ * IDs between 1040 and 1999 (inclusive) are available for use by the
+ * current SVGA3D protocol.
+ *
+ * FIFO clients other than SVGA3D should stay below 1000, or at 2000
+ * and up.
+ */
+
+#define SVGA_3D_CMD_LEGACY_BASE 1000
+#define SVGA_3D_CMD_BASE 1040
+
+#define SVGA_3D_CMD_SURFACE_DEFINE SVGA_3D_CMD_BASE + 0 // Deprecated
+#define SVGA_3D_CMD_SURFACE_DESTROY SVGA_3D_CMD_BASE + 1
+#define SVGA_3D_CMD_SURFACE_COPY SVGA_3D_CMD_BASE + 2
+#define SVGA_3D_CMD_SURFACE_STRETCHBLT SVGA_3D_CMD_BASE + 3
+#define SVGA_3D_CMD_SURFACE_DMA SVGA_3D_CMD_BASE + 4
+#define SVGA_3D_CMD_CONTEXT_DEFINE SVGA_3D_CMD_BASE + 5
+#define SVGA_3D_CMD_CONTEXT_DESTROY SVGA_3D_CMD_BASE + 6
+#define SVGA_3D_CMD_SETTRANSFORM SVGA_3D_CMD_BASE + 7
+#define SVGA_3D_CMD_SETZRANGE SVGA_3D_CMD_BASE + 8
+#define SVGA_3D_CMD_SETRENDERSTATE SVGA_3D_CMD_BASE + 9
+#define SVGA_3D_CMD_SETRENDERTARGET SVGA_3D_CMD_BASE + 10
+#define SVGA_3D_CMD_SETTEXTURESTATE SVGA_3D_CMD_BASE + 11
+#define SVGA_3D_CMD_SETMATERIAL SVGA_3D_CMD_BASE + 12
+#define SVGA_3D_CMD_SETLIGHTDATA SVGA_3D_CMD_BASE + 13
+#define SVGA_3D_CMD_SETLIGHTENABLED SVGA_3D_CMD_BASE + 14
+#define SVGA_3D_CMD_SETVIEWPORT SVGA_3D_CMD_BASE + 15
+#define SVGA_3D_CMD_SETCLIPPLANE SVGA_3D_CMD_BASE + 16
+#define SVGA_3D_CMD_CLEAR SVGA_3D_CMD_BASE + 17
+#define SVGA_3D_CMD_PRESENT SVGA_3D_CMD_BASE + 18 // Deprecated
+#define SVGA_3D_CMD_SHADER_DEFINE SVGA_3D_CMD_BASE + 19
+#define SVGA_3D_CMD_SHADER_DESTROY SVGA_3D_CMD_BASE + 20
+#define SVGA_3D_CMD_SET_SHADER SVGA_3D_CMD_BASE + 21
+#define SVGA_3D_CMD_SET_SHADER_CONST SVGA_3D_CMD_BASE + 22
+#define SVGA_3D_CMD_DRAW_PRIMITIVES SVGA_3D_CMD_BASE + 23
+#define SVGA_3D_CMD_SETSCISSORRECT SVGA_3D_CMD_BASE + 24
+#define SVGA_3D_CMD_BEGIN_QUERY SVGA_3D_CMD_BASE + 25
+#define SVGA_3D_CMD_END_QUERY SVGA_3D_CMD_BASE + 26
+#define SVGA_3D_CMD_WAIT_FOR_QUERY SVGA_3D_CMD_BASE + 27
+#define SVGA_3D_CMD_PRESENT_READBACK SVGA_3D_CMD_BASE + 28 // Deprecated
+#define SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN SVGA_3D_CMD_BASE + 29
+#define SVGA_3D_CMD_SURFACE_DEFINE_V2 SVGA_3D_CMD_BASE + 30
+#define SVGA_3D_CMD_GENERATE_MIPMAPS SVGA_3D_CMD_BASE + 31
+#define SVGA_3D_CMD_ACTIVATE_SURFACE SVGA_3D_CMD_BASE + 40
+#define SVGA_3D_CMD_DEACTIVATE_SURFACE SVGA_3D_CMD_BASE + 41
+//#define SVGA_3D_CMD_MAX SVGA_3D_CMD_BASE + 42
+
+/* GPU10 commands */
+#define SVGA_3D_CMD_SCREEN_DMA 1082
+#define SVGA_3D_CMD_DEAD1 1083
+#define SVGA_3D_CMD_DEAD2 1084
+
+#define SVGA_3D_CMD_DEAD12 1085
+#define SVGA_3D_CMD_DEAD13 1086
+#define SVGA_3D_CMD_DEAD14 1087
+#define SVGA_3D_CMD_DEAD15 1088
+#define SVGA_3D_CMD_DEAD16 1089
+#define SVGA_3D_CMD_DEAD17 1090
+
+#define SVGA_3D_CMD_SET_OTABLE_BASE 1091
+#define SVGA_3D_CMD_READBACK_OTABLE 1092
+
+#define SVGA_3D_CMD_DEFINE_GB_MOB 1093
+#define SVGA_3D_CMD_DESTROY_GB_MOB 1094
+#define SVGA_3D_CMD_DEAD3 1095
+#define SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING 1096
+
+#define SVGA_3D_CMD_DEFINE_GB_SURFACE 1097
+#define SVGA_3D_CMD_DESTROY_GB_SURFACE 1098
+#define SVGA_3D_CMD_BIND_GB_SURFACE 1099
+#define SVGA_3D_CMD_COND_BIND_GB_SURFACE 1100
+#define SVGA_3D_CMD_UPDATE_GB_IMAGE 1101
+#define SVGA_3D_CMD_UPDATE_GB_SURFACE 1102
+#define SVGA_3D_CMD_READBACK_GB_IMAGE 1103
+#define SVGA_3D_CMD_READBACK_GB_SURFACE 1104
+#define SVGA_3D_CMD_INVALIDATE_GB_IMAGE 1105
+#define SVGA_3D_CMD_INVALIDATE_GB_SURFACE 1106
+
+#define SVGA_3D_CMD_DEFINE_GB_CONTEXT 1107
+#define SVGA_3D_CMD_DESTROY_GB_CONTEXT 1108
+#define SVGA_3D_CMD_BIND_GB_CONTEXT 1109
+#define SVGA_3D_CMD_READBACK_GB_CONTEXT 1110
+#define SVGA_3D_CMD_INVALIDATE_GB_CONTEXT 1111
+
+#define SVGA_3D_CMD_DEFINE_GB_SHADER 1112
+#define SVGA_3D_CMD_DESTROY_GB_SHADER 1113
+#define SVGA_3D_CMD_BIND_GB_SHADER 1114
+
+#define SVGA_3D_CMD_SET_OTABLE_BASE64 1115
+
+#define SVGA_3D_CMD_BEGIN_GB_QUERY 1116
+#define SVGA_3D_CMD_END_GB_QUERY 1117
+#define SVGA_3D_CMD_WAIT_FOR_GB_QUERY 1118
+
+#define SVGA_3D_CMD_NOP 1119
+
+#define SVGA_3D_CMD_ENABLE_GART 1120
+#define SVGA_3D_CMD_DISABLE_GART 1121
+#define SVGA_3D_CMD_MAP_MOB_INTO_GART 1122
+#define SVGA_3D_CMD_UNMAP_GART_RANGE 1123
+
+#define SVGA_3D_CMD_DEFINE_GB_SCREENTARGET 1124
+#define SVGA_3D_CMD_DESTROY_GB_SCREENTARGET 1125
+#define SVGA_3D_CMD_BIND_GB_SCREENTARGET 1126
+#define SVGA_3D_CMD_UPDATE_GB_SCREENTARGET 1127
+
+#define SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL 1128
+#define SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL 1129
+
+#define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130
+
+#define SVGA_3D_CMD_GB_SCREEN_DMA 1131
+#define SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH 1132
+#define SVGA_3D_CMD_GB_MOB_FENCE 1133
+#define SVGA_3D_CMD_DEFINE_GB_SURFACE_V2 1134
+#define SVGA_3D_CMD_DEFINE_GB_MOB64 1135
+#define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136
+#define SVGA_3D_CMD_NOP_ERROR 1137
+
+#define SVGA_3D_CMD_SET_VERTEX_STREAMS 1138
+#define SVGA_3D_CMD_SET_VERTEX_DECLS 1139
+#define SVGA_3D_CMD_SET_VERTEX_DIVISORS 1140
+#define SVGA_3D_CMD_DRAW 1141
+#define SVGA_3D_CMD_DRAW_INDEXED 1142
+
+#define SVGA_3D_CMD_DX_MIN 1143
+#define SVGA_3D_CMD_DX_DEFINE_CONTEXT 1143
+#define SVGA_3D_CMD_DX_DESTROY_CONTEXT 1144
+#define SVGA_3D_CMD_DX_BIND_CONTEXT 1145
+#define SVGA_3D_CMD_DX_READBACK_CONTEXT 1146
+#define SVGA_3D_CMD_DX_INVALIDATE_CONTEXT 1147
+#define SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER 1148
+#define SVGA_3D_CMD_DX_SET_SHADER_RESOURCES 1149
+#define SVGA_3D_CMD_DX_SET_SHADER 1150
+#define SVGA_3D_CMD_DX_SET_SAMPLERS 1151
+#define SVGA_3D_CMD_DX_DRAW 1152
+#define SVGA_3D_CMD_DX_DRAW_INDEXED 1153
+#define SVGA_3D_CMD_DX_DRAW_INSTANCED 1154
+#define SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED 1155
+#define SVGA_3D_CMD_DX_DRAW_AUTO 1156
+#define SVGA_3D_CMD_DX_SET_INPUT_LAYOUT 1157
+#define SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS 1158
+#define SVGA_3D_CMD_DX_SET_INDEX_BUFFER 1159
+#define SVGA_3D_CMD_DX_SET_TOPOLOGY 1160
+#define SVGA_3D_CMD_DX_SET_RENDERTARGETS 1161
+#define SVGA_3D_CMD_DX_SET_BLEND_STATE 1162
+#define SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE 1163
+#define SVGA_3D_CMD_DX_SET_RASTERIZER_STATE 1164
+#define SVGA_3D_CMD_DX_DEFINE_QUERY 1165
+#define SVGA_3D_CMD_DX_DESTROY_QUERY 1166
+#define SVGA_3D_CMD_DX_BIND_QUERY 1167
+#define SVGA_3D_CMD_DX_SET_QUERY_OFFSET 1168
+#define SVGA_3D_CMD_DX_BEGIN_QUERY 1169
+#define SVGA_3D_CMD_DX_END_QUERY 1170
+#define SVGA_3D_CMD_DX_READBACK_QUERY 1171
+#define SVGA_3D_CMD_DX_SET_PREDICATION 1172
+#define SVGA_3D_CMD_DX_SET_SOTARGETS 1173
+#define SVGA_3D_CMD_DX_SET_VIEWPORTS 1174
+#define SVGA_3D_CMD_DX_SET_SCISSORRECTS 1175
+#define SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW 1176
+#define SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW 1177
+#define SVGA_3D_CMD_DX_PRED_COPY_REGION 1178
+#define SVGA_3D_CMD_DX_PRED_COPY 1179
+#define SVGA_3D_CMD_DX_PRESENTBLT 1180
+#define SVGA_3D_CMD_DX_GENMIPS 1181
+#define SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE 1182
+#define SVGA_3D_CMD_DX_READBACK_SUBRESOURCE 1183
+#define SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE 1184
+#define SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW 1185
+#define SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW 1186
+#define SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW 1187
+#define SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW 1188
+#define SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW 1189
+#define SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW 1190
+#define SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT 1191
+#define SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT 1192
+#define SVGA_3D_CMD_DX_DEFINE_BLEND_STATE 1193
+#define SVGA_3D_CMD_DX_DESTROY_BLEND_STATE 1194
+#define SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE 1195
+#define SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE 1196
+#define SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE 1197
+#define SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE 1198
+#define SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE 1199
+#define SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE 1200
+#define SVGA_3D_CMD_DX_DEFINE_SHADER 1201
+#define SVGA_3D_CMD_DX_DESTROY_SHADER 1202
+#define SVGA_3D_CMD_DX_BIND_SHADER 1203
+#define SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT 1204
+#define SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT 1205
+#define SVGA_3D_CMD_DX_SET_STREAMOUTPUT 1206
+#define SVGA_3D_CMD_DX_SET_COTABLE 1207
+#define SVGA_3D_CMD_DX_READBACK_COTABLE 1208
+#define SVGA_3D_CMD_DX_BUFFER_COPY 1209
+#define SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER 1210
+#define SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK 1211
+#define SVGA_3D_CMD_DX_MOVE_QUERY 1212
+#define SVGA_3D_CMD_DX_BIND_ALL_QUERY 1213
+#define SVGA_3D_CMD_DX_READBACK_ALL_QUERY 1214
+#define SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER 1215
+#define SVGA_3D_CMD_DX_MOB_FENCE_64 1216
+#define SVGA_3D_CMD_DX_BIND_ALL_SHADER 1217
+#define SVGA_3D_CMD_DX_HINT 1218
+#define SVGA_3D_CMD_DX_BUFFER_UPDATE 1219
+#define SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET 1220
+#define SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET 1221
+#define SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET 1222
+#define SVGA_3D_CMD_DX_SET_HS_CONSTANT_BUFFER_OFFSET 1223
+#define SVGA_3D_CMD_DX_SET_DS_CONSTANT_BUFFER_OFFSET 1224
+#define SVGA_3D_CMD_DX_SET_CS_CONSTANT_BUFFER_OFFSET 1225
+
+#define SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER 1226
+#define SVGA_3D_CMD_DX_MAX 1227
+
+#define SVGA_3D_CMD_SCREEN_COPY 1227
+
+#define SVGA_3D_CMD_RESERVED1 1228
+#define SVGA_3D_CMD_RESERVED2 1229
+#define SVGA_3D_CMD_RESERVED3 1230
+#define SVGA_3D_CMD_RESERVED4 1231
+#define SVGA_3D_CMD_RESERVED5 1232
+#define SVGA_3D_CMD_RESERVED6 1233
+#define SVGA_3D_CMD_RESERVED7 1234
+#define SVGA_3D_CMD_RESERVED8 1235
+
+#define SVGA_3D_CMD_GROW_OTABLE 1236
+#define SVGA_3D_CMD_DX_GROW_COTABLE 1237
+#define SVGA_3D_CMD_INTRA_SURFACE_COPY 1238
+
+#define SVGA_3D_CMD_DEFINE_GB_SURFACE_V3 1239
+
+#define SVGA_3D_CMD_DX_RESOLVE_COPY 1240
+#define SVGA_3D_CMD_DX_PRED_RESOLVE_COPY 1241
+#define SVGA_3D_CMD_DX_PRED_CONVERT_REGION 1242
+#define SVGA_3D_CMD_DX_PRED_CONVERT 1243
+#define SVGA_3D_CMD_WHOLE_SURFACE_COPY 1244
+
+#define SVGA_3D_CMD_DX_DEFINE_UA_VIEW 1245
+#define SVGA_3D_CMD_DX_DESTROY_UA_VIEW 1246
+#define SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT 1247
+#define SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT 1248
+#define SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT 1249
+#define SVGA_3D_CMD_DX_SET_UA_VIEWS 1250
+
+#define SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT 1251
+#define SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT 1252
+#define SVGA_3D_CMD_DX_DISPATCH 1253
+#define SVGA_3D_CMD_DX_DISPATCH_INDIRECT 1254
+
+#define SVGA_3D_CMD_WRITE_ZERO_SURFACE 1255
+#define SVGA_3D_CMD_UPDATE_ZERO_SURFACE 1256
+#define SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER 1257
+#define SVGA_3D_CMD_DX_SET_STRUCTURE_COUNT 1258
+
+#define SVGA_3D_CMD_LOGICOPS_BITBLT 1259
+#define SVGA_3D_CMD_LOGICOPS_TRANSBLT 1260
+#define SVGA_3D_CMD_LOGICOPS_STRETCHBLT 1261
+#define SVGA_3D_CMD_LOGICOPS_COLORFILL 1262
+#define SVGA_3D_CMD_LOGICOPS_ALPHABLEND 1263
+#define SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND 1264
+
+#define SVGA_3D_CMD_DX_COPY_COTABLE_INTO_MOB 1265
+
+#define SVGA_3D_CMD_UPDATE_GB_SCREENTARGET_V2 1266
+
+#define SVGA_3D_CMD_DEFINE_GB_SURFACE_V4 1267
+#define SVGA_3D_CMD_DX_SET_CS_UA_VIEWS 1268
+#define SVGA_3D_CMD_DX_SET_MIN_LOD 1269
+
+#define SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2 1272
+#define SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB 1273
+#define SVGA_3D_CMD_DX_SET_SHADER_IFACE 1274
+#define SVGA_3D_CMD_DX_BIND_STREAMOUTPUT 1275
+#define SVGA_3D_CMD_SURFACE_STRETCHBLT_NON_MS_TO_MS 1276
+#define SVGA_3D_CMD_DX_BIND_SHADER_IFACE 1277
+
+#define SVGA_3D_CMD_UPDATE_GB_SCREENTARGET_MOVE 1278
+
+#define SVGA_3D_CMD_DX_PRED_STAGING_COPY 1281
+#define SVGA_3D_CMD_DX_STAGING_COPY 1282
+#define SVGA_3D_CMD_DX_PRED_STAGING_COPY_REGION 1283
+#define SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS_V2 1284
+#define SVGA_3D_CMD_DX_SET_INDEX_BUFFER_V2 1285
+#define SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS_OFFSET_AND_SIZE 1286
+#define SVGA_3D_CMD_DX_SET_INDEX_BUFFER_OFFSET_AND_SIZE 1287
+#define SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE_V2 1288
+#define SVGA_3D_CMD_DX_PRED_STAGING_CONVERT_REGION 1289
+#define SVGA_3D_CMD_DX_PRED_STAGING_CONVERT 1290
+#define SVGA_3D_CMD_DX_STAGING_BUFFER_COPY 1291
+
+#define SVGA_3D_CMD_MAX 1303
+#define SVGA_3D_CMD_FUTURE_MAX 3000
+
+/*
+ * Common substructures used in multiple FIFO commands:
+ */
+
+typedef struct {
+ union {
+ struct {
+ uint16 function; // SVGA3dFogFunction
+ uint8 type; // SVGA3dFogType
+ uint8 base; // SVGA3dFogBase
+ };
+ uint32 uintValue;
+ };
+} SVGA3dFogMode;
+
+/*
+ * Uniquely identify one image (a 1D/2D/3D array) from a surface. This
+ * is a surface ID as well as face/mipmap indices.
+ */
+
+typedef
+struct SVGA3dSurfaceImageId {
+ uint32 sid;
+ uint32 face;
+ uint32 mipmap;
+} SVGA3dSurfaceImageId;
+
+typedef
+struct SVGA3dGuestImage {
+ SVGAGuestPtr ptr;
+
+ /*
+ * A note on interpretation of pitch: This value of pitch is the
+ * number of bytes between vertically adjacent image
+ * blocks. Normally this is the number of bytes between the first
+ * pixel of two adjacent scanlines. With compressed textures,
+ * however, this may represent the number of bytes between
+ * compression blocks rather than between rows of pixels.
+ *
+ * XXX: Compressed textures currently must be tightly packed in guest memory.
+ *
+ * If the image is 1-dimensional, pitch is ignored.
+ *
+ * If 'pitch' is zero, the SVGA3D device calculates a pitch value
+ * assuming each row of blocks is tightly packed.
+ */
+ uint32 pitch;
+} SVGA3dGuestImage;
+
+
+/*
+ * FIFO command format definitions:
+ */
+
+/*
+ * The data size header following cmdNum for every 3d command
+ */
+typedef
+struct {
+ uint32 id;
+ uint32 size;
+} SVGA3dCmdHeader;
+
+/*
+ * A surface is a hierarchy of host VRAM surfaces: 1D, 2D, or 3D, with
+ * optional mipmaps and cube faces.
+ */
+
+typedef
+struct {
+ uint32 width;
+ uint32 height;
+ uint32 depth;
+} SVGA3dSize;
+
+/*
+ * Guest-backed objects definitions.
+ */
+typedef enum {
+ SVGA_OTABLE_MOB = 0,
+ SVGA_OTABLE_MIN = 0,
+ SVGA_OTABLE_SURFACE = 1,
+ SVGA_OTABLE_CONTEXT = 2,
+ SVGA_OTABLE_SHADER = 3,
+ SVGA_OTABLE_SCREENTARGET = 4,
+
+ SVGA_OTABLE_DX9_MAX = 5,
+
+ SVGA_OTABLE_DXCONTEXT = 5,
+ SVGA_OTABLE_DX_MAX = 6,
+
+ SVGA_OTABLE_RESERVED1 = 6,
+ SVGA_OTABLE_RESERVED2 = 7,
+
+ /*
+ * Additions to this table need to be tied to HW-version features and
+ * checkpointed accordingly.
+ */
+ SVGA_OTABLE_DEVEL_MAX = 8,
+ SVGA_OTABLE_MAX = 8
+} SVGAOTableType;
+
+typedef enum {
+ SVGA_COTABLE_MIN = 0,
+ SVGA_COTABLE_RTVIEW = 0,
+ SVGA_COTABLE_DSVIEW = 1,
+ SVGA_COTABLE_SRVIEW = 2,
+ SVGA_COTABLE_ELEMENTLAYOUT = 3,
+ SVGA_COTABLE_BLENDSTATE = 4,
+ SVGA_COTABLE_DEPTHSTENCIL = 5,
+ SVGA_COTABLE_RASTERIZERSTATE = 6,
+ SVGA_COTABLE_SAMPLER = 7,
+ SVGA_COTABLE_STREAMOUTPUT = 8,
+ SVGA_COTABLE_DXQUERY = 9,
+ SVGA_COTABLE_DXSHADER = 10,
+ SVGA_COTABLE_DX10_MAX = 11,
+ SVGA_COTABLE_UAVIEW = 11,
+ SVGA_COTABLE_MAX = 12,
+} SVGACOTableType;
+
+
+/*
+ * The largest size (number of entries) allowed in a COTable.
+ */
+#define SVGA_COTABLE_MAX_IDS (MAX_UINT16 - 2)
+
+typedef enum SVGAMobFormat {
+ SVGA3D_MOBFMT_INVALID = SVGA3D_INVALID_ID,
+ SVGA3D_MOBFMT_PTDEPTH_0 = 0,
+ SVGA3D_MOBFMT_MIN = 0,
+ SVGA3D_MOBFMT_PTDEPTH_1 = 1,
+ SVGA3D_MOBFMT_PTDEPTH_2 = 2,
+ SVGA3D_MOBFMT_RANGE = 3,
+ SVGA3D_MOBFMT_PTDEPTH64_0 = 4,
+ SVGA3D_MOBFMT_PTDEPTH64_1 = 5,
+ SVGA3D_MOBFMT_PTDEPTH64_2 = 6,
+ SVGA3D_MOBFMT_PREDX_MAX = 7,
+ SVGA3D_MOBFMT_EMPTY = 7,
+ SVGA3D_MOBFMT_MAX,
+
+ /*
+ * This isn't actually used by the guest, but is a mob-format used
+ * internally by the SVGA device (and is therefore not binary compatible).
+ */
+ SVGA3D_MOBFMT_HB,
+} SVGAMobFormat;
+
+#define SVGA3D_MOB_EMPTY_BASE 1
+
+/*
+ * Multisample pattern types.
+ */
+
+typedef enum SVGA3dMSPattern {
+ SVGA3D_MS_PATTERN_NONE = 0,
+ SVGA3D_MS_PATTERN_MIN = 0,
+ SVGA3D_MS_PATTERN_STANDARD = 1,
+ SVGA3D_MS_PATTERN_CENTER = 2,
+ SVGA3D_MS_PATTERN_MAX = 3,
+} SVGA3dMSPattern;
+
+/*
+ * Precision settings for each sample.
+ */
+
+typedef enum SVGA3dMSQualityLevel {
+ SVGA3D_MS_QUALITY_NONE = 0,
+ SVGA3D_MS_QUALITY_MIN = 0,
+ SVGA3D_MS_QUALITY_FULL = 1,
+ SVGA3D_MS_QUALITY_MAX = 2,
+} SVGA3dMSQualityLevel;
+
+
+typedef enum {
+ SVGA3D_SURFACE_CUBEMAP = (1 << 0),
+ SVGA3D_SURFACE_HINT_STATIC = (1 << 1),
+ SVGA3D_SURFACE_HINT_DYNAMIC = (1 << 2),
+ SVGA3D_SURFACE_HINT_INDEXBUFFER = (1 << 3),
+ SVGA3D_SURFACE_HINT_VERTEXBUFFER = (1 << 4),
+ SVGA3D_SURFACE_HINT_TEXTURE = (1 << 5),
+ SVGA3D_SURFACE_HINT_RENDERTARGET = (1 << 6),
+ SVGA3D_SURFACE_HINT_DEPTHSTENCIL = (1 << 7),
+ SVGA3D_SURFACE_HINT_WRITEONLY = (1 << 8),
+ SVGA3D_SURFACE_MASKABLE_ANTIALIAS = (1 << 9),
+ SVGA3D_SURFACE_AUTOGENMIPMAPS = (1 << 10),
+} SVGA3dSurfaceFlags;
+
+typedef
+struct {
+ uint32 numMipLevels;
+} SVGA3dSurfaceFace;
+
+typedef
+struct {
+ uint32 sid;
+ SVGA3dSurfaceFlags surfaceFlags;
+ SVGA3dSurfaceFormat format;
+ /*
+ * If surfaceFlags has SVGA3D_SURFACE_CUBEMAP bit set, all SVGA3dSurfaceFace
+ * structures must have the same value of numMipLevels field.
+ * Otherwise, all but the first SVGA3dSurfaceFace structures must have the
+ * numMipLevels set to 0.
+ */
+ SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES];
+ /*
+ * Followed by an SVGA3dSize structure for each mip level in each face.
+ *
+ * A note on surface sizes: Sizes are always specified in pixels,
+ * even if the true surface size is not a multiple of the minimum
+ * block size of the surface's format. For example, a 3x3x1 DXT1
+ * compressed texture would actually be stored as a 4x4x1 image in
+ * memory.
+ */
+} SVGA3dCmdDefineSurface; /* SVGA_3D_CMD_SURFACE_DEFINE */
+
+typedef
+struct {
+ uint32 sid;
+ SVGA3dSurfaceFlags surfaceFlags;
+ SVGA3dSurfaceFormat format;
+ /*
+ * If surfaceFlags has SVGA3D_SURFACE_CUBEMAP bit set, all SVGA3dSurfaceFace
+ * structures must have the same value of numMipLevels field.
+ * Otherwise, all but the first SVGA3dSurfaceFace structures must have the
+ * numMipLevels set to 0.
+ */
+ SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES];
+ uint32 multisampleCount;
+ SVGA3dTextureFilter autogenFilter;
+ /*
+ * Followed by an SVGA3dSize structure for each mip level in each face.
+ *
+ * A note on surface sizes: Sizes are always specified in pixels,
+ * even if the true surface size is not a multiple of the minimum
+ * block size of the surface's format. For example, a 3x3x1 DXT1
+ * compressed texture would actually be stored as a 4x4x1 image in
+ * memory.
+ */
+} SVGA3dCmdDefineSurface_v2; /* SVGA_3D_CMD_SURFACE_DEFINE_V2 */
+
+typedef
+struct {
+ uint32 sid;
+} SVGA3dCmdDestroySurface; /* SVGA_3D_CMD_SURFACE_DESTROY */
+
+typedef
+struct {
+ uint32 cid;
+} SVGA3dCmdDefineContext; /* SVGA_3D_CMD_CONTEXT_DEFINE */
+
+typedef
+struct {
+ uint32 cid;
+} SVGA3dCmdDestroyContext; /* SVGA_3D_CMD_CONTEXT_DESTROY */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dClearFlag clearFlag;
+ uint32 color;
+ float depth;
+ uint32 stencil;
+ /* Followed by variable number of SVGA3dRect structures */
+} SVGA3dCmdClear; /* SVGA_3D_CMD_CLEAR */
+
+typedef
+struct SVGA3dCopyRect {
+ uint32 x;
+ uint32 y;
+ uint32 w;
+ uint32 h;
+ uint32 srcx;
+ uint32 srcy;
+} SVGA3dCopyRect;
+
+typedef
+struct SVGA3dCopyBox {
+ uint32 x;
+ uint32 y;
+ uint32 z;
+ uint32 w;
+ uint32 h;
+ uint32 d;
+ uint32 srcx;
+ uint32 srcy;
+ uint32 srcz;
+} SVGA3dCopyBox;
+
+typedef
+struct {
+ uint32 x;
+ uint32 y;
+ uint32 w;
+ uint32 h;
+} SVGA3dRect;
+
+typedef
+struct {
+ uint32 x;
+ uint32 y;
+ uint32 z;
+ uint32 w;
+ uint32 h;
+ uint32 d;
+} SVGA3dBox;
+
+typedef
+struct {
+ uint32 x;
+ uint32 y;
+ uint32 z;
+} SVGA3dPoint;
+
+typedef
+struct {
+ SVGA3dLightType type;
+ SVGA3dBool inWorldSpace;
+ float diffuse[4];
+ float specular[4];
+ float ambient[4];
+ float position[4];
+ float direction[4];
+ float range;
+ float falloff;
+ float attenuation0;
+ float attenuation1;
+ float attenuation2;
+ float theta;
+ float phi;
+} SVGA3dLightData;
+
+typedef
+struct {
+ uint32 sid;
+ /* Followed by variable number of SVGA3dCopyRect structures */
+} SVGA3dCmdPresent; /* SVGA_3D_CMD_PRESENT */
+
+typedef
+struct {
+ SVGA3dRenderStateName state;
+ union {
+ uint32 uintValue;
+ float floatValue;
+ };
+} SVGA3dRenderState;
+
+typedef
+struct {
+ uint32 cid;
+ /* Followed by variable number of SVGA3dRenderState structures */
+} SVGA3dCmdSetRenderState; /* SVGA_3D_CMD_SETRENDERSTATE */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dRenderTargetType type;
+ SVGA3dSurfaceImageId target;
+} SVGA3dCmdSetRenderTarget; /* SVGA_3D_CMD_SETRENDERTARGET */
+
+typedef
+struct {
+ SVGA3dSurfaceImageId src;
+ SVGA3dSurfaceImageId dest;
+ /* Followed by variable number of SVGA3dCopyBox structures */
+} SVGA3dCmdSurfaceCopy; /* SVGA_3D_CMD_SURFACE_COPY */
+
+typedef
+struct {
+ SVGA3dSurfaceImageId src;
+ SVGA3dSurfaceImageId dest;
+ SVGA3dBox boxSrc;
+ SVGA3dBox boxDest;
+ SVGA3dStretchBltMode mode;
+} SVGA3dCmdSurfaceStretchBlt; /* SVGA_3D_CMD_SURFACE_STRETCHBLT */
+
+typedef
+struct {
+ /*
+ * If the discard flag is present in a surface DMA operation, the host may
+ * discard the contents of the current mipmap level and face of the target
+ * surface before applying the surface DMA contents.
+ */
+ uint32 discard : 1;
+
+ /*
+ * If the unsynchronized flag is present, the host may perform this upload
+ * without syncing to pending reads on this surface.
+ */
+ uint32 unsynchronized : 1;
+
+ /*
+ * Guests *MUST* set the reserved bits to 0 before submitting the command
+ * suffix as future flags may occupy these bits.
+ */
+ uint32 reserved : 30;
+} SVGA3dSurfaceDMAFlags;
+
+typedef
+struct {
+ SVGA3dGuestImage guest;
+ SVGA3dSurfaceImageId host;
+ SVGA3dTransferType transfer;
+ /*
+ * Followed by variable number of SVGA3dCopyBox structures. For consistency
+ * in all clipping logic and coordinate translation, we define the
+ * "source" in each copyBox as the guest image and the
+ * "destination" as the host image, regardless of transfer
+ * direction.
+ *
+ * For efficiency, the SVGA3D device is free to copy more data than
+ * specified. For example, it may round copy boxes outwards such
+ * that they lie on particular alignment boundaries.
+ */
+} SVGA3dCmdSurfaceDMA; /* SVGA_3D_CMD_SURFACE_DMA */
+
+/*
+ * SVGA3dCmdSurfaceDMASuffix --
+ *
+ * This is a command suffix that will appear after a SurfaceDMA command in
+ * the FIFO. It contains some extra information that hosts may use to
+ * optimize performance or protect the guest. This suffix exists to preserve
+ * backwards compatibility while also allowing for new functionality to be
+ * implemented.
+ */
+
+typedef
+struct {
+ uint32 suffixSize;
+
+ /*
+ * The maximum offset is used to determine the maximum offset from the
+ * guestPtr base address that will be accessed or written to during this
+ * surfaceDMA. If the suffix is supported, the host will respect this
+ * boundary while performing surface DMAs.
+ *
+ * Defaults to MAX_UINT32
+ */
+ uint32 maximumOffset;
+
+ /*
+ * A set of flags that describes optimizations that the host may perform
+ * while performing this surface DMA operation. The guest should never rely
+ * on behaviour that is different when these flags are set for correctness.
+ *
+ * Defaults to 0
+ */
+ SVGA3dSurfaceDMAFlags flags;
+} SVGA3dCmdSurfaceDMASuffix;
+
+/*
+ * SVGA_3D_CMD_DRAW_PRIMITIVES --
+ *
+ * This command is the SVGA3D device's generic drawing entry point.
+ * It can draw multiple ranges of primitives, optionally using an
+ * index buffer, using an arbitrary collection of vertex buffers.
+ *
+ * Each SVGA3dVertexDecl defines a distinct vertex array to bind
+ * during this draw call. The declarations specify which surface
+ * the vertex data lives in, what that vertex data is used for,
+ * and how to interpret it.
+ *
+ * Each SVGA3dPrimitiveRange defines a collection of primitives
+ * to render using the same vertex arrays. An index buffer is
+ * optional.
+ */
+
+typedef
+struct {
+ /*
+ * A range hint is an optional specification for the range of indices
+ * in an SVGA3dArray that will be used. If 'last' is zero, it is assumed
+ * that the entire array will be used.
+ *
+ * These are only hints. The SVGA3D device may use them for
+ * performance optimization if possible, but it's also allowed to
+ * ignore these values.
+ */
+ uint32 first;
+ uint32 last;
+} SVGA3dArrayRangeHint;
+
+typedef
+struct {
+ /*
+ * Define the origin and shape of a vertex or index array. Both
+ * 'offset' and 'stride' are in bytes. The provided surface will be
+ * reinterpreted as a flat array of bytes in the same format used
+ * by surface DMA operations. To avoid unnecessary conversions, the
+ * surface should be created with the SVGA3D_BUFFER format.
+ *
+ * Index 0 in the array starts 'offset' bytes into the surface.
+ * Index 1 begins at byte 'offset + stride', etc. Array indices may
+ * not be negative.
+ */
+ uint32 surfaceId;
+ uint32 offset;
+ uint32 stride;
+} SVGA3dArray;
+
+typedef
+struct {
+ /*
+ * Describe a vertex array's data type, and define how it is to be
+ * used by the fixed function pipeline or the vertex shader. It
+ * isn't useful to have two VertexDecls with the same
+ * VertexArrayIdentity in one draw call.
+ */
+ SVGA3dDeclType type;
+ SVGA3dDeclMethod method;
+ SVGA3dDeclUsage usage;
+ uint32 usageIndex;
+} SVGA3dVertexArrayIdentity;
+
+typedef
+struct {
+ SVGA3dVertexArrayIdentity identity;
+ SVGA3dArray array;
+ SVGA3dArrayRangeHint rangeHint;
+} SVGA3dVertexDecl;
+
+typedef
+struct {
+ /*
+ * Define a group of primitives to render, from sequential indices.
+ *
+ * The value of 'primitiveType' and 'primitiveCount' imply the
+ * total number of vertices that will be rendered.
+ */
+ SVGA3dPrimitiveType primType;
+ uint32 primitiveCount;
+
+ /*
+ * Optional index buffer. If indexArray.surfaceId is
+ * SVGA3D_INVALID_ID, we render without an index buffer. Rendering
+ * without an index buffer is identical to rendering with an index
+ * buffer containing the sequence [0, 1, 2, 3, ...].
+ *
+ * If an index buffer is in use, indexWidth specifies the width in
+ * bytes of each index value. It must be less than or equal to
+ * indexArray.stride.
+ *
+ * (Currently, the SVGA3D device requires index buffers to be tightly
+ * packed. In other words, indexWidth == indexArray.stride)
+ */
+ SVGA3dArray indexArray;
+ uint32 indexWidth;
+
+ /*
+ * Optional index bias. This number is added to all indices from
+ * indexArray before they are used as vertex array indices. This
+ * can be used in multiple ways:
+ *
+ * - When not using an indexArray, this bias can be used to
+ * specify where in the vertex arrays to begin rendering.
+ *
+ * - A positive number here is equivalent to increasing the
+ * offset in each vertex array.
+ *
+ * - A negative number can be used to render using a small
+ * vertex array and an index buffer that contains large
+ * values. This may be used by some applications that
+ * crop a vertex buffer without modifying their index
+ * buffer.
+ *
+ * Note that rendering with a negative bias value may be slower and
+ * use more memory than rendering with a positive or zero bias.
+ */
+ int32 indexBias;
+} SVGA3dPrimitiveRange;
+
+typedef
+struct {
+ uint32 cid;
+ uint32 numVertexDecls;
+ uint32 numRanges;
+
+ /*
+ * There are two variable size arrays after the
+ * SVGA3dCmdDrawPrimitives structure. In order,
+ * they are:
+ *
+ * 1. SVGA3dVertexDecl, quantity 'numVertexDecls', but no more than
+ * SVGA3D_MAX_VERTEX_ARRAYS;
+ * 2. SVGA3dPrimitiveRange, quantity 'numRanges', but no more than
+ * SVGA3D_MAX_DRAW_PRIMITIVE_RANGES;
+ * 3. Optionally, SVGA3dVertexDivisor, quantity 'numVertexDecls' (contains
+ * the frequency divisor for the corresponding vertex decl).
+ */
+} SVGA3dCmdDrawPrimitives; /* SVGA_3D_CMD_DRAWPRIMITIVES */
+
+typedef
+struct {
+ uint32 stage;
+ SVGA3dTextureStateName name;
+ union {
+ uint32 value;
+ float floatValue;
+ };
+} SVGA3dTextureState;
+
+typedef
+struct {
+ uint32 cid;
+ /* Followed by variable number of SVGA3dTextureState structures */
+} SVGA3dCmdSetTextureState; /* SVGA_3D_CMD_SETTEXTURESTATE */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dTransformType type;
+ float matrix[16];
+} SVGA3dCmdSetTransform; /* SVGA_3D_CMD_SETTRANSFORM */
+
+typedef
+struct {
+ float min;
+ float max;
+} SVGA3dZRange;
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dZRange zRange;
+} SVGA3dCmdSetZRange; /* SVGA_3D_CMD_SETZRANGE */
+
+typedef
+struct {
+ float diffuse[4];
+ float ambient[4];
+ float specular[4];
+ float emissive[4];
+ float shininess;
+} SVGA3dMaterial;
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dFace face;
+ SVGA3dMaterial material;
+} SVGA3dCmdSetMaterial; /* SVGA_3D_CMD_SETMATERIAL */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 index;
+ SVGA3dLightData data;
+} SVGA3dCmdSetLightData; /* SVGA_3D_CMD_SETLIGHTDATA */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 index;
+ uint32 enabled;
+} SVGA3dCmdSetLightEnabled; /* SVGA_3D_CMD_SETLIGHTENABLED */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dRect rect;
+} SVGA3dCmdSetViewport; /* SVGA_3D_CMD_SETVIEWPORT */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dRect rect;
+} SVGA3dCmdSetScissorRect; /* SVGA_3D_CMD_SETSCISSORRECT */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 index;
+ float plane[4];
+} SVGA3dCmdSetClipPlane; /* SVGA_3D_CMD_SETCLIPPLANE */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 shid;
+ SVGA3dShaderType type;
+ /* Followed by variable number of DWORDs for shader bycode */
+} SVGA3dCmdDefineShader; /* SVGA_3D_CMD_SHADER_DEFINE */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 shid;
+ SVGA3dShaderType type;
+} SVGA3dCmdDestroyShader; /* SVGA_3D_CMD_SHADER_DESTROY */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 reg; /* register number */
+ SVGA3dShaderType type;
+ SVGA3dShaderConstType ctype;
+ uint32 values[4];
+} SVGA3dCmdSetShaderConst; /* SVGA_3D_CMD_SET_SHADER_CONST */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dShaderType type;
+ uint32 shid;
+} SVGA3dCmdSetShader; /* SVGA_3D_CMD_SET_SHADER */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dQueryType type;
+} SVGA3dCmdBeginQuery; /* SVGA_3D_CMD_BEGIN_QUERY */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dQueryType type;
+ SVGAGuestPtr guestResult; /* Points to an SVGA3dQueryResult structure */
+} SVGA3dCmdEndQuery; /* SVGA_3D_CMD_END_QUERY */
+
+typedef
+struct {
+ uint32 cid; /* Same parameters passed to END_QUERY */
+ SVGA3dQueryType type;
+ SVGAGuestPtr guestResult;
+} SVGA3dCmdWaitForQuery; /* SVGA_3D_CMD_WAIT_FOR_QUERY */
+
+typedef
+struct {
+ uint32 totalSize; /* Set by guest before query is ended. */
+ SVGA3dQueryState state; /* Set by host or guest. See SVGA3dQueryState. */
+ union { /* Set by host on exit from PENDING state */
+ uint32 result32;
+ };
+} SVGA3dQueryResult;
+
+/*
+ * SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN --
+ *
+ * This is a blit from an SVGA3D surface to a Screen Object. Just
+ * like GMR-to-screen blits, this blit may be directed at a
+ * specific screen or to the virtual coordinate space.
+ *
+ * The blit copies from a rectangular region of an SVGA3D surface
+ * image to a rectangular region of a screen or screens.
+ *
+ * This command takes an optional variable-length list of clipping
+ * rectangles after the body of the command. If no rectangles are
+ * specified, there is no clipping region. The entire destRect is
+ * drawn to. If one or more rectangles are included, they describe
+ * a clipping region. The clip rectangle coordinates are measured
+ * relative to the top-left corner of destRect.
+ *
+ * This clipping region serves multiple purposes:
+ *
+ * - It can be used to perform an irregularly shaped blit more
+ * efficiently than by issuing many separate blit commands.
+ *
+ * - It is equivalent to allowing blits with non-integer
+ * source coordinates. You could blit just one half-pixel
+ * of a source, for example, by specifying a larger
+ * destination rectangle than you need, then removing
+ * part of it using a clip rectangle.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT
+ *
+ * Limitations:
+ *
+ * - Currently, no backend supports blits from a mipmap or face
+ * other than the first one.
+ */
+
+typedef
+struct {
+ SVGA3dSurfaceImageId srcImage;
+ SVGASignedRect srcRect;
+ uint32 destScreenId; /* Screen ID or SVGA_ID_INVALID for virt. coords */
+ SVGASignedRect destRect; /* Supports scaling if src/rest different size */
+ /* Clipping: zero or more SVGASignedRects follow */
+} SVGA3dCmdBlitSurfaceToScreen; /* SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN */
+
+typedef
+struct {
+ uint32 sid;
+ SVGA3dTextureFilter filter;
+} SVGA3dCmdGenerateMipmaps; /* SVGA_3D_CMD_GENERATE_MIPMAPS */
+
+
+/*
+ * Capability query index.
+ *
+ * Notes:
+ *
+ * 1. SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of
+ * fixed-function texture units available. Each of these units
+ * work in both FFP and Shader modes, and they support texture
+ * transforms and texture coordinates. The host may have additional
+ * texture image units that are only usable with shaders.
+ *
+ * 2. The BUFFER_FORMAT capabilities are deprecated, and they always
+ * return TRUE. Even on physical hardware that does not support
+ * these formats natively, the SVGA3D device will provide an emulation
+ * which should be invisible to the guest OS.
+ *
+ * In general, the SVGA3D device should support any operation on
+ * any surface format, it just may perform some of these
+ * operations in software depending on the capabilities of the
+ * available physical hardware.
+ *
+ * XXX: In the future, we will add capabilities that describe in
+ * detail what formats are supported in hardware for what kinds
+ * of operations.
+ */
+
+typedef enum {
+ SVGA3D_DEVCAP_3D = 0,
+ SVGA3D_DEVCAP_MAX_LIGHTS = 1,
+ SVGA3D_DEVCAP_MAX_TEXTURES = 2, /* See note (1) */
+ SVGA3D_DEVCAP_MAX_CLIP_PLANES = 3,
+ SVGA3D_DEVCAP_VERTEX_SHADER_VERSION = 4,
+ SVGA3D_DEVCAP_VERTEX_SHADER = 5,
+ SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION = 6,
+ SVGA3D_DEVCAP_FRAGMENT_SHADER = 7,
+ SVGA3D_DEVCAP_MAX_RENDER_TARGETS = 8,
+ SVGA3D_DEVCAP_S23E8_TEXTURES = 9,
+ SVGA3D_DEVCAP_S10E5_TEXTURES = 10,
+ SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND = 11,
+ SVGA3D_DEVCAP_D16_BUFFER_FORMAT = 12, /* See note (2) */
+ SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT = 13, /* See note (2) */
+ SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT = 14, /* See note (2) */
+ SVGA3D_DEVCAP_QUERY_TYPES = 15,
+ SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING = 16,
+ SVGA3D_DEVCAP_MAX_POINT_SIZE = 17,
+ SVGA3D_DEVCAP_MAX_SHADER_TEXTURES = 18,
+ SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH = 19,
+ SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT = 20,
+ SVGA3D_DEVCAP_MAX_VOLUME_EXTENT = 21,
+ SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT = 22,
+ SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO = 23,
+ SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY = 24,
+ SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT = 25,
+ SVGA3D_DEVCAP_MAX_VERTEX_INDEX = 26,
+ SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS = 27,
+ SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS = 28,
+ SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS = 29,
+ SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS = 30,
+ SVGA3D_DEVCAP_TEXTURE_OPS = 31,
+ SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 = 32,
+ SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 = 33,
+ SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 = 34,
+ SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 = 35,
+ SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 = 36,
+ SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 = 37,
+ SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 = 38,
+ SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 = 39,
+ SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 = 40,
+ SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 = 41,
+ SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 = 42,
+ SVGA3D_DEVCAP_SURFACEFMT_Z_D16 = 43,
+ SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 = 44,
+ SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 = 45,
+ SVGA3D_DEVCAP_SURFACEFMT_DXT1 = 46,
+ SVGA3D_DEVCAP_SURFACEFMT_DXT2 = 47,
+ SVGA3D_DEVCAP_SURFACEFMT_DXT3 = 48,
+ SVGA3D_DEVCAP_SURFACEFMT_DXT4 = 49,
+ SVGA3D_DEVCAP_SURFACEFMT_DXT5 = 50,
+ SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 = 51,
+ SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 = 52,
+ SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 = 53,
+ SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 = 54,
+ SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 = 55,
+ SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 = 56,
+ SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 = 57,
+ SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 = 58,
+ SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 = 59,
+ SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 = 60,
+ SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 = 61,
+ SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES = 63,
+
+ /*
+ * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color
+ * render targets. This does no include the depth or stencil targets.
+ */
+ SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS = 64,
+
+ SVGA3D_DEVCAP_SURFACEFMT_V16U16 = 65,
+ SVGA3D_DEVCAP_SURFACEFMT_G16R16 = 66,
+ SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = 67,
+ SVGA3D_DEVCAP_SURFACEFMT_UYVY = 68,
+ SVGA3D_DEVCAP_SURFACEFMT_YUY2 = 69,
+ SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES = 70,
+ SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES = 71,
+ SVGA3D_DEVCAP_ALPHATOCOVERAGE = 72,
+ SVGA3D_DEVCAP_SUPERSAMPLE = 73,
+ SVGA3D_DEVCAP_AUTOGENMIPMAPS = 74,
+ SVGA3D_DEVCAP_SURFACEFMT_NV12 = 75,
+ SVGA3D_DEVCAP_SURFACEFMT_AYUV = 76,
+
+ /*
+ * This is the maximum number of SVGA context IDs that the guest
+ * can define using SVGA_3D_CMD_CONTEXT_DEFINE.
+ */
+ SVGA3D_DEVCAP_MAX_CONTEXT_IDS = 77,
+
+ /*
+ * This is the maximum number of SVGA surface IDs that the guest
+ * can define using SVGA_3D_CMD_SURFACE_DEFINE*.
+ */
+ SVGA3D_DEVCAP_MAX_SURFACE_IDS = 78,
+
+ SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 = 79,
+ SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 = 80,
+ SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT = 81,
+
+ SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM = 82,
+ SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM = 83,
+
+ /*
+ * Don't add new caps into the previous section; the values in this
+ * enumeration must not change. You can put new values right before
+ * SVGA3D_DEVCAP_MAX.
+ */
+ SVGA3D_DEVCAP_MAX /* This must be the last index. */
+} SVGA3dDevCapIndex;
+
+typedef union {
+ Bool b;
+ uint32 u;
+ int32 i;
+ float f;
+} SVGA3dDevCapResult;
+
+/*******************************************************************************
+ *
+ * G P U 1 0
+ *
+ ******************************************************************************/
+
+/* https://elixir.bootlin.com/linux/v5.2-rc3/source/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h */
+
+/*
+ * Screen DMA command
+ *
+ * Available with SVGA_FIFO_CAP_SCREEN_OBJECT_2. The SVGA_CAP_3D device
+ * cap bit is not required.
+ *
+ * - refBuffer and destBuffer are 32bit BGRX; refBuffer and destBuffer could
+ * be different, but it is required that guest makes sure refBuffer has
+ * exactly the same contents that were written to when last time screen DMA
+ * command is received by host.
+ *
+ * - changemap is generated by lib/blit, and it has the changes from last
+ * received screen DMA or more.
+ */
+
+typedef struct SVGA3dCmdScreenDMA {
+ uint32 screenId;
+ SVGAGuestImage refBuffer;
+ SVGAGuestImage destBuffer;
+ SVGAGuestImage changeMap;
+}
+SVGA3dCmdScreenDMA; /* SVGA_3D_CMD_SCREEN_DMA */
+
+/*
+ * Logic ops
+ */
+
+#define SVGA3D_LOTRANSBLT_HONORALPHA (0x01)
+#define SVGA3D_LOSTRETCHBLT_MIRRORX (0x01)
+#define SVGA3D_LOSTRETCHBLT_MIRRORY (0x02)
+#define SVGA3D_LOALPHABLEND_SRCHASALPHA (0x01)
+
+typedef
+struct SVGA3dCmdLogicOpsBitBlt {
+ /*
+ * All LogicOps surfaces are one-level
+ * surfaces so mipmap & face should always
+ * be zero.
+ */
+ SVGA3dSurfaceImageId src;
+ SVGA3dSurfaceImageId dst;
+ SVGA3dLogicOp logicOp;
+ /* Followed by variable number of SVGA3dCopyBox structures */
+}
+SVGA3dCmdLogicOpsBitBlt; /* SVGA_3D_CMD_LOGICOPS_BITBLT */
+
+
+typedef
+struct SVGA3dCmdLogicOpsTransBlt {
+ /*
+ * All LogicOps surfaces are one-level
+ * surfaces so mipmap & face should always
+ * be zero.
+ */
+ SVGA3dSurfaceImageId src;
+ SVGA3dSurfaceImageId dst;
+ uint32 color;
+ uint32 flags;
+ SVGA3dBox srcBox;
+ SVGA3dBox dstBox;
+}
+SVGA3dCmdLogicOpsTransBlt; /* SVGA_3D_CMD_LOGICOPS_TRANSBLT */
+
+
+typedef
+struct SVGA3dCmdLogicOpsStretchBlt {
+ /*
+ * All LogicOps surfaces are one-level
+ * surfaces so mipmap & face should always
+ * be zero.
+ */
+ SVGA3dSurfaceImageId src;
+ SVGA3dSurfaceImageId dst;
+ uint16 mode;
+ uint16 flags;
+ SVGA3dBox srcBox;
+ SVGA3dBox dstBox;
+}
+SVGA3dCmdLogicOpsStretchBlt; /* SVGA_3D_CMD_LOGICOPS_STRETCHBLT */
+
+
+typedef
+struct SVGA3dCmdLogicOpsColorFill {
+ /*
+ * All LogicOps surfaces are one-level
+ * surfaces so mipmap & face should always
+ * be zero.
+ */
+ SVGA3dSurfaceImageId dst;
+ uint32 color;
+ SVGA3dLogicOp logicOp;
+ /* Followed by variable number of SVGA3dRect structures. */
+}
+SVGA3dCmdLogicOpsColorFill; /* SVGA_3D_CMD_LOGICOPS_COLORFILL */
+
+
+typedef
+struct SVGA3dCmdLogicOpsAlphaBlend {
+ /*
+ * All LogicOps surfaces are one-level
+ * surfaces so mipmap & face should always
+ * be zero.
+ */
+ SVGA3dSurfaceImageId src;
+ SVGA3dSurfaceImageId dst;
+ uint32 alphaVal;
+ uint32 flags;
+ SVGA3dBox srcBox;
+ SVGA3dBox dstBox;
+}
+SVGA3dCmdLogicOpsAlphaBlend; /* SVGA_3D_CMD_LOGICOPS_ALPHABLEND */
+
+#define SVGA3D_CLEARTYPE_INVALID_GAMMA_INDEX 0xFFFFFFFF
+
+#define SVGA3D_CLEARTYPE_GAMMA_WIDTH 512
+#define SVGA3D_CLEARTYPE_GAMMA_HEIGHT 16
+
+typedef
+struct SVGA3dCmdLogicOpsClearTypeBlend {
+ /*
+ * All LogicOps surfaces are one-level
+ * surfaces so mipmap & face should always
+ * be zero.
+ */
+ SVGA3dSurfaceImageId tmp;
+ SVGA3dSurfaceImageId dst;
+ SVGA3dSurfaceImageId gammaSurf;
+ SVGA3dSurfaceImageId alphaSurf;
+ uint32 gamma;
+ uint32 color;
+ uint32 color2;
+ int32 alphaOffsetX;
+ int32 alphaOffsetY;
+ /* Followed by variable number of SVGA3dBox structures */
+}
+SVGA3dCmdLogicOpsClearTypeBlend; /* SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND */
+
+
+/*
+ * Guest-backed objects definitions.
+ */
+
+typedef
+struct {
+ SVGAMobFormat ptDepth;
+ uint32 sizeInBytes;
+ PPN64 base;
+}
+SVGAOTableMobEntry;
+#define SVGA3D_OTABLE_MOB_ENTRY_SIZE (sizeof(SVGAOTableMobEntry))
+
+typedef
+struct {
+ SVGA3dSurfaceFormat format;
+ SVGA3dSurface1Flags surface1Flags;
+ uint32 numMipLevels;
+ uint32 multisampleCount;
+ SVGA3dTextureFilter autogenFilter;
+ SVGA3dSize size;
+ SVGAMobId mobid;
+ uint32 arraySize;
+ uint32 mobPitch;
+ SVGA3dSurface2Flags surface2Flags;
+ uint8 multisamplePattern;
+ uint8 qualityLevel;
+ uint8 pad0[2];
+ uint32 pad1[3];
+}
+SVGAOTableSurfaceEntry;
+#define SVGA3D_OTABLE_SURFACE_ENTRY_SIZE (sizeof(SVGAOTableSurfaceEntry))
+
+typedef
+struct {
+ uint32 cid;
+ SVGAMobId mobid;
+}
+SVGAOTableContextEntry;
+#define SVGA3D_OTABLE_CONTEXT_ENTRY_SIZE (sizeof(SVGAOTableContextEntry))
+
+typedef
+struct {
+ SVGA3dShaderType type;
+ uint32 sizeInBytes;
+ uint32 offsetInBytes;
+ SVGAMobId mobid;
+}
+SVGAOTableShaderEntry;
+#define SVGA3D_OTABLE_SHADER_ENTRY_SIZE (sizeof(SVGAOTableShaderEntry))
+
+#define SVGA_STFLAG_PRIMARY (1 << 0)
+#define SVGA_STFLAG_RESERVED (1 << 1) /* Added with cap SVGA_CAP_HP_CMD_QUEUE */
+typedef uint32 SVGAScreenTargetFlags;
+
+typedef
+struct {
+ SVGA3dSurfaceImageId image;
+ uint32 width;
+ uint32 height;
+ int32 xRoot;
+ int32 yRoot;
+ SVGAScreenTargetFlags flags;
+ uint32 dpi;
+ uint32 pad[7];
+}
+SVGAOTableScreenTargetEntry;
+#define SVGA3D_OTABLE_SCREEN_TARGET_ENTRY_SIZE \
+ (sizeof(SVGAOTableScreenTargetEntry))
+
+typedef
+struct {
+ float value[4];
+}
+SVGA3dShaderConstFloat;
+
+typedef
+struct {
+ int32 value[4];
+}
+SVGA3dShaderConstInt;
+
+typedef
+struct {
+ uint32 value;
+}
+SVGA3dShaderConstBool;
+
+typedef
+struct {
+ uint16 streamOffset;
+ uint8 stream;
+ uint8 type;
+ uint8 methodUsage;
+ uint8 usageIndex;
+}
+SVGAGBVertexElement;
+
+typedef
+struct {
+ uint32 sid;
+ uint16 stride;
+ uint32 offset;
+}
+SVGAGBVertexStream;
+typedef
+struct {
+ SVGA3dRect viewport;
+ SVGA3dRect scissorRect;
+ SVGA3dZRange zRange;
+
+ SVGA3dSurfaceImageId renderTargets[SVGA3D_RT_MAX];
+ SVGAGBVertexElement decl1[4];
+
+ uint32 renderStates[SVGA3D_RS_MAX];
+ SVGAGBVertexElement decl2[18];
+ uint32 pad0[2];
+
+ struct {
+ SVGA3dFace face;
+ SVGA3dMaterial material;
+ } material;
+
+ float clipPlanes[SVGA3D_NUM_CLIPPLANES][4];
+ float matrices[SVGA3D_TRANSFORM_MAX][16];
+
+ SVGA3dBool lightEnabled[SVGA3D_NUM_LIGHTS];
+ SVGA3dLightData lightData[SVGA3D_NUM_LIGHTS];
+
+ /*
+ * Shaders currently bound
+ */
+ uint32 shaders[SVGA3D_NUM_SHADERTYPE_PREDX];
+ SVGAGBVertexElement decl3[10];
+ uint32 pad1[3];
+
+ uint32 occQueryActive;
+ uint32 occQueryValue;
+
+ /*
+ * Int/Bool Shader constants
+ */
+ SVGA3dShaderConstInt pShaderIValues[SVGA3D_CONSTINTREG_MAX];
+ SVGA3dShaderConstInt vShaderIValues[SVGA3D_CONSTINTREG_MAX];
+ uint16 pShaderBValues;
+ uint16 vShaderBValues;
+
+
+ SVGAGBVertexStream streams[SVGA3D_MAX_VERTEX_ARRAYS];
+ SVGA3dVertexDivisor divisors[SVGA3D_MAX_VERTEX_ARRAYS];
+ uint32 numVertexDecls;
+ uint32 numVertexStreams;
+ uint32 numVertexDivisors;
+ uint32 pad2[30];
+
+ /*
+ * Texture Stages
+ *
+ * SVGA3D_TS_INVALID through SVGA3D_TS_CONSTANT are in the
+ * textureStages array.
+ * SVGA3D_TS_COLOR_KEY is in tsColorKey.
+ */
+ uint32 tsColorKey[SVGA3D_NUM_TEXTURE_UNITS];
+ uint32 textureStages[SVGA3D_NUM_TEXTURE_UNITS][SVGA3D_TS_CONSTANT + 1];
+ uint32 tsColorKeyEnable[SVGA3D_NUM_TEXTURE_UNITS];
+
+ /*
+ * Float Shader constants.
+ */
+ SVGA3dShaderConstFloat pShaderFValues[SVGA3D_CONSTREG_MAX];
+ SVGA3dShaderConstFloat vShaderFValues[SVGA3D_CONSTREG_MAX];
+}
+SVGAGBContextData;
+#define SVGA3D_CONTEXT_DATA_SIZE (sizeof(SVGAGBContextData))
+
+/*
+ * SVGA3dCmdSetOTableBase --
+ *
+ * This command allows the guest to specify the base PPN of the
+ * specified object table.
+ */
+
+typedef
+struct {
+ SVGAOTableType type;
+ PPN baseAddress;
+ uint32 sizeInBytes;
+ uint32 validSizeInBytes;
+ SVGAMobFormat ptDepth;
+}
+SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */
+
+typedef
+struct {
+ SVGAOTableType type;
+ PPN64 baseAddress;
+ uint32 sizeInBytes;
+ uint32 validSizeInBytes;
+ SVGAMobFormat ptDepth;
+}
+SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */
+
+/*
+ * Guests using SVGA_3D_CMD_GROW_OTABLE are promising that
+ * the new OTable contains the same contents as the old one, except possibly
+ * for some new invalid entries at the end.
+ *
+ * (Otherwise, guests should use one of the SetOTableBase commands.)
+ */
+typedef
+struct {
+ SVGAOTableType type;
+ PPN64 baseAddress;
+ uint32 sizeInBytes;
+ uint32 validSizeInBytes;
+ SVGAMobFormat ptDepth;
+}
+SVGA3dCmdGrowOTable; /* SVGA_3D_CMD_GROW_OTABLE */
+
+typedef
+struct {
+ SVGAOTableType type;
+}
+SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */
+
+/*
+ * Define a memory object (Mob) in the OTable.
+ */
+
+typedef
+struct SVGA3dCmdDefineGBMob {
+ SVGAMobId mobid;
+ SVGAMobFormat ptDepth;
+ PPN base;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */
+
+
+/*
+ * Destroys an object in the OTable.
+ */
+
+typedef
+struct SVGA3dCmdDestroyGBMob {
+ SVGAMobId mobid;
+}
+SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */
+
+
+/*
+ * Define a memory object (Mob) in the OTable with a PPN64 base.
+ */
+
+typedef
+struct SVGA3dCmdDefineGBMob64 {
+ SVGAMobId mobid;
+ SVGAMobFormat ptDepth;
+ PPN64 base;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */
+
+/*
+ * Redefine an object in the OTable with PPN64 base.
+ */
+
+typedef
+struct SVGA3dCmdRedefineGBMob64 {
+ SVGAMobId mobid;
+ SVGAMobFormat ptDepth;
+ PPN64 base;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */
+
+/*
+ * Notification that the page tables have been modified.
+ */
+
+typedef
+struct SVGA3dCmdUpdateGBMobMapping {
+ SVGAMobId mobid;
+}
+SVGA3dCmdUpdateGBMobMapping; /* SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING */
+
+/*
+ * Define a guest-backed surface.
+ */
+
+typedef
+struct SVGA3dCmdDefineGBSurface {
+ uint32 sid;
+ SVGA3dSurface1Flags surfaceFlags;
+ SVGA3dSurfaceFormat format;
+ uint32 numMipLevels;
+ uint32 multisampleCount;
+ SVGA3dTextureFilter autogenFilter;
+ SVGA3dSize size;
+}
+SVGA3dCmdDefineGBSurface; /* SVGA_3D_CMD_DEFINE_GB_SURFACE */
+
+/*
+ * Defines a guest-backed surface, adding the arraySize field.
+ */
+typedef
+struct SVGA3dCmdDefineGBSurface_v2 {
+ uint32 sid;
+ SVGA3dSurface1Flags surfaceFlags;
+ SVGA3dSurfaceFormat format;
+ uint32 numMipLevels;
+ uint32 multisampleCount;
+ SVGA3dTextureFilter autogenFilter;
+ SVGA3dSize size;
+ uint32 arraySize;
+ uint32 pad;
+}
+SVGA3dCmdDefineGBSurface_v2; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V2 */
+
+/*
+ * Defines a guest-backed surface, adding the larger flags.
+ */
+typedef
+struct SVGA3dCmdDefineGBSurface_v3 {
+ uint32 sid;
+ SVGA3dSurfaceAllFlags surfaceFlags;
+ SVGA3dSurfaceFormat format;
+ uint32 numMipLevels;
+ uint32 multisampleCount;
+ SVGA3dMSPattern multisamplePattern;
+ SVGA3dMSQualityLevel qualityLevel;
+ SVGA3dTextureFilter autogenFilter;
+ SVGA3dSize size;
+ uint32 arraySize;
+}
+SVGA3dCmdDefineGBSurface_v3; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V3 */
+
+/*
+ * Defines a guest-backed surface, adding buffer byte stride.
+ */
+typedef
+struct SVGA3dCmdDefineGBSurface_v4 {
+ uint32 sid;
+ SVGA3dSurfaceAllFlags surfaceFlags;
+ SVGA3dSurfaceFormat format;
+ uint32 numMipLevels;
+ uint32 multisampleCount;
+ SVGA3dMSPattern multisamplePattern;
+ SVGA3dMSQualityLevel qualityLevel;
+ SVGA3dTextureFilter autogenFilter;
+ SVGA3dSize size;
+ uint32 arraySize;
+ uint32 bufferByteStride;
+}
+SVGA3dCmdDefineGBSurface_v4; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V4 */
+
+/*
+ * Destroy a guest-backed surface.
+ */
+
+typedef
+struct SVGA3dCmdDestroyGBSurface {
+ uint32 sid;
+}
+SVGA3dCmdDestroyGBSurface; /* SVGA_3D_CMD_DESTROY_GB_SURFACE */
+
+/*
+ * Bind a guest-backed surface to a mob.
+ */
+
+typedef
+struct SVGA3dCmdBindGBSurface {
+ uint32 sid;
+ SVGAMobId mobid;
+}
+SVGA3dCmdBindGBSurface; /* SVGA_3D_CMD_BIND_GB_SURFACE */
+
+typedef
+struct SVGA3dCmdBindGBSurfaceWithPitch {
+ uint32 sid;
+ SVGAMobId mobid;
+ uint32 baseLevelPitch;
+}
+SVGA3dCmdBindGBSurfaceWithPitch; /* SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH */
+
+/*
+ * Conditionally bind a mob to a guest-backed surface if testMobid
+ * matches the currently bound mob. Optionally issue a
+ * readback/update on the surface while it is still bound to the old
+ * mobid if the mobid is changed by this command.
+ */
+
+#define SVGA3D_COND_BIND_GB_SURFACE_FLAG_READBACK (1 << 0)
+#define SVGA3D_COND_BIND_GB_SURFACE_FLAG_UPDATE (1 << 1)
+
+typedef
+struct SVGA3dCmdCondBindGBSurface {
+ uint32 sid;
+ SVGAMobId testMobid;
+ SVGAMobId mobid;
+ uint32 flags;
+}
+SVGA3dCmdCondBindGBSurface; /* SVGA_3D_CMD_COND_BIND_GB_SURFACE */
+
+/*
+ * Update an image in a guest-backed surface.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+
+typedef
+struct SVGA3dCmdUpdateGBImage {
+ SVGA3dSurfaceImageId image;
+ SVGA3dBox box;
+}
+SVGA3dCmdUpdateGBImage; /* SVGA_3D_CMD_UPDATE_GB_IMAGE */
+
+/*
+ * Update an entire guest-backed surface.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+
+typedef
+struct SVGA3dCmdUpdateGBSurface {
+ uint32 sid;
+}
+SVGA3dCmdUpdateGBSurface; /* SVGA_3D_CMD_UPDATE_GB_SURFACE */
+
+/*
+ * Readback an image in a guest-backed surface.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+
+typedef
+struct SVGA3dCmdReadbackGBImage {
+ SVGA3dSurfaceImageId image;
+}
+SVGA3dCmdReadbackGBImage; /* SVGA_3D_CMD_READBACK_GB_IMAGE */
+
+/*
+ * Readback an entire guest-backed surface.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+
+typedef
+struct SVGA3dCmdReadbackGBSurface {
+ uint32 sid;
+}
+SVGA3dCmdReadbackGBSurface; /* SVGA_3D_CMD_READBACK_GB_SURFACE */
+
+/*
+ * Readback a sub rect of an image in a guest-backed surface. After
+ * issuing this command the driver is required to issue an update call
+ * of the same region before issuing any other commands that reference
+ * this surface or rendering is not guaranteed.
+ */
+
+typedef
+struct SVGA3dCmdReadbackGBImagePartial {
+ SVGA3dSurfaceImageId image;
+ SVGA3dBox box;
+ uint32 invertBox;
+}
+SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */
+
+
+/*
+ * Invalidate an image in a guest-backed surface.
+ * (Notify the device that the contents can be lost.)
+ */
+
+typedef
+struct SVGA3dCmdInvalidateGBImage {
+ SVGA3dSurfaceImageId image;
+}
+SVGA3dCmdInvalidateGBImage; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE */
+
+/*
+ * Invalidate an entire guest-backed surface.
+ * (Notify the device that the contents if all images can be lost.)
+ */
+
+typedef
+struct SVGA3dCmdInvalidateGBSurface {
+ uint32 sid;
+}
+SVGA3dCmdInvalidateGBSurface; /* SVGA_3D_CMD_INVALIDATE_GB_SURFACE */
+
+/*
+ * Invalidate a sub rect of an image in a guest-backed surface. After
+ * issuing this command the driver is required to issue an update call
+ * of the same region before issuing any other commands that reference
+ * this surface or rendering is not guaranteed.
+ */
+
+typedef
+struct SVGA3dCmdInvalidateGBImagePartial {
+ SVGA3dSurfaceImageId image;
+ SVGA3dBox box;
+ uint32 invertBox;
+}
+SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */
+
+
+/*
+ * Define a guest-backed context.
+ */
+
+typedef
+struct SVGA3dCmdDefineGBContext {
+ uint32 cid;
+}
+SVGA3dCmdDefineGBContext; /* SVGA_3D_CMD_DEFINE_GB_CONTEXT */
+
+/*
+ * Destroy a guest-backed context.
+ */
+
+typedef
+struct SVGA3dCmdDestroyGBContext {
+ uint32 cid;
+}
+SVGA3dCmdDestroyGBContext; /* SVGA_3D_CMD_DESTROY_GB_CONTEXT */
+
+/*
+ * Bind a guest-backed context.
+ *
+ * validContents should be set to 0 for new contexts,
+ * and 1 if this is an old context which is getting paged
+ * back on to the device.
+ *
+ * For new contexts, it is recommended that the driver
+ * issue commands to initialize all interesting state
+ * prior to rendering.
+ */
+
+typedef
+struct SVGA3dCmdBindGBContext {
+ uint32 cid;
+ SVGAMobId mobid;
+ uint32 validContents;
+}
+SVGA3dCmdBindGBContext; /* SVGA_3D_CMD_BIND_GB_CONTEXT */
+
+/*
+ * Readback a guest-backed context.
+ * (Request that the device flush the contents back into guest memory.)
+ */
+
+typedef
+struct SVGA3dCmdReadbackGBContext {
+ uint32 cid;
+}
+SVGA3dCmdReadbackGBContext; /* SVGA_3D_CMD_READBACK_GB_CONTEXT */
+
+/*
+ * Invalidate a guest-backed context.
+ */
+typedef
+struct SVGA3dCmdInvalidateGBContext {
+ uint32 cid;
+}
+SVGA3dCmdInvalidateGBContext; /* SVGA_3D_CMD_INVALIDATE_GB_CONTEXT */
+
+/*
+ * Define a guest-backed shader.
+ */
+
+typedef
+struct SVGA3dCmdDefineGBShader {
+ uint32 shid;
+ SVGA3dShaderType type;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdDefineGBShader; /* SVGA_3D_CMD_DEFINE_GB_SHADER */
+
+/*
+ * Bind a guest-backed shader.
+ */
+
+typedef
+struct SVGA3dCmdBindGBShader {
+ uint32 shid;
+ SVGAMobId mobid;
+ uint32 offsetInBytes;
+}
+SVGA3dCmdBindGBShader; /* SVGA_3D_CMD_BIND_GB_SHADER */
+
+/*
+ * Destroy a guest-backed shader.
+ */
+
+typedef
+struct SVGA3dCmdDestroyGBShader {
+ uint32 shid;
+}
+SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */
+
+typedef
+struct {
+ uint32 cid;
+ uint32 regStart;
+ SVGA3dShaderType shaderType;
+ SVGA3dShaderConstType constType;
+
+ /*
+ * Followed by a variable number of shader constants.
+ *
+ * Note that FLOAT and INT constants are 4-dwords in length, while
+ * BOOL constants are 1-dword in length.
+ */
+}
+SVGA3dCmdSetGBShaderConstInline; /* SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE */
+
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dQueryType type;
+}
+SVGA3dCmdBeginGBQuery; /* SVGA_3D_CMD_BEGIN_GB_QUERY */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dQueryType type;
+ SVGAMobId mobid;
+ uint32 offset;
+}
+SVGA3dCmdEndGBQuery; /* SVGA_3D_CMD_END_GB_QUERY */
+
+
+/*
+ * SVGA_3D_CMD_WAIT_FOR_GB_QUERY --
+ *
+ * The semantics of this command are identical to the
+ * SVGA_3D_CMD_WAIT_FOR_QUERY except that the results are written
+ * to a Mob instead of a GMR.
+ */
+
+typedef
+struct {
+ uint32 cid;
+ SVGA3dQueryType type;
+ SVGAMobId mobid;
+ uint32 offset;
+}
+SVGA3dCmdWaitForGBQuery; /* SVGA_3D_CMD_WAIT_FOR_GB_QUERY */
+
+
+typedef
+struct {
+ SVGAMobId mobid;
+ uint32 mustBeZero;
+ uint32 initialized;
+}
+SVGA3dCmdEnableGart; /* SVGA_3D_CMD_ENABLE_GART */
+
+typedef
+struct {
+ SVGAMobId mobid;
+ uint32 gartOffset;
+}
+SVGA3dCmdMapMobIntoGart; /* SVGA_3D_CMD_MAP_MOB_INTO_GART */
+
+
+typedef
+struct {
+ uint32 gartOffset;
+ uint32 numPages;
+}
+SVGA3dCmdUnmapGartRange; /* SVGA_3D_CMD_UNMAP_GART_RANGE */
+
+
+/*
+ * Screen Targets
+ */
+
+typedef
+struct {
+ uint32 stid;
+ uint32 width;
+ uint32 height;
+ int32 xRoot;
+ int32 yRoot;
+ SVGAScreenTargetFlags flags;
+
+ /*
+ * The physical DPI that the guest expects this screen displayed at.
+ *
+ * Guests which are not DPI-aware should set this to zero.
+ */
+ uint32 dpi;
+}
+SVGA3dCmdDefineGBScreenTarget; /* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET */
+
+typedef
+struct {
+ uint32 stid;
+}
+SVGA3dCmdDestroyGBScreenTarget; /* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET */
+
+typedef
+struct {
+ uint32 stid;
+ SVGA3dSurfaceImageId image;
+}
+SVGA3dCmdBindGBScreenTarget; /* SVGA_3D_CMD_BIND_GB_SCREENTARGET */
+
+typedef
+struct {
+ uint32 stid;
+ SVGA3dRect rect;
+}
+SVGA3dCmdUpdateGBScreenTarget; /* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET */
+
+typedef
+struct SVGA3dCmdGBScreenDMA {
+ uint32 screenId;
+ uint32 dead;
+ SVGAMobId destMobID;
+ uint32 destPitch;
+ SVGAMobId changeMapMobID;
+}
+SVGA3dCmdGBScreenDMA; /* SVGA_3D_CMD_GB_SCREEN_DMA */
+
+typedef
+struct {
+ uint32 value;
+ uint32 mobId;
+ uint32 mobOffset;
+}
+SVGA3dCmdGBMobFence; /* SVGA_3D_CMD_GB_MOB_FENCE */
+
+typedef
+struct {
+ uint32 stid;
+ SVGA3dSurfaceImageId dest;
+
+ uint32 statusMobId;
+ uint32 statusMobOffset;
+
+ /* Reserved fields */
+ uint32 mustBeInvalidId;
+ uint32 mustBeZero;
+}
+SVGA3dCmdScreenCopy; /* SVGA_3D_CMD_SCREEN_COPY */
+
+#define SVGA_SCREEN_COPY_STATUS_FAILURE 0x00
+#define SVGA_SCREEN_COPY_STATUS_SUCCESS 0x01
+#define SVGA_SCREEN_COPY_STATUS_INVALID 0xFFFFFFFF
+
+
+#endif /* _SVGA3D_REG_H_ */
diff --git a/vmware/svga_all.h b/vmware/svga_all.h
new file mode 100644
index 0000000..de26664
--- /dev/null
+++ b/vmware/svga_all.h
@@ -0,0 +1,13 @@
+#ifndef __SVGA_ALL_H__INCLUDED__
+#define __SVGA_ALL_H__INCLUDED__
+
+#pragma pack(push)
+#pragma pack(1)
+#include "svga.h"
+#include "svga_reg.h"
+#include "svga3d.h"
+#include "svga3d_reg.h"
+#include "svga3d_caps.h"
+#pragma pack(pop)
+
+#endif /* __SVGA_ALL_H__INCLUDED__ */
diff --git a/vmware/svga_escape.h b/vmware/svga_escape.h
new file mode 100644
index 0000000..7b85e9b
--- /dev/null
+++ b/vmware/svga_escape.h
@@ -0,0 +1,89 @@
+/**********************************************************
+ * Copyright 2007-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga_escape.h --
+ *
+ * Definitions for our own (vendor-specific) SVGA Escape commands.
+ */
+
+#ifndef _SVGA_ESCAPE_H_
+#define _SVGA_ESCAPE_H_
+
+
+/*
+ * Namespace IDs for the escape command
+ */
+
+#define SVGA_ESCAPE_NSID_VMWARE 0x00000000
+#define SVGA_ESCAPE_NSID_DEVEL 0xFFFFFFFF
+
+
+/*
+ * Within SVGA_ESCAPE_NSID_VMWARE, we multiplex commands according to
+ * the first DWORD of escape data (after the nsID and size). As a
+ * guideline we're using the high word and low word as a major and
+ * minor command number, respectively.
+ *
+ * Major command number allocation:
+ *
+ * 0000: Reserved
+ * 0001: SVGA_ESCAPE_VMWARE_LOG (svga_binary_logger.h)
+ * 0002: SVGA_ESCAPE_VMWARE_VIDEO (svga_overlay.h)
+ * 0003: SVGA_ESCAPE_VMWARE_HINT (svga_escape.h)
+ */
+
+#define SVGA_ESCAPE_VMWARE_MAJOR_MASK 0xFFFF0000
+
+
+/*
+ * SVGA Hint commands.
+ *
+ * These escapes let the SVGA driver provide optional information to
+ * he host about the state of the guest or guest applications. The
+ * host can use these hints to make user interface or performance
+ * decisions.
+ *
+ * Notes:
+ *
+ * - SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN is deprecated for guests
+ * that use the SVGA Screen Object extension. Instead of sending
+ * this escape, use the SVGA_SCREEN_FULLSCREEN_HINT flag on your
+ * Screen Object.
+ */
+
+#define SVGA_ESCAPE_VMWARE_HINT 0x00030000
+#define SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN 0x00030001 // Deprecated
+
+typedef
+struct {
+ uint32 command;
+ uint32 fullscreen;
+ struct {
+ int32 x, y;
+ } monitorPosition;
+} SVGAEscapeHintFullscreen;
+
+#endif /* _SVGA_ESCAPE_H_ */
diff --git a/vmware/svga_overlay.h b/vmware/svga_overlay.h
new file mode 100644
index 0000000..82c1d3f
--- /dev/null
+++ b/vmware/svga_overlay.h
@@ -0,0 +1,201 @@
+/**********************************************************
+ * Copyright 2007-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga_overlay.h --
+ *
+ * Definitions for video-overlay support.
+ */
+
+#ifndef _SVGA_OVERLAY_H_
+#define _SVGA_OVERLAY_H_
+
+#include "svga_reg.h"
+
+/*
+ * Video formats we support
+ */
+
+#define VMWARE_FOURCC_YV12 0x32315659 // 'Y' 'V' '1' '2'
+#define VMWARE_FOURCC_YUY2 0x32595559 // 'Y' 'U' 'Y' '2'
+#define VMWARE_FOURCC_UYVY 0x59565955 // 'U' 'Y' 'V' 'Y'
+
+typedef enum {
+ SVGA_OVERLAY_FORMAT_INVALID = 0,
+ SVGA_OVERLAY_FORMAT_YV12 = VMWARE_FOURCC_YV12,
+ SVGA_OVERLAY_FORMAT_YUY2 = VMWARE_FOURCC_YUY2,
+ SVGA_OVERLAY_FORMAT_UYVY = VMWARE_FOURCC_UYVY,
+} SVGAOverlayFormat;
+
+#define SVGA_VIDEO_COLORKEY_MASK 0x00ffffff
+
+#define SVGA_ESCAPE_VMWARE_VIDEO 0x00020000
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS 0x00020001
+ /* FIFO escape layout:
+ * Type, Stream Id, (Register Id, Value) pairs */
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_FLUSH 0x00020002
+ /* FIFO escape layout:
+ * Type, Stream Id */
+
+typedef
+struct SVGAEscapeVideoSetRegs {
+ struct {
+ uint32 cmdType;
+ uint32 streamId;
+ } header;
+
+ // May include zero or more items.
+ struct {
+ uint32 registerId;
+ uint32 value;
+ } items[1];
+} SVGAEscapeVideoSetRegs;
+
+typedef
+struct SVGAEscapeVideoFlush {
+ uint32 cmdType;
+ uint32 streamId;
+} SVGAEscapeVideoFlush;
+
+
+/*
+ * Struct definitions for the video overlay commands built on
+ * SVGAFifoCmdEscape.
+ */
+typedef
+struct {
+ uint32 command;
+ uint32 overlay;
+} SVGAFifoEscapeCmdVideoBase;
+
+typedef
+struct {
+ SVGAFifoEscapeCmdVideoBase videoCmd;
+} SVGAFifoEscapeCmdVideoFlush;
+
+typedef
+struct {
+ SVGAFifoEscapeCmdVideoBase videoCmd;
+ struct {
+ uint32 regId;
+ uint32 value;
+ } items[1];
+} SVGAFifoEscapeCmdVideoSetRegs;
+
+typedef
+struct {
+ SVGAFifoEscapeCmdVideoBase videoCmd;
+ struct {
+ uint32 regId;
+ uint32 value;
+ } items[SVGA_VIDEO_NUM_REGS];
+} SVGAFifoEscapeCmdVideoSetAllRegs;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMwareVideoGetAttributes --
+ *
+ * Computes the size, pitches and offsets for YUV frames.
+ *
+ * Results:
+ * TRUE on success; otherwise FALSE on failure.
+ *
+ * Side effects:
+ * Pitches and offsets for the given YUV frame are put in 'pitches'
+ * and 'offsets' respectively. They are both optional though.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE Bool
+VMwareVideoGetAttributes(const SVGAOverlayFormat format, // IN
+ uint32 *width, // IN / OUT
+ uint32 *height, // IN / OUT
+ uint32 *size, // OUT
+ uint32 *pitches, // OUT (optional)
+ uint32 *offsets) // OUT (optional)
+{
+ int tmp;
+
+ *width = (*width + 1) & ~1;
+
+ if (offsets) {
+ offsets[0] = 0;
+ }
+
+ switch (format) {
+ case VMWARE_FOURCC_YV12:
+ *height = (*height + 1) & ~1;
+ *size = (*width + 3) & ~3;
+
+ if (pitches) {
+ pitches[0] = *size;
+ }
+
+ *size *= *height;
+
+ if (offsets) {
+ offsets[1] = *size;
+ }
+
+ tmp = ((*width >> 1) + 3) & ~3;
+
+ if (pitches) {
+ pitches[1] = pitches[2] = tmp;
+ }
+
+ tmp *= (*height >> 1);
+ *size += tmp;
+
+ if (offsets) {
+ offsets[2] = *size;
+ }
+
+ *size += tmp;
+ break;
+
+ case VMWARE_FOURCC_YUY2:
+ case VMWARE_FOURCC_UYVY:
+ *size = *width * 2;
+
+ if (pitches) {
+ pitches[0] = *size;
+ }
+
+ *size *= *height;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#endif // _SVGA_OVERLAY_H_
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
new file mode 100644
index 0000000..04707c3
--- /dev/null
+++ b/vmware/svga_reg.h
@@ -0,0 +1,1610 @@
+/**********************************************************
+ * Copyright 1998-2009 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ * Virtual hardware definitions for the VMware SVGA II device.
+ */
+
+#ifndef _SVGA_REG_H_
+#define _SVGA_REG_H_
+
+/*
+ * PCI device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE 0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
+
+#define PCI_VENDOR_ID_INNOTEK 0x80EE
+#define PCI_DEVICE_ID_VBOX_VGA 0xBEEF
+
+#define PCI_SUBCLASS_ID_SVGA2 0x040515ADUL
+
+/*
+ * SVGA_REG_ENABLE bit definitions.
+ */
+#define SVGA_REG_ENABLE_DISABLE 0
+#define SVGA_REG_ENABLE_ENABLE 1
+#define SVGA_REG_ENABLE_HIDE 2
+#define SVGA_REG_ENABLE_ENABLE_HIDE (SVGA_REG_ENABLE_ENABLE |\
+ SVGA_REG_ENABLE_HIDE)
+
+/*
+ * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned
+ * cursor bypass mode. This is still supported, but no new guest
+ * drivers should use it.
+ */
+#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */
+
+/*
+ * The maximum framebuffer size that can traced for e.g. guests in VESA mode.
+ * The changeMap in the monitor is proportional to this number. Therefore, we'd
+ * like to keep it as small as possible to reduce monitor overhead (using
+ * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over
+ * 4k!).
+ *
+ * NB: For compatibility reasons, this value must be greater than 0xff0000.
+ * See bug 335072.
+ */
+#define SVGA_FB_MAX_TRACEABLE_SIZE 0x1000000
+
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8
+#define SVGA_MAX_PSEUDOCOLORS (1UL << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+#define SVGA_NUM_PALETTE_REGS (3UL * SVGA_MAX_PSEUDOCOLORS)
+
+#define SVGA_MAGIC 0x900000UL
+#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
+
+#define SVGA_VERSION_3 3
+#define SVGA_ID_3 SVGA_MAKE_ID(SVGA_VERSION_3)
+
+/* Version 2 let the address of the frame buffer be unsigned on Win32 */
+#define SVGA_VERSION_2 2
+#define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2)
+
+/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
+ PALETTE_BASE has moved */
+#define SVGA_VERSION_1 1
+#define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1)
+
+/* Version 0 is the initial version */
+#define SVGA_VERSION_0 0
+#define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0)
+
+/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */
+#define SVGA_ID_INVALID 0xFFFFFFFF
+
+/* Port offsets, relative to BAR0 */
+#define SVGA_INDEX_PORT 0x0
+#define SVGA_VALUE_PORT 0x1
+#define SVGA_BIOS_PORT 0x2
+#define SVGA_IRQSTATUS_PORT 0x8
+
+/*
+ * Interrupt source flags for IRQSTATUS_PORT and IRQMASK.
+ *
+ * Interrupts are only supported when the
+ * SVGA_CAP_IRQMASK capability is present.
+ */
+#define SVGA_IRQFLAG_ANY_FENCE 0x1 /* Any fence was passed */
+#define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */
+#define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */
+
+/*
+ * Registers
+ */
+
+enum {
+ SVGA_REG_ID = 0,
+ SVGA_REG_ENABLE = 1,
+ SVGA_REG_WIDTH = 2,
+ SVGA_REG_HEIGHT = 3,
+ SVGA_REG_MAX_WIDTH = 4,
+ SVGA_REG_MAX_HEIGHT = 5,
+ SVGA_REG_DEPTH = 6,
+ SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */
+ SVGA_REG_PSEUDOCOLOR = 8,
+ SVGA_REG_RED_MASK = 9,
+ SVGA_REG_GREEN_MASK = 10,
+ SVGA_REG_BLUE_MASK = 11,
+ SVGA_REG_BYTES_PER_LINE = 12,
+ SVGA_REG_FB_START = 13, /* (Deprecated) */
+ SVGA_REG_FB_OFFSET = 14,
+ SVGA_REG_VRAM_SIZE = 15,
+ SVGA_REG_FB_SIZE = 16,
+
+ /* ID 0 implementation only had the above registers, then the palette */
+
+ SVGA_REG_CAPABILITIES = 17,
+ SVGA_REG_MEM_START = 18, /* (Deprecated) */
+ SVGA_REG_MEM_SIZE = 19,
+ SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */
+ SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */
+ SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */
+ SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */
+ SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */
+ SVGA_REG_CURSOR_X = 25, /* (Deprecated) */
+ SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */
+ SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */
+ SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */
+ SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */
+ SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */
+ SVGA_REG_NUM_DISPLAYS = 31, /* (Deprecated) */
+ SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */
+ SVGA_REG_IRQMASK = 33, /* Interrupt mask */
+
+ /* Legacy multi-monitor support */
+ SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */
+ SVGA_REG_DISPLAY_ID = 35, /* Display ID for the following display attributes */
+ SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */
+ SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */
+ SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */
+ SVGA_REG_DISPLAY_WIDTH = 39, /* The display's width */
+ SVGA_REG_DISPLAY_HEIGHT = 40, /* The display's height */
+
+ /* See "Guest memory regions" below. */
+ SVGA_REG_GMR_ID = 41,
+ SVGA_REG_GMR_DESCRIPTOR = 42,
+ SVGA_REG_GMR_MAX_IDS = 43,
+ SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44,
+
+ SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */
+ SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */
+ SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */
+
+ /* SVGA_3 registers */
+ SVGA_REG_COMMAND_LOW = 48,
+ SVGA_REG_COMMAND_HIGH = 49,
+ SVGA_REG_MAX_PRIMARY_MEM = 50,
+ SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51,
+ SVGA_REG_DEV_CAP = 52,
+ SVGA_REG_CMD_PREPEND_LOW = 53,
+ SVGA_REG_CMD_PREPEND_HIGH = 54,
+ SVGA_REG_SCREENTARGET_MAX_WIDTH = 55,
+ SVGA_REG_SCREENTARGET_MAX_HEIGHT = 56,
+ SVGA_REG_MOB_MAX_SIZE = 57,
+ SVGA_REG_BLANK_SCREEN_TARGETS = 58,
+ SVGA_REG_CAP2 = 59,
+ SVGA_REG_DEVEL_CAP = 60,
+ SVGA_REG_GUEST_DRIVER_ID = 61,
+ SVGA_REG_GUEST_DRIVER_VERSION1 = 62,
+ SVGA_REG_GUEST_DRIVER_VERSION2 = 63,
+ SVGA_REG_GUEST_DRIVER_VERSION3 = 64,
+ SVGA_REG_CURSOR_MOBID = 65,
+ SVGA_REG_CURSOR_MAX_BYTE_SIZE = 66,
+ SVGA_REG_CURSOR_MAX_DIMENSION = 67,
+ SVGA_REG_FIFO_CAPS = 68,
+ SVGA_REG_FENCE = 69,
+ SVGA_REG_CURSOR4_ON = 70,
+ SVGA_REG_CURSOR4_X = 71,
+ SVGA_REG_CURSOR4_Y = 72,
+ SVGA_REG_CURSOR4_SCREEN_ID = 73,
+ SVGA_REG_CURSOR4_SUBMIT = 74,
+ SVGA_REG_SCREENDMA = 75,
+ SVGA_REG_GBOBJECT_MEM_SIZE_KB = 76,
+ SVGA_REG_REGS_START_HIGH32 = 77,
+ SVGA_REG_REGS_START_LOW32 = 78,
+ SVGA_REG_FB_START_HIGH32 = 79,
+ SVGA_REG_FB_START_LOW32 = 80,
+ SVGA_REG_MSHINT = 81,
+ SVGA_REG_IRQ_STATUS = 82,
+ SVGA_REG_DIRTY_TRACKING = 83,
+ SVGA_REG_FENCE_GOAL = 84,
+ SVGA_REG_TOP = 85, /* Must be 1 more than the last register */
+
+ SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */
+ /* Next 768 (== 256*3) registers exist for colormap */
+
+ SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS
+ /* Base of scratch registers */
+ /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage:
+ First 4 are reserved for VESA BIOS Extension; any remaining are for
+ the use of the current SVGA driver. */
+};
+
+
+/*
+ * Guest memory regions (GMRs):
+ *
+ * This is a new memory mapping feature available in SVGA devices
+ * which have the SVGA_CAP_GMR bit set. Previously, there were two
+ * fixed memory regions available with which to share data between the
+ * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs
+ * are our name for an extensible way of providing arbitrary DMA
+ * buffers for use between the driver and the SVGA device. They are a
+ * new alternative to framebuffer memory, usable for both 2D and 3D
+ * graphics operations.
+ *
+ * Since GMR mapping must be done synchronously with guest CPU
+ * execution, we use a new pair of SVGA registers:
+ *
+ * SVGA_REG_GMR_ID --
+ *
+ * Read/write.
+ * This register holds the 32-bit ID (a small positive integer)
+ * of a GMR to create, delete, or redefine. Writing this register
+ * has no side-effects.
+ *
+ * SVGA_REG_GMR_DESCRIPTOR --
+ *
+ * Write-only.
+ * Writing this register will create, delete, or redefine the GMR
+ * specified by the above ID register. If this register is zero,
+ * the GMR is deleted. Any pointers into this GMR (including those
+ * currently being processed by FIFO commands) will be
+ * synchronously invalidated.
+ *
+ * If this register is nonzero, it must be the physical page
+ * number (PPN) of a data structure which describes the physical
+ * layout of the memory region this GMR should describe. The
+ * descriptor structure will be read synchronously by the SVGA
+ * device when this register is written. The descriptor need not
+ * remain allocated for the lifetime of the GMR.
+ *
+ * The guest driver should write SVGA_REG_GMR_ID first, then
+ * SVGA_REG_GMR_DESCRIPTOR.
+ *
+ * SVGA_REG_GMR_MAX_IDS --
+ *
+ * Read-only.
+ * The SVGA device may choose to support a maximum number of
+ * user-defined GMR IDs. This register holds the number of supported
+ * IDs. (The maximum supported ID plus 1)
+ *
+ * SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH --
+ *
+ * Read-only.
+ * The SVGA device may choose to put a limit on the total number
+ * of SVGAGuestMemDescriptor structures it will read when defining
+ * a single GMR.
+ *
+ * The descriptor structure is an array of SVGAGuestMemDescriptor
+ * structures. Each structure may do one of three things:
+ *
+ * - Terminate the GMR descriptor list.
+ * (ppn==0, numPages==0)
+ *
+ * - Add a PPN or range of PPNs to the GMR's virtual address space.
+ * (ppn != 0, numPages != 0)
+ *
+ * - Provide the PPN of the next SVGAGuestMemDescriptor, in order to
+ * support multi-page GMR descriptor tables without forcing the
+ * driver to allocate physically contiguous memory.
+ * (ppn != 0, numPages == 0)
+ *
+ * Note that each physical page of SVGAGuestMemDescriptor structures
+ * can describe at least 2MB of guest memory. If the driver needs to
+ * use more than one page of descriptor structures, it must use one of
+ * its SVGAGuestMemDescriptors to point to an additional page. The
+ * device will never automatically cross a page boundary.
+ *
+ * Once the driver has described a GMR, it is immediately available
+ * for use via any FIFO command that uses an SVGAGuestPtr structure.
+ * These pointers include a GMR identifier plus an offset into that
+ * GMR.
+ *
+ * The driver must check the SVGA_CAP_GMR bit before using the GMR
+ * registers.
+ */
+
+/*
+ * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer
+ * memory as well. In the future, these IDs could even be used to
+ * allow legacy memory regions to be redefined by the guest as GMRs.
+ *
+ * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA
+ * is being phased out. Please try to use user-defined GMRs whenever
+ * possible.
+ */
+#define SVGA_GMR_NULL ((uint32) -1)
+#define SVGA_GMR_FRAMEBUFFER ((uint32) -2) // Guest Framebuffer (GFB)
+
+typedef
+struct SVGAGuestMemDescriptor {
+ uint32 ppn;
+ uint32 numPages;
+} SVGAGuestMemDescriptor;
+
+typedef
+struct SVGAGuestPtr {
+ uint32 gmrId;
+ uint32 offset;
+} SVGAGuestPtr;
+
+
+/*
+ * SVGAGMRImageFormat --
+ *
+ * This is a packed representation of the source 2D image format
+ * for a GMR-to-screen blit. Currently it is defined as an encoding
+ * of the screen's color depth and bits-per-pixel, however, 16 bits
+ * are reserved for future use to identify other encodings (such as
+ * RGBA or higher-precision images).
+ *
+ * Currently supported formats:
+ *
+ * bpp depth Format Name
+ * --- ----- -----------
+ * 32 24 32-bit BGRX
+ * 24 24 24-bit BGR
+ * 16 16 RGB 5-6-5
+ * 16 15 RGB 5-5-5
+ *
+ */
+
+typedef
+struct SVGAGMRImageFormat {
+ union {
+ struct {
+ uint32 bitsPerPixel : 8;
+ uint32 colorDepth : 8;
+ uint32 reserved : 16; // Must be zero
+ };
+
+ uint32 value;
+ };
+} SVGAGMRImageFormat;
+
+typedef
+struct SVGAGuestImage {
+ SVGAGuestPtr ptr;
+
+ /*
+ * A note on interpretation of pitch: This value of pitch is the
+ * number of bytes between vertically adjacent image
+ * blocks. Normally this is the number of bytes between the first
+ * pixel of two adjacent scanlines. With compressed textures,
+ * however, this may represent the number of bytes between
+ * compression blocks rather than between rows of pixels.
+ *
+ * XXX: Compressed textures currently must be tightly packed in guest memory.
+ *
+ * If the image is 1-dimensional, pitch is ignored.
+ *
+ * If 'pitch' is zero, the SVGA3D device calculates a pitch value
+ * assuming each row of blocks is tightly packed.
+ */
+ uint32 pitch;
+} SVGAGuestImage;
+
+/*
+ * SVGAColorBGRX --
+ *
+ * A 24-bit color format (BGRX), which does not depend on the
+ * format of the legacy guest framebuffer (GFB) or the current
+ * GMRFB state.
+ */
+
+typedef
+struct SVGAColorBGRX {
+ union {
+ struct {
+ uint32 b : 8;
+ uint32 g : 8;
+ uint32 r : 8;
+ uint32 x : 8; // Unused
+ };
+
+ uint32 value;
+ };
+} SVGAColorBGRX;
+
+
+/*
+ * SVGASignedRect --
+ * SVGASignedPoint --
+ *
+ * Signed rectangle and point primitives. These are used by the new
+ * 2D primitives for drawing to Screen Objects, which can occupy a
+ * signed virtual coordinate space.
+ *
+ * SVGASignedRect specifies a half-open interval: the (left, top)
+ * pixel is part of the rectangle, but the (right, bottom) pixel is
+ * not.
+ */
+
+typedef
+struct SVGASignedRect {
+ int32 left;
+ int32 top;
+ int32 right;
+ int32 bottom;
+} SVGASignedRect;
+
+typedef
+struct SVGASignedPoint {
+ int32 x;
+ int32 y;
+} SVGASignedPoint;
+
+
+/*
+ * Capabilities
+ *
+ * Note the holes in the bitfield. Missing bits have been deprecated,
+ * and must not be reused. Those capabilities will never be reported
+ * by new versions of the SVGA device.
+ *
+ * SVGA_CAP_GMR2 --
+ * Provides asynchronous commands to define and remap guest memory
+ * regions. Adds device registers SVGA_REG_GMRS_MAX_PAGES and
+ * SVGA_REG_MEMORY_SIZE.
+ *
+ * SVGA_CAP_SCREEN_OBJECT_2 --
+ * Allow screen object support, and require backing stores from the
+ * guest for each screen object.
+ */
+
+#define SVGA_CAP_NONE 0x00000000UL
+#define SVGA_CAP_RECT_COPY 0x00000002UL
+#define SVGA_CAP_CURSOR 0x00000020UL
+#define SVGA_CAP_CURSOR_BYPASS 0x00000040UL // Legacy (Use Cursor Bypass 3 instead)
+#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080UL // Legacy (Use Cursor Bypass 3 instead)
+#define SVGA_CAP_8BIT_EMULATION 0x00000100UL
+#define SVGA_CAP_ALPHA_CURSOR 0x00000200UL
+#define SVGA_CAP_3D 0x00004000UL
+#define SVGA_CAP_EXTENDED_FIFO 0x00008000UL
+#define SVGA_CAP_MULTIMON 0x00010000UL // Legacy multi-monitor support
+#define SVGA_CAP_PITCHLOCK 0x00020000UL
+#define SVGA_CAP_IRQMASK 0x00040000UL
+#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000UL // Legacy multi-monitor support
+#define SVGA_CAP_GMR 0x00100000UL
+#define SVGA_CAP_TRACES 0x00200000UL
+#define SVGA_CAP_GMR2 0x00400000UL
+#define SVGA_CAP_SCREEN_OBJECT_2 0x00800000UL
+/* svga3 caps */
+#define SVGA_CAP_COMMAND_BUFFERS 0x01000000UL
+#define SVGA_CAP_DEAD1 0x02000000UL
+#define SVGA_CAP_CMD_BUFFERS_2 0x04000000UL
+#define SVGA_CAP_GBOBJECTS 0x08000000UL
+#define SVGA_CAP_DX 0x10000000UL
+#define SVGA_CAP_HP_CMD_QUEUE 0x20000000UL
+#define SVGA_CAP_NO_BB_RESTRICTION 0x40000000UL
+#define SVGA_CAP_CAP2_REGISTER 0x80000000UL
+
+/*
+ * FIFO register indices.
+ *
+ * The FIFO is a chunk of device memory mapped into guest physmem. It
+ * is always treated as 32-bit words.
+ *
+ * The guest driver gets to decide how to partition it between
+ * - FIFO registers (there are always at least 4, specifying where the
+ * following data area is and how much data it contains; there may be
+ * more registers following these, depending on the FIFO protocol
+ * version in use)
+ * - FIFO data, written by the guest and slurped out by the VMX.
+ * These indices are 32-bit word offsets into the FIFO.
+ */
+
+enum {
+ /*
+ * Block 1 (basic registers): The originally defined FIFO registers.
+ * These exist and are valid for all versions of the FIFO protocol.
+ */
+
+ SVGA_FIFO_MIN = 0,
+ SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */
+ SVGA_FIFO_NEXT_CMD,
+ SVGA_FIFO_STOP,
+
+ /*
+ * Block 2 (extended registers): Mandatory registers for the extended
+ * FIFO. These exist if the SVGA caps register includes
+ * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their
+ * associated capability bit is enabled.
+ *
+ * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied
+ * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE.
+ * This means that the guest has to test individually (in most cases
+ * using FIFO caps) for the presence of registers after this; the VMX
+ * can define "extended FIFO" to mean whatever it wants, and currently
+ * won't enable it unless there's room for that set and much more.
+ */
+
+ SVGA_FIFO_CAPABILITIES = 4,
+ SVGA_FIFO_FLAGS,
+ // Valid with SVGA_FIFO_CAP_FENCE:
+ SVGA_FIFO_FENCE,
+
+ /*
+ * Block 3a (optional extended registers): Additional registers for the
+ * extended FIFO, whose presence isn't actually implied by
+ * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to
+ * leave room for them.
+ *
+ * These in block 3a, the VMX currently considers mandatory for the
+ * extended FIFO.
+ */
+
+ // Valid if exists (i.e. if extended FIFO enabled):
+ SVGA_FIFO_3D_HWVERSION, /* See SVGA3dHardwareVersion in svga3d_reg.h */
+ // Valid with SVGA_FIFO_CAP_PITCHLOCK:
+ SVGA_FIFO_PITCHLOCK,
+
+ // Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3:
+ SVGA_FIFO_CURSOR_ON, /* Cursor bypass 3 show/hide register */
+ SVGA_FIFO_CURSOR_X, /* Cursor bypass 3 x register */
+ SVGA_FIFO_CURSOR_Y, /* Cursor bypass 3 y register */
+ SVGA_FIFO_CURSOR_COUNT, /* Incremented when any of the other 3 change */
+ SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */
+
+ // Valid with SVGA_FIFO_CAP_RESERVE:
+ SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */
+
+ /*
+ * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2:
+ *
+ * By default this is SVGA_ID_INVALID, to indicate that the cursor
+ * coordinates are specified relative to the virtual root. If this
+ * is set to a specific screen ID, cursor position is reinterpreted
+ * as a signed offset relative to that screen's origin.
+ */
+ SVGA_FIFO_CURSOR_SCREEN_ID,
+
+ /*
+ * Valid with SVGA_FIFO_CAP_DEAD
+ *
+ * An arbitrary value written by the host, drivers should not use it.
+ */
+ SVGA_FIFO_DEAD,
+
+ /*
+ * Valid with SVGA_FIFO_CAP_3D_HWVERSION_REVISED:
+ *
+ * Contains 3D HWVERSION (see SVGA3dHardwareVersion in svga3d_reg.h)
+ * on platforms that can enforce graphics resource limits.
+ */
+ SVGA_FIFO_3D_HWVERSION_REVISED,
+
+ /*
+ * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new
+ * registers, but this must be done carefully and with judicious use of
+ * capability bits, since comparisons based on SVGA_FIFO_MIN aren't
+ * enough to tell you whether the register exists: we've shipped drivers
+ * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of
+ * the earlier ones. The actual order of introduction was:
+ * - PITCHLOCK
+ * - 3D_CAPS
+ * - CURSOR_* (cursor bypass 3)
+ * - RESERVED
+ * So, code that wants to know whether it can use any of the
+ * aforementioned registers, or anything else added after PITCHLOCK and
+ * before 3D_CAPS, needs to reason about something other than
+ * SVGA_FIFO_MIN.
+ */
+
+ /*
+ * 3D caps block space; valid with 3D hardware version >=
+ * SVGA3D_HWVERSION_WS6_B1.
+ */
+ SVGA_FIFO_3D_CAPS = 32,
+ SVGA_FIFO_3D_CAPS_LAST = 32 + 255,
+
+ /*
+ * End of VMX's current definition of "extended-FIFO registers".
+ * Registers before here are always enabled/disabled as a block; either
+ * the extended FIFO is enabled and includes all preceding registers, or
+ * it's disabled entirely.
+ *
+ * Block 3b (truly optional extended registers): Additional registers for
+ * the extended FIFO, which the VMX already knows how to enable and
+ * disable with correct granularity.
+ *
+ * Registers after here exist if and only if the guest SVGA driver
+ * sets SVGA_FIFO_MIN high enough to leave room for them.
+ */
+
+ // Valid if register exists:
+ SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */
+ SVGA_FIFO_FENCE_GOAL, /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */
+ SVGA_FIFO_BUSY, /* See "FIFO Synchronization Registers" */
+
+ /*
+ * Always keep this last. This defines the maximum number of
+ * registers we know about. At power-on, this value is placed in
+ * the SVGA_REG_MEM_REGS register, and we expect the guest driver
+ * to allocate this much space in FIFO memory for registers.
+ */
+ SVGA_FIFO_NUM_REGS
+};
+
+
+/*
+ * Definition of registers included in extended FIFO support.
+ *
+ * The guest SVGA driver gets to allocate the FIFO between registers
+ * and data. It must always allocate at least 4 registers, but old
+ * drivers stopped there.
+ *
+ * The VMX will enable extended FIFO support if and only if the guest
+ * left enough room for all registers defined as part of the mandatory
+ * set for the extended FIFO.
+ *
+ * Note that the guest drivers typically allocate the FIFO only at
+ * initialization time, not at mode switches, so it's likely that the
+ * number of FIFO registers won't change without a reboot.
+ *
+ * All registers less than this value are guaranteed to be present if
+ * svgaUser->fifo.extended is set. Any later registers must be tested
+ * individually for compatibility at each use (in the VMX).
+ *
+ * This value is used only by the VMX, so it can change without
+ * affecting driver compatibility; keep it that way?
+ */
+#define SVGA_FIFO_EXTENDED_MANDATORY_REGS (SVGA_FIFO_3D_CAPS_LAST + 1)
+
+
+/*
+ * FIFO Synchronization Registers
+ *
+ * This explains the relationship between the various FIFO
+ * sync-related registers in IOSpace and in FIFO space.
+ *
+ * SVGA_REG_SYNC --
+ *
+ * The SYNC register can be used in two different ways by the guest:
+ *
+ * 1. If the guest wishes to fully sync (drain) the FIFO,
+ * it will write once to SYNC then poll on the BUSY
+ * register. The FIFO is sync'ed once BUSY is zero.
+ *
+ * 2. If the guest wants to asynchronously wake up the host,
+ * it will write once to SYNC without polling on BUSY.
+ * Ideally it will do this after some new commands have
+ * been placed in the FIFO, and after reading a zero
+ * from SVGA_FIFO_BUSY.
+ *
+ * (1) is the original behaviour that SYNC was designed to
+ * support. Originally, a write to SYNC would implicitly
+ * trigger a read from BUSY. This causes us to synchronously
+ * process the FIFO.
+ *
+ * This behaviour has since been changed so that writing SYNC
+ * will *not* implicitly cause a read from BUSY. Instead, it
+ * makes a channel call which asynchronously wakes up the MKS
+ * thread.
+ *
+ * New guests can use this new behaviour to implement (2)
+ * efficiently. This lets guests get the host's attention
+ * without waiting for the MKS to poll, which gives us much
+ * better CPU utilization on SMP hosts and on UP hosts while
+ * we're blocked on the host GPU.
+ *
+ * Old guests shouldn't notice the behaviour change. SYNC was
+ * never guaranteed to process the entire FIFO, since it was
+ * bounded to a particular number of CPU cycles. Old guests will
+ * still loop on the BUSY register until the FIFO is empty.
+ *
+ * Writing to SYNC currently has the following side-effects:
+ *
+ * - Sets SVGA_REG_BUSY to TRUE (in the monitor)
+ * - Asynchronously wakes up the MKS thread for FIFO processing
+ * - The value written to SYNC is recorded as a "reason", for
+ * stats purposes.
+ *
+ * If SVGA_FIFO_BUSY is available, drivers are advised to only
+ * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set
+ * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will
+ * eventually set SVGA_FIFO_BUSY on its own, but this approach
+ * lets the driver avoid sending multiple asynchronous wakeup
+ * messages to the MKS thread.
+ *
+ * SVGA_REG_BUSY --
+ *
+ * This register is set to TRUE when SVGA_REG_SYNC is written,
+ * and it reads as FALSE when the FIFO has been completely
+ * drained.
+ *
+ * Every read from this register causes us to synchronously
+ * process FIFO commands. There is no guarantee as to how many
+ * commands each read will process.
+ *
+ * CPU time spent processing FIFO commands will be billed to
+ * the guest.
+ *
+ * New drivers should avoid using this register unless they
+ * need to guarantee that the FIFO is completely drained. It
+ * is overkill for performing a sync-to-fence. Older drivers
+ * will use this register for any type of synchronization.
+ *
+ * SVGA_FIFO_BUSY --
+ *
+ * This register is a fast way for the guest driver to check
+ * whether the FIFO is already being processed. It reads and
+ * writes at normal RAM speeds, with no monitor intervention.
+ *
+ * If this register reads as TRUE, the host is guaranteeing that
+ * any new commands written into the FIFO will be noticed before
+ * the MKS goes back to sleep.
+ *
+ * If this register reads as FALSE, no such guarantee can be
+ * made.
+ *
+ * The guest should use this register to quickly determine
+ * whether or not it needs to wake up the host. If the guest
+ * just wrote a command or group of commands that it would like
+ * the host to begin processing, it should:
+ *
+ * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further
+ * action is necessary.
+ *
+ * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest
+ * code that we've already sent a SYNC to the host and we
+ * don't need to send a duplicate.
+ *
+ * 3. Write a reason to SVGA_REG_SYNC. This will send an
+ * asynchronous wakeup to the MKS thread.
+ */
+
+
+/*
+ * FIFO Capabilities
+ *
+ * Fence -- Fence register and command are supported
+ * Accel Front -- Front buffer only commands are supported
+ * Pitch Lock -- Pitch lock register is supported
+ * Video -- SVGA Video overlay units are supported
+ * Escape -- Escape command is supported
+ *
+ * XXX: Add longer descriptions for each capability, including a list
+ * of the new features that each capability provides.
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT --
+ *
+ * Provides dynamic multi-screen rendering, for improved Unity and
+ * multi-monitor modes. With Screen Object, the guest can
+ * dynamically create and destroy 'screens', which can represent
+ * Unity windows or virtual monitors. Screen Object also provides
+ * strong guarantees that DMA operations happen only when
+ * guest-initiated. Screen Object deprecates the BAR1 guest
+ * framebuffer (GFB) and all commands that work only with the GFB.
+ *
+ * New registers:
+ * FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID
+ *
+ * New 2D commands:
+ * DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN,
+ * BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY
+ *
+ * New 3D commands:
+ * BLIT_SURFACE_TO_SCREEN
+ *
+ * New guarantees:
+ *
+ * - The host will not read or write guest memory, including the GFB,
+ * except when explicitly initiated by a DMA command.
+ *
+ * - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK,
+ * is guaranteed to complete before any subsequent FENCEs.
+ *
+ * - All legacy commands which affect a Screen (UPDATE, PRESENT,
+ * PRESENT_READBACK) as well as new Screen blit commands will
+ * all behave consistently as blits, and memory will be read
+ * or written in FIFO order.
+ *
+ * For example, if you PRESENT from one SVGA3D surface to multiple
+ * places on the screen, the data copied will always be from the
+ * SVGA3D surface at the time the PRESENT was issued in the FIFO.
+ * This was not necessarily true on devices without Screen Object.
+ *
+ * This means that on devices that support Screen Object, the
+ * PRESENT_READBACK command should not be necessary unless you
+ * actually want to read back the results of 3D rendering into
+ * system memory. (And for that, the BLIT_SCREEN_TO_GMRFB
+ * command provides a strict superset of functionality.)
+ *
+ * - When a screen is resized, either using Screen Object commands or
+ * legacy multimon registers, its contents are preserved.
+ *
+ * SVGA_FIFO_CAP_GMR2 --
+ *
+ * Provides new commands to define and remap guest memory regions (GMR).
+ *
+ * New 2D commands:
+ * DEFINE_GMR2, REMAP_GMR2.
+ *
+ * SVGA_FIFO_CAP_3D_HWVERSION_REVISED --
+ *
+ * Indicates new register SVGA_FIFO_3D_HWVERSION_REVISED exists.
+ * This register may replace SVGA_FIFO_3D_HWVERSION on platforms
+ * that enforce graphics resource limits. This allows the platform
+ * to clear SVGA_FIFO_3D_HWVERSION and disable 3D in legacy guest
+ * drivers that do not limit their resources.
+ *
+ * Note this is an alias to SVGA_FIFO_CAP_GMR2 because these indicators
+ * are codependent (and thus we use a single capability bit).
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT_2 --
+ *
+ * Modifies the DEFINE_SCREEN command to include a guest provided
+ * backing store in GMR memory and the bytesPerLine for the backing
+ * store. This capability requires the use of a backing store when
+ * creating screen objects. However if SVGA_FIFO_CAP_SCREEN_OBJECT
+ * is present then backing stores are optional.
+ *
+ * SVGA_FIFO_CAP_DEAD --
+ *
+ * Drivers should not use this cap bit. This cap bit can not be
+ * reused since some hosts already expose it.
+ */
+
+#define SVGA_FIFO_CAP_NONE 0
+#define SVGA_FIFO_CAP_FENCE (1<<0)
+#define SVGA_FIFO_CAP_ACCELFRONT (1<<1)
+#define SVGA_FIFO_CAP_PITCHLOCK (1<<2)
+#define SVGA_FIFO_CAP_VIDEO (1<<3)
+#define SVGA_FIFO_CAP_CURSOR_BYPASS_3 (1<<4)
+#define SVGA_FIFO_CAP_ESCAPE (1<<5)
+#define SVGA_FIFO_CAP_RESERVE (1<<6)
+#define SVGA_FIFO_CAP_SCREEN_OBJECT (1<<7)
+#define SVGA_FIFO_CAP_GMR2 (1<<8)
+#define SVGA_FIFO_CAP_3D_HWVERSION_REVISED SVGA_FIFO_CAP_GMR2
+#define SVGA_FIFO_CAP_SCREEN_OBJECT_2 (1<<9)
+#define SVGA_FIFO_CAP_DEAD (1<<10)
+
+
+/*
+ * FIFO Flags
+ *
+ * Accel Front -- Driver should use front buffer only commands
+ */
+
+#define SVGA_FIFO_FLAG_NONE 0
+#define SVGA_FIFO_FLAG_ACCELFRONT (1<<0)
+#define SVGA_FIFO_FLAG_RESERVED (1<<31) // Internal use only
+
+/*
+ * FIFO reservation sentinel value
+ */
+
+#define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff
+
+
+/*
+ * Video overlay support
+ */
+
+#define SVGA_NUM_OVERLAY_UNITS 32
+
+
+/*
+ * Video capabilities that the guest is currently using
+ */
+
+#define SVGA_VIDEO_FLAG_COLORKEY 0x0001
+
+
+/*
+ * Offsets for the video overlay registers
+ */
+
+enum {
+ SVGA_VIDEO_ENABLED = 0,
+ SVGA_VIDEO_FLAGS,
+ SVGA_VIDEO_DATA_OFFSET,
+ SVGA_VIDEO_FORMAT,
+ SVGA_VIDEO_COLORKEY,
+ SVGA_VIDEO_SIZE, // Deprecated
+ SVGA_VIDEO_WIDTH,
+ SVGA_VIDEO_HEIGHT,
+ SVGA_VIDEO_SRC_X,
+ SVGA_VIDEO_SRC_Y,
+ SVGA_VIDEO_SRC_WIDTH,
+ SVGA_VIDEO_SRC_HEIGHT,
+ SVGA_VIDEO_DST_X, // Signed int32
+ SVGA_VIDEO_DST_Y, // Signed int32
+ SVGA_VIDEO_DST_WIDTH,
+ SVGA_VIDEO_DST_HEIGHT,
+ SVGA_VIDEO_PITCH_1,
+ SVGA_VIDEO_PITCH_2,
+ SVGA_VIDEO_PITCH_3,
+ SVGA_VIDEO_DATA_GMRID, // Optional, defaults to SVGA_GMR_FRAMEBUFFER
+ SVGA_VIDEO_DST_SCREEN_ID, // Optional, defaults to virtual coords (SVGA_ID_INVALID)
+ SVGA_VIDEO_NUM_REGS
+};
+
+
+/*
+ * SVGA Overlay Units
+ *
+ * width and height relate to the entire source video frame.
+ * srcX, srcY, srcWidth and srcHeight represent subset of the source
+ * video frame to be displayed.
+ */
+
+typedef struct SVGAOverlayUnit {
+ uint32 enabled;
+ uint32 flags;
+ uint32 dataOffset;
+ uint32 format;
+ uint32 colorKey;
+ uint32 size;
+ uint32 width;
+ uint32 height;
+ uint32 srcX;
+ uint32 srcY;
+ uint32 srcWidth;
+ uint32 srcHeight;
+ int32 dstX;
+ int32 dstY;
+ uint32 dstWidth;
+ uint32 dstHeight;
+ uint32 pitches[3];
+ uint32 dataGMRId;
+ uint32 dstScreenId;
+} SVGAOverlayUnit;
+
+
+/*
+ * SVGAScreenObject --
+ *
+ * This is a new way to represent a guest's multi-monitor screen or
+ * Unity window. Screen objects are only supported if the
+ * SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set.
+ *
+ * If Screen Objects are supported, they can be used to fully
+ * replace the functionality provided by the framebuffer registers
+ * (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY.
+ *
+ * The screen object is a struct with guaranteed binary
+ * compatibility. New flags can be added, and the struct may grow,
+ * but existing fields must retain their meaning.
+ *
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2 are required fields of
+ * a SVGAGuestPtr that is used to back the screen contents. This
+ * memory must come from the GFB. The guest is not allowed to
+ * access the memory and doing so will have undefined results. The
+ * backing store is required to be page aligned and the size is
+ * padded to the next page boundry. The number of pages is:
+ * (bytesPerLine * size.width * 4 + PAGE_SIZE - 1) / PAGE_SIZE
+ *
+ * The pitch in the backingStore is required to be at least large
+ * enough to hold a 32bbp scanline. It is recommended that the
+ * driver pad bytesPerLine for a potential performance win.
+ *
+ * The cloneCount field is treated as a hint from the guest that
+ * the user wants this display to be cloned, countCount times. A
+ * value of zero means no cloning should happen.
+ */
+
+#define SVGA_SCREEN_MUST_BE_SET (1 << 0) // Must be set or results undefined
+#define SVGA_SCREEN_HAS_ROOT SVGA_SCREEN_MUST_BE_SET // Deprecated
+#define SVGA_SCREEN_IS_PRIMARY (1 << 1) // Guest considers this screen to be 'primary'
+#define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2) // Guest is running a fullscreen app here
+
+/*
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When the screen is
+ * deactivated the base layer is defined to lose all contents and
+ * become black. When a screen is deactivated the backing store is
+ * optional. When set backingPtr and bytesPerLine will be ignored.
+ */
+#define SVGA_SCREEN_DEACTIVATE (1 << 3)
+
+/*
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When this flag is set
+ * the screen contents will be outputted as all black to the user
+ * though the base layer contents is preserved. The screen base layer
+ * can still be read and written to like normal though the no visible
+ * effect will be seen by the user. When the flag is changed the
+ * screen will be blanked or redrawn to the current contents as needed
+ * without any extra commands from the driver. This flag only has an
+ * effect when the screen is not deactivated.
+ */
+#define SVGA_SCREEN_BLANKING (1 << 4)
+
+typedef
+struct SVGAScreenObject {
+ uint32 structSize; // sizeof(SVGAScreenObject)
+ uint32 id;
+ uint32 flags;
+ struct {
+ uint32 width;
+ uint32 height;
+ } size;
+ struct {
+ int32 x;
+ int32 y;
+ } root;
+
+ /*
+ * Added and required by SVGA_FIFO_CAP_SCREEN_OBJECT_2, optional
+ * with SVGA_FIFO_CAP_SCREEN_OBJECT.
+ */
+ SVGAGuestImage backingStore;
+ uint32 cloneCount;
+} SVGAScreenObject;
+
+
+/*
+ * Commands in the command FIFO:
+ *
+ * Command IDs defined below are used for the traditional 2D FIFO
+ * communication (not all commands are available for all versions of the
+ * SVGA FIFO protocol).
+ *
+ * Note the holes in the command ID numbers: These commands have been
+ * deprecated, and the old IDs must not be reused.
+ *
+ * Command IDs from 1000 to 1999 are reserved for use by the SVGA3D
+ * protocol.
+ *
+ * Each command's parameters are described by the comments and
+ * structs below.
+ */
+
+typedef enum {
+ SVGA_CMD_INVALID_CMD = 0,
+ SVGA_CMD_UPDATE = 1,
+ SVGA_CMD_RECT_COPY = 3,
+ SVGA_CMD_DEFINE_CURSOR = 19,
+ SVGA_CMD_DEFINE_ALPHA_CURSOR = 22,
+ SVGA_CMD_UPDATE_VERBOSE = 25,
+ SVGA_CMD_FRONT_ROP_FILL = 29,
+ SVGA_CMD_FENCE = 30,
+ SVGA_CMD_ESCAPE = 33,
+ SVGA_CMD_DEFINE_SCREEN = 34,
+ SVGA_CMD_DESTROY_SCREEN = 35,
+ SVGA_CMD_DEFINE_GMRFB = 36,
+ SVGA_CMD_BLIT_GMRFB_TO_SCREEN = 37,
+ SVGA_CMD_BLIT_SCREEN_TO_GMRFB = 38,
+ SVGA_CMD_ANNOTATION_FILL = 39,
+ SVGA_CMD_ANNOTATION_COPY = 40,
+ SVGA_CMD_DEFINE_GMR2 = 41,
+ SVGA_CMD_REMAP_GMR2 = 42,
+ SVGA_CMD_MAX
+} SVGAFifoCmdId;
+
+#define SVGA_CMD_MAX_DATASIZE (256 * 1024)
+#define SVGA_CMD_MAX_ARGS 64
+
+
+/*
+ * SVGA_CMD_UPDATE --
+ *
+ * This is a DMA transfer which copies from the Guest Framebuffer
+ * (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which
+ * intersect with the provided virtual rectangle.
+ *
+ * This command does not support using arbitrary guest memory as a
+ * data source- it only works with the pre-defined GFB memory.
+ * This command also does not support signed virtual coordinates.
+ * If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with
+ * negative root x/y coordinates, the negative portion of those
+ * screens will not be reachable by this command.
+ *
+ * This command is not necessary when using framebuffer
+ * traces. Traces are automatically enabled if the SVGA FIFO is
+ * disabled, and you may explicitly enable/disable traces using
+ * SVGA_REG_TRACES. With traces enabled, any write to the GFB will
+ * automatically act as if a subsequent SVGA_CMD_UPDATE was issued.
+ *
+ * Traces and SVGA_CMD_UPDATE are the only supported ways to render
+ * pseudocolor screen updates. The newer Screen Object commands
+ * only support true color formats.
+ *
+ * Availability:
+ * Always available.
+ */
+
+typedef
+struct {
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+} SVGAFifoCmdUpdate;
+
+
+/*
+ * SVGA_CMD_RECT_COPY --
+ *
+ * Perform a rectangular DMA transfer from one area of the GFB to
+ * another, and copy the result to any screens which intersect it.
+ *
+ * Availability:
+ * SVGA_CAP_RECT_COPY
+ */
+
+typedef
+struct {
+ uint32 srcX;
+ uint32 srcY;
+ uint32 destX;
+ uint32 destY;
+ uint32 width;
+ uint32 height;
+} SVGAFifoCmdRectCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_CURSOR --
+ *
+ * Provide a new cursor image, as an AND/XOR mask.
+ *
+ * The recommended way to position the cursor overlay is by using
+ * the SVGA_FIFO_CURSOR_* registers, supported by the
+ * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ * SVGA_CAP_CURSOR
+ */
+
+typedef
+struct {
+ uint32 id; // Reserved, must be zero.
+ uint32 hotspotX;
+ uint32 hotspotY;
+ uint32 width;
+ uint32 height;
+ uint32 andMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL
+ uint32 xorMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL
+ /*
+ * Followed by scanline data for AND mask, then XOR mask.
+ * Each scanline is padded to a 32-bit boundary.
+ */
+} SVGAFifoCmdDefineCursor;
+
+
+/*
+ * SVGA_CMD_DEFINE_ALPHA_CURSOR --
+ *
+ * Provide a new cursor image, in 32-bit BGRA format.
+ *
+ * The recommended way to position the cursor overlay is by using
+ * the SVGA_FIFO_CURSOR_* registers, supported by the
+ * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ * SVGA_CAP_ALPHA_CURSOR
+ */
+
+typedef
+struct {
+ uint32 id; // Reserved, must be zero.
+ uint32 hotspotX;
+ uint32 hotspotY;
+ uint32 width;
+ uint32 height;
+ /* Followed by scanline data */
+} SVGAFifoCmdDefineAlphaCursor;
+
+
+/*
+ * SVGA_CMD_UPDATE_VERBOSE --
+ *
+ * Just like SVGA_CMD_UPDATE, but also provide a per-rectangle
+ * 'reason' value, an opaque cookie which is used by internal
+ * debugging tools. Third party drivers should not use this
+ * command.
+ *
+ * Availability:
+ * SVGA_CAP_EXTENDED_FIFO
+ */
+
+typedef
+struct {
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 reason;
+} SVGAFifoCmdUpdateVerbose;
+
+
+/*
+ * SVGA_CMD_FRONT_ROP_FILL --
+ *
+ * This is a hint which tells the SVGA device that the driver has
+ * just filled a rectangular region of the GFB with a solid
+ * color. Instead of reading these pixels from the GFB, the device
+ * can assume that they all equal 'color'. This is primarily used
+ * for remote desktop protocols.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_ACCELFRONT
+ */
+
+#define SVGA_ROP_COPY 0x03
+
+typedef
+struct {
+ uint32 color; // In the same format as the GFB
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 rop; // Must be SVGA_ROP_COPY
+} SVGAFifoCmdFrontRopFill;
+
+
+/*
+ * SVGA_CMD_FENCE --
+ *
+ * Insert a synchronization fence. When the SVGA device reaches
+ * this command, it will copy the 'fence' value into the
+ * SVGA_FIFO_FENCE register. It will also compare the fence against
+ * SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the
+ * SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will
+ * raise this interrupt.
+ *
+ * Availability:
+ * SVGA_FIFO_FENCE for this command,
+ * SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL.
+ */
+
+typedef
+struct {
+ uint32 fence;
+} SVGAFifoCmdFence;
+
+
+/*
+ * SVGA_CMD_ESCAPE --
+ *
+ * Send an extended or vendor-specific variable length command.
+ * This is used for video overlay, third party plugins, and
+ * internal debugging tools. See svga_escape.h
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_ESCAPE
+ */
+
+typedef
+struct {
+ uint32 nsid;
+ uint32 size;
+ /* followed by 'size' bytes of data */
+} SVGAFifoCmdEscape;
+
+
+/*
+ * SVGA_CMD_DEFINE_SCREEN --
+ *
+ * Define or redefine an SVGAScreenObject. See the description of
+ * SVGAScreenObject above. The video driver is responsible for
+ * generating new screen IDs. They should be small positive
+ * integers. The virtual device will have an implementation
+ * specific upper limit on the number of screen IDs
+ * supported. Drivers are responsible for recycling IDs. The first
+ * valid ID is zero.
+ *
+ * - Interaction with other registers:
+ *
+ * For backwards compatibility, when the GFB mode registers (WIDTH,
+ * HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device
+ * deletes all screens other than screen #0, and redefines screen
+ * #0 according to the specified mode. Drivers that use
+ * SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0.
+ *
+ * If you use screen objects, do not use the legacy multi-mon
+ * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*).
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAScreenObject screen; // Variable-length according to version
+} SVGAFifoCmdDefineScreen;
+
+
+/*
+ * SVGA_CMD_DESTROY_SCREEN --
+ *
+ * Destroy an SVGAScreenObject. Its ID is immediately available for
+ * re-use.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ uint32 screenId;
+} SVGAFifoCmdDestroyScreen;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMRFB --
+ *
+ * This command sets a piece of SVGA device state called the
+ * Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a
+ * piece of light-weight state which identifies the location and
+ * format of an image in guest memory or in BAR1. The GMRFB has
+ * an arbitrary size, and it doesn't need to match the geometry
+ * of the GFB or any screen object.
+ *
+ * The GMRFB can be redefined as often as you like. You could
+ * always use the same GMRFB, you could redefine it before
+ * rendering from a different guest screen, or you could even
+ * redefine it before every blit.
+ *
+ * There are multiple ways to use this command. The simplest way is
+ * to use it to move the framebuffer either to elsewhere in the GFB
+ * (BAR1) memory region, or to a user-defined GMR. This lets a
+ * driver use a framebuffer allocated entirely out of normal system
+ * memory, which we encourage.
+ *
+ * Another way to use this command is to set up a ring buffer of
+ * updates in GFB memory. If a driver wants to ensure that no
+ * frames are skipped by the SVGA device, it is important that the
+ * driver not modify the source data for a blit until the device is
+ * done processing the command. One efficient way to accomplish
+ * this is to use a ring of small DMA buffers. Each buffer is used
+ * for one blit, then we move on to the next buffer in the
+ * ring. The FENCE mechanism is used to protect each buffer from
+ * re-use until the device is finished with that buffer's
+ * corresponding blit.
+ *
+ * This command does not affect the meaning of SVGA_CMD_UPDATE.
+ * UPDATEs always occur from the legacy GFB memory area. This
+ * command has no support for pseudocolor GMRFBs. Currently only
+ * true-color 15, 16, and 24-bit depths are supported. Future
+ * devices may expose capabilities for additional framebuffer
+ * formats.
+ *
+ * The default GMRFB value is undefined. Drivers must always send
+ * this command at least once before performing any blit from the
+ * GMRFB.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAGuestPtr ptr;
+ uint32 bytesPerLine;
+ SVGAGMRImageFormat format;
+} SVGAFifoCmdDefineGMRFB;
+
+
+/*
+ * SVGA_CMD_BLIT_GMRFB_TO_SCREEN --
+ *
+ * This is a guest-to-host blit. It performs a DMA operation to
+ * copy a rectangular region of pixels from the current GMRFB to
+ * one or more Screen Objects.
+ *
+ * The destination coordinate may be specified relative to a
+ * screen's origin (if a screen ID is specified) or relative to the
+ * virtual coordinate system's origin (if the screen ID is
+ * SVGA_ID_INVALID). The actual destination may span zero or more
+ * screens, in the case of a virtual destination rect or a rect
+ * which extends off the edge of the specified screen.
+ *
+ * This command writes to the screen's "base layer": the underlying
+ * framebuffer which exists below any cursor or video overlays. No
+ * action is necessary to explicitly hide or update any overlays
+ * which exist on top of the updated region.
+ *
+ * The SVGA device is guaranteed to finish reading from the GMRFB
+ * by the time any subsequent FENCE commands are reached.
+ *
+ * This command consumes an annotation. See the
+ * SVGA_CMD_ANNOTATION_* commands for details.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint srcOrigin;
+ SVGASignedRect destRect;
+ uint32 destScreenId;
+} SVGAFifoCmdBlitGMRFBToScreen;
+
+
+/*
+ * SVGA_CMD_BLIT_SCREEN_TO_GMRFB --
+ *
+ * This is a host-to-guest blit. It performs a DMA operation to
+ * copy a rectangular region of pixels from a single Screen Object
+ * back to the current GMRFB.
+ *
+ * Usage note: This command should be used rarely. It will
+ * typically be inefficient, but it is necessary for some types of
+ * synchronization between 3D (GPU) and 2D (CPU) rendering into
+ * overlapping areas of a screen.
+ *
+ * The source coordinate is specified relative to a screen's
+ * origin. The provided screen ID must be valid. If any parameters
+ * are invalid, the resulting pixel values are undefined.
+ *
+ * This command reads the screen's "base layer". Overlays like
+ * video and cursor are not included, but any data which was sent
+ * using a blit-to-screen primitive will be available, no matter
+ * whether the data's original source was the GMRFB or the 3D
+ * acceleration hardware.
+ *
+ * Note that our guest-to-host blits and host-to-guest blits aren't
+ * symmetric in their current implementation. While the parameters
+ * are identical, host-to-guest blits are a lot less featureful.
+ * They do not support clipping: If the source parameters don't
+ * fully fit within a screen, the blit fails. They must originate
+ * from exactly one screen. Virtual coordinates are not directly
+ * supported.
+ *
+ * Host-to-guest blits do support the same set of GMRFB formats
+ * offered by guest-to-host blits.
+ *
+ * The SVGA device is guaranteed to finish writing to the GMRFB by
+ * the time any subsequent FENCE commands are reached.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint destOrigin;
+ SVGASignedRect srcRect;
+ uint32 srcScreenId;
+} SVGAFifoCmdBlitScreenToGMRFB;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_FILL --
+ *
+ * This is a blit annotation. This command stores a small piece of
+ * device state which is consumed by the next blit-to-screen
+ * command. The state is only cleared by commands which are
+ * specifically documented as consuming an annotation. Other
+ * commands (such as ESCAPEs for debugging) may intervene between
+ * the annotation and its associated blit.
+ *
+ * This annotation is a promise about the contents of the next
+ * blit: The video driver is guaranteeing that all pixels in that
+ * blit will have the same value, specified here as a color in
+ * SVGAColorBGRX format.
+ *
+ * The SVGA device can still render the blit correctly even if it
+ * ignores this annotation, but the annotation may allow it to
+ * perform the blit more efficiently, for example by ignoring the
+ * source data and performing a fill in hardware.
+ *
+ * This annotation is most important for performance when the
+ * user's display is being remoted over a network connection.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAColorBGRX color;
+} SVGAFifoCmdAnnotationFill;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_COPY --
+ *
+ * This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more
+ * information about annotations.
+ *
+ * This annotation is a promise about the contents of the next
+ * blit: The video driver is guaranteeing that all pixels in that
+ * blit will have the same value as those which already exist at an
+ * identically-sized region on the same or a different screen.
+ *
+ * Note that the source pixels for the COPY in this annotation are
+ * sampled before applying the anqnotation's associated blit. They
+ * are allowed to overlap with the blit's destination pixels.
+ *
+ * The copy source rectangle is specified the same way as the blit
+ * destination: it can be a rectangle which spans zero or more
+ * screens, specified relative to either a screen or to the virtual
+ * coordinate system's origin. If the source rectangle includes
+ * pixels which are not from exactly one screen, the results are
+ * undefined.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint srcOrigin;
+ uint32 srcScreenId;
+} SVGAFifoCmdAnnotationCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMR2 --
+ *
+ * Define guest memory region v2. See the description of GMRs above.
+ *
+ * Availability:
+ * SVGA_CAP_GMR2
+ */
+
+typedef
+struct {
+ uint32 gmrId;
+ uint32 numPages;
+}
+SVGAFifoCmdDefineGMR2;
+
+
+/*
+ * SVGA_CMD_REMAP_GMR2 --
+ *
+ * Remap guest memory region v2. See the description of GMRs above.
+ *
+ * This command allows guest to modify a portion of an existing GMR by
+ * invalidating it or reassigning it to different guest physical pages.
+ * The pages are identified by physical page number (PPN). The pages
+ * are assumed to be pinned and valid for DMA operations.
+ *
+ * Description of command flags:
+ *
+ * SVGA_REMAP_GMR2_VIA_GMR: If enabled, references a PPN list in a GMR.
+ * The PPN list must not overlap with the remap region (this can be
+ * handled trivially by referencing a separate GMR). If flag is
+ * disabled, PPN list is appended to SVGARemapGMR command.
+ *
+ * SVGA_REMAP_GMR2_PPN64: If set, PPN list is in PPN64 format, otherwise
+ * it is in PPN32 format.
+ *
+ * SVGA_REMAP_GMR2_SINGLE_PPN: If set, PPN list contains a single entry.
+ * A single PPN can be used to invalidate a portion of a GMR or
+ * map it to to a single guest scratch page.
+ *
+ * Availability:
+ * SVGA_CAP_GMR2
+ */
+
+typedef enum {
+ SVGA_REMAP_GMR2_PPN32 = 0,
+ SVGA_REMAP_GMR2_VIA_GMR = (1 << 0),
+ SVGA_REMAP_GMR2_PPN64 = (1 << 1),
+ SVGA_REMAP_GMR2_SINGLE_PPN = (1 << 2),
+} SVGARemapGMR2Flags;
+
+typedef
+struct {
+ uint32 gmrId;
+ SVGARemapGMR2Flags flags;
+ uint32 offsetPages; // offset in pages to begin remap
+ uint32 numPages; // number of pages to remap
+ /*
+ * Followed by additional data depending on SVGARemapGMR2Flags.
+ *
+ * If flag SVGA_REMAP_GMR2_VIA_GMR is set, single SVGAGuestPtr follows.
+ * Otherwise an array of page descriptors in PPN32 or PPN64 format
+ * (according to flag SVGA_REMAP_GMR2_PPN64) follows. If flag
+ * SVGA_REMAP_GMR2_SINGLE_PPN is set, array contains a single entry.
+ */
+}
+SVGAFifoCmdRemapGMR2;
+
+#endif