diff --git a/examples/rt-gamma-test/main.c b/examples/rt-gamma-test/main.c index 046d0ac..425c67e 100644 --- a/examples/rt-gamma-test/main.c +++ b/examples/rt-gamma-test/main.c @@ -110,8 +110,6 @@ render(void) } SVGA_FIFOCommitAll(); - gamma += 0.1f; - SVGA3D_BeginDrawPrimitives(CID, &decls, 2, &ranges, 1); { decls[0].identity.type = SVGA3D_DECLTYPE_FLOAT3; diff --git a/examples/screen-annotation/main.c b/examples/screen-annotation/main.c index 0f74cc1..ed5f316 100644 --- a/examples/screen-annotation/main.c +++ b/examples/screen-annotation/main.c @@ -259,7 +259,7 @@ main(void) .size = { 800, 600 }, .root = { 0, 0 }, }; - Screen_Define(&myScreen); + Screen_Create(&myScreen); /* * Draw some explanatory text. diff --git a/examples/screen-cursor/main.c b/examples/screen-cursor/main.c index c82b827..fca7949 100644 --- a/examples/screen-cursor/main.c +++ b/examples/screen-cursor/main.c @@ -757,7 +757,7 @@ main(void) Screen_Init(); ScreenDraw_Init(GMRID_SCREEN_DRAW); allocNoise(); - Screen_Define(&myScreen); + Screen_Create(&myScreen); /* * Draw the menu of test modes. diff --git a/examples/screen-dma-coalesce/main.c b/examples/screen-dma-coalesce/main.c index 6792357..e427ca9 100644 --- a/examples/screen-dma-coalesce/main.c +++ b/examples/screen-dma-coalesce/main.c @@ -141,7 +141,7 @@ main(void) .size = { 800, 600 }, .root = { 0, 0 }, }; - Screen_Define(&myScreen); + Screen_Create(&myScreen); /* * Draw some intro text. diff --git a/examples/screen-gmr-discontig/main.c b/examples/screen-gmr-discontig/main.c index 39ceef7..894e527 100644 --- a/examples/screen-gmr-discontig/main.c +++ b/examples/screen-gmr-discontig/main.c @@ -34,7 +34,7 @@ main(void) .size = { 1600, 1200 }, .root = { -1234, 5678 }, }; - Screen_Define(&myScreen); + Screen_Create(&myScreen); const uint32 gmrId = 0; uint32 numPages = 1 + (myScreen.size.width * myScreen.size.height * diff --git a/examples/screen-gmr-remap/main.c b/examples/screen-gmr-remap/main.c index 2940157..faef7c0 100644 --- a/examples/screen-gmr-remap/main.c +++ b/examples/screen-gmr-remap/main.c @@ -79,7 +79,7 @@ main(void) .size = { 800, 600 }, .root = { -1234, 5678 }, }; - Screen_Define(&myScreen); + Screen_Create(&myScreen); const uint32 numPages = 4096; const uint32 tileSize = 32; diff --git a/examples/screen-multimon/main.c b/examples/screen-multimon/main.c index aa60d39..6d7bf10 100644 --- a/examples/screen-multimon/main.c +++ b/examples/screen-multimon/main.c @@ -198,6 +198,7 @@ toggleScreenExistence(void) if (screen->id == SVGA_ID_INVALID) { screen->id = currentScreen; + // FIXME: Need to call Screen_Create Screen_Define(screen); paintScreen(screen); } else { diff --git a/examples/screen-present-clip/main.c b/examples/screen-present-clip/main.c index 730354c..e1eb7b3 100644 --- a/examples/screen-present-clip/main.c +++ b/examples/screen-present-clip/main.c @@ -70,7 +70,7 @@ const uint32 numLines = arraysize(indexData) / 2; static void initScreens(void) { - static const SVGAScreenObject screen = { + static SVGAScreenObject screen = { .structSize = sizeof(SVGAScreenObject), .id = 0, .flags = SVGA_SCREEN_HAS_ROOT | SVGA_SCREEN_IS_PRIMARY, @@ -78,7 +78,7 @@ initScreens(void) .root = { 1000, 2000 }, }; - Screen_Define(&screen); + Screen_Create(&screen); ScreenDraw_SetScreen(screen.id, screen.size.width, screen.size.height); Console_Clear(); diff --git a/examples/screen-render-test/main.c b/examples/screen-render-test/main.c index e15ab68..83a2731 100644 --- a/examples/screen-render-test/main.c +++ b/examples/screen-render-test/main.c @@ -113,9 +113,9 @@ initScreens(void) }; for (i = 0; i < arraysize(screens); i++) { - const SVGAScreenObject *screen = &screens[i]; + SVGAScreenObject *screen = &screens[i]; - Screen_Define(screen); + Screen_Create(screen); ScreenDraw_SetScreen(screen->id, screen->size.width, screen->size.height); Console_Clear(); diff --git a/examples/screen-simple/main.c b/examples/screen-simple/main.c index 82157d0..921826c 100644 --- a/examples/screen-simple/main.c +++ b/examples/screen-simple/main.c @@ -73,7 +73,7 @@ main(void) .size = { 640, 480 }, .root = { -500, 10000 }, }; - Screen_Define(&myScreen); + Screen_Create(&myScreen); /* * Create a system memory framebuffer. diff --git a/examples/screen-text/main.c b/examples/screen-text/main.c index 316f454..02c03ab 100644 --- a/examples/screen-text/main.c +++ b/examples/screen-text/main.c @@ -36,7 +36,7 @@ main(void) .size = { 800, 600 }, .root = { 0, 0 }, }; - Screen_Define(&myScreen); + Screen_Create(&myScreen); /* * Draw some text. diff --git a/lib/Makefile.rules b/lib/Makefile.rules index 5ee78a2..99c26a6 100644 --- a/lib/Makefile.rules +++ b/lib/Makefile.rules @@ -128,7 +128,7 @@ listing: $(ELF_TARGET) $(VMX_TARGET): @echo config.version = 8 > $(VMX_TARGET) - @echo virtualHW.version = 7 >> $(VMX_TARGET) + @echo virtualHW.version = 8 >> $(VMX_TARGET) @echo memsize = $(VMX_MEMSIZE) >> $(VMX_TARGET) @echo displayname = $(PLAIN_TARGET) >> $(VMX_TARGET) @echo guestOS = other >> $(VMX_TARGET) diff --git a/lib/refdriver/gmr.c b/lib/refdriver/gmr.c index acdb714..8298686 100644 --- a/lib/refdriver/gmr.c +++ b/lib/refdriver/gmr.c @@ -361,7 +361,7 @@ GMR_FreeAll(void) * * GMR_Init -- * - * Read GMR capabilities, or panic of GMRs aren't supported. + * Read GMR capabilities, or panic if GMRs aren't supported. * * Results: * None. @@ -382,3 +382,31 @@ GMR_Init(void) SVGA_Panic("Virtual device does not have Guest Memory Region (GMR) support."); } } + + +/* + *----------------------------------------------------------------------------- + * + * GMR2_Init -- + * + * Read GMR2 capabilities, or panic if GMR2 isn't supported. + * + * Results: + * None. + * + * Side effects: + * Fills in 'gGMR'. + * + *----------------------------------------------------------------------------- + */ + +void +GMR2_Init(void) +{ + if (gSVGA.capabilities & SVGA_CAP_GMR2) { + gGMR.maxIds = SVGA_ReadReg(SVGA_REG_GMR_MAX_IDS); + gGMR.maxPages = SVGA_ReadReg(SVGA_REG_GMRS_MAX_PAGES); + } else { + SVGA_Panic("Virtual device does not have Guest Memory Region version 2 (GMR2) support."); + } +} diff --git a/lib/refdriver/gmr.h b/lib/refdriver/gmr.h index 34b4433..42175aa 100644 --- a/lib/refdriver/gmr.h +++ b/lib/refdriver/gmr.h @@ -32,6 +32,7 @@ #ifndef __GMR_H__ #define __GMR_H__ +#include "svga_reg.h" /* * Macros for physical memory pages, in our flat memory model. @@ -40,6 +41,7 @@ */ #define PAGE_SIZE 4096 +#define PAGE_SHIFT 12 #define PAGE_MASK (PAGE_SIZE - 1) #define PPN_POINTER(ppn) ((void*)((ppn)*PAGE_SIZE)) typedef uint32 PPN; @@ -52,6 +54,7 @@ typedef uint32 PPN; typedef struct GMRState { uint32 maxIds; uint32 maxDescriptorLen; + uint32 maxPages; } GMRState; extern GMRState gGMR; @@ -77,6 +80,7 @@ void Heap_DiscardPages(PPN firstPage, uint32 numPages); */ void GMR_Init(void); +void GMR2_Init(void); /* diff --git a/lib/refdriver/screen.c b/lib/refdriver/screen.c index eea329f..9320b10 100644 --- a/lib/refdriver/screen.c +++ b/lib/refdriver/screen.c @@ -54,12 +54,48 @@ void Screen_Init(void) { - if (!SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT)) { + if (!(SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT) || + SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT_2))) { SVGA_Panic("Virtual device does not have Screen Object support."); } } +/* + *----------------------------------------------------------------------------- + * + * Screen_Create -- + * + * Create an SVGA Screen Object. + * + * Also create the backing store when supported/required. + * + * Results: + * None. + * + * Side effects: + * It may create a backing store. + * + *----------------------------------------------------------------------------- + */ + +void +Screen_Create(SVGAScreenObject *screen) // IN/OUT +{ + if (SVGA_HasFIFOCap(SVGA_FIFO_CAP_SCREEN_OBJECT_2)) { + const uint32 pitch = screen->size.width * sizeof(uint32); + const uint32 size = screen->size.height*pitch; + screen->structSize = sizeof(SVGAScreenObject); + SVGA_AllocGMR(size, &screen->backingStore.ptr); + screen->backingStore.ptr.offset = 0; + screen->backingStore.pitch = pitch; + } else { + screen->structSize = offsetof(SVGAScreenObject, backingStore); + } + Screen_Define(screen); +} + + /* *----------------------------------------------------------------------------- * diff --git a/lib/refdriver/screen.h b/lib/refdriver/screen.h index a687529..32945f3 100644 --- a/lib/refdriver/screen.h +++ b/lib/refdriver/screen.h @@ -45,6 +45,7 @@ void Screen_Init(void); * Creating/destroying screens */ +void Screen_Create(SVGAScreenObject *screen); void Screen_Define(const SVGAScreenObject *screen); void Screen_Destroy(uint32 id); diff --git a/lib/refdriver/svga.c b/lib/refdriver/svga.c index c7c0136..a876b20 100644 --- a/lib/refdriver/svga.c +++ b/lib/refdriver/svga.c @@ -1477,6 +1477,38 @@ SVGAInterruptHandler(int vector) // IN (unused) #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 * +SVGA_AllocGMR(uint32 size, // IN + SVGAGuestPtr *ptr) // OUT +{ + static SVGAGuestPtr nextPtr = { SVGA_GMR_FRAMEBUFFER, 0 }; + *ptr = nextPtr; + nextPtr.offset += size; + return gSVGA.fbMem + ptr->offset; +} + + /* *----------------------------------------------------------------------------- * diff --git a/lib/refdriver/svga.h b/lib/refdriver/svga.h index 1936a25..0442223 100644 --- a/lib/refdriver/svga.h +++ b/lib/refdriver/svga.h @@ -108,6 +108,8 @@ void SVGA_SyncToFence(uint32 fence); Bool SVGA_HasFencePassed(uint32 fence); void SVGA_RingDoorbell(void); +void * SVGA_AllocGMR(uint32 size, SVGAGuestPtr *ptr); + /* 2D commands */ void SVGA_Update(uint32 x, uint32 y, uint32 width, uint32 height); diff --git a/lib/refdriver/svga3d.c b/lib/refdriver/svga3d.c index 126142d..f985c71 100644 --- a/lib/refdriver/svga3d.c +++ b/lib/refdriver/svga3d.c @@ -70,22 +70,29 @@ void SVGA3D_Init(void) { + SVGA3dHardwareVersion hwVersion; + if (!(gSVGA.capabilities & SVGA_CAP_EXTENDED_FIFO)) { SVGA_Panic("3D requires the Extended FIFO capability."); } - if (gSVGA.fifoMem[SVGA_FIFO_MIN] <= sizeof(uint32) * SVGA_FIFO_GUEST_3D_HWVERSION) { - SVGA_Panic("GUEST_3D_HWVERSION register not present."); + 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) { + SVGA_Panic("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 (gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION] == 0) { + if (hwVersion == 0) { SVGA_Panic("3D disabled by host."); } - if (gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS65_B1) { + if (hwVersion < SVGA3D_HWVERSION_WS65_B1) { SVGA_Panic("Host SVGA3D protocol is too old, not binary compatible."); } } diff --git a/lib/util/svga3dutil.c b/lib/util/svga3dutil.c index bc4176b..8b79494 100644 --- a/lib/util/svga3dutil.c +++ b/lib/util/svga3dutil.c @@ -371,9 +371,6 @@ SVGA3DUtil_AllocSurfaceID(void) * (for us to use) and an SVGAGuestPtr (for the SVGA3D 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. * @@ -387,10 +384,7 @@ void * SVGA3DUtil_AllocDMABuffer(uint32 size, // IN SVGAGuestPtr *ptr) // OUT { - static SVGAGuestPtr nextPtr = { SVGA_GMR_FRAMEBUFFER, 0 }; - *ptr = nextPtr; - nextPtr.offset += size; - return gSVGA.fbMem + ptr->offset; + return SVGA_AllocGMR(size, ptr); } diff --git a/lib/vmware/svga3d_reg.h b/lib/vmware/svga3d_reg.h index 77cb453..67f7218 100644 --- a/lib/vmware/svga3d_reg.h +++ b/lib/vmware/svga3d_reg.h @@ -57,7 +57,8 @@ typedef enum { 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_CURRENT = SVGA3D_HWVERSION_WS65_B1, + SVGA3D_HWVERSION_WS8_B1 = SVGA3D_MAKE_HWVERSION(2, 1), + SVGA3D_HWVERSION_CURRENT = SVGA3D_HWVERSION_WS8_B1, } SVGA3dHardwareVersion; /* @@ -67,7 +68,8 @@ typedef enum { 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. @@ -79,76 +81,91 @@ typedef uint32 SVGA3dBool; /* 32-bit Bool definition */ */ typedef enum SVGA3dSurfaceFormat { - SVGA3D_FORMAT_INVALID = 0, + SVGA3D_FORMAT_INVALID = 0, - SVGA3D_X8R8G8B8 = 1, - SVGA3D_A8R8G8B8 = 2, + SVGA3D_X8R8G8B8 = 1, + SVGA3D_A8R8G8B8 = 2, - SVGA3D_R5G6B5 = 3, - SVGA3D_X1R5G5B5 = 4, - SVGA3D_A1R5G5B5 = 5, - SVGA3D_A4R4G4B4 = 6, + 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_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_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_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_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_ARGB_S10E5 = 24, /* 16-bit floating-point ARGB */ + SVGA3D_ARGB_S23E8 = 25, /* 32-bit floating-point ARGB */ - SVGA3D_A2R10G10B10 = 26, + SVGA3D_A2R10G10B10 = 26, /* signed formats */ - SVGA3D_V8U8 = 27, - SVGA3D_Q8W8V8U8 = 28, - SVGA3D_CxV8U8 = 29, + SVGA3D_V8U8 = 27, + SVGA3D_Q8W8V8U8 = 28, + SVGA3D_CxV8U8 = 29, /* mixed formats */ - SVGA3D_X8L8V8U8 = 30, - SVGA3D_A2W10V10U10 = 31, + SVGA3D_X8L8V8U8 = 30, + SVGA3D_A2W10V10U10 = 31, - SVGA3D_ALPHA8 = 32, + 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, + 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_BUFFER = 37, - SVGA3D_V16U16 = 39, + SVGA3D_Z_D24X8 = 38, - SVGA3D_G16R16 = 40, - SVGA3D_A16B16G16R16 = 41, + SVGA3D_V16U16 = 39, + + SVGA3D_G16R16 = 40, + SVGA3D_A16B16G16R16 = 41, /* Packed Video formats */ - SVGA3D_UYVY = 42, - SVGA3D_YUY2 = 43, + 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; @@ -414,9 +431,19 @@ typedef enum { 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 */ @@ -930,7 +957,6 @@ typedef enum { } SVGA3dCubeFace; typedef enum { - SVGA3D_SHADERTYPE_COMPILED_DX8 = 0, SVGA3D_SHADERTYPE_VS = 1, SVGA3D_SHADERTYPE_PS = 2, SVGA3D_SHADERTYPE_MAX @@ -968,11 +994,17 @@ typedef enum { } SVGA3dTransferType; /* - * The maximum number vertex arrays we're guaranteed to support in + * 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. * @@ -990,7 +1022,7 @@ typedef enum { #define SVGA_3D_CMD_LEGACY_BASE 1000 #define SVGA_3D_CMD_BASE 1040 -#define SVGA_3D_CMD_SURFACE_DEFINE SVGA_3D_CMD_BASE + 0 +#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 @@ -1020,7 +1052,11 @@ typedef enum { #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_MAX SVGA_3D_CMD_BASE + 30 +#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 #define SVGA_3D_CMD_FUTURE_MAX 2000 @@ -1109,6 +1145,8 @@ typedef enum { 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 @@ -1121,6 +1159,12 @@ 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. @@ -1133,6 +1177,31 @@ struct { */ } 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; @@ -1474,10 +1543,12 @@ struct { * SVGA3dCmdDrawPrimitives structure. In order, * they are: * - * 1. SVGA3dVertexDecl, quantity 'numVertexDecls' - * 2. SVGA3dPrimitiveRange, quantity 'numRanges' + * 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 this the corresponding vertex decl) + * the frequency divisor for the corresponding vertex decl). */ } SVGA3dCmdDrawPrimitives; /* SVGA_3D_CMD_DRAWPRIMITIVES */ @@ -1671,6 +1742,12 @@ struct { /* 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. @@ -1774,6 +1851,32 @@ typedef enum { 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 diff --git a/lib/vmware/svga_reg.h b/lib/vmware/svga_reg.h index 1b96c2e..8b0cbe0 100644 --- a/lib/vmware/svga_reg.h +++ b/lib/vmware/svga_reg.h @@ -38,6 +38,15 @@ #define PCI_VENDOR_ID_VMWARE 0x15AD #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 +/* + * 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 @@ -158,7 +167,9 @@ enum { SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44, SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ - SVGA_REG_TOP = 46, /* Must be 1 more than the last register */ + 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_REG_TOP = 48, /* 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 */ @@ -313,6 +324,28 @@ struct SVGAGMRImageFormat { }; } 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 -- * @@ -370,6 +403,15 @@ struct SVGASignedPoint { * 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 0x00000000 @@ -387,6 +429,8 @@ struct SVGASignedPoint { #define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000 // Legacy multi-monitor support #define SVGA_CAP_GMR 0x00100000 #define SVGA_CAP_TRACES 0x00200000 +#define SVGA_CAP_GMR2 0x00400000 +#define SVGA_CAP_SCREEN_OBJECT_2 0x00800000 /* @@ -460,16 +504,30 @@ enum { SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */ /* - * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT: + * 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. This is the - * only way to place the cursor on a non-rooted screen. + * 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 @@ -709,6 +767,37 @@ enum { * * - 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 @@ -720,6 +809,10 @@ enum { #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) /* @@ -829,11 +922,47 @@ typedef struct SVGAOverlayUnit { * 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_HAS_ROOT (1 << 0) // Screen is present in the virtual coord space -#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 +#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 { @@ -847,7 +976,14 @@ struct SVGAScreenObject { struct { int32 x; int32 y; - } root; // Only used if SVGA_SCREEN_HAS_ROOT is set. + } root; + + /* + * Added and required by SVGA_FIFO_CAP_SCREEN_OBJECT_2, optional + * with SVGA_FIFO_CAP_SCREEN_OBJECT. + */ + SVGAGuestImage backingStore; + uint32 cloneCount; } SVGAScreenObject; @@ -885,9 +1021,12 @@ typedef enum { 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 @@ -1113,7 +1252,7 @@ struct { * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*). * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1129,7 +1268,7 @@ struct { * re-use. * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1182,7 +1321,7 @@ struct { * GMRFB. * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1219,7 +1358,7 @@ struct { * SVGA_CMD_ANNOTATION_* commands for details. * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1267,7 +1406,7 @@ struct { * the time any subsequent FENCE commands are reached. * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1302,7 +1441,7 @@ struct { * user's display is being remoted over a network connection. * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1334,7 +1473,7 @@ struct { * undefined. * * Availability: - * SVGA_FIFO_CAP_SCREEN_OBJECT + * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 */ typedef @@ -1343,4 +1482,74 @@ struct { 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