Home | History | Annotate | Download | only in svga
      1 /**********************************************************
      2  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  **********************************************************/
     25 
     26 /**
     27  * svga_cmd.c --
     28  *
     29  *      Command construction utility for the SVGA3D protocol used by
     30  *      the VMware SVGA device, based on the svgautil library.
     31  */
     32 
     33 #include "svga_winsys.h"
     34 #include "svga_resource_buffer.h"
     35 #include "svga_resource_texture.h"
     36 #include "svga_surface.h"
     37 #include "svga_cmd.h"
     38 
     39 /*
     40  *----------------------------------------------------------------------
     41  *
     42  * surface_to_surfaceid --
     43  *
     44  *      Utility function for surface ids.
     45  *      Can handle null surface. Does a surface_reallocation so you need
     46  *      to have allocated the fifo space before converting.
     47  *
     48  * Results:
     49  *      id is filled out.
     50  *
     51  * Side effects:
     52  *      One surface relocation is performed for texture handle.
     53  *
     54  *----------------------------------------------------------------------
     55  */
     56 
     57 static INLINE
     58 void surface_to_surfaceid(struct svga_winsys_context *swc, // IN
     59                           struct pipe_surface *surface,    // IN
     60                           SVGA3dSurfaceImageId *id,        // OUT
     61                           unsigned flags)                  // IN
     62 {
     63    if(surface) {
     64       struct svga_surface *s = svga_surface(surface);
     65       swc->surface_relocation(swc, &id->sid, s->handle, flags);
     66       id->face = s->real_face; /* faces have the same order */
     67       id->mipmap = s->real_level;
     68    }
     69    else {
     70       swc->surface_relocation(swc, &id->sid, NULL, flags);
     71       id->face = 0;
     72       id->mipmap = 0;
     73    }
     74 }
     75 
     76 
     77 /*
     78  *----------------------------------------------------------------------
     79  *
     80  * SVGA3D_FIFOReserve --
     81  *
     82  *      Reserve space for an SVGA3D FIFO command.
     83  *
     84  *      The 2D SVGA commands have been around for a while, so they
     85  *      have a rather asymmetric structure. The SVGA3D protocol is
     86  *      more uniform: each command begins with a header containing the
     87  *      command number and the full size.
     88  *
     89  *      This is a convenience wrapper around SVGA_FIFOReserve. We
     90  *      reserve space for the whole command, and write the header.
     91  *
     92  *      This function must be paired with SVGA_FIFOCommitAll().
     93  *
     94  * Results:
     95  *      Returns a pointer to the space reserved for command-specific
     96  *      data. It must be 'cmdSize' bytes long.
     97  *
     98  * Side effects:
     99  *      Begins a FIFO reservation.
    100  *
    101  *----------------------------------------------------------------------
    102  */
    103 
    104 void *
    105 SVGA3D_FIFOReserve(struct svga_winsys_context *swc,
    106                    uint32 cmd,       // IN
    107                    uint32 cmdSize,   // IN
    108                    uint32 nr_relocs) // IN
    109 {
    110    SVGA3dCmdHeader *header;
    111 
    112    header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs);
    113    if(!header)
    114       return NULL;
    115 
    116    header->id = cmd;
    117    header->size = cmdSize;
    118 
    119    return &header[1];
    120 }
    121 
    122 
    123 void
    124 SVGA_FIFOCommitAll(struct svga_winsys_context *swc)
    125 {
    126    swc->commit(swc);
    127 }
    128 
    129 
    130 /*
    131  *----------------------------------------------------------------------
    132  *
    133  * SVGA3D_DefineContext --
    134  *
    135  *      Create a new context, to be referred to with the provided ID.
    136  *
    137  *      Context objects encapsulate all render state, and shader
    138  *      objects are per-context.
    139  *
    140  *      Surfaces are not per-context. The same surface can be shared
    141  *      between multiple contexts, and surface operations can occur
    142  *      without a context.
    143  *
    144  *      If the provided context ID already existed, it is redefined.
    145  *
    146  *      Context IDs are arbitrary small non-negative integers,
    147  *      global to the entire SVGA device.
    148  *
    149  * Results:
    150  *      None.
    151  *
    152  * Side effects:
    153  *      None.
    154  *
    155  *----------------------------------------------------------------------
    156  */
    157 
    158 enum pipe_error
    159 SVGA3D_DefineContext(struct svga_winsys_context *swc)  // IN
    160 {
    161    SVGA3dCmdDefineContext *cmd;
    162 
    163    cmd = SVGA3D_FIFOReserve(swc,
    164                             SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0);
    165    if(!cmd)
    166       return PIPE_ERROR_OUT_OF_MEMORY;
    167 
    168    cmd->cid = swc->cid;
    169 
    170    swc->commit(swc);
    171 
    172    return PIPE_OK;
    173 }
    174 
    175 
    176 /*
    177  *----------------------------------------------------------------------
    178  *
    179  * SVGA3D_DestroyContext --
    180  *
    181  *      Delete a context created with SVGA3D_DefineContext.
    182  *
    183  * Results:
    184  *      None.
    185  *
    186  * Side effects:
    187  *      None.
    188  *
    189  *----------------------------------------------------------------------
    190  */
    191 
    192 enum pipe_error
    193 SVGA3D_DestroyContext(struct svga_winsys_context *swc)  // IN
    194 {
    195    SVGA3dCmdDestroyContext *cmd;
    196 
    197    cmd = SVGA3D_FIFOReserve(swc,
    198                             SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0);
    199    if(!cmd)
    200       return PIPE_ERROR_OUT_OF_MEMORY;
    201 
    202    cmd->cid = swc->cid;
    203 
    204    swc->commit(swc);
    205 
    206    return PIPE_OK;
    207 }
    208 
    209 
    210 /*
    211  *----------------------------------------------------------------------
    212  *
    213  * SVGA3D_BeginDefineSurface --
    214  *
    215  *      Begin a SURFACE_DEFINE command. This reserves space for it in
    216  *      the FIFO, and returns pointers to the command's faces and
    217  *      mipsizes arrays.
    218  *
    219  *      This function must be paired with SVGA_FIFOCommitAll().
    220  *      The faces and mipSizes arrays are initialized to zero.
    221  *
    222  *      This creates a "surface" object in the SVGA3D device,
    223  *      with the provided surface ID (sid). Surfaces are generic
    224  *      containers for host VRAM objects like textures, vertex
    225  *      buffers, and depth/stencil buffers.
    226  *
    227  *      Surfaces are hierarchical:
    228  *
    229  *        - Surface may have multiple faces (for cube maps)
    230  *
    231  *          - Each face has a list of mipmap levels
    232  *
    233  *             - Each mipmap image may have multiple volume
    234  *               slices, if the image is three dimensional.
    235  *
    236  *                - Each slice is a 2D array of 'blocks'
    237  *
    238  *                   - Each block may be one or more pixels.
    239  *                     (Usually 1, more for DXT or YUV formats.)
    240  *
    241  *      Surfaces are generic host VRAM objects. The SVGA3D device
    242  *      may optimize surfaces according to the format they were
    243  *      created with, but this format does not limit the ways in
    244  *      which the surface may be used. For example, a depth surface
    245  *      can be used as a texture, or a floating point image may
    246  *      be used as a vertex buffer. Some surface usages may be
    247  *      lower performance, due to software emulation, but any
    248  *      usage should work with any surface.
    249  *
    250  *      If 'sid' is already defined, the old surface is deleted
    251  *      and this new surface replaces it.
    252  *
    253  *      Surface IDs are arbitrary small non-negative integers,
    254  *      global to the entire SVGA device.
    255  *
    256  * Results:
    257  *      Returns pointers to arrays allocated in the FIFO for 'faces'
    258  *      and 'mipSizes'.
    259  *
    260  * Side effects:
    261  *      Begins a FIFO reservation.
    262  *
    263  *----------------------------------------------------------------------
    264  */
    265 
    266 enum pipe_error
    267 SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
    268                           struct svga_winsys_surface *sid, // IN
    269                           SVGA3dSurfaceFlags flags,    // IN
    270                           SVGA3dSurfaceFormat format,  // IN
    271                           SVGA3dSurfaceFace **faces,   // OUT
    272                           SVGA3dSize **mipSizes,       // OUT
    273                           uint32 numMipSizes)          // IN
    274 {
    275    SVGA3dCmdDefineSurface *cmd;
    276 
    277    cmd = SVGA3D_FIFOReserve(swc,
    278                             SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +
    279                             sizeof **mipSizes * numMipSizes, 1);
    280    if(!cmd)
    281       return PIPE_ERROR_OUT_OF_MEMORY;
    282 
    283    swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE);
    284    cmd->surfaceFlags = flags;
    285    cmd->format = format;
    286 
    287    *faces = &cmd->face[0];
    288    *mipSizes = (SVGA3dSize*) &cmd[1];
    289 
    290    memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);
    291    memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);
    292 
    293    return PIPE_OK;
    294 }
    295 
    296 
    297 /*
    298  *----------------------------------------------------------------------
    299  *
    300  * SVGA3D_DefineSurface2D --
    301  *
    302  *      This is a simplified version of SVGA3D_BeginDefineSurface(),
    303  *      which does not support cube maps, mipmaps, or volume textures.
    304  *
    305  * Results:
    306  *      None.
    307  *
    308  * Side effects:
    309  *      None.
    310  *
    311  *----------------------------------------------------------------------
    312  */
    313 
    314 enum pipe_error
    315 SVGA3D_DefineSurface2D(struct svga_winsys_context *swc,    // IN
    316                        struct svga_winsys_surface *sid, // IN
    317                        uint32 width,                // IN
    318                        uint32 height,               // IN
    319                        SVGA3dSurfaceFormat format)  // IN
    320 {
    321    SVGA3dSize *mipSizes;
    322    SVGA3dSurfaceFace *faces;
    323    enum pipe_error ret;
    324 
    325    ret = SVGA3D_BeginDefineSurface(swc,
    326                                    sid, 0, format, &faces, &mipSizes, 1);
    327    if(ret != PIPE_OK)
    328       return ret;
    329 
    330    faces[0].numMipLevels = 1;
    331 
    332    mipSizes[0].width = width;
    333    mipSizes[0].height = height;
    334    mipSizes[0].depth = 1;
    335 
    336    swc->commit(swc);;
    337 
    338    return PIPE_OK;
    339 }
    340 
    341 
    342 /*
    343  *----------------------------------------------------------------------
    344  *
    345  * SVGA3D_DestroySurface --
    346  *
    347  *      Release the host VRAM encapsulated by a particular surface ID.
    348  *
    349  * Results:
    350  *      None.
    351  *
    352  * Side effects:
    353  *      None.
    354  *
    355  *----------------------------------------------------------------------
    356  */
    357 
    358 enum pipe_error
    359 SVGA3D_DestroySurface(struct svga_winsys_context *swc,
    360                       struct svga_winsys_surface *sid)  // IN
    361 {
    362    SVGA3dCmdDestroySurface *cmd;
    363 
    364    cmd = SVGA3D_FIFOReserve(swc,
    365                             SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);
    366    if(!cmd)
    367       return PIPE_ERROR_OUT_OF_MEMORY;
    368 
    369    swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ);
    370    swc->commit(swc);;
    371 
    372    return PIPE_OK;
    373 }
    374 
    375 
    376 /*
    377  *----------------------------------------------------------------------
    378  *
    379  * SVGA3D_SurfaceDMA--
    380  *
    381  *      Emit a SURFACE_DMA command.
    382  *
    383  *      When the SVGA3D device asynchronously processes this FIFO
    384  *      command, a DMA operation is performed between host VRAM and
    385  *      a generic SVGAGuestPtr. The guest pointer may refer to guest
    386  *      VRAM (provided by the SVGA PCI device) or to guest system
    387  *      memory that has been set up as a Guest Memory Region (GMR)
    388  *      by the SVGA device.
    389  *
    390  *      The guest's DMA buffer must remain valid (not freed, paged out,
    391  *      or overwritten) until the host has finished processing this
    392  *      command. The guest can determine that the host has finished
    393  *      by using the SVGA device's FIFO Fence mechanism.
    394  *
    395  *      The guest's image buffer can be an arbitrary size and shape.
    396  *      Guest image data is interpreted according to the SVGA3D surface
    397  *      format specified when the surface was defined.
    398  *
    399  *      The caller may optionally define the guest image's pitch.
    400  *      guestImage->pitch can either be zero (assume image is tightly
    401  *      packed) or it must be the number of bytes between vertically
    402  *      adjacent image blocks.
    403  *
    404  *      The provided copybox list specifies which regions of the source
    405  *      image are to be copied, and where they appear on the destination.
    406  *
    407  *      NOTE: srcx/srcy are always on the guest image and x/y are
    408  *      always on the host image, regardless of the actual transfer
    409  *      direction!
    410  *
    411  *      For efficiency, the SVGA3D device is free to copy more data
    412  *      than specified. For example, it may round copy boxes outwards
    413  *      such that they lie on particular alignment boundaries.
    414  *
    415  *----------------------------------------------------------------------
    416  */
    417 
    418 enum pipe_error
    419 SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
    420                   struct svga_transfer *st,         // IN
    421                   SVGA3dTransferType transfer,      // IN
    422                   const SVGA3dCopyBox *boxes,       // IN
    423                   uint32 numBoxes,                  // IN
    424                   SVGA3dSurfaceDMAFlags flags)      // IN
    425 {
    426    struct svga_texture *texture = svga_texture(st->base.resource);
    427    SVGA3dCmdSurfaceDMA *cmd;
    428    SVGA3dCmdSurfaceDMASuffix *pSuffix;
    429    uint32 boxesSize = sizeof *boxes * numBoxes;
    430    unsigned region_flags;
    431    unsigned surface_flags;
    432 
    433    if(transfer == SVGA3D_WRITE_HOST_VRAM) {
    434       region_flags = SVGA_RELOC_READ;
    435       surface_flags = SVGA_RELOC_WRITE;
    436    }
    437    else if(transfer == SVGA3D_READ_HOST_VRAM) {
    438       region_flags = SVGA_RELOC_WRITE;
    439       surface_flags = SVGA_RELOC_READ;
    440    }
    441    else {
    442       assert(0);
    443       return PIPE_ERROR_BAD_INPUT;
    444    }
    445 
    446    cmd = SVGA3D_FIFOReserve(swc,
    447                             SVGA_3D_CMD_SURFACE_DMA,
    448                             sizeof *cmd + boxesSize + sizeof *pSuffix,
    449                             2);
    450    if(!cmd)
    451       return PIPE_ERROR_OUT_OF_MEMORY;
    452 
    453    swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
    454    cmd->guest.pitch = st->base.stride;
    455 
    456    swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
    457    cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
    458    cmd->host.mipmap = st->base.level;
    459 
    460    cmd->transfer = transfer;
    461 
    462    memcpy(&cmd[1], boxes, boxesSize);
    463 
    464    pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
    465    pSuffix->suffixSize = sizeof *pSuffix;
    466    pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
    467    pSuffix->flags = flags;
    468 
    469    swc->commit(swc);
    470 
    471    return PIPE_OK;
    472 }
    473 
    474 
    475 enum pipe_error
    476 SVGA3D_BufferDMA(struct svga_winsys_context *swc,
    477                  struct svga_winsys_buffer *guest,
    478                  struct svga_winsys_surface *host,
    479                  SVGA3dTransferType transfer,      // IN
    480                  uint32 size,                      // IN
    481                  uint32 guest_offset,              // IN
    482                  uint32 host_offset,               // IN
    483                  SVGA3dSurfaceDMAFlags flags)      // IN
    484 {
    485    SVGA3dCmdSurfaceDMA *cmd;
    486    SVGA3dCopyBox *box;
    487    SVGA3dCmdSurfaceDMASuffix *pSuffix;
    488    unsigned region_flags;
    489    unsigned surface_flags;
    490 
    491    if(transfer == SVGA3D_WRITE_HOST_VRAM) {
    492       region_flags = SVGA_RELOC_READ;
    493       surface_flags = SVGA_RELOC_WRITE;
    494    }
    495    else if(transfer == SVGA3D_READ_HOST_VRAM) {
    496       region_flags = SVGA_RELOC_WRITE;
    497       surface_flags = SVGA_RELOC_READ;
    498    }
    499    else {
    500       assert(0);
    501       return PIPE_ERROR_BAD_INPUT;
    502    }
    503 
    504    cmd = SVGA3D_FIFOReserve(swc,
    505                             SVGA_3D_CMD_SURFACE_DMA,
    506                             sizeof *cmd + sizeof *box + sizeof *pSuffix,
    507                             2);
    508    if(!cmd)
    509       return PIPE_ERROR_OUT_OF_MEMORY;
    510 
    511    swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
    512    cmd->guest.pitch = 0;
    513 
    514    swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
    515    cmd->host.face = 0;
    516    cmd->host.mipmap = 0;
    517 
    518    cmd->transfer = transfer;
    519 
    520    box = (SVGA3dCopyBox *)&cmd[1];
    521    box->x = host_offset;
    522    box->y = 0;
    523    box->z = 0;
    524    box->w = size;
    525    box->h = 1;
    526    box->d = 1;
    527    box->srcx = guest_offset;
    528    box->srcy = 0;
    529    box->srcz = 0;
    530 
    531    pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
    532    pSuffix->suffixSize = sizeof *pSuffix;
    533    pSuffix->maximumOffset = guest_offset + size;
    534    pSuffix->flags = flags;
    535 
    536    swc->commit(swc);
    537 
    538    return PIPE_OK;
    539 }
    540 
    541 
    542 /*
    543  *----------------------------------------------------------------------
    544  *
    545  * SVGA3D_SetRenderTarget --
    546  *
    547  *      Bind a surface object to a particular render target attachment
    548  *      point on the current context. Render target attachment points
    549  *      exist for color buffers, a depth buffer, and a stencil buffer.
    550  *
    551  *      The SVGA3D device is quite lenient about the types of surfaces
    552  *      that may be used as render targets. The color buffers must
    553  *      all be the same size, but the depth and stencil buffers do not
    554  *      have to be the same size as the color buffer. All attachments
    555  *      are optional.
    556  *
    557  *      Some combinations of render target formats may require software
    558  *      emulation, depending on the capabilities of the host graphics
    559  *      API and graphics hardware.
    560  *
    561  * Results:
    562  *      None.
    563  *
    564  * Side effects:
    565  *      None.
    566  *
    567  *----------------------------------------------------------------------
    568  */
    569 
    570 enum pipe_error
    571 SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
    572                        SVGA3dRenderTargetType type,   // IN
    573                        struct pipe_surface *surface)  // IN
    574 {
    575    SVGA3dCmdSetRenderTarget *cmd;
    576 
    577    cmd = SVGA3D_FIFOReserve(swc,
    578                             SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);
    579    if(!cmd)
    580       return PIPE_ERROR_OUT_OF_MEMORY;
    581 
    582 
    583    cmd->cid = swc->cid;
    584 
    585    cmd->type = type;
    586 
    587    surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
    588 
    589    swc->commit(swc);
    590 
    591    return PIPE_OK;
    592 }
    593 
    594 
    595 
    596 
    597 
    598 
    599 /*
    600  *----------------------------------------------------------------------
    601  *
    602  * SVGA3D_DefineShader --
    603  *
    604  *      Upload the bytecode for a new shader. The bytecode is "SVGA3D
    605  *      format", which is theoretically a binary-compatible superset
    606  *      of Microsoft's DirectX shader bytecode. In practice, the
    607  *      SVGA3D bytecode doesn't yet have any extensions to DirectX's
    608  *      bytecode format.
    609  *
    610  *      The SVGA3D device supports shader models 1.1 through 2.0.
    611  *
    612  *      The caller chooses a shader ID (small positive integer) by
    613  *      which this shader will be identified in future commands. This
    614  *      ID is in a namespace which is per-context and per-shader-type.
    615  *
    616  *      'bytecodeLen' is specified in bytes. It must be a multiple of 4.
    617  *
    618  * Results:
    619  *      None.
    620  *
    621  * Side effects:
    622  *      None.
    623  *
    624  *----------------------------------------------------------------------
    625  */
    626 
    627 enum pipe_error
    628 SVGA3D_DefineShader(struct svga_winsys_context *swc,
    629                     uint32 shid,                  // IN
    630                     SVGA3dShaderType type,        // IN
    631                     const uint32 *bytecode,       // IN
    632                     uint32 bytecodeLen)           // IN
    633 {
    634    SVGA3dCmdDefineShader *cmd;
    635 
    636    assert(bytecodeLen % 4 == 0);
    637 
    638    cmd = SVGA3D_FIFOReserve(swc,
    639                             SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,
    640                             0);
    641    if(!cmd)
    642       return PIPE_ERROR_OUT_OF_MEMORY;
    643 
    644    cmd->cid = swc->cid;
    645    cmd->shid = shid;
    646    cmd->type = type;
    647    memcpy(&cmd[1], bytecode, bytecodeLen);
    648    swc->commit(swc);
    649 
    650    return PIPE_OK;
    651 }
    652 
    653 
    654 /*
    655  *----------------------------------------------------------------------
    656  *
    657  * SVGA3D_DestroyShader --
    658  *
    659  *      Delete a shader that was created by SVGA3D_DefineShader. If
    660  *      the shader was the current vertex or pixel shader for its
    661  *      context, rendering results are undefined until a new shader is
    662  *      bound.
    663  *
    664  * Results:
    665  *      None.
    666  *
    667  * Side effects:
    668  *      None.
    669  *
    670  *----------------------------------------------------------------------
    671  */
    672 
    673 enum pipe_error
    674 SVGA3D_DestroyShader(struct svga_winsys_context *swc,
    675                      uint32 shid,            // IN
    676                      SVGA3dShaderType type)  // IN
    677 {
    678    SVGA3dCmdDestroyShader *cmd;
    679 
    680    cmd = SVGA3D_FIFOReserve(swc,
    681                             SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,
    682                             0);
    683    if(!cmd)
    684       return PIPE_ERROR_OUT_OF_MEMORY;
    685 
    686    cmd->cid = swc->cid;
    687    cmd->shid = shid;
    688    cmd->type = type;
    689    swc->commit(swc);
    690 
    691    return PIPE_OK;
    692 }
    693 
    694 
    695 /*
    696  *----------------------------------------------------------------------
    697  *
    698  * SVGA3D_SetShaderConst --
    699  *
    700  *      Set the value of a shader constant.
    701  *
    702  *      Shader constants are analogous to uniform variables in GLSL,
    703  *      except that they belong to the render context rather than to
    704  *      an individual shader.
    705  *
    706  *      Constants may have one of three types: A 4-vector of floats,
    707  *      a 4-vector of integers, or a single boolean flag.
    708  *
    709  * Results:
    710  *      None.
    711  *
    712  * Side effects:
    713  *      None.
    714  *
    715  *----------------------------------------------------------------------
    716  */
    717 
    718 enum pipe_error
    719 SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
    720                       uint32 reg,                   // IN
    721                       SVGA3dShaderType type,        // IN
    722                       SVGA3dShaderConstType ctype,  // IN
    723                       const void *value)            // IN
    724 {
    725    SVGA3dCmdSetShaderConst *cmd;
    726 
    727    cmd = SVGA3D_FIFOReserve(swc,
    728                             SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,
    729                             0);
    730    if(!cmd)
    731       return PIPE_ERROR_OUT_OF_MEMORY;
    732 
    733    cmd->cid = swc->cid;
    734    cmd->reg = reg;
    735    cmd->type = type;
    736    cmd->ctype = ctype;
    737 
    738    switch (ctype) {
    739 
    740    case SVGA3D_CONST_TYPE_FLOAT:
    741    case SVGA3D_CONST_TYPE_INT:
    742       memcpy(&cmd->values, value, sizeof cmd->values);
    743       break;
    744 
    745    case SVGA3D_CONST_TYPE_BOOL:
    746       memset(&cmd->values, 0, sizeof cmd->values);
    747       cmd->values[0] = *(uint32*)value;
    748       break;
    749 
    750    default:
    751       assert(0);
    752       break;
    753 
    754    }
    755    swc->commit(swc);
    756 
    757    return PIPE_OK;
    758 }
    759 
    760 
    761 /*
    762  *----------------------------------------------------------------------
    763  *
    764  * SVGA3D_SetShaderConsts --
    765  *
    766  *      Set the value of successive shader constants.
    767  *
    768  *      Shader constants are analogous to uniform variables in GLSL,
    769  *      except that they belong to the render context rather than to
    770  *      an individual shader.
    771  *
    772  *      Constants may have one of three types: A 4-vector of floats,
    773  *      a 4-vector of integers, or a single boolean flag.
    774  *
    775  * Results:
    776  *      None.
    777  *
    778  * Side effects:
    779  *      None.
    780  *
    781  *----------------------------------------------------------------------
    782  */
    783 
    784 enum pipe_error
    785 SVGA3D_SetShaderConsts(struct svga_winsys_context *swc,
    786                         uint32 reg,                   // IN
    787                         uint32 numRegs,               // IN
    788                         SVGA3dShaderType type,        // IN
    789                         SVGA3dShaderConstType ctype,  // IN
    790                         const void *values)           // IN
    791 {
    792    SVGA3dCmdSetShaderConst *cmd;
    793 
    794    cmd = SVGA3D_FIFOReserve(swc,
    795                             SVGA_3D_CMD_SET_SHADER_CONST,
    796                             sizeof *cmd + (numRegs - 1) * sizeof cmd->values,
    797                             0);
    798    if(!cmd)
    799       return PIPE_ERROR_OUT_OF_MEMORY;
    800 
    801    cmd->cid = swc->cid;
    802    cmd->reg = reg;
    803    cmd->type = type;
    804    cmd->ctype = ctype;
    805 
    806    memcpy(&cmd->values, values, numRegs * sizeof cmd->values);
    807 
    808    swc->commit(swc);
    809 
    810    return PIPE_OK;
    811 }
    812 
    813 
    814 
    815 
    816 
    817 /*
    818  *----------------------------------------------------------------------
    819  *
    820  * SVGA3D_SetShader --
    821  *
    822  *      Switch active shaders. This binds a new vertex or pixel shader
    823  *      to the specified context.
    824  *
    825  *      A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
    826  *      back to the fixed function vertex or pixel pipeline.
    827  *
    828  * Results:
    829  *      None.
    830  *
    831  * Side effects:
    832  *      None.
    833  *
    834  *----------------------------------------------------------------------
    835  */
    836 
    837 enum pipe_error
    838 SVGA3D_SetShader(struct svga_winsys_context *swc,
    839                  SVGA3dShaderType type,  // IN
    840                  uint32 shid)            // IN
    841 {
    842    SVGA3dCmdSetShader *cmd;
    843 
    844    cmd = SVGA3D_FIFOReserve(swc,
    845                             SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
    846                             0);
    847    if(!cmd)
    848       return PIPE_ERROR_OUT_OF_MEMORY;
    849 
    850    cmd->cid = swc->cid;
    851    cmd->type = type;
    852    cmd->shid = shid;
    853    swc->commit(swc);
    854 
    855    return PIPE_OK;
    856 }
    857 
    858 
    859 /*
    860  *----------------------------------------------------------------------
    861  *
    862  * SVGA3D_BeginClear --
    863  *
    864  *      Begin a CLEAR command. This reserves space for it in the FIFO,
    865  *      and returns a pointer to the command's rectangle array.  This
    866  *      function must be paired with SVGA_FIFOCommitAll().
    867  *
    868  *      Clear is a rendering operation which fills a list of
    869  *      rectangles with constant values on all render target types
    870  *      indicated by 'flags'.
    871  *
    872  *      Clear is not affected by clipping, depth test, or other
    873  *      render state which affects the fragment pipeline.
    874  *
    875  * Results:
    876  *      None.
    877  *
    878  * Side effects:
    879  *      May write to attached render target surfaces.
    880  *
    881  *----------------------------------------------------------------------
    882  */
    883 
    884 enum pipe_error
    885 SVGA3D_BeginClear(struct svga_winsys_context *swc,
    886                   SVGA3dClearFlag flags,  // IN
    887                   uint32 color,           // IN
    888                   float depth,            // IN
    889                   uint32 stencil,         // IN
    890                   SVGA3dRect **rects,     // OUT
    891                   uint32 numRects)        // IN
    892 {
    893    SVGA3dCmdClear *cmd;
    894 
    895    cmd = SVGA3D_FIFOReserve(swc,
    896                             SVGA_3D_CMD_CLEAR,
    897                             sizeof *cmd + sizeof **rects * numRects,
    898                             0);
    899    if(!cmd)
    900       return PIPE_ERROR_OUT_OF_MEMORY;
    901 
    902    cmd->cid = swc->cid;
    903    cmd->clearFlag = flags;
    904    cmd->color = color;
    905    cmd->depth = depth;
    906    cmd->stencil = stencil;
    907    *rects = (SVGA3dRect*) &cmd[1];
    908 
    909    return PIPE_OK;
    910 }
    911 
    912 
    913 /*
    914  *----------------------------------------------------------------------
    915  *
    916  * SVGA3D_ClearRect --
    917  *
    918  *      This is a simplified version of SVGA3D_BeginClear().
    919  *
    920  * Results:
    921  *      None.
    922  *
    923  * Side effects:
    924  *      None.
    925  *
    926  *----------------------------------------------------------------------
    927  */
    928 
    929 enum pipe_error
    930 SVGA3D_ClearRect(struct svga_winsys_context *swc,
    931                  SVGA3dClearFlag flags,  // IN
    932                  uint32 color,           // IN
    933                  float depth,            // IN
    934                  uint32 stencil,         // IN
    935                  uint32 x,               // IN
    936                  uint32 y,               // IN
    937                  uint32 w,               // IN
    938                  uint32 h)               // IN
    939 {
    940    SVGA3dRect *rect;
    941    enum pipe_error ret;
    942 
    943    ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
    944    if(ret != PIPE_OK)
    945       return PIPE_ERROR_OUT_OF_MEMORY;
    946 
    947    memset(rect, 0, sizeof *rect);
    948    rect->x = x;
    949    rect->y = y;
    950    rect->w = w;
    951    rect->h = h;
    952    swc->commit(swc);
    953 
    954    return PIPE_OK;
    955 }
    956 
    957 
    958 /*
    959  *----------------------------------------------------------------------
    960  *
    961  * SVGA3D_BeginDrawPrimitives --
    962  *
    963  *      Begin a DRAW_PRIMITIVES command. This reserves space for it in
    964  *      the FIFO, and returns a pointer to the command's arrays.
    965  *      This function must be paired with SVGA_FIFOCommitAll().
    966  *
    967  *      Drawing commands consist of two variable-length arrays:
    968  *      SVGA3dVertexDecl elements declare a set of vertex buffers to
    969  *      use while rendering, and SVGA3dPrimitiveRange elements specify
    970  *      groups of primitives each with an optional index buffer.
    971  *
    972  *      The decls and ranges arrays are initialized to zero.
    973  *
    974  * Results:
    975  *      None.
    976  *
    977  * Side effects:
    978  *      May write to attached render target surfaces.
    979  *
    980  *----------------------------------------------------------------------
    981  */
    982 
    983 enum pipe_error
    984 SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
    985                            SVGA3dVertexDecl **decls,      // OUT
    986                            uint32 numVertexDecls,         // IN
    987                            SVGA3dPrimitiveRange **ranges, // OUT
    988                            uint32 numRanges)              // IN
    989 {
    990    SVGA3dCmdDrawPrimitives *cmd;
    991    SVGA3dVertexDecl *declArray;
    992    SVGA3dPrimitiveRange *rangeArray;
    993    uint32 declSize = sizeof **decls * numVertexDecls;
    994    uint32 rangeSize = sizeof **ranges * numRanges;
    995 
    996    cmd = SVGA3D_FIFOReserve(swc,
    997                             SVGA_3D_CMD_DRAW_PRIMITIVES,
    998                             sizeof *cmd + declSize + rangeSize,
    999                             numVertexDecls + numRanges);
   1000    if(!cmd)
   1001       return PIPE_ERROR_OUT_OF_MEMORY;
   1002 
   1003    cmd->cid = swc->cid;
   1004    cmd->numVertexDecls = numVertexDecls;
   1005    cmd->numRanges = numRanges;
   1006 
   1007    declArray = (SVGA3dVertexDecl*) &cmd[1];
   1008    rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
   1009 
   1010    memset(declArray, 0, declSize);
   1011    memset(rangeArray, 0, rangeSize);
   1012 
   1013    *decls = declArray;
   1014    *ranges = rangeArray;
   1015 
   1016    return PIPE_OK;
   1017 }
   1018 
   1019 
   1020 /*
   1021  *----------------------------------------------------------------------
   1022  *
   1023  * SVGA3D_BeginSurfaceCopy --
   1024  *
   1025  *      Begin a SURFACE_COPY command. This reserves space for it in
   1026  *      the FIFO, and returns a pointer to the command's arrays.  This
   1027  *      function must be paired with SVGA_FIFOCommitAll().
   1028  *
   1029  *      The box array is initialized with zeroes.
   1030  *
   1031  * Results:
   1032  *      None.
   1033  *
   1034  * Side effects:
   1035  *      Asynchronously copies a list of boxes from surface to surface.
   1036  *
   1037  *----------------------------------------------------------------------
   1038  */
   1039 
   1040 enum pipe_error
   1041 SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
   1042                         struct pipe_surface *src,    // IN
   1043                         struct pipe_surface *dest,   // IN
   1044                         SVGA3dCopyBox **boxes,       // OUT
   1045                         uint32 numBoxes)             // IN
   1046 {
   1047    SVGA3dCmdSurfaceCopy *cmd;
   1048    uint32 boxesSize = sizeof **boxes * numBoxes;
   1049 
   1050    cmd = SVGA3D_FIFOReserve(swc,
   1051                             SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
   1052                             2);
   1053    if(!cmd)
   1054       return PIPE_ERROR_OUT_OF_MEMORY;
   1055 
   1056    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
   1057    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
   1058    *boxes = (SVGA3dCopyBox*) &cmd[1];
   1059 
   1060    memset(*boxes, 0, boxesSize);
   1061 
   1062    return PIPE_OK;
   1063 }
   1064 
   1065 
   1066 /*
   1067  *----------------------------------------------------------------------
   1068  *
   1069  * SVGA3D_SurfaceStretchBlt --
   1070  *
   1071  *      Issue a SURFACE_STRETCHBLT command: an asynchronous
   1072  *      surface-to-surface blit, with scaling.
   1073  *
   1074  * Results:
   1075  *      None.
   1076  *
   1077  * Side effects:
   1078  *      Asynchronously copies one box from surface to surface.
   1079  *
   1080  *----------------------------------------------------------------------
   1081  */
   1082 
   1083 enum pipe_error
   1084 SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
   1085                          struct pipe_surface *src,    // IN
   1086                          struct pipe_surface *dest,   // IN
   1087                          SVGA3dBox *boxSrc,           // IN
   1088                          SVGA3dBox *boxDest,          // IN
   1089                          SVGA3dStretchBltMode mode)   // IN
   1090 {
   1091    SVGA3dCmdSurfaceStretchBlt *cmd;
   1092 
   1093    cmd = SVGA3D_FIFOReserve(swc,
   1094                             SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
   1095                             2);
   1096    if(!cmd)
   1097       return PIPE_ERROR_OUT_OF_MEMORY;
   1098 
   1099    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
   1100    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
   1101    cmd->boxSrc = *boxSrc;
   1102    cmd->boxDest = *boxDest;
   1103    cmd->mode = mode;
   1104    swc->commit(swc);
   1105 
   1106    return PIPE_OK;
   1107 }
   1108 
   1109 
   1110 /*
   1111  *----------------------------------------------------------------------
   1112  *
   1113  * SVGA3D_SetViewport --
   1114  *
   1115  *      Set the current context's viewport rectangle. The viewport
   1116  *      is clipped to the dimensions of the current render target,
   1117  *      then all rendering is clipped to the viewport.
   1118  *
   1119  * Results:
   1120  *      None.
   1121  *
   1122  * Side effects:
   1123  *      None.
   1124  *
   1125  *----------------------------------------------------------------------
   1126  */
   1127 
   1128 enum pipe_error
   1129 SVGA3D_SetViewport(struct svga_winsys_context *swc,
   1130                    SVGA3dRect *rect)  // IN
   1131 {
   1132    SVGA3dCmdSetViewport *cmd;
   1133 
   1134    cmd = SVGA3D_FIFOReserve(swc,
   1135                             SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
   1136                             0);
   1137    if(!cmd)
   1138       return PIPE_ERROR_OUT_OF_MEMORY;
   1139 
   1140    cmd->cid = swc->cid;
   1141    cmd->rect = *rect;
   1142    swc->commit(swc);
   1143 
   1144    return PIPE_OK;
   1145 }
   1146 
   1147 
   1148 
   1149 
   1150 /*
   1151  *----------------------------------------------------------------------
   1152  *
   1153  * SVGA3D_SetScissorRect --
   1154  *
   1155  *      Set the current context's scissor rectangle. If scissor
   1156  *      is enabled then all rendering is clipped to the scissor.
   1157  *
   1158  * Results:
   1159  *      None.
   1160  *
   1161  * Side effects:
   1162  *      None.
   1163  *
   1164  *----------------------------------------------------------------------
   1165  */
   1166 
   1167 enum pipe_error
   1168 SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
   1169                       SVGA3dRect *rect)  // IN
   1170 {
   1171    SVGA3dCmdSetScissorRect *cmd;
   1172 
   1173    cmd = SVGA3D_FIFOReserve(swc,
   1174                             SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
   1175                             0);
   1176    if(!cmd)
   1177       return PIPE_ERROR_OUT_OF_MEMORY;
   1178 
   1179    cmd->cid = swc->cid;
   1180    cmd->rect = *rect;
   1181    swc->commit(swc);
   1182 
   1183    return PIPE_OK;
   1184 }
   1185 
   1186 /*
   1187  *----------------------------------------------------------------------
   1188  *
   1189  * SVGA3D_SetClipPlane --
   1190  *
   1191  *      Set one of the current context's clip planes. If the clip
   1192  *      plane is enabled then all 3d rendering is clipped to against
   1193  *      the plane.
   1194  *
   1195  * Results:
   1196  *      None.
   1197  *
   1198  * Side effects:
   1199  *      None.
   1200  *
   1201  *----------------------------------------------------------------------
   1202  */
   1203 
   1204 enum pipe_error
   1205 SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
   1206                     uint32 index, const float *plane)
   1207 {
   1208    SVGA3dCmdSetClipPlane *cmd;
   1209 
   1210    cmd = SVGA3D_FIFOReserve(swc,
   1211                             SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
   1212                             0);
   1213    if(!cmd)
   1214       return PIPE_ERROR_OUT_OF_MEMORY;
   1215 
   1216    cmd->cid = swc->cid;
   1217    cmd->index = index;
   1218    cmd->plane[0] = plane[0];
   1219    cmd->plane[1] = plane[1];
   1220    cmd->plane[2] = plane[2];
   1221    cmd->plane[3] = plane[3];
   1222    swc->commit(swc);
   1223 
   1224    return PIPE_OK;
   1225 }
   1226 
   1227 /*
   1228  *----------------------------------------------------------------------
   1229  *
   1230  * SVGA3D_SetZRange --
   1231  *
   1232  *      Set the range of the depth buffer to use. 'min' and 'max'
   1233  *      are values between 0.0 and 1.0.
   1234  *
   1235  * Results:
   1236  *      None.
   1237  *
   1238  * Side effects:
   1239  *      None.
   1240  *
   1241  *----------------------------------------------------------------------
   1242  */
   1243 
   1244 enum pipe_error
   1245 SVGA3D_SetZRange(struct svga_winsys_context *swc,
   1246                  float zMin,  // IN
   1247                  float zMax)  // IN
   1248 {
   1249    SVGA3dCmdSetZRange *cmd;
   1250 
   1251    cmd = SVGA3D_FIFOReserve(swc,
   1252                             SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
   1253                             0);
   1254    if(!cmd)
   1255       return PIPE_ERROR_OUT_OF_MEMORY;
   1256 
   1257    cmd->cid = swc->cid;
   1258    cmd->zRange.min = zMin;
   1259    cmd->zRange.max = zMax;
   1260    swc->commit(swc);
   1261 
   1262    return PIPE_OK;
   1263 }
   1264 
   1265 
   1266 /*
   1267  *----------------------------------------------------------------------
   1268  *
   1269  * SVGA3D_BeginSetTextureState --
   1270  *
   1271  *      Begin a SETTEXTURESTATE command. This reserves space for it in
   1272  *      the FIFO, and returns a pointer to the command's texture state
   1273  *      array.  This function must be paired with SVGA_FIFOCommitAll().
   1274  *
   1275  *      This command sets rendering state which is per-texture-unit.
   1276  *
   1277  *      XXX: Individual texture states need documentation. However,
   1278  *           they are very similar to the texture states defined by
   1279  *           Direct3D. The D3D documentation is a good starting point
   1280  *           for understanding SVGA3D texture states.
   1281  *
   1282  * Results:
   1283  *      None.
   1284  *
   1285  * Side effects:
   1286  *      None.
   1287  *
   1288  *----------------------------------------------------------------------
   1289  */
   1290 
   1291 enum pipe_error
   1292 SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
   1293                             SVGA3dTextureState **states,  // OUT
   1294                             uint32 numStates)             // IN
   1295 {
   1296    SVGA3dCmdSetTextureState *cmd;
   1297 
   1298    cmd = SVGA3D_FIFOReserve(swc,
   1299                             SVGA_3D_CMD_SETTEXTURESTATE,
   1300                             sizeof *cmd + sizeof **states * numStates,
   1301                             numStates);
   1302    if(!cmd)
   1303       return PIPE_ERROR_OUT_OF_MEMORY;
   1304 
   1305    cmd->cid = swc->cid;
   1306    *states = (SVGA3dTextureState*) &cmd[1];
   1307 
   1308    return PIPE_OK;
   1309 }
   1310 
   1311 
   1312 /*
   1313  *----------------------------------------------------------------------
   1314  *
   1315  * SVGA3D_BeginSetRenderState --
   1316  *
   1317  *      Begin a SETRENDERSTATE command. This reserves space for it in
   1318  *      the FIFO, and returns a pointer to the command's texture state
   1319  *      array.  This function must be paired with SVGA_FIFOCommitAll().
   1320  *
   1321  *      This command sets rendering state which is global to the context.
   1322  *
   1323  *      XXX: Individual render states need documentation. However,
   1324  *           they are very similar to the render states defined by
   1325  *           Direct3D. The D3D documentation is a good starting point
   1326  *           for understanding SVGA3D render states.
   1327  *
   1328  * Results:
   1329  *      None.
   1330  *
   1331  * Side effects:
   1332  *      None.
   1333  *
   1334  *----------------------------------------------------------------------
   1335  */
   1336 
   1337 enum pipe_error
   1338 SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
   1339                            SVGA3dRenderState **states,  // OUT
   1340                            uint32 numStates)            // IN
   1341 {
   1342    SVGA3dCmdSetRenderState *cmd;
   1343 
   1344    cmd = SVGA3D_FIFOReserve(swc,
   1345                             SVGA_3D_CMD_SETRENDERSTATE,
   1346                             sizeof *cmd + sizeof **states * numStates,
   1347                             0);
   1348    if(!cmd)
   1349       return PIPE_ERROR_OUT_OF_MEMORY;
   1350 
   1351    cmd->cid = swc->cid;
   1352    *states = (SVGA3dRenderState*) &cmd[1];
   1353 
   1354    return PIPE_OK;
   1355 }
   1356 
   1357 
   1358 /*
   1359  *----------------------------------------------------------------------
   1360  *
   1361  * SVGA3D_BeginQuery--
   1362  *
   1363  *      Issues a SVGA_3D_CMD_BEGIN_QUERY command.
   1364  *
   1365  * Results:
   1366  *      None.
   1367  *
   1368  * Side effects:
   1369  *      Commits space in the FIFO memory.
   1370  *
   1371  *----------------------------------------------------------------------
   1372  */
   1373 
   1374 enum pipe_error
   1375 SVGA3D_BeginQuery(struct svga_winsys_context *swc,
   1376                   SVGA3dQueryType type) // IN
   1377 {
   1378    SVGA3dCmdBeginQuery *cmd;
   1379 
   1380    cmd = SVGA3D_FIFOReserve(swc,
   1381                             SVGA_3D_CMD_BEGIN_QUERY,
   1382                             sizeof *cmd,
   1383                             0);
   1384    if(!cmd)
   1385       return PIPE_ERROR_OUT_OF_MEMORY;
   1386 
   1387    cmd->cid = swc->cid;
   1388    cmd->type = type;
   1389 
   1390    swc->commit(swc);
   1391 
   1392    return PIPE_OK;
   1393 }
   1394 
   1395 
   1396 /*
   1397  *----------------------------------------------------------------------
   1398  *
   1399  * SVGA3D_EndQuery--
   1400  *
   1401  *      Issues a SVGA_3D_CMD_END_QUERY command.
   1402  *
   1403  * Results:
   1404  *      None.
   1405  *
   1406  * Side effects:
   1407  *      Commits space in the FIFO memory.
   1408  *
   1409  *----------------------------------------------------------------------
   1410  */
   1411 
   1412 enum pipe_error
   1413 SVGA3D_EndQuery(struct svga_winsys_context *swc,
   1414                 SVGA3dQueryType type,              // IN
   1415                 struct svga_winsys_buffer *buffer) // IN/OUT
   1416 {
   1417    SVGA3dCmdEndQuery *cmd;
   1418 
   1419    cmd = SVGA3D_FIFOReserve(swc,
   1420                             SVGA_3D_CMD_END_QUERY,
   1421                             sizeof *cmd,
   1422                             1);
   1423    if(!cmd)
   1424       return PIPE_ERROR_OUT_OF_MEMORY;
   1425 
   1426    cmd->cid = swc->cid;
   1427    cmd->type = type;
   1428 
   1429    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
   1430                           SVGA_RELOC_WRITE);
   1431 
   1432    swc->commit(swc);
   1433 
   1434    return PIPE_OK;
   1435 }
   1436 
   1437 
   1438 /*
   1439  *----------------------------------------------------------------------
   1440  *
   1441  * SVGA3D_WaitForQuery--
   1442  *
   1443  *      Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command.  This reserves space
   1444  *      for it in the FIFO.  This doesn't actually wait for the query to
   1445  *      finish but instead tells the host to start a wait at the driver
   1446  *      level.  The caller can wait on the status variable in the
   1447  *      guestPtr memory or send an insert fence instruction after this
   1448  *      command and wait on the fence.
   1449  *
   1450  * Results:
   1451  *      None.
   1452  *
   1453  * Side effects:
   1454  *      Commits space in the FIFO memory.
   1455  *
   1456  *----------------------------------------------------------------------
   1457  */
   1458 
   1459 enum pipe_error
   1460 SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
   1461                     SVGA3dQueryType type,              // IN
   1462                     struct svga_winsys_buffer *buffer) // IN/OUT
   1463 {
   1464    SVGA3dCmdWaitForQuery *cmd;
   1465 
   1466    cmd = SVGA3D_FIFOReserve(swc,
   1467                             SVGA_3D_CMD_WAIT_FOR_QUERY,
   1468                             sizeof *cmd,
   1469                             1);
   1470    if(!cmd)
   1471       return PIPE_ERROR_OUT_OF_MEMORY;
   1472 
   1473    cmd->cid = swc->cid;
   1474    cmd->type = type;
   1475 
   1476    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
   1477                           SVGA_RELOC_WRITE);
   1478 
   1479    swc->commit(swc);
   1480 
   1481    return PIPE_OK;
   1482 }
   1483