vmware-svga/lib/refdriver/svga3d.c
Micah Dowty 68478eab4b There are many new tests and examples that we wrote internally at VMware,
but couldn't release immediately since they depended on virtual GPU features
which were not yet publicly released in any products.  This checkin moves those
features from our internal repository to the open source repository. Future   
development on these tests and examples will take place directly in the open
source repository.

The primary feature added by this patch is 'Screen Object', a new dynamic
display management extension supported by Workstation 7.0 and Fusion 3.0.
See the README for a quick explanation.
2009-10-21 20:20:49 +00:00

1207 lines
35 KiB
C

/**********************************************************
* 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 "svga.h"
#include "svga3d.h"
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
void
SVGA3D_Init(void)
{
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.");
}
/*
* Check the host's version, make sure we're binary compatible.
*/
if (gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION] == 0) {
SVGA_Panic("3D disabled by host.");
}
if (gSVGA.fifoMem[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS65_B1) {
SVGA_Panic("Host SVGA3D protocol is too old, not binary compatible.");
}
}
/*
*----------------------------------------------------------------------
*
* 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 *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) {
SVGA_Panic("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:
SVGA_Panic("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();
}