diff options
Diffstat (limited to 'src/gallium/drivers/svga/svga_cmd.c')
-rw-r--r-- | src/gallium/drivers/svga/svga_cmd.c | 1427 |
1 files changed, 1427 insertions, 0 deletions
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c new file mode 100644 index 00000000000..a0da7d7e5d5 --- /dev/null +++ b/src/gallium/drivers/svga/svga_cmd.c @@ -0,0 +1,1427 @@ +/********************************************************** + * 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_cmd.c -- + * + * Command construction utility for the SVGA3D protocol used by + * the VMware SVGA device, based on the svgautil library. + */ + +#include "svga_winsys.h" +#include "svga_screen_buffer.h" +#include "svga_screen_texture.h" +#include "svga_cmd.h" + +/* + *---------------------------------------------------------------------- + * + * surface_to_surfaceid -- + * + * Utility function for surface ids. + * Can handle null surface. Does a surface_reallocation so you need + * to have allocated the fifo space before converting. + * + * Results: + * id is filld out. + * + * Side effects: + * One surface relocation is preformed for texture handle. + * + *---------------------------------------------------------------------- + */ + +static INLINE +void surface_to_surfaceid(struct svga_winsys_context *swc, // IN + struct pipe_surface *surface, // IN + SVGA3dSurfaceImageId *id, // OUT + unsigned flags) // IN +{ + if(surface) { + struct svga_surface *s = svga_surface(surface); + swc->surface_relocation(swc, &id->sid, s->handle, flags); + id->face = s->real_face; /* faces have the same order */ + id->mipmap = s->real_level; + } + else { + id->sid = SVGA3D_INVALID_ID; + id->face = 0; + id->mipmap = 0; + } +} + + +/* + *---------------------------------------------------------------------- + * + * 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(struct svga_winsys_context *swc, + uint32 cmd, // IN + uint32 cmdSize, // IN + uint32 nr_relocs) // IN +{ + SVGA3dCmdHeader *header; + + header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs); + if(!header) + return NULL; + + header->id = cmd; + header->size = cmdSize; + + return &header[1]; +} + + +void +SVGA_FIFOCommitAll(struct svga_winsys_context *swc) +{ + swc->commit(swc); +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_DefineContext(struct svga_winsys_context *swc) // IN +{ + SVGA3dCmdDefineContext *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_DestroyContext -- + * + * Delete a context created with SVGA3D_DefineContext. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_DestroyContext(struct svga_winsys_context *swc) // IN +{ + SVGA3dCmdDestroyContext *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc, + struct svga_winsys_surface *sid, // IN + SVGA3dSurfaceFlags flags, // IN + SVGA3dSurfaceFormat format, // IN + SVGA3dSurfaceFace **faces, // OUT + SVGA3dSize **mipSizes, // OUT + uint32 numMipSizes) // IN +{ + SVGA3dCmdDefineSurface *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd + + sizeof **mipSizes * numMipSizes, 1); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_WRITE); + 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); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_DefineSurface2D -- + * + * This is a simplified version of SVGA3D_BeginDefineSurface(), + * which does not support cube maps, mipmaps, or volume textures. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_DefineSurface2D(struct svga_winsys_context *swc, // IN + struct svga_winsys_surface *sid, // IN + uint32 width, // IN + uint32 height, // IN + SVGA3dSurfaceFormat format) // IN +{ + SVGA3dSize *mipSizes; + SVGA3dSurfaceFace *faces; + enum pipe_error ret; + + ret = SVGA3D_BeginDefineSurface(swc, + sid, 0, format, &faces, &mipSizes, 1); + if(ret != PIPE_OK) + return ret; + + faces[0].numMipLevels = 1; + + mipSizes[0].width = width; + mipSizes[0].height = height; + mipSizes[0].depth = 1; + + swc->commit(swc);; + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_DestroySurface -- + * + * Release the host VRAM encapsulated by a particular surface ID. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_DestroySurface(struct svga_winsys_context *swc, + struct svga_winsys_surface *sid) // IN +{ + SVGA3dCmdDestroySurface *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_READ); + swc->commit(swc);; + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, + struct svga_transfer *st, // IN + SVGA3dTransferType transfer, // IN + const SVGA3dCopyBox *boxes, // IN + uint32 numBoxes) // IN +{ + struct svga_texture *texture = svga_texture(st->base.texture); + SVGA3dCmdSurfaceDMA *cmd; + SVGA3dCmdSurfaceDMASuffix *pSuffix; + uint32 boxesSize = sizeof *boxes * numBoxes; + unsigned region_flags; + unsigned surface_flags; + + if(transfer == SVGA3D_WRITE_HOST_VRAM) { + region_flags = PIPE_BUFFER_USAGE_GPU_READ; + surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + } + else if(transfer == SVGA3D_READ_HOST_VRAM) { + region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + surface_flags = PIPE_BUFFER_USAGE_GPU_READ; + } + else { + assert(0); + return PIPE_ERROR_BAD_INPUT; + } + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SURFACE_DMA, + sizeof *cmd + boxesSize + sizeof *pSuffix, + 2); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags); + cmd->guest.pitch = st->base.stride; + + swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags); + cmd->host.face = st->base.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */ + cmd->host.mipmap = st->base.level; + + cmd->transfer = transfer; + + memcpy(&cmd[1], boxes, boxesSize); + + pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize); + pSuffix->suffixSize = sizeof *pSuffix; + pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride; + memset(&pSuffix->flags, 0, sizeof pSuffix->flags); + + swc->commit(swc); + + return PIPE_OK; +} + + +enum pipe_error +SVGA3D_BufferDMA(struct svga_winsys_context *swc, + struct svga_winsys_buffer *guest, + struct svga_winsys_surface *host, + SVGA3dTransferType transfer, // IN + uint32 size, // IN + uint32 offset, // IN + SVGA3dSurfaceDMAFlags flags) // IN +{ + SVGA3dCmdSurfaceDMA *cmd; + SVGA3dCopyBox *box; + SVGA3dCmdSurfaceDMASuffix *pSuffix; + unsigned region_flags; + unsigned surface_flags; + + if(transfer == SVGA3D_WRITE_HOST_VRAM) { + region_flags = PIPE_BUFFER_USAGE_GPU_READ; + surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + } + else if(transfer == SVGA3D_READ_HOST_VRAM) { + region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; + surface_flags = PIPE_BUFFER_USAGE_GPU_READ; + } + else { + assert(0); + return PIPE_ERROR_BAD_INPUT; + } + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SURFACE_DMA, + sizeof *cmd + sizeof *box + sizeof *pSuffix, + 2); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags); + cmd->guest.pitch = 0; + + swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags); + cmd->host.face = 0; + cmd->host.mipmap = 0; + + cmd->transfer = transfer; + + box = (SVGA3dCopyBox *)&cmd[1]; + box->x = offset; + box->y = 0; + box->z = 0; + box->w = size; + box->h = 1; + box->d = 1; + box->srcx = offset; + box->srcy = 0; + box->srcz = 0; + + pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box); + pSuffix->suffixSize = sizeof *pSuffix; + pSuffix->maximumOffset = offset + size; + pSuffix->flags = flags; + + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SetRenderTarget(struct svga_winsys_context *swc, + SVGA3dRenderTargetType type, // IN + struct pipe_surface *surface) // IN +{ + SVGA3dCmdSetRenderTarget *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + + cmd->cid = swc->cid; + + cmd->type = type; + + surface_to_surfaceid(swc, surface, &cmd->target, PIPE_BUFFER_USAGE_GPU_WRITE); + + swc->commit(swc); + + return PIPE_OK; +} + + + + + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_DefineShader(struct svga_winsys_context *swc, + uint32 shid, // IN + SVGA3dShaderType type, // IN + const uint32 *bytecode, // IN + uint32 bytecodeLen) // IN +{ + SVGA3dCmdDefineShader *cmd; + + assert(bytecodeLen % 4 == 0); + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->shid = shid; + cmd->type = type; + memcpy(&cmd[1], bytecode, bytecodeLen); + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_DestroyShader(struct svga_winsys_context *swc, + uint32 shid, // IN + SVGA3dShaderType type) // IN +{ + SVGA3dCmdDestroyShader *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->shid = shid; + cmd->type = type; + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SetShaderConst(struct svga_winsys_context *swc, + uint32 reg, // IN + SVGA3dShaderType type, // IN + SVGA3dShaderConstType ctype, // IN + const void *value) // IN +{ + SVGA3dCmdSetShaderConst *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->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: + assert(0); + break; + + } + swc->commit(swc); + + return PIPE_OK; +} + + + + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SetShader(struct svga_winsys_context *swc, + SVGA3dShaderType type, // IN + uint32 shid) // IN +{ + SVGA3dCmdSetShader *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SET_SHADER, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->type = type; + cmd->shid = shid; + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginClear(struct svga_winsys_context *swc, + SVGA3dClearFlag flags, // IN + uint32 color, // IN + float depth, // IN + uint32 stencil, // IN + SVGA3dRect **rects, // OUT + uint32 numRects) // IN +{ + SVGA3dCmdClear *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_CLEAR, + sizeof *cmd + sizeof **rects * numRects, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->clearFlag = flags; + cmd->color = color; + cmd->depth = depth; + cmd->stencil = stencil; + *rects = (SVGA3dRect*) &cmd[1]; + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_ClearRect -- + * + * This is a simplified version of SVGA3D_BeginClear(). + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_ClearRect(struct svga_winsys_context *swc, + SVGA3dClearFlag flags, // IN + uint32 color, // IN + float depth, // IN + uint32 stencil, // IN + uint32 x, // IN + uint32 y, // IN + uint32 w, // IN + uint32 h) // IN +{ + SVGA3dRect *rect; + enum pipe_error ret; + + ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1); + if(ret != PIPE_OK) + return PIPE_ERROR_OUT_OF_MEMORY; + + memset(rect, 0, sizeof *rect); + rect->x = x; + rect->y = y; + rect->w = w; + rect->h = h; + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc, + 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(swc, + SVGA_3D_CMD_DRAW_PRIMITIVES, + sizeof *cmd + declSize + rangeSize, + numVertexDecls + numRanges); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->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; + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc, + struct pipe_surface *src, // IN + struct pipe_surface *dest, // IN + SVGA3dCopyBox **boxes, // OUT + uint32 numBoxes) // IN +{ + SVGA3dCmdSurfaceCopy *cmd; + uint32 boxesSize = sizeof **boxes * numBoxes; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize, + 2); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ); + surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE); + *boxes = (SVGA3dCopyBox*) &cmd[1]; + + memset(*boxes, 0, boxesSize); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc, + struct pipe_surface *src, // IN + struct pipe_surface *dest, // IN + SVGA3dBox *boxSrc, // IN + SVGA3dBox *boxDest, // IN + SVGA3dStretchBltMode mode) // IN +{ + SVGA3dCmdSurfaceStretchBlt *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd, + 2); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ); + surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE); + cmd->boxSrc = *boxSrc; + cmd->boxDest = *boxDest; + cmd->mode = mode; + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SetViewport(struct svga_winsys_context *swc, + SVGA3dRect *rect) // IN +{ + SVGA3dCmdSetViewport *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->rect = *rect; + swc->commit(swc); + + return PIPE_OK; +} + + + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_SetScissorRect -- + * + * Set the current context's scissor rectangle. If scissor + * is enabled then all rendering is clipped to the scissor. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SetScissorRect(struct svga_winsys_context *swc, + SVGA3dRect *rect) // IN +{ + SVGA3dCmdSetScissorRect *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->rect = *rect; + swc->commit(swc); + + return PIPE_OK; +} + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_SetClipPlane -- + * + * Set one of the current context's clip planes. If the clip + * plane is enabled then all 3d rendering is clipped to against + * the plane. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error SVGA3D_SetClipPlane(struct svga_winsys_context *swc, + uint32 index, const float *plane) +{ + SVGA3dCmdSetClipPlane *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->index = index; + cmd->plane[0] = plane[0]; + cmd->plane[1] = plane[1]; + cmd->plane[2] = plane[2]; + cmd->plane[3] = plane[3]; + swc->commit(swc); + + return PIPE_OK; +} + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_SetZRange(struct svga_winsys_context *swc, + float zMin, // IN + float zMax) // IN +{ + SVGA3dCmdSetZRange *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETZRANGE, sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->zRange.min = zMin; + cmd->zRange.max = zMax; + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc, + SVGA3dTextureState **states, // OUT + uint32 numStates) // IN +{ + SVGA3dCmdSetTextureState *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETTEXTURESTATE, + sizeof *cmd + sizeof **states * numStates, + numStates); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + *states = (SVGA3dTextureState*) &cmd[1]; + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * 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. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc, + SVGA3dRenderState **states, // OUT + uint32 numStates) // IN +{ + SVGA3dCmdSetRenderState *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_SETRENDERSTATE, + sizeof *cmd + sizeof **states * numStates, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + *states = (SVGA3dRenderState*) &cmd[1]; + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_BeginQuery-- + * + * Issues a SVGA_3D_CMD_BEGIN_QUERY command. + * + * Results: + * None. + * + * Side effects: + * Commits space in the FIFO memory. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_BeginQuery(struct svga_winsys_context *swc, + SVGA3dQueryType type) // IN +{ + SVGA3dCmdBeginQuery *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_BEGIN_QUERY, + sizeof *cmd, + 0); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->type = type; + + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_EndQuery-- + * + * Issues a SVGA_3D_CMD_END_QUERY command. + * + * Results: + * None. + * + * Side effects: + * Commits space in the FIFO memory. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_EndQuery(struct svga_winsys_context *swc, + SVGA3dQueryType type, // IN + struct svga_winsys_buffer *buffer) // IN/OUT +{ + SVGA3dCmdEndQuery *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_END_QUERY, + sizeof *cmd, + 1); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->type = type; + + swc->region_relocation(swc, &cmd->guestResult, buffer, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + swc->commit(swc); + + return PIPE_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * SVGA3D_WaitForQuery-- + * + * Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space + * for it in the FIFO. This doesn't actually wait for the query to + * finish but instead tells the host to start a wait at the driver + * level. The caller can wait on the status variable in the + * guestPtr memory or send an insert fence instruction after this + * command and wait on the fence. + * + * Results: + * None. + * + * Side effects: + * Commits space in the FIFO memory. + * + *---------------------------------------------------------------------- + */ + +enum pipe_error +SVGA3D_WaitForQuery(struct svga_winsys_context *swc, + SVGA3dQueryType type, // IN + struct svga_winsys_buffer *buffer) // IN/OUT +{ + SVGA3dCmdWaitForQuery *cmd; + + cmd = SVGA3D_FIFOReserve(swc, + SVGA_3D_CMD_WAIT_FOR_QUERY, + sizeof *cmd, + 1); + if(!cmd) + return PIPE_ERROR_OUT_OF_MEMORY; + + cmd->cid = swc->cid; + cmd->type = type; + + swc->region_relocation(swc, &cmd->guestResult, buffer, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + swc->commit(swc); + + return PIPE_OK; +} |