Path: blob/21.2-virgl/src/gallium/drivers/svga/svga_cmd.c
4570 views
/**********************************************************1* Copyright 2008-2009 VMware, Inc. All rights reserved.2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation5* files (the "Software"), to deal in the Software without6* restriction, including without limitation the rights to use, copy,7* modify, merge, publish, distribute, sublicense, and/or sell copies8* of the Software, and to permit persons to whom the Software is9* furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23**********************************************************/2425/**26* svga_cmd.c --27*28* Command construction utility for the SVGA3D protocol used by29* the VMware SVGA device, based on the svgautil library.30*/3132#include "svga_winsys.h"33#include "svga_resource_buffer.h"34#include "svga_resource_texture.h"35#include "svga_surface.h"36#include "svga_cmd.h"3738/*39*----------------------------------------------------------------------40*41* surface_to_surfaceid --42*43* Utility function for surface ids.44* Can handle null surface. Does a surface_reallocation so you need45* to have allocated the fifo space before converting.46*47*48* param flags mask of SVGA_RELOC_READ / _WRITE49*50* Results:51* id is filled out.52*53* Side effects:54* One surface relocation is performed for texture handle.55*56*----------------------------------------------------------------------57*/5859static inline void60surface_to_surfaceid(struct svga_winsys_context *swc, // IN61struct pipe_surface *surface, // IN62SVGA3dSurfaceImageId *id, // OUT63unsigned flags) // IN64{65if (surface) {66struct svga_surface *s = svga_surface(surface);67swc->surface_relocation(swc, &id->sid, NULL, s->handle, flags);68id->face = s->real_layer; /* faces have the same order */69id->mipmap = s->real_level;70}71else {72swc->surface_relocation(swc, &id->sid, NULL, NULL, flags);73id->face = 0;74id->mipmap = 0;75}76}777879/*80*----------------------------------------------------------------------81*82* SVGA3D_FIFOReserve --83*84* Reserve space for an SVGA3D FIFO command.85*86* The 2D SVGA commands have been around for a while, so they87* have a rather asymmetric structure. The SVGA3D protocol is88* more uniform: each command begins with a header containing the89* command number and the full size.90*91* This is a convenience wrapper around SVGA_FIFOReserve. We92* reserve space for the whole command, and write the header.93*94* This function must be paired with SVGA_FIFOCommitAll().95*96* Results:97* Returns a pointer to the space reserved for command-specific98* data. It must be 'cmdSize' bytes long.99*100* Side effects:101* Begins a FIFO reservation.102*103*----------------------------------------------------------------------104*/105106void *107SVGA3D_FIFOReserve(struct svga_winsys_context *swc,108uint32 cmd, // IN109uint32 cmdSize, // IN110uint32 nr_relocs) // IN111{112SVGA3dCmdHeader *header;113114header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs);115if (!header)116return NULL;117118header->id = cmd;119header->size = cmdSize;120121swc->last_command = cmd;122123swc->num_commands++;124125return &header[1];126}127128129void130SVGA_FIFOCommitAll(struct svga_winsys_context *swc)131{132swc->commit(swc);133}134135136/*137*----------------------------------------------------------------------138*139* SVGA3D_DefineContext --140*141* Create a new context, to be referred to with the provided ID.142*143* Context objects encapsulate all render state, and shader144* objects are per-context.145*146* Surfaces are not per-context. The same surface can be shared147* between multiple contexts, and surface operations can occur148* without a context.149*150* If the provided context ID already existed, it is redefined.151*152* Context IDs are arbitrary small non-negative integers,153* global to the entire SVGA device.154*155* Results:156* None.157*158* Side effects:159* None.160*161*----------------------------------------------------------------------162*/163164enum pipe_error165SVGA3D_DefineContext(struct svga_winsys_context *swc) // IN166{167SVGA3dCmdDefineContext *cmd;168169cmd = SVGA3D_FIFOReserve(swc,170SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0);171if (!cmd)172return PIPE_ERROR_OUT_OF_MEMORY;173174cmd->cid = swc->cid;175176swc->commit(swc);177178return PIPE_OK;179}180181182/*183*----------------------------------------------------------------------184*185* SVGA3D_DestroyContext --186*187* Delete a context created with SVGA3D_DefineContext.188*189* Results:190* None.191*192* Side effects:193* None.194*195*----------------------------------------------------------------------196*/197198enum pipe_error199SVGA3D_DestroyContext(struct svga_winsys_context *swc) // IN200{201SVGA3dCmdDestroyContext *cmd;202203cmd = SVGA3D_FIFOReserve(swc,204SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0);205if (!cmd)206return PIPE_ERROR_OUT_OF_MEMORY;207208cmd->cid = swc->cid;209210swc->commit(swc);211212return PIPE_OK;213}214215216/*217*----------------------------------------------------------------------218*219* SVGA3D_BeginDefineSurface --220*221* Begin a SURFACE_DEFINE command. This reserves space for it in222* the FIFO, and returns pointers to the command's faces and223* mipsizes arrays.224*225* This function must be paired with SVGA_FIFOCommitAll().226* The faces and mipSizes arrays are initialized to zero.227*228* This creates a "surface" object in the SVGA3D device,229* with the provided surface ID (sid). Surfaces are generic230* containers for host VRAM objects like textures, vertex231* buffers, and depth/stencil buffers.232*233* Surfaces are hierarchical:234*235* - Surface may have multiple faces (for cube maps)236*237* - Each face has a list of mipmap levels238*239* - Each mipmap image may have multiple volume240* slices, if the image is three dimensional.241*242* - Each slice is a 2D array of 'blocks'243*244* - Each block may be one or more pixels.245* (Usually 1, more for DXT or YUV formats.)246*247* Surfaces are generic host VRAM objects. The SVGA3D device248* may optimize surfaces according to the format they were249* created with, but this format does not limit the ways in250* which the surface may be used. For example, a depth surface251* can be used as a texture, or a floating point image may252* be used as a vertex buffer. Some surface usages may be253* lower performance, due to software emulation, but any254* usage should work with any surface.255*256* If 'sid' is already defined, the old surface is deleted257* and this new surface replaces it.258*259* Surface IDs are arbitrary small non-negative integers,260* global to the entire SVGA device.261*262* Results:263* Returns pointers to arrays allocated in the FIFO for 'faces'264* and 'mipSizes'.265*266* Side effects:267* Begins a FIFO reservation.268*269*----------------------------------------------------------------------270*/271272enum pipe_error273SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,274struct svga_winsys_surface *sid, // IN275SVGA3dSurface1Flags flags, // IN276SVGA3dSurfaceFormat format, // IN277SVGA3dSurfaceFace **faces, // OUT278SVGA3dSize **mipSizes, // OUT279uint32 numMipSizes) // IN280{281SVGA3dCmdDefineSurface *cmd;282283cmd = SVGA3D_FIFOReserve(swc,284SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +285sizeof **mipSizes * numMipSizes, 1);286if (!cmd)287return PIPE_ERROR_OUT_OF_MEMORY;288289swc->surface_relocation(swc, &cmd->sid, NULL, sid,290SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);291cmd->surfaceFlags = flags;292cmd->format = format;293294*faces = &cmd->face[0];295*mipSizes = (SVGA3dSize*) &cmd[1];296297memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);298memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);299300return PIPE_OK;301}302303304/*305*----------------------------------------------------------------------306*307* SVGA3D_DefineSurface2D --308*309* This is a simplified version of SVGA3D_BeginDefineSurface(),310* which does not support cube maps, mipmaps, or volume textures.311*312* Results:313* None.314*315* Side effects:316* None.317*318*----------------------------------------------------------------------319*/320321enum pipe_error322SVGA3D_DefineSurface2D(struct svga_winsys_context *swc, // IN323struct svga_winsys_surface *sid, // IN324uint32 width, // IN325uint32 height, // IN326SVGA3dSurfaceFormat format) // IN327{328SVGA3dSize *mipSizes;329SVGA3dSurfaceFace *faces;330enum pipe_error ret;331332ret = SVGA3D_BeginDefineSurface(swc,333sid, 0, format, &faces, &mipSizes, 1);334if (ret != PIPE_OK)335return ret;336337faces[0].numMipLevels = 1;338339mipSizes[0].width = width;340mipSizes[0].height = height;341mipSizes[0].depth = 1;342343swc->commit(swc);344345return PIPE_OK;346}347348349/*350*----------------------------------------------------------------------351*352* SVGA3D_DestroySurface --353*354* Release the host VRAM encapsulated by a particular surface ID.355*356* Results:357* None.358*359* Side effects:360* None.361*362*----------------------------------------------------------------------363*/364365enum pipe_error366SVGA3D_DestroySurface(struct svga_winsys_context *swc,367struct svga_winsys_surface *sid) // IN368{369SVGA3dCmdDestroySurface *cmd;370371cmd = SVGA3D_FIFOReserve(swc,372SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);373if (!cmd)374return PIPE_ERROR_OUT_OF_MEMORY;375376swc->surface_relocation(swc, &cmd->sid, NULL, sid,377SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);378swc->commit(swc);379380return PIPE_OK;381}382383384/*385*----------------------------------------------------------------------386*387* SVGA3D_SurfaceDMA--388*389* Emit a SURFACE_DMA command.390*391* When the SVGA3D device asynchronously processes this FIFO392* command, a DMA operation is performed between host VRAM and393* a generic SVGAGuestPtr. The guest pointer may refer to guest394* VRAM (provided by the SVGA PCI device) or to guest system395* memory that has been set up as a Guest Memory Region (GMR)396* by the SVGA device.397*398* The guest's DMA buffer must remain valid (not freed, paged out,399* or overwritten) until the host has finished processing this400* command. The guest can determine that the host has finished401* by using the SVGA device's FIFO Fence mechanism.402*403* The guest's image buffer can be an arbitrary size and shape.404* Guest image data is interpreted according to the SVGA3D surface405* format specified when the surface was defined.406*407* The caller may optionally define the guest image's pitch.408* guestImage->pitch can either be zero (assume image is tightly409* packed) or it must be the number of bytes between vertically410* adjacent image blocks.411*412* The provided copybox list specifies which regions of the source413* image are to be copied, and where they appear on the destination.414*415* NOTE: srcx/srcy are always on the guest image and x/y are416* always on the host image, regardless of the actual transfer417* direction!418*419* For efficiency, the SVGA3D device is free to copy more data420* than specified. For example, it may round copy boxes outwards421* such that they lie on particular alignment boundaries.422*423*----------------------------------------------------------------------424*/425426enum pipe_error427SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,428struct svga_transfer *st, // IN429SVGA3dTransferType transfer, // IN430const SVGA3dCopyBox *boxes, // IN431uint32 numBoxes, // IN432SVGA3dSurfaceDMAFlags flags) // IN433{434struct svga_texture *texture = svga_texture(st->base.resource);435SVGA3dCmdSurfaceDMA *cmd;436SVGA3dCmdSurfaceDMASuffix *pSuffix;437uint32 boxesSize = sizeof *boxes * numBoxes;438unsigned region_flags;439unsigned surface_flags;440441if (transfer == SVGA3D_WRITE_HOST_VRAM) {442region_flags = SVGA_RELOC_READ;443surface_flags = SVGA_RELOC_WRITE;444}445else if (transfer == SVGA3D_READ_HOST_VRAM) {446region_flags = SVGA_RELOC_WRITE;447surface_flags = SVGA_RELOC_READ;448}449else {450assert(0);451return PIPE_ERROR_BAD_INPUT;452}453454cmd = SVGA3D_FIFOReserve(swc,455SVGA_3D_CMD_SURFACE_DMA,456sizeof *cmd + boxesSize + sizeof *pSuffix,4572);458if (!cmd)459return PIPE_ERROR_OUT_OF_MEMORY;460461swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);462cmd->guest.pitch = st->base.stride;463464swc->surface_relocation(swc, &cmd->host.sid, NULL,465texture->handle, surface_flags);466cmd->host.face = st->slice; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */467cmd->host.mipmap = st->base.level;468469cmd->transfer = transfer;470471memcpy(&cmd[1], boxes, boxesSize);472473pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);474pSuffix->suffixSize = sizeof *pSuffix;475pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;476pSuffix->flags = flags;477478swc->commit(swc);479swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;480481return PIPE_OK;482}483484485enum pipe_error486SVGA3D_BufferDMA(struct svga_winsys_context *swc,487struct svga_winsys_buffer *guest,488struct svga_winsys_surface *host,489SVGA3dTransferType transfer, // IN490uint32 size, // IN491uint32 guest_offset, // IN492uint32 host_offset, // IN493SVGA3dSurfaceDMAFlags flags) // IN494{495SVGA3dCmdSurfaceDMA *cmd;496SVGA3dCopyBox *box;497SVGA3dCmdSurfaceDMASuffix *pSuffix;498unsigned region_flags;499unsigned surface_flags;500501assert(!swc->have_gb_objects);502503if (transfer == SVGA3D_WRITE_HOST_VRAM) {504region_flags = SVGA_RELOC_READ;505surface_flags = SVGA_RELOC_WRITE;506}507else if (transfer == SVGA3D_READ_HOST_VRAM) {508region_flags = SVGA_RELOC_WRITE;509surface_flags = SVGA_RELOC_READ;510}511else {512assert(0);513return PIPE_ERROR_BAD_INPUT;514}515516cmd = SVGA3D_FIFOReserve(swc,517SVGA_3D_CMD_SURFACE_DMA,518sizeof *cmd + sizeof *box + sizeof *pSuffix,5192);520if (!cmd)521return PIPE_ERROR_OUT_OF_MEMORY;522523swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);524cmd->guest.pitch = 0;525526swc->surface_relocation(swc, &cmd->host.sid,527NULL, host, surface_flags);528cmd->host.face = 0;529cmd->host.mipmap = 0;530531cmd->transfer = transfer;532533box = (SVGA3dCopyBox *)&cmd[1];534box->x = host_offset;535box->y = 0;536box->z = 0;537box->w = size;538box->h = 1;539box->d = 1;540box->srcx = guest_offset;541box->srcy = 0;542box->srcz = 0;543544pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);545pSuffix->suffixSize = sizeof *pSuffix;546pSuffix->maximumOffset = guest_offset + size;547pSuffix->flags = flags;548549swc->commit(swc);550swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;551552return PIPE_OK;553}554555556/*557*----------------------------------------------------------------------558*559* SVGA3D_SetRenderTarget --560*561* Bind a surface object to a particular render target attachment562* point on the current context. Render target attachment points563* exist for color buffers, a depth buffer, and a stencil buffer.564*565* The SVGA3D device is quite lenient about the types of surfaces566* that may be used as render targets. The color buffers must567* all be the same size, but the depth and stencil buffers do not568* have to be the same size as the color buffer. All attachments569* are optional.570*571* Some combinations of render target formats may require software572* emulation, depending on the capabilities of the host graphics573* API and graphics hardware.574*575* Results:576* None.577*578* Side effects:579* None.580*581*----------------------------------------------------------------------582*/583584enum pipe_error585SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,586SVGA3dRenderTargetType type, // IN587struct pipe_surface *surface) // IN588{589SVGA3dCmdSetRenderTarget *cmd;590591cmd = SVGA3D_FIFOReserve(swc,592SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);593if (!cmd)594return PIPE_ERROR_OUT_OF_MEMORY;595596cmd->cid = swc->cid;597cmd->type = type;598surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);599swc->commit(swc);600601return PIPE_OK;602}603604605/*606*----------------------------------------------------------------------607*608* SVGA3D_DefineShader --609*610* Upload the bytecode for a new shader. The bytecode is "SVGA3D611* format", which is theoretically a binary-compatible superset612* of Microsoft's DirectX shader bytecode. In practice, the613* SVGA3D bytecode doesn't yet have any extensions to DirectX's614* bytecode format.615*616* The SVGA3D device supports shader models 1.1 through 2.0.617*618* The caller chooses a shader ID (small positive integer) by619* which this shader will be identified in future commands. This620* ID is in a namespace which is per-context and per-shader-type.621*622* 'bytecodeLen' is specified in bytes. It must be a multiple of 4.623*624* Results:625* None.626*627* Side effects:628* None.629*630*----------------------------------------------------------------------631*/632633enum pipe_error634SVGA3D_DefineShader(struct svga_winsys_context *swc,635uint32 shid, // IN636SVGA3dShaderType type, // IN637const uint32 *bytecode, // IN638uint32 bytecodeLen) // IN639{640SVGA3dCmdDefineShader *cmd;641642assert(bytecodeLen % 4 == 0);643644cmd = SVGA3D_FIFOReserve(swc,645SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,6460);647if (!cmd)648return PIPE_ERROR_OUT_OF_MEMORY;649650cmd->cid = swc->cid;651cmd->shid = shid;652cmd->type = type;653memcpy(&cmd[1], bytecode, bytecodeLen);654swc->commit(swc);655656return PIPE_OK;657}658659660/*661*----------------------------------------------------------------------662*663* SVGA3D_DestroyShader --664*665* Delete a shader that was created by SVGA3D_DefineShader. If666* the shader was the current vertex or pixel shader for its667* context, rendering results are undefined until a new shader is668* bound.669*670* Results:671* None.672*673* Side effects:674* None.675*676*----------------------------------------------------------------------677*/678679enum pipe_error680SVGA3D_DestroyShader(struct svga_winsys_context *swc,681uint32 shid, // IN682SVGA3dShaderType type) // IN683{684SVGA3dCmdDestroyShader *cmd;685686cmd = SVGA3D_FIFOReserve(swc,687SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,6880);689if (!cmd)690return PIPE_ERROR_OUT_OF_MEMORY;691692cmd->cid = swc->cid;693cmd->shid = shid;694cmd->type = type;695swc->commit(swc);696697return PIPE_OK;698}699700701/*702*----------------------------------------------------------------------703*704* SVGA3D_SetShaderConst --705*706* Set the value of a shader constant.707*708* Shader constants are analogous to uniform variables in GLSL,709* except that they belong to the render context rather than to710* an individual shader.711*712* Constants may have one of three types: A 4-vector of floats,713* a 4-vector of integers, or a single boolean flag.714*715* Results:716* None.717*718* Side effects:719* None.720*721*----------------------------------------------------------------------722*/723724enum pipe_error725SVGA3D_SetShaderConst(struct svga_winsys_context *swc,726uint32 reg, // IN727SVGA3dShaderType type, // IN728SVGA3dShaderConstType ctype, // IN729const void *value) // IN730{731SVGA3dCmdSetShaderConst *cmd;732733cmd = SVGA3D_FIFOReserve(swc,734SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,7350);736if (!cmd)737return PIPE_ERROR_OUT_OF_MEMORY;738739cmd->cid = swc->cid;740cmd->reg = reg;741cmd->type = type;742cmd->ctype = ctype;743744switch (ctype) {745746case SVGA3D_CONST_TYPE_FLOAT:747case SVGA3D_CONST_TYPE_INT:748memcpy(&cmd->values, value, sizeof cmd->values);749break;750751case SVGA3D_CONST_TYPE_BOOL:752memset(&cmd->values, 0, sizeof cmd->values);753cmd->values[0] = *(uint32*)value;754break;755756default:757assert(0);758break;759760}761swc->commit(swc);762763return PIPE_OK;764}765766767/*768*----------------------------------------------------------------------769*770* SVGA3D_SetShaderConsts --771*772* Set the value of successive shader constants.773*774* Shader constants are analogous to uniform variables in GLSL,775* except that they belong to the render context rather than to776* an individual shader.777*778* Constants may have one of three types: A 4-vector of floats,779* a 4-vector of integers, or a single boolean flag.780*781* Results:782* None.783*784* Side effects:785* None.786*787*----------------------------------------------------------------------788*/789790enum pipe_error791SVGA3D_SetShaderConsts(struct svga_winsys_context *swc,792uint32 reg, // IN793uint32 numRegs, // IN794SVGA3dShaderType type, // IN795SVGA3dShaderConstType ctype, // IN796const void *values) // IN797{798SVGA3dCmdSetShaderConst *cmd;799800cmd = SVGA3D_FIFOReserve(swc,801SVGA_3D_CMD_SET_SHADER_CONST,802sizeof *cmd + (numRegs - 1) * sizeof cmd->values,8030);804if (!cmd)805return PIPE_ERROR_OUT_OF_MEMORY;806807cmd->cid = swc->cid;808cmd->reg = reg;809cmd->type = type;810cmd->ctype = ctype;811812memcpy(&cmd->values, values, numRegs * sizeof cmd->values);813814swc->commit(swc);815816return PIPE_OK;817}818819820821822823/*824*----------------------------------------------------------------------825*826* SVGA3D_SetShader --827*828* Switch active shaders. This binds a new vertex or pixel shader829* to the specified context.830*831* A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching832* back to the fixed function vertex or pixel pipeline.833*834* Results:835* None.836*837* Side effects:838* None.839*840*----------------------------------------------------------------------841*/842843enum pipe_error844SVGA3D_SetShader(struct svga_winsys_context *swc,845SVGA3dShaderType type, // IN846uint32 shid) // IN847{848SVGA3dCmdSetShader *cmd;849850assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS);851852cmd = SVGA3D_FIFOReserve(swc,853SVGA_3D_CMD_SET_SHADER, sizeof *cmd,8540);855if (!cmd)856return PIPE_ERROR_OUT_OF_MEMORY;857858cmd->cid = swc->cid;859cmd->type = type;860cmd->shid = shid;861swc->commit(swc);862863return PIPE_OK;864}865866867/*868*----------------------------------------------------------------------869*870* SVGA3D_BeginClear --871*872* Begin a CLEAR command. This reserves space for it in the FIFO,873* and returns a pointer to the command's rectangle array. This874* function must be paired with SVGA_FIFOCommitAll().875*876* Clear is a rendering operation which fills a list of877* rectangles with constant values on all render target types878* indicated by 'flags'.879*880* Clear is not affected by clipping, depth test, or other881* render state which affects the fragment pipeline.882*883* Results:884* None.885*886* Side effects:887* May write to attached render target surfaces.888*889*----------------------------------------------------------------------890*/891892enum pipe_error893SVGA3D_BeginClear(struct svga_winsys_context *swc,894SVGA3dClearFlag flags, // IN895uint32 color, // IN896float depth, // IN897uint32 stencil, // IN898SVGA3dRect **rects, // OUT899uint32 numRects) // IN900{901SVGA3dCmdClear *cmd;902903cmd = SVGA3D_FIFOReserve(swc,904SVGA_3D_CMD_CLEAR,905sizeof *cmd + sizeof **rects * numRects,9060);907if (!cmd)908return PIPE_ERROR_OUT_OF_MEMORY;909910cmd->cid = swc->cid;911cmd->clearFlag = flags;912cmd->color = color;913cmd->depth = depth;914cmd->stencil = stencil;915*rects = (SVGA3dRect*) &cmd[1];916917return PIPE_OK;918}919920921/*922*----------------------------------------------------------------------923*924* SVGA3D_ClearRect --925*926* This is a simplified version of SVGA3D_BeginClear().927*928* Results:929* None.930*931* Side effects:932* None.933*934*----------------------------------------------------------------------935*/936937enum pipe_error938SVGA3D_ClearRect(struct svga_winsys_context *swc,939SVGA3dClearFlag flags, // IN940uint32 color, // IN941float depth, // IN942uint32 stencil, // IN943uint32 x, // IN944uint32 y, // IN945uint32 w, // IN946uint32 h) // IN947{948SVGA3dRect *rect;949enum pipe_error ret;950951ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);952if (ret != PIPE_OK)953return PIPE_ERROR_OUT_OF_MEMORY;954955memset(rect, 0, sizeof *rect);956rect->x = x;957rect->y = y;958rect->w = w;959rect->h = h;960swc->commit(swc);961962return PIPE_OK;963}964965966/*967*----------------------------------------------------------------------968*969* SVGA3D_BeginDrawPrimitives --970*971* Begin a DRAW_PRIMITIVES command. This reserves space for it in972* the FIFO, and returns a pointer to the command's arrays.973* This function must be paired with SVGA_FIFOCommitAll().974*975* Drawing commands consist of two variable-length arrays:976* SVGA3dVertexDecl elements declare a set of vertex buffers to977* use while rendering, and SVGA3dPrimitiveRange elements specify978* groups of primitives each with an optional index buffer.979*980* The decls and ranges arrays are initialized to zero.981*982* Results:983* None.984*985* Side effects:986* May write to attached render target surfaces.987*988*----------------------------------------------------------------------989*/990991enum pipe_error992SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,993SVGA3dVertexDecl **decls, // OUT994uint32 numVertexDecls, // IN995SVGA3dPrimitiveRange **ranges, // OUT996uint32 numRanges) // IN997{998SVGA3dCmdDrawPrimitives *cmd;999SVGA3dVertexDecl *declArray;1000SVGA3dPrimitiveRange *rangeArray;1001uint32 declSize = sizeof **decls * numVertexDecls;1002uint32 rangeSize = sizeof **ranges * numRanges;10031004cmd = SVGA3D_FIFOReserve(swc,1005SVGA_3D_CMD_DRAW_PRIMITIVES,1006sizeof *cmd + declSize + rangeSize,1007numVertexDecls + numRanges);1008if (!cmd)1009return PIPE_ERROR_OUT_OF_MEMORY;10101011cmd->cid = swc->cid;1012cmd->numVertexDecls = numVertexDecls;1013cmd->numRanges = numRanges;10141015declArray = (SVGA3dVertexDecl*) &cmd[1];1016rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];10171018memset(declArray, 0, declSize);1019memset(rangeArray, 0, rangeSize);10201021*decls = declArray;1022*ranges = rangeArray;10231024swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;10251026swc->num_draw_commands++;10271028return PIPE_OK;1029}103010311032/*1033*----------------------------------------------------------------------1034*1035* SVGA3D_BeginSurfaceCopy --1036*1037* Begin a SURFACE_COPY command. This reserves space for it in1038* the FIFO, and returns a pointer to the command's arrays. This1039* function must be paired with SVGA_FIFOCommitAll().1040*1041* The box array is initialized with zeroes.1042*1043* Results:1044* None.1045*1046* Side effects:1047* Asynchronously copies a list of boxes from surface to surface.1048*1049*----------------------------------------------------------------------1050*/10511052enum pipe_error1053SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,1054struct pipe_surface *src, // IN1055struct pipe_surface *dest, // IN1056SVGA3dCopyBox **boxes, // OUT1057uint32 numBoxes) // IN1058{1059SVGA3dCmdSurfaceCopy *cmd;1060uint32 boxesSize = sizeof **boxes * numBoxes;10611062cmd = SVGA3D_FIFOReserve(swc,1063SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,10642);1065if (!cmd)1066return PIPE_ERROR_OUT_OF_MEMORY;10671068surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);1069surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);1070*boxes = (SVGA3dCopyBox*) &cmd[1];10711072memset(*boxes, 0, boxesSize);10731074return PIPE_OK;1075}107610771078/*1079*----------------------------------------------------------------------1080*1081* SVGA3D_SurfaceStretchBlt --1082*1083* Issue a SURFACE_STRETCHBLT command: an asynchronous1084* surface-to-surface blit, with scaling.1085*1086* Results:1087* None.1088*1089* Side effects:1090* Asynchronously copies one box from surface to surface.1091*1092*----------------------------------------------------------------------1093*/10941095enum pipe_error1096SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,1097struct pipe_surface *src, // IN1098struct pipe_surface *dest, // IN1099SVGA3dBox *boxSrc, // IN1100SVGA3dBox *boxDest, // IN1101SVGA3dStretchBltMode mode) // IN1102{1103SVGA3dCmdSurfaceStretchBlt *cmd;11041105cmd = SVGA3D_FIFOReserve(swc,1106SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,11072);1108if (!cmd)1109return PIPE_ERROR_OUT_OF_MEMORY;11101111surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);1112surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);1113cmd->boxSrc = *boxSrc;1114cmd->boxDest = *boxDest;1115cmd->mode = mode;1116swc->commit(swc);11171118return PIPE_OK;1119}112011211122/*1123*----------------------------------------------------------------------1124*1125* SVGA3D_SetViewport --1126*1127* Set the current context's viewport rectangle. The viewport1128* is clipped to the dimensions of the current render target,1129* then all rendering is clipped to the viewport.1130*1131* Results:1132* None.1133*1134* Side effects:1135* None.1136*1137*----------------------------------------------------------------------1138*/11391140enum pipe_error1141SVGA3D_SetViewport(struct svga_winsys_context *swc,1142SVGA3dRect *rect) // IN1143{1144SVGA3dCmdSetViewport *cmd;11451146cmd = SVGA3D_FIFOReserve(swc,1147SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,11480);1149if (!cmd)1150return PIPE_ERROR_OUT_OF_MEMORY;11511152cmd->cid = swc->cid;1153cmd->rect = *rect;1154swc->commit(swc);11551156return PIPE_OK;1157}11581159116011611162/*1163*----------------------------------------------------------------------1164*1165* SVGA3D_SetScissorRect --1166*1167* Set the current context's scissor rectangle. If scissoring1168* is enabled then all rendering is clipped to the scissor bounds.1169*1170* Results:1171* None.1172*1173* Side effects:1174* None.1175*1176*----------------------------------------------------------------------1177*/11781179enum pipe_error1180SVGA3D_SetScissorRect(struct svga_winsys_context *swc,1181SVGA3dRect *rect) // IN1182{1183SVGA3dCmdSetScissorRect *cmd;11841185cmd = SVGA3D_FIFOReserve(swc,1186SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,11870);1188if (!cmd)1189return PIPE_ERROR_OUT_OF_MEMORY;11901191cmd->cid = swc->cid;1192cmd->rect = *rect;1193swc->commit(swc);11941195return PIPE_OK;1196}11971198/*1199*----------------------------------------------------------------------1200*1201* SVGA3D_SetClipPlane --1202*1203* Set one of the current context's clip planes. If the clip1204* plane is enabled then all 3d rendering is clipped against1205* the plane.1206*1207* Results:1208* None.1209*1210* Side effects:1211* None.1212*1213*----------------------------------------------------------------------1214*/12151216enum pipe_error1217SVGA3D_SetClipPlane(struct svga_winsys_context *swc,1218uint32 index, const float *plane)1219{1220SVGA3dCmdSetClipPlane *cmd;12211222cmd = SVGA3D_FIFOReserve(swc,1223SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,12240);1225if (!cmd)1226return PIPE_ERROR_OUT_OF_MEMORY;12271228cmd->cid = swc->cid;1229cmd->index = index;1230cmd->plane[0] = plane[0];1231cmd->plane[1] = plane[1];1232cmd->plane[2] = plane[2];1233cmd->plane[3] = plane[3];1234swc->commit(swc);12351236return PIPE_OK;1237}12381239/*1240*----------------------------------------------------------------------1241*1242* SVGA3D_SetZRange --1243*1244* Set the range of the depth buffer to use. 'min' and 'max'1245* are values between 0.0 and 1.0.1246*1247* Results:1248* None.1249*1250* Side effects:1251* None.1252*1253*----------------------------------------------------------------------1254*/12551256enum pipe_error1257SVGA3D_SetZRange(struct svga_winsys_context *swc,1258float zMin, // IN1259float zMax) // IN1260{1261SVGA3dCmdSetZRange *cmd;12621263cmd = SVGA3D_FIFOReserve(swc,1264SVGA_3D_CMD_SETZRANGE, sizeof *cmd,12650);1266if (!cmd)1267return PIPE_ERROR_OUT_OF_MEMORY;12681269cmd->cid = swc->cid;1270cmd->zRange.min = zMin;1271cmd->zRange.max = zMax;1272swc->commit(swc);12731274return PIPE_OK;1275}127612771278/*1279*----------------------------------------------------------------------1280*1281* SVGA3D_BeginSetTextureState --1282*1283* Begin a SETTEXTURESTATE command. This reserves space for it in1284* the FIFO, and returns a pointer to the command's texture state1285* array. This function must be paired with SVGA_FIFOCommitAll().1286*1287* This command sets rendering state which is per-texture-unit.1288*1289* XXX: Individual texture states need documentation. However,1290* they are very similar to the texture states defined by1291* Direct3D. The D3D documentation is a good starting point1292* for understanding SVGA3D texture states.1293*1294* Results:1295* None.1296*1297* Side effects:1298* None.1299*1300*----------------------------------------------------------------------1301*/13021303enum pipe_error1304SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,1305SVGA3dTextureState **states, // OUT1306uint32 numStates) // IN1307{1308SVGA3dCmdSetTextureState *cmd;13091310cmd = SVGA3D_FIFOReserve(swc,1311SVGA_3D_CMD_SETTEXTURESTATE,1312sizeof *cmd + sizeof **states * numStates,1313numStates);1314if (!cmd)1315return PIPE_ERROR_OUT_OF_MEMORY;13161317cmd->cid = swc->cid;1318*states = (SVGA3dTextureState*) &cmd[1];13191320return PIPE_OK;1321}132213231324/*1325*----------------------------------------------------------------------1326*1327* SVGA3D_BeginSetRenderState --1328*1329* Begin a SETRENDERSTATE command. This reserves space for it in1330* the FIFO, and returns a pointer to the command's texture state1331* array. This function must be paired with SVGA_FIFOCommitAll().1332*1333* This command sets rendering state which is global to the context.1334*1335* XXX: Individual render states need documentation. However,1336* they are very similar to the render states defined by1337* Direct3D. The D3D documentation is a good starting point1338* for understanding SVGA3D render states.1339*1340* Results:1341* None.1342*1343* Side effects:1344* None.1345*1346*----------------------------------------------------------------------1347*/13481349enum pipe_error1350SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,1351SVGA3dRenderState **states, // OUT1352uint32 numStates) // IN1353{1354SVGA3dCmdSetRenderState *cmd;13551356cmd = SVGA3D_FIFOReserve(swc,1357SVGA_3D_CMD_SETRENDERSTATE,1358sizeof *cmd + sizeof **states * numStates,13590);1360if (!cmd)1361return PIPE_ERROR_OUT_OF_MEMORY;13621363cmd->cid = swc->cid;1364*states = (SVGA3dRenderState*) &cmd[1];13651366return PIPE_OK;1367}136813691370/*1371*----------------------------------------------------------------------1372*1373* SVGA3D_BeginGBQuery--1374*1375* GB resource version of SVGA3D_BeginQuery.1376*1377* Results:1378* None.1379*1380* Side effects:1381* Commits space in the FIFO memory.1382*1383*----------------------------------------------------------------------1384*/13851386static enum pipe_error1387SVGA3D_BeginGBQuery(struct svga_winsys_context *swc,1388SVGA3dQueryType type) // IN1389{1390SVGA3dCmdBeginGBQuery *cmd;13911392cmd = SVGA3D_FIFOReserve(swc,1393SVGA_3D_CMD_BEGIN_GB_QUERY,1394sizeof *cmd,13951);1396if (!cmd)1397return PIPE_ERROR_OUT_OF_MEMORY;13981399cmd->cid = swc->cid;1400cmd->type = type;14011402swc->commit(swc);14031404return PIPE_OK;1405}140614071408/*1409*----------------------------------------------------------------------1410*1411* SVGA3D_BeginQuery--1412*1413* Issues a SVGA_3D_CMD_BEGIN_QUERY command.1414*1415* Results:1416* None.1417*1418* Side effects:1419* Commits space in the FIFO memory.1420*1421*----------------------------------------------------------------------1422*/14231424enum pipe_error1425SVGA3D_BeginQuery(struct svga_winsys_context *swc,1426SVGA3dQueryType type) // IN1427{1428SVGA3dCmdBeginQuery *cmd;14291430if (swc->have_gb_objects)1431return SVGA3D_BeginGBQuery(swc, type);14321433cmd = SVGA3D_FIFOReserve(swc,1434SVGA_3D_CMD_BEGIN_QUERY,1435sizeof *cmd,14360);1437if (!cmd)1438return PIPE_ERROR_OUT_OF_MEMORY;14391440cmd->cid = swc->cid;1441cmd->type = type;14421443swc->commit(swc);14441445return PIPE_OK;1446}144714481449/*1450*----------------------------------------------------------------------1451*1452* SVGA3D_EndGBQuery--1453*1454* GB resource version of SVGA3D_EndQuery.1455*1456* Results:1457* None.1458*1459* Side effects:1460* Commits space in the FIFO memory.1461*1462*----------------------------------------------------------------------1463*/14641465static enum pipe_error1466SVGA3D_EndGBQuery(struct svga_winsys_context *swc,1467SVGA3dQueryType type, // IN1468struct svga_winsys_buffer *buffer) // IN/OUT1469{1470SVGA3dCmdEndGBQuery *cmd;14711472cmd = SVGA3D_FIFOReserve(swc,1473SVGA_3D_CMD_END_GB_QUERY,1474sizeof *cmd,14752);1476if (!cmd)1477return PIPE_ERROR_OUT_OF_MEMORY;14781479cmd->cid = swc->cid;1480cmd->type = type;14811482swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,14830, SVGA_RELOC_READ | SVGA_RELOC_WRITE);14841485swc->commit(swc);14861487return PIPE_OK;1488}148914901491/*1492*----------------------------------------------------------------------1493*1494* SVGA3D_EndQuery--1495*1496* Issues a SVGA_3D_CMD_END_QUERY command.1497*1498* Results:1499* None.1500*1501* Side effects:1502* Commits space in the FIFO memory.1503*1504*----------------------------------------------------------------------1505*/15061507enum pipe_error1508SVGA3D_EndQuery(struct svga_winsys_context *swc,1509SVGA3dQueryType type, // IN1510struct svga_winsys_buffer *buffer) // IN/OUT1511{1512SVGA3dCmdEndQuery *cmd;15131514if (swc->have_gb_objects)1515return SVGA3D_EndGBQuery(swc, type, buffer);15161517cmd = SVGA3D_FIFOReserve(swc,1518SVGA_3D_CMD_END_QUERY,1519sizeof *cmd,15201);1521if (!cmd)1522return PIPE_ERROR_OUT_OF_MEMORY;15231524cmd->cid = swc->cid;1525cmd->type = type;15261527swc->region_relocation(swc, &cmd->guestResult, buffer, 0,1528SVGA_RELOC_READ | SVGA_RELOC_WRITE);15291530swc->commit(swc);15311532return PIPE_OK;1533}153415351536/*1537*----------------------------------------------------------------------1538*1539* SVGA3D_WaitForGBQuery--1540*1541* GB resource version of SVGA3D_WaitForQuery.1542*1543* Results:1544* None.1545*1546* Side effects:1547* Commits space in the FIFO memory.1548*1549*----------------------------------------------------------------------1550*/15511552static enum pipe_error1553SVGA3D_WaitForGBQuery(struct svga_winsys_context *swc,1554SVGA3dQueryType type, // IN1555struct svga_winsys_buffer *buffer) // IN/OUT1556{1557SVGA3dCmdWaitForGBQuery *cmd;15581559cmd = SVGA3D_FIFOReserve(swc,1560SVGA_3D_CMD_WAIT_FOR_GB_QUERY,1561sizeof *cmd,15622);1563if (!cmd)1564return PIPE_ERROR_OUT_OF_MEMORY;15651566cmd->cid = swc->cid;1567cmd->type = type;15681569swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,15700, SVGA_RELOC_READ | SVGA_RELOC_WRITE);15711572swc->commit(swc);15731574return PIPE_OK;1575}157615771578/*1579*----------------------------------------------------------------------1580*1581* SVGA3D_WaitForQuery--1582*1583* Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space1584* for it in the FIFO. This doesn't actually wait for the query to1585* finish but instead tells the host to start a wait at the driver1586* level. The caller can wait on the status variable in the1587* guestPtr memory or send an insert fence instruction after this1588* command and wait on the fence.1589*1590* Results:1591* None.1592*1593* Side effects:1594* Commits space in the FIFO memory.1595*1596*----------------------------------------------------------------------1597*/15981599enum pipe_error1600SVGA3D_WaitForQuery(struct svga_winsys_context *swc,1601SVGA3dQueryType type, // IN1602struct svga_winsys_buffer *buffer) // IN/OUT1603{1604SVGA3dCmdWaitForQuery *cmd;16051606if (swc->have_gb_objects)1607return SVGA3D_WaitForGBQuery(swc, type, buffer);16081609cmd = SVGA3D_FIFOReserve(swc,1610SVGA_3D_CMD_WAIT_FOR_QUERY,1611sizeof *cmd,16121);1613if (!cmd)1614return PIPE_ERROR_OUT_OF_MEMORY;16151616cmd->cid = swc->cid;1617cmd->type = type;16181619swc->region_relocation(swc, &cmd->guestResult, buffer, 0,1620SVGA_RELOC_READ | SVGA_RELOC_WRITE);16211622swc->commit(swc);16231624return PIPE_OK;1625}162616271628enum pipe_error1629SVGA3D_BindGBShader(struct svga_winsys_context *swc,1630struct svga_winsys_gb_shader *gbshader)1631{1632SVGA3dCmdBindGBShader *cmd =1633SVGA3D_FIFOReserve(swc,1634SVGA_3D_CMD_BIND_GB_SHADER,1635sizeof *cmd,16362); /* two relocations */16371638if (!cmd)1639return PIPE_ERROR_OUT_OF_MEMORY;16401641swc->shader_relocation(swc, &cmd->shid, &cmd->mobid,1642&cmd->offsetInBytes, gbshader, 0);16431644swc->commit(swc);16451646return PIPE_OK;1647}164816491650enum pipe_error1651SVGA3D_SetGBShader(struct svga_winsys_context *swc,1652SVGA3dShaderType type, // IN1653struct svga_winsys_gb_shader *gbshader)1654{1655SVGA3dCmdSetShader *cmd;16561657assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS);16581659cmd = SVGA3D_FIFOReserve(swc,1660SVGA_3D_CMD_SET_SHADER,1661sizeof *cmd,16622); /* two relocations */1663if (!cmd)1664return PIPE_ERROR_OUT_OF_MEMORY;16651666cmd->cid = swc->cid;1667cmd->type = type;1668if (gbshader)1669swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader, 0);1670else1671cmd->shid = SVGA_ID_INVALID;1672swc->commit(swc);16731674return PIPE_OK;1675}167616771678/**1679* \param flags mask of SVGA_RELOC_READ / _WRITE1680*/1681enum pipe_error1682SVGA3D_BindGBSurface(struct svga_winsys_context *swc,1683struct svga_winsys_surface *surface)1684{1685SVGA3dCmdBindGBSurface *cmd =1686SVGA3D_FIFOReserve(swc,1687SVGA_3D_CMD_BIND_GB_SURFACE,1688sizeof *cmd,16892); /* two relocations */16901691if (!cmd)1692return PIPE_ERROR_OUT_OF_MEMORY;16931694swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface,1695SVGA_RELOC_READ);16961697swc->commit(swc);16981699return PIPE_OK;1700}170117021703/**1704* Update an image in a guest-backed surface.1705* (Inform the device that the guest-contents have been updated.)1706*/1707enum pipe_error1708SVGA3D_UpdateGBImage(struct svga_winsys_context *swc,1709struct svga_winsys_surface *surface,1710const SVGA3dBox *box,1711unsigned face, unsigned mipLevel)17121713{1714SVGA3dCmdUpdateGBImage *cmd =1715SVGA3D_FIFOReserve(swc,1716SVGA_3D_CMD_UPDATE_GB_IMAGE,1717sizeof *cmd,17181); /* one relocation */17191720if (!cmd)1721return PIPE_ERROR_OUT_OF_MEMORY;17221723swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,1724SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);1725cmd->image.face = face;1726cmd->image.mipmap = mipLevel;1727cmd->box = *box;17281729swc->commit(swc);1730swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;17311732return PIPE_OK;1733}173417351736/**1737* Update an entire guest-backed surface.1738* (Inform the device that the guest-contents have been updated.)1739*/1740enum pipe_error1741SVGA3D_UpdateGBSurface(struct svga_winsys_context *swc,1742struct svga_winsys_surface *surface)1743{1744SVGA3dCmdUpdateGBSurface *cmd =1745SVGA3D_FIFOReserve(swc,1746SVGA_3D_CMD_UPDATE_GB_SURFACE,1747sizeof *cmd,17481); /* one relocation */17491750if (!cmd)1751return PIPE_ERROR_OUT_OF_MEMORY;17521753swc->surface_relocation(swc, &cmd->sid, NULL, surface,1754SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);17551756swc->commit(swc);1757swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;17581759return PIPE_OK;1760}176117621763/**1764* Readback an image in a guest-backed surface.1765* (Request the device to flush the dirty contents into the guest.)1766*/1767enum pipe_error1768SVGA3D_ReadbackGBImage(struct svga_winsys_context *swc,1769struct svga_winsys_surface *surface,1770unsigned face, unsigned mipLevel)1771{1772SVGA3dCmdReadbackGBImage *cmd =1773SVGA3D_FIFOReserve(swc,1774SVGA_3D_CMD_READBACK_GB_IMAGE,1775sizeof *cmd,17761); /* one relocation */17771778if (!cmd)1779return PIPE_ERROR_OUT_OF_MEMORY;17801781swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,1782SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);1783cmd->image.face = face;1784cmd->image.mipmap = mipLevel;17851786swc->commit(swc);1787swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;17881789return PIPE_OK;1790}179117921793/**1794* Readback an entire guest-backed surface.1795* (Request the device to flush the dirty contents into the guest.)1796*/1797enum pipe_error1798SVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc,1799struct svga_winsys_surface *surface)1800{1801SVGA3dCmdReadbackGBSurface *cmd =1802SVGA3D_FIFOReserve(swc,1803SVGA_3D_CMD_READBACK_GB_SURFACE,1804sizeof *cmd,18051); /* one relocation */18061807if (!cmd)1808return PIPE_ERROR_OUT_OF_MEMORY;18091810swc->surface_relocation(swc, &cmd->sid, NULL, surface,1811SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);18121813swc->commit(swc);1814swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;18151816return PIPE_OK;1817}181818191820enum pipe_error1821SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc,1822struct svga_winsys_surface *surface,1823unsigned face, unsigned mipLevel,1824const SVGA3dBox *box,1825bool invertBox)1826{1827SVGA3dCmdReadbackGBImagePartial *cmd =1828SVGA3D_FIFOReserve(swc,1829SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL,1830sizeof *cmd,18311); /* one relocation */1832if (!cmd)1833return PIPE_ERROR_OUT_OF_MEMORY;18341835swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,1836SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);1837cmd->image.face = face;1838cmd->image.mipmap = mipLevel;1839cmd->box = *box;1840cmd->invertBox = invertBox;18411842swc->commit(swc);1843swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;18441845return PIPE_OK;1846}184718481849enum pipe_error1850SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc,1851struct svga_winsys_surface *surface,1852unsigned face, unsigned mipLevel,1853const SVGA3dBox *box,1854bool invertBox)1855{1856SVGA3dCmdInvalidateGBImagePartial *cmd =1857SVGA3D_FIFOReserve(swc,1858SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL,1859sizeof *cmd,18601); /* one relocation */1861if (!cmd)1862return PIPE_ERROR_OUT_OF_MEMORY;18631864swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,1865SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);1866cmd->image.face = face;1867cmd->image.mipmap = mipLevel;1868cmd->box = *box;1869cmd->invertBox = invertBox;18701871swc->commit(swc);18721873return PIPE_OK;1874}18751876enum pipe_error1877SVGA3D_InvalidateGBSurface(struct svga_winsys_context *swc,1878struct svga_winsys_surface *surface)1879{1880SVGA3dCmdInvalidateGBSurface *cmd =1881SVGA3D_FIFOReserve(swc,1882SVGA_3D_CMD_INVALIDATE_GB_SURFACE,1883sizeof *cmd,18841); /* one relocation */1885if (!cmd)1886return PIPE_ERROR_OUT_OF_MEMORY;18871888swc->surface_relocation(swc, &cmd->sid, NULL, surface,1889SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);1890swc->commit(swc);18911892return PIPE_OK;1893}18941895enum pipe_error1896SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,1897unsigned regStart,1898unsigned numRegs,1899SVGA3dShaderType shaderType,1900SVGA3dShaderConstType constType,1901const void *values)1902{1903SVGA3dCmdSetGBShaderConstInline *cmd;19041905assert(numRegs > 0);19061907cmd = SVGA3D_FIFOReserve(swc,1908SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE,1909sizeof *cmd + numRegs * sizeof(float[4]),19100); /* no relocations */1911if (!cmd)1912return PIPE_ERROR_OUT_OF_MEMORY;19131914cmd->cid = swc->cid;1915cmd->regStart = regStart;1916cmd->shaderType = shaderType;1917cmd->constType = constType;19181919memcpy(&cmd[1], values, numRegs * sizeof(float[4]));19201921swc->commit(swc);19221923return PIPE_OK;1924}192519261927