Home | History | Annotate | Download | only in svga
      1 /**********************************************************
      2  * Copyright 2008-2013 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  * @file svga_cmd_vgpu10.c
     28  *
     29  * Command construction utility for the vgpu10 SVGA3D protocol.
     30  *
     31  * \author Mingcheng Chen
     32  * \author Brian Paul
     33  */
     34 
     35 
     36 #include "svga_winsys.h"
     37 #include "svga_resource_buffer.h"
     38 #include "svga_resource_texture.h"
     39 #include "svga_surface.h"
     40 #include "svga_cmd.h"
     41 
     42 
     43 /**
     44  * Emit a surface relocation for RenderTargetViewId
     45  */
     46 static void
     47 view_relocation(struct svga_winsys_context *swc, // IN
     48                 struct pipe_surface *surface,    // IN
     49                 SVGA3dRenderTargetViewId *id,    // OUT
     50                 unsigned flags)
     51 {
     52    if (surface) {
     53       struct svga_surface *s = svga_surface(surface);
     54       assert(s->handle);
     55       swc->surface_relocation(swc, id, NULL, s->handle, flags);
     56    }
     57    else {
     58       swc->surface_relocation(swc, id, NULL, NULL, flags);
     59    }
     60 }
     61 
     62 
     63 /**
     64  * Emit a surface relocation for a ResourceId.
     65  */
     66 static void
     67 surface_to_resourceid(struct svga_winsys_context *swc, // IN
     68                       struct svga_winsys_surface *surface,    // IN
     69                       SVGA3dSurfaceId *sid,            // OUT
     70                       unsigned flags)                  // IN
     71 {
     72    if (surface) {
     73       swc->surface_relocation(swc, sid, NULL, surface, flags);
     74    }
     75    else {
     76       swc->surface_relocation(swc, sid, NULL, NULL, flags);
     77    }
     78 }
     79 
     80 
     81 #define SVGA3D_CREATE_COMMAND(CommandName, CommandCode) \
     82 SVGA3dCmdDX##CommandName *cmd; \
     83 { \
     84    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_##CommandCode, \
     85                             sizeof(SVGA3dCmdDX##CommandName), 0); \
     86    if (!cmd) \
     87       return PIPE_ERROR_OUT_OF_MEMORY; \
     88 }
     89 
     90 #define SVGA3D_CREATE_CMD_COUNT(CommandName, CommandCode, ElementClassName) \
     91 SVGA3dCmdDX##CommandName *cmd; \
     92 { \
     93    assert(count > 0); \
     94    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_##CommandCode, \
     95                             sizeof(SVGA3dCmdDX##CommandName) + \
     96                             count * sizeof(ElementClassName), 0); \
     97    if (!cmd) \
     98       return PIPE_ERROR_OUT_OF_MEMORY; \
     99 }
    100 
    101 #define SVGA3D_COPY_BASIC(VariableName) \
    102 { \
    103    cmd->VariableName = VariableName; \
    104 }
    105 
    106 #define SVGA3D_COPY_BASIC_2(VariableName1, VariableName2) \
    107 { \
    108    SVGA3D_COPY_BASIC(VariableName1); \
    109    SVGA3D_COPY_BASIC(VariableName2); \
    110 }
    111 
    112 #define SVGA3D_COPY_BASIC_3(VariableName1, VariableName2, VariableName3) \
    113 { \
    114    SVGA3D_COPY_BASIC_2(VariableName1, VariableName2); \
    115    SVGA3D_COPY_BASIC(VariableName3); \
    116 }
    117 
    118 #define SVGA3D_COPY_BASIC_4(VariableName1, VariableName2, VariableName3, \
    119                             VariableName4) \
    120 { \
    121    SVGA3D_COPY_BASIC_2(VariableName1, VariableName2); \
    122    SVGA3D_COPY_BASIC_2(VariableName3, VariableName4); \
    123 }
    124 
    125 #define SVGA3D_COPY_BASIC_5(VariableName1, VariableName2, VariableName3, \
    126                             VariableName4, VariableName5) \
    127 {\
    128    SVGA3D_COPY_BASIC_3(VariableName1, VariableName2, VariableName3); \
    129    SVGA3D_COPY_BASIC_2(VariableName4, VariableName5); \
    130 }
    131 
    132 #define SVGA3D_COPY_BASIC_6(VariableName1, VariableName2, VariableName3, \
    133                             VariableName4, VariableName5, VariableName6) \
    134 {\
    135    SVGA3D_COPY_BASIC_3(VariableName1, VariableName2, VariableName3); \
    136    SVGA3D_COPY_BASIC_3(VariableName4, VariableName5, VariableName6); \
    137 }
    138 
    139 #define SVGA3D_COPY_BASIC_7(VariableName1, VariableName2, VariableName3, \
    140                             VariableName4, VariableName5, VariableName6, \
    141                             VariableName7) \
    142 {\
    143    SVGA3D_COPY_BASIC_4(VariableName1, VariableName2, VariableName3, \
    144                        VariableName4); \
    145    SVGA3D_COPY_BASIC_3(VariableName5, VariableName6, VariableName7); \
    146 }
    147 
    148 #define SVGA3D_COPY_BASIC_8(VariableName1, VariableName2, VariableName3, \
    149                             VariableName4, VariableName5, VariableName6, \
    150                             VariableName7, VariableName8) \
    151 {\
    152    SVGA3D_COPY_BASIC_4(VariableName1, VariableName2, VariableName3, \
    153                        VariableName4); \
    154    SVGA3D_COPY_BASIC_4(VariableName5, VariableName6, VariableName7, \
    155                        VariableName8); \
    156 }
    157 
    158 #define SVGA3D_COPY_BASIC_9(VariableName1, VariableName2, VariableName3, \
    159                             VariableName4, VariableName5, VariableName6, \
    160                             VariableName7, VariableName8, VariableName9) \
    161 {\
    162    SVGA3D_COPY_BASIC_5(VariableName1, VariableName2, VariableName3, \
    163                        VariableName4, VariableName5); \
    164    SVGA3D_COPY_BASIC_4(VariableName6, VariableName7, VariableName8, \
    165                        VariableName9); \
    166 }
    167 
    168 
    169 enum pipe_error
    170 SVGA3D_vgpu10_PredCopyRegion(struct svga_winsys_context *swc,
    171                              struct svga_winsys_surface *dstSurf,
    172                              uint32 dstSubResource,
    173                              struct svga_winsys_surface *srcSurf,
    174                              uint32 srcSubResource,
    175                              const SVGA3dCopyBox *box)
    176 {
    177    SVGA3dCmdDXPredCopyRegion *cmd =
    178       SVGA3D_FIFOReserve(swc,
    179                          SVGA_3D_CMD_DX_PRED_COPY_REGION,
    180                          sizeof(SVGA3dCmdDXPredCopyRegion),
    181                          2);  /* two relocations */
    182    if (!cmd)
    183       return PIPE_ERROR_OUT_OF_MEMORY;
    184 
    185    swc->surface_relocation(swc, &cmd->dstSid, NULL, dstSurf, SVGA_RELOC_WRITE);
    186    swc->surface_relocation(swc, &cmd->srcSid, NULL, srcSurf, SVGA_RELOC_READ);
    187    cmd->dstSubResource = dstSubResource;
    188    cmd->srcSubResource = srcSubResource;
    189    cmd->box = *box;
    190 
    191    swc->commit(swc);
    192 
    193    return PIPE_OK;
    194 }
    195 
    196 
    197 enum pipe_error
    198 SVGA3D_vgpu10_PredCopy(struct svga_winsys_context *swc,
    199                        struct svga_winsys_surface *dstSurf,
    200                        struct svga_winsys_surface *srcSurf)
    201 {
    202    SVGA3dCmdDXPredCopy *cmd =
    203       SVGA3D_FIFOReserve(swc,
    204                          SVGA_3D_CMD_DX_PRED_COPY,
    205                          sizeof(SVGA3dCmdDXPredCopy),
    206                          2);  /* two relocations */
    207    if (!cmd)
    208       return PIPE_ERROR_OUT_OF_MEMORY;
    209 
    210    swc->surface_relocation(swc, &cmd->dstSid, NULL, dstSurf, SVGA_RELOC_WRITE);
    211    swc->surface_relocation(swc, &cmd->srcSid, NULL, srcSurf, SVGA_RELOC_READ);
    212 
    213    swc->commit(swc);
    214 
    215    return PIPE_OK;
    216 }
    217 
    218 enum pipe_error
    219 SVGA3D_vgpu10_SetViewports(struct svga_winsys_context *swc,
    220                            unsigned count,
    221                            const SVGA3dViewport *viewports)
    222 {
    223    SVGA3D_CREATE_CMD_COUNT(SetViewports, SET_VIEWPORTS, SVGA3dViewport);
    224 
    225    memcpy(cmd + 1, viewports, count * sizeof(SVGA3dViewport));
    226 
    227    swc->commit(swc);
    228    return PIPE_OK;
    229 }
    230 
    231 
    232 enum pipe_error
    233 SVGA3D_vgpu10_SetShader(struct svga_winsys_context *swc,
    234                         SVGA3dShaderType type,
    235                         struct svga_winsys_gb_shader *gbshader,
    236                         SVGA3dShaderId shaderId)
    237 {
    238    SVGA3dCmdDXSetShader *cmd = SVGA3D_FIFOReserve(swc,
    239                                                   SVGA_3D_CMD_DX_SET_SHADER,
    240                                                   sizeof *cmd,
    241                                                   1);  /* one relocation */
    242    if (!cmd)
    243       return PIPE_ERROR_OUT_OF_MEMORY;
    244 
    245    swc->shader_relocation(swc, &cmd->shaderId, NULL, NULL, gbshader, 0);
    246 
    247    cmd->type = type;
    248    cmd->shaderId = shaderId;
    249    swc->commit(swc);
    250 
    251    return PIPE_OK;
    252 }
    253 
    254 
    255 enum pipe_error
    256 SVGA3D_vgpu10_SetShaderResources(struct svga_winsys_context *swc,
    257                                  SVGA3dShaderType type,
    258                                  uint32 startView,
    259                                  unsigned count,
    260                                  const SVGA3dShaderResourceViewId ids[],
    261                                  struct svga_winsys_surface **views)
    262 {
    263    SVGA3dCmdDXSetShaderResources *cmd;
    264    SVGA3dShaderResourceViewId *cmd_ids;
    265    unsigned i;
    266 
    267    cmd = SVGA3D_FIFOReserve(swc,
    268                             SVGA_3D_CMD_DX_SET_SHADER_RESOURCES,
    269                             sizeof(SVGA3dCmdDXSetShaderResources) +
    270                             count * sizeof(SVGA3dShaderResourceViewId),
    271                             count); /* 'count' relocations */
    272    if (!cmd)
    273       return PIPE_ERROR_OUT_OF_MEMORY;
    274 
    275 
    276    cmd->type = type;
    277    cmd->startView = startView;
    278 
    279    cmd_ids = (SVGA3dShaderResourceViewId *) (cmd + 1);
    280    for (i = 0; i < count; i++) {
    281       swc->surface_relocation(swc, cmd_ids + i, NULL, views[i],
    282                               SVGA_RELOC_READ);
    283       cmd_ids[i] = ids[i];
    284    }
    285 
    286    swc->commit(swc);
    287    return PIPE_OK;
    288 }
    289 
    290 
    291 enum pipe_error
    292 SVGA3D_vgpu10_SetSamplers(struct svga_winsys_context *swc,
    293                           unsigned count,
    294                           uint32 startSampler,
    295                           SVGA3dShaderType type,
    296                           const SVGA3dSamplerId *samplerIds)
    297 {
    298    SVGA3D_CREATE_CMD_COUNT(SetSamplers, SET_SAMPLERS, SVGA3dSamplerId);
    299 
    300    SVGA3D_COPY_BASIC_2(startSampler, type);
    301    memcpy(cmd + 1, samplerIds, count * sizeof(SVGA3dSamplerId));
    302 
    303    swc->commit(swc);
    304    return PIPE_OK;
    305 }
    306 
    307 
    308 enum pipe_error
    309 SVGA3D_vgpu10_ClearRenderTargetView(struct svga_winsys_context *swc,
    310                                     struct pipe_surface *color_surf,
    311                                     const float *rgba)
    312 {
    313    SVGA3dCmdDXClearRenderTargetView *cmd;
    314    struct svga_surface *ss = svga_surface(color_surf);
    315 
    316    cmd = SVGA3D_FIFOReserve(swc,
    317                             SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW,
    318                             sizeof(SVGA3dCmdDXClearRenderTargetView),
    319                             1); /* one relocation */
    320    if (!cmd)
    321       return PIPE_ERROR_OUT_OF_MEMORY;
    322 
    323 
    324    /* NOTE: The following is pretty tricky.  We need to emit a view/surface
    325     * relocation and we have to provide a pointer to an ID which lies in
    326     * the bounds of the command space which we just allocated.  However,
    327     * we then need to overwrite it with the original RenderTargetViewId.
    328     */
    329    view_relocation(swc, color_surf, &cmd->renderTargetViewId,
    330                    SVGA_RELOC_WRITE);
    331    cmd->renderTargetViewId = ss->view_id;
    332 
    333    COPY_4V(cmd->rgba.value, rgba);
    334 
    335    swc->commit(swc);
    336    return PIPE_OK;
    337 }
    338 
    339 
    340 enum pipe_error
    341 SVGA3D_vgpu10_SetRenderTargets(struct svga_winsys_context *swc,
    342                                unsigned color_count,
    343                                struct pipe_surface **color_surfs,
    344                                struct pipe_surface *depth_stencil_surf)
    345 {
    346    const unsigned surf_count = color_count + 1;
    347    SVGA3dCmdDXSetRenderTargets *cmd;
    348    SVGA3dRenderTargetViewId *ctarget;
    349    struct svga_surface *ss;
    350    unsigned i;
    351 
    352    assert(surf_count > 0);
    353 
    354    cmd = SVGA3D_FIFOReserve(swc,
    355                             SVGA_3D_CMD_DX_SET_RENDERTARGETS,
    356                             sizeof(SVGA3dCmdDXSetRenderTargets) +
    357                             color_count * sizeof(SVGA3dRenderTargetViewId),
    358                             surf_count); /* 'surf_count' relocations */
    359    if (!cmd)
    360       return PIPE_ERROR_OUT_OF_MEMORY;
    361 
    362    /* NOTE: See earlier comment about the tricky handling of the ViewIds.
    363     */
    364 
    365    /* Depth / Stencil buffer */
    366    if (depth_stencil_surf) {
    367       ss = svga_surface(depth_stencil_surf);
    368       view_relocation(swc, depth_stencil_surf, &cmd->depthStencilViewId,
    369                       SVGA_RELOC_WRITE);
    370       cmd->depthStencilViewId = ss->view_id;
    371    }
    372    else {
    373       /* no depth/stencil buffer - still need a relocation */
    374       view_relocation(swc, NULL, &cmd->depthStencilViewId,
    375                       SVGA_RELOC_WRITE);
    376       cmd->depthStencilViewId = SVGA3D_INVALID_ID;
    377    }
    378 
    379    /* Color buffers */
    380    ctarget = (SVGA3dRenderTargetViewId *) &cmd[1];
    381    for (i = 0; i < color_count; i++) {
    382       if (color_surfs[i]) {
    383          ss = svga_surface(color_surfs[i]);
    384          view_relocation(swc, color_surfs[i], ctarget + i, SVGA_RELOC_WRITE);
    385          ctarget[i] = ss->view_id;
    386       }
    387       else {
    388          view_relocation(swc, NULL, ctarget + i, SVGA_RELOC_WRITE);
    389          ctarget[i] = SVGA3D_INVALID_ID;
    390       }
    391    }
    392 
    393    swc->commit(swc);
    394    return PIPE_OK;
    395 }
    396 
    397 
    398 enum pipe_error
    399 SVGA3D_vgpu10_SetBlendState(struct svga_winsys_context *swc,
    400                             SVGA3dBlendStateId blendId,
    401                             const float *blendFactor,
    402                             uint32 sampleMask)
    403 {
    404    SVGA3D_CREATE_COMMAND(SetBlendState, SET_BLEND_STATE);
    405 
    406    SVGA3D_COPY_BASIC_2(blendId, sampleMask);
    407    memcpy(cmd->blendFactor, blendFactor, sizeof(float) * 4);
    408 
    409    swc->commit(swc);
    410    return PIPE_OK;
    411 }
    412 
    413 enum pipe_error
    414 SVGA3D_vgpu10_SetDepthStencilState(struct svga_winsys_context *swc,
    415                                    SVGA3dDepthStencilStateId depthStencilId,
    416                                    uint32 stencilRef)
    417 {
    418    SVGA3D_CREATE_COMMAND(SetDepthStencilState, SET_DEPTHSTENCIL_STATE);
    419 
    420    SVGA3D_COPY_BASIC_2(depthStencilId, stencilRef);
    421 
    422    swc->commit(swc);
    423    return PIPE_OK;
    424 }
    425 
    426 enum pipe_error
    427 SVGA3D_vgpu10_SetRasterizerState(struct svga_winsys_context *swc,
    428                                  SVGA3dRasterizerStateId rasterizerId)
    429 {
    430    SVGA3D_CREATE_COMMAND(SetRasterizerState, SET_RASTERIZER_STATE);
    431 
    432    cmd->rasterizerId = rasterizerId;
    433 
    434    swc->commit(swc);
    435    return PIPE_OK;
    436 }
    437 
    438 enum pipe_error
    439 SVGA3D_vgpu10_SetPredication(struct svga_winsys_context *swc,
    440                              SVGA3dQueryId queryId,
    441                              uint32 predicateValue)
    442 {
    443    SVGA3dCmdDXSetPredication *cmd;
    444 
    445    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_PREDICATION,
    446                             sizeof *cmd, 0);
    447 
    448    if (!cmd)
    449       return PIPE_ERROR_OUT_OF_MEMORY;
    450 
    451    cmd->queryId = queryId;
    452    cmd->predicateValue = predicateValue;
    453    swc->commit(swc);
    454    return PIPE_OK;
    455 }
    456 
    457 enum pipe_error
    458 SVGA3D_vgpu10_SetSOTargets(struct svga_winsys_context *swc,
    459                            unsigned count,
    460                            const SVGA3dSoTarget *targets,
    461                            struct svga_winsys_surface **surfaces)
    462 {
    463    SVGA3dCmdDXSetSOTargets *cmd;
    464    SVGA3dSoTarget *sot;
    465    unsigned i;
    466 
    467    cmd = SVGA3D_FIFOReserve(swc,
    468                             SVGA_3D_CMD_DX_SET_SOTARGETS,
    469                             sizeof(SVGA3dCmdDXSetSOTargets) +
    470                             count * sizeof(SVGA3dSoTarget),
    471                             count);
    472 
    473    if (!cmd)
    474       return PIPE_ERROR_OUT_OF_MEMORY;
    475 
    476    cmd->pad0 = 0;
    477    sot = (SVGA3dSoTarget *)(cmd + 1);
    478    for (i = 0; i < count; i++, sot++) {
    479       if (surfaces[i]) {
    480          sot->offset = targets[i].offset;
    481          sot->sizeInBytes = targets[i].sizeInBytes;
    482          swc->surface_relocation(swc, &sot->sid, NULL, surfaces[i],
    483                                  SVGA_RELOC_WRITE);
    484       }
    485       else {
    486          sot->offset = 0;
    487          sot->sizeInBytes = ~0u;
    488          swc->surface_relocation(swc, &sot->sid, NULL, NULL,
    489                                  SVGA_RELOC_WRITE);
    490       }
    491    }
    492    swc->commit(swc);
    493    return PIPE_OK;
    494 }
    495 
    496 enum pipe_error
    497 SVGA3D_vgpu10_SetScissorRects(struct svga_winsys_context *swc,
    498                               unsigned count,
    499                               const SVGASignedRect *rects)
    500 {
    501    SVGA3dCmdDXSetScissorRects *cmd;
    502 
    503    assert(count > 0);
    504    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_SCISSORRECTS,
    505                             sizeof(SVGA3dCmdDXSetScissorRects) +
    506                             count * sizeof(SVGASignedRect),
    507                             0);
    508    if (!cmd)
    509       return PIPE_ERROR_OUT_OF_MEMORY;
    510 
    511    memcpy(cmd + 1, rects, count * sizeof(SVGASignedRect));
    512 
    513    swc->commit(swc);
    514    return PIPE_OK;
    515 }
    516 
    517 enum pipe_error
    518 SVGA3D_vgpu10_SetStreamOutput(struct svga_winsys_context *swc,
    519                               SVGA3dStreamOutputId soid)
    520 {
    521    SVGA3D_CREATE_COMMAND(SetStreamOutput, SET_STREAMOUTPUT);
    522 
    523    cmd->soid = soid;
    524 
    525    swc->commit(swc);
    526    return PIPE_OK;
    527 }
    528 
    529 enum pipe_error
    530 SVGA3D_vgpu10_Draw(struct svga_winsys_context *swc,
    531                    uint32 vertexCount,
    532                    uint32 startVertexLocation)
    533 {
    534    SVGA3D_CREATE_COMMAND(Draw, DRAW);
    535 
    536    SVGA3D_COPY_BASIC_2(vertexCount, startVertexLocation);
    537 
    538    swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    539    swc->commit(swc);
    540    return PIPE_OK;
    541 }
    542 
    543 enum pipe_error
    544 SVGA3D_vgpu10_DrawIndexed(struct svga_winsys_context *swc,
    545                           uint32 indexCount,
    546                           uint32 startIndexLocation,
    547                           int32 baseVertexLocation)
    548 {
    549    SVGA3D_CREATE_COMMAND(DrawIndexed, DRAW_INDEXED);
    550 
    551    SVGA3D_COPY_BASIC_3(indexCount, startIndexLocation,
    552                        baseVertexLocation);
    553 
    554    swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    555    swc->commit(swc);
    556    return PIPE_OK;
    557 }
    558 
    559 enum pipe_error
    560 SVGA3D_vgpu10_DrawInstanced(struct svga_winsys_context *swc,
    561                             uint32 vertexCountPerInstance,
    562                             uint32 instanceCount,
    563                             uint32 startVertexLocation,
    564                             uint32 startInstanceLocation)
    565 {
    566    SVGA3D_CREATE_COMMAND(DrawInstanced, DRAW_INSTANCED);
    567 
    568    SVGA3D_COPY_BASIC_4(vertexCountPerInstance, instanceCount,
    569                        startVertexLocation, startInstanceLocation);
    570 
    571    swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    572    swc->commit(swc);
    573    return PIPE_OK;
    574 }
    575 
    576 enum pipe_error
    577 SVGA3D_vgpu10_DrawIndexedInstanced(struct svga_winsys_context *swc,
    578                                    uint32 indexCountPerInstance,
    579                                    uint32 instanceCount,
    580                                    uint32 startIndexLocation,
    581                                    int32  baseVertexLocation,
    582                                    uint32 startInstanceLocation)
    583 {
    584    SVGA3D_CREATE_COMMAND(DrawIndexedInstanced, DRAW_INDEXED_INSTANCED);
    585 
    586    SVGA3D_COPY_BASIC_5(indexCountPerInstance, instanceCount,
    587                        startIndexLocation, baseVertexLocation,
    588                        startInstanceLocation);
    589 
    590 
    591    swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    592    swc->commit(swc);
    593    return PIPE_OK;
    594 }
    595 
    596 enum pipe_error
    597 SVGA3D_vgpu10_DrawAuto(struct svga_winsys_context *swc)
    598 {
    599    SVGA3D_CREATE_COMMAND(DrawAuto, DRAW_AUTO);
    600 
    601    swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    602    swc->commit(swc);
    603    return PIPE_OK;
    604 }
    605 
    606 enum pipe_error
    607 SVGA3D_vgpu10_DefineQuery(struct svga_winsys_context *swc,
    608                           SVGA3dQueryId queryId,
    609                           SVGA3dQueryType type,
    610                           SVGA3dDXQueryFlags flags)
    611 {
    612    SVGA3D_CREATE_COMMAND(DefineQuery, DEFINE_QUERY);
    613 
    614    SVGA3D_COPY_BASIC_3(queryId, type, flags);
    615 
    616    swc->commit(swc);
    617    return PIPE_OK;
    618 }
    619 
    620 enum pipe_error
    621 SVGA3D_vgpu10_DestroyQuery(struct svga_winsys_context *swc,
    622                            SVGA3dQueryId queryId)
    623 {
    624    SVGA3D_CREATE_COMMAND(DestroyQuery, DESTROY_QUERY);
    625 
    626    cmd->queryId = queryId;
    627 
    628    swc->commit(swc);
    629    return PIPE_OK;
    630 }
    631 
    632 enum pipe_error
    633 SVGA3D_vgpu10_BindQuery(struct svga_winsys_context *swc,
    634                         struct svga_winsys_gb_query *gbQuery,
    635                         SVGA3dQueryId queryId)
    636 {
    637    SVGA3dCmdDXBindQuery *cmd = SVGA3D_FIFOReserve(swc,
    638                                                   SVGA_3D_CMD_DX_BIND_QUERY,
    639                                                   sizeof *cmd,
    640                                                   1);
    641    if (!cmd)
    642       return PIPE_ERROR_OUT_OF_MEMORY;
    643 
    644    cmd->queryId = queryId;
    645    swc->query_relocation(swc, &cmd->mobid, gbQuery);
    646 
    647    swc->commit(swc);
    648    return PIPE_OK;
    649 }
    650 
    651 enum pipe_error
    652 SVGA3D_vgpu10_SetQueryOffset(struct svga_winsys_context *swc,
    653                              SVGA3dQueryId queryId,
    654                              uint32 mobOffset)
    655 {
    656    SVGA3D_CREATE_COMMAND(SetQueryOffset, SET_QUERY_OFFSET);
    657    SVGA3D_COPY_BASIC_2(queryId, mobOffset);
    658    swc->commit(swc);
    659    return PIPE_OK;
    660 }
    661 
    662 enum pipe_error
    663 SVGA3D_vgpu10_BeginQuery(struct svga_winsys_context *swc,
    664                          SVGA3dQueryId queryId)
    665 {
    666    SVGA3D_CREATE_COMMAND(BeginQuery, BEGIN_QUERY);
    667    cmd->queryId = queryId;
    668    swc->commit(swc);
    669    return PIPE_OK;
    670 }
    671 
    672 enum pipe_error
    673 SVGA3D_vgpu10_EndQuery(struct svga_winsys_context *swc,
    674                        SVGA3dQueryId queryId)
    675 {
    676    SVGA3D_CREATE_COMMAND(EndQuery, END_QUERY);
    677    cmd->queryId = queryId;
    678    swc->commit(swc);
    679    return PIPE_OK;
    680 }
    681 
    682 
    683 enum pipe_error
    684 SVGA3D_vgpu10_ClearDepthStencilView(struct svga_winsys_context *swc,
    685                                     struct pipe_surface *ds_surf,
    686                                     uint16 flags,
    687                                     uint16 stencil,
    688                                     float depth)
    689 {
    690    SVGA3dCmdDXClearDepthStencilView *cmd;
    691    struct svga_surface *ss = svga_surface(ds_surf);
    692 
    693    cmd = SVGA3D_FIFOReserve(swc,
    694                             SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW,
    695                             sizeof(SVGA3dCmdDXClearDepthStencilView),
    696                             1); /* one relocation */
    697    if (!cmd)
    698       return PIPE_ERROR_OUT_OF_MEMORY;
    699 
    700    /* NOTE: The following is pretty tricky.  We need to emit a view/surface
    701     * relocation and we have to provide a pointer to an ID which lies in
    702     * the bounds of the command space which we just allocated.  However,
    703     * we then need to overwrite it with the original DepthStencilViewId.
    704     */
    705    view_relocation(swc, ds_surf, &cmd->depthStencilViewId,
    706                    SVGA_RELOC_WRITE);
    707    cmd->depthStencilViewId = ss->view_id;
    708    cmd->flags = flags;
    709    cmd->stencil = stencil;
    710    cmd->depth = depth;
    711 
    712    swc->commit(swc);
    713    return PIPE_OK;
    714 }
    715 
    716 enum pipe_error
    717 SVGA3D_vgpu10_DefineShaderResourceView(struct svga_winsys_context *swc,
    718                              SVGA3dShaderResourceViewId shaderResourceViewId,
    719                              struct svga_winsys_surface *surface,
    720                              SVGA3dSurfaceFormat format,
    721                              SVGA3dResourceType resourceDimension,
    722                              const SVGA3dShaderResourceViewDesc *desc)
    723 {
    724    SVGA3dCmdDXDefineShaderResourceView *cmd;
    725 
    726    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW,
    727                             sizeof(SVGA3dCmdDXDefineShaderResourceView),
    728                             1); /* one relocation */
    729    if (!cmd)
    730       return PIPE_ERROR_OUT_OF_MEMORY;
    731 
    732    SVGA3D_COPY_BASIC_3(shaderResourceViewId, format, resourceDimension);
    733 
    734    swc->surface_relocation(swc, &cmd->sid, NULL, surface,
    735                            SVGA_RELOC_READ);
    736 
    737    cmd->desc = *desc;
    738 
    739    swc->commit(swc);
    740    return PIPE_OK;
    741 }
    742 
    743 enum pipe_error
    744 SVGA3D_vgpu10_DestroyShaderResourceView(struct svga_winsys_context *swc,
    745                              SVGA3dShaderResourceViewId shaderResourceViewId)
    746 {
    747    SVGA3D_CREATE_COMMAND(DestroyShaderResourceView,
    748                        DESTROY_SHADERRESOURCE_VIEW);
    749 
    750    cmd->shaderResourceViewId = shaderResourceViewId;
    751 
    752    swc->commit(swc);
    753    return PIPE_OK;
    754 }
    755 
    756 
    757 enum pipe_error
    758 SVGA3D_vgpu10_DefineRenderTargetView(struct svga_winsys_context *swc,
    759                                   SVGA3dRenderTargetViewId renderTargetViewId,
    760                                   struct svga_winsys_surface *surface,
    761                                   SVGA3dSurfaceFormat format,
    762                                   SVGA3dResourceType resourceDimension,
    763                                   const SVGA3dRenderTargetViewDesc *desc)
    764 {
    765    SVGA3dCmdDXDefineRenderTargetView *cmd;
    766 
    767    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW,
    768                             sizeof(SVGA3dCmdDXDefineRenderTargetView),
    769                             1); /* one relocation */
    770    if (!cmd)
    771       return PIPE_ERROR_OUT_OF_MEMORY;
    772 
    773    SVGA3D_COPY_BASIC_3(renderTargetViewId, format, resourceDimension);
    774    cmd->desc = *desc;
    775 
    776    surface_to_resourceid(swc, surface,
    777                          &cmd->sid,
    778                          SVGA_RELOC_READ | SVGA_RELOC_WRITE);
    779 
    780    swc->commit(swc);
    781    return PIPE_OK;
    782 }
    783 
    784 enum pipe_error
    785 SVGA3D_vgpu10_DestroyRenderTargetView(struct svga_winsys_context *swc,
    786                                  SVGA3dRenderTargetViewId renderTargetViewId)
    787 {
    788    SVGA3D_CREATE_COMMAND(DestroyRenderTargetView, DESTROY_RENDERTARGET_VIEW);
    789 
    790    cmd->renderTargetViewId = renderTargetViewId;
    791 
    792    swc->commit(swc);
    793    return PIPE_OK;
    794 }
    795 
    796 
    797 enum pipe_error
    798 SVGA3D_vgpu10_DefineDepthStencilView(struct svga_winsys_context *swc,
    799                                   SVGA3dDepthStencilViewId depthStencilViewId,
    800                                   struct svga_winsys_surface *surface,
    801                                   SVGA3dSurfaceFormat format,
    802                                   SVGA3dResourceType resourceDimension,
    803                                   const SVGA3dRenderTargetViewDesc *desc)
    804 {
    805    SVGA3dCmdDXDefineDepthStencilView *cmd;
    806 
    807    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW,
    808                             sizeof(SVGA3dCmdDXDefineDepthStencilView),
    809                             1); /* one relocation */
    810    if (!cmd)
    811       return PIPE_ERROR_OUT_OF_MEMORY;
    812 
    813    SVGA3D_COPY_BASIC_3(depthStencilViewId, format, resourceDimension);
    814    cmd->mipSlice = desc->tex.mipSlice;
    815    cmd->firstArraySlice = desc->tex.firstArraySlice;
    816    cmd->arraySize = desc->tex.arraySize;
    817 
    818    surface_to_resourceid(swc, surface,
    819                          &cmd->sid,
    820                          SVGA_RELOC_READ | SVGA_RELOC_WRITE);
    821 
    822    swc->commit(swc);
    823    return PIPE_OK;
    824 }
    825 
    826 enum pipe_error
    827 SVGA3D_vgpu10_DestroyDepthStencilView(struct svga_winsys_context *swc,
    828                                  SVGA3dDepthStencilViewId depthStencilViewId)
    829 {
    830    SVGA3D_CREATE_COMMAND(DestroyDepthStencilView, DESTROY_DEPTHSTENCIL_VIEW);
    831 
    832    cmd->depthStencilViewId = depthStencilViewId;
    833 
    834    swc->commit(swc);
    835    return PIPE_OK;
    836 }
    837 
    838 enum pipe_error
    839 SVGA3D_vgpu10_DefineElementLayout(struct svga_winsys_context *swc,
    840                                   unsigned count,
    841                                   SVGA3dElementLayoutId elementLayoutId,
    842                                   const SVGA3dInputElementDesc *elements)
    843 {
    844    SVGA3dCmdDXDefineElementLayout *cmd;
    845    unsigned i;
    846 
    847    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT,
    848                             sizeof(SVGA3dCmdDXDefineElementLayout) +
    849                             count * sizeof(SVGA3dInputElementDesc), 0);
    850    if (!cmd)
    851       return PIPE_ERROR_OUT_OF_MEMORY;
    852 
    853    /* check that all offsets are multiples of four */
    854    for (i = 0; i < count; i++) {
    855       assert(elements[i].alignedByteOffset % 4 == 0);
    856    }
    857    (void) i; /* silence unused var in release build */
    858 
    859    cmd->elementLayoutId = elementLayoutId;
    860    memcpy(cmd + 1, elements, count * sizeof(SVGA3dInputElementDesc));
    861 
    862    swc->commit(swc);
    863    return PIPE_OK;
    864 }
    865 
    866 enum pipe_error
    867 SVGA3D_vgpu10_DestroyElementLayout(struct svga_winsys_context *swc,
    868                                    SVGA3dElementLayoutId elementLayoutId)
    869 {
    870    SVGA3D_CREATE_COMMAND(DestroyElementLayout, DESTROY_ELEMENTLAYOUT);
    871 
    872    cmd->elementLayoutId = elementLayoutId;
    873 
    874    swc->commit(swc);
    875    return PIPE_OK;
    876 }
    877 
    878 enum pipe_error
    879 SVGA3D_vgpu10_DefineBlendState(struct svga_winsys_context *swc,
    880                                SVGA3dBlendStateId blendId,
    881                                uint8 alphaToCoverageEnable,
    882                                uint8 independentBlendEnable,
    883                                const SVGA3dDXBlendStatePerRT *perRT)
    884 {
    885    SVGA3D_CREATE_COMMAND(DefineBlendState, DEFINE_BLEND_STATE);
    886 
    887    cmd->blendId = blendId;
    888    cmd->alphaToCoverageEnable = alphaToCoverageEnable;
    889    cmd->independentBlendEnable = independentBlendEnable;
    890    memcpy(cmd->perRT, perRT, sizeof(cmd->perRT));
    891    cmd->pad0 = 0;
    892 
    893    swc->commit(swc);
    894    return PIPE_OK;
    895 }
    896 
    897 enum pipe_error
    898 SVGA3D_vgpu10_DestroyBlendState(struct svga_winsys_context *swc,
    899                                 SVGA3dBlendStateId blendId)
    900 {
    901    SVGA3D_CREATE_COMMAND(DestroyBlendState, DESTROY_BLEND_STATE);
    902 
    903    cmd->blendId = blendId;
    904 
    905    swc->commit(swc);
    906    return PIPE_OK;
    907 }
    908 
    909 enum pipe_error
    910 SVGA3D_vgpu10_DefineDepthStencilState(struct svga_winsys_context *swc,
    911                                       SVGA3dDepthStencilStateId depthStencilId,
    912                                       uint8 depthEnable,
    913                                       SVGA3dDepthWriteMask depthWriteMask,
    914                                       SVGA3dComparisonFunc depthFunc,
    915                                       uint8 stencilEnable,
    916                                       uint8 frontEnable,
    917                                       uint8 backEnable,
    918                                       uint8 stencilReadMask,
    919                                       uint8 stencilWriteMask,
    920                                       uint8 frontStencilFailOp,
    921                                       uint8 frontStencilDepthFailOp,
    922                                       uint8 frontStencilPassOp,
    923                                       SVGA3dComparisonFunc frontStencilFunc,
    924                                       uint8 backStencilFailOp,
    925                                       uint8 backStencilDepthFailOp,
    926                                       uint8 backStencilPassOp,
    927                                       SVGA3dComparisonFunc backStencilFunc)
    928 {
    929    SVGA3D_CREATE_COMMAND(DefineDepthStencilState, DEFINE_DEPTHSTENCIL_STATE);
    930 
    931    SVGA3D_COPY_BASIC_9(depthStencilId, depthEnable,
    932                        depthWriteMask, depthFunc,
    933                        stencilEnable, frontEnable,
    934                        backEnable, stencilReadMask,
    935                        stencilWriteMask);
    936    SVGA3D_COPY_BASIC_8(frontStencilFailOp, frontStencilDepthFailOp,
    937                        frontStencilPassOp, frontStencilFunc,
    938                        backStencilFailOp, backStencilDepthFailOp,
    939                        backStencilPassOp, backStencilFunc);
    940 
    941    swc->commit(swc);
    942    return PIPE_OK;
    943 }
    944 
    945 enum pipe_error
    946 SVGA3D_vgpu10_DestroyDepthStencilState(struct svga_winsys_context *swc,
    947                                     SVGA3dDepthStencilStateId depthStencilId)
    948 {
    949    SVGA3D_CREATE_COMMAND(DestroyDepthStencilState,
    950                          DESTROY_DEPTHSTENCIL_STATE);
    951 
    952    cmd->depthStencilId = depthStencilId;
    953 
    954    swc->commit(swc);
    955    return PIPE_OK;
    956 }
    957 
    958 enum pipe_error
    959 SVGA3D_vgpu10_DefineRasterizerState(struct svga_winsys_context *swc,
    960                                     SVGA3dRasterizerStateId rasterizerId,
    961                                     uint8 fillMode,
    962                                     SVGA3dCullMode cullMode,
    963                                     uint8 frontCounterClockwise,
    964                                     int32 depthBias,
    965                                     float depthBiasClamp,
    966                                     float slopeScaledDepthBias,
    967                                     uint8 depthClipEnable,
    968                                     uint8 scissorEnable,
    969                                     uint8 multisampleEnable,
    970                                     uint8 antialiasedLineEnable,
    971                                     float lineWidth,
    972                                     uint8 lineStippleEnable,
    973                                     uint8 lineStippleFactor,
    974                                     uint16 lineStipplePattern,
    975                                     uint8 provokingVertexLast)
    976 {
    977    SVGA3D_CREATE_COMMAND(DefineRasterizerState, DEFINE_RASTERIZER_STATE);
    978 
    979    SVGA3D_COPY_BASIC_5(rasterizerId, fillMode,
    980                        cullMode, frontCounterClockwise,
    981                        depthBias);
    982    SVGA3D_COPY_BASIC_6(depthBiasClamp, slopeScaledDepthBias,
    983                        depthClipEnable, scissorEnable,
    984                        multisampleEnable, antialiasedLineEnable);
    985    cmd->lineWidth = lineWidth;
    986    cmd->lineStippleEnable = lineStippleEnable;
    987    cmd->lineStippleFactor = lineStippleFactor;
    988    cmd->lineStipplePattern = lineStipplePattern;
    989    cmd->provokingVertexLast = provokingVertexLast;
    990 
    991    swc->commit(swc);
    992    return PIPE_OK;
    993 }
    994 
    995 enum pipe_error
    996 SVGA3D_vgpu10_DestroyRasterizerState(struct svga_winsys_context *swc,
    997                                      SVGA3dRasterizerStateId rasterizerId)
    998 {
    999    SVGA3D_CREATE_COMMAND(DestroyRasterizerState, DESTROY_RASTERIZER_STATE);
   1000 
   1001    cmd->rasterizerId = rasterizerId;
   1002 
   1003    swc->commit(swc);
   1004    return PIPE_OK;
   1005 }
   1006 
   1007 enum pipe_error
   1008 SVGA3D_vgpu10_DefineSamplerState(struct svga_winsys_context *swc,
   1009                                  SVGA3dSamplerId samplerId,
   1010                                  SVGA3dFilter filter,
   1011                                  uint8 addressU,
   1012                                  uint8 addressV,
   1013                                  uint8 addressW,
   1014                                  float mipLODBias,
   1015                                  uint8 maxAnisotropy,
   1016                                  uint8 comparisonFunc,
   1017                                  SVGA3dRGBAFloat borderColor,
   1018                                  float minLOD,
   1019                                  float maxLOD)
   1020 {
   1021    SVGA3D_CREATE_COMMAND(DefineSamplerState, DEFINE_SAMPLER_STATE);
   1022 
   1023    SVGA3D_COPY_BASIC_6(samplerId, filter,
   1024                        addressU, addressV,
   1025                        addressW, mipLODBias);
   1026    SVGA3D_COPY_BASIC_5(maxAnisotropy, comparisonFunc,
   1027                        borderColor, minLOD,
   1028                        maxLOD);
   1029 
   1030    swc->commit(swc);
   1031    return PIPE_OK;
   1032 }
   1033 
   1034 enum pipe_error
   1035 SVGA3D_vgpu10_DestroySamplerState(struct svga_winsys_context *swc,
   1036                                   SVGA3dSamplerId samplerId)
   1037 {
   1038    SVGA3D_CREATE_COMMAND(DestroySamplerState, DESTROY_SAMPLER_STATE);
   1039 
   1040    cmd->samplerId = samplerId;
   1041 
   1042    swc->commit(swc);
   1043    return PIPE_OK;
   1044 }
   1045 
   1046 
   1047 enum pipe_error
   1048 SVGA3D_vgpu10_DefineAndBindShader(struct svga_winsys_context *swc,
   1049                                   struct svga_winsys_gb_shader *gbshader,
   1050                                   SVGA3dShaderId shaderId,
   1051                                   SVGA3dShaderType type,
   1052                                   uint32 sizeInBytes)
   1053 {
   1054    SVGA3dCmdHeader *header;
   1055    SVGA3dCmdDXDefineShader *dcmd;
   1056    SVGA3dCmdDXBindShader *bcmd;
   1057    unsigned totalSize = 2 * sizeof(*header) +
   1058                         sizeof(*dcmd) + sizeof(*bcmd);
   1059 
   1060    /* Make sure there is room for both commands */
   1061    header = swc->reserve(swc, totalSize, 2);
   1062    if (!header)
   1063       return PIPE_ERROR_OUT_OF_MEMORY;
   1064 
   1065    /* DXDefineShader command */
   1066    header->id = SVGA_3D_CMD_DX_DEFINE_SHADER;
   1067    header->size = sizeof(*dcmd);
   1068    dcmd = (SVGA3dCmdDXDefineShader *)(header + 1);
   1069    dcmd->shaderId = shaderId;
   1070    dcmd->type = type;
   1071    dcmd->sizeInBytes = sizeInBytes;
   1072 
   1073    /* DXBindShader command */
   1074    header = (SVGA3dCmdHeader *)(dcmd + 1);
   1075 
   1076    header->id = SVGA_3D_CMD_DX_BIND_SHADER;
   1077    header->size = sizeof(*bcmd);
   1078    bcmd = (SVGA3dCmdDXBindShader *)(header + 1);
   1079 
   1080    bcmd->cid = swc->cid;
   1081    swc->shader_relocation(swc, NULL, &bcmd->mobid,
   1082                           &bcmd->offsetInBytes, gbshader, 0);
   1083 
   1084    bcmd->shid = shaderId;
   1085 
   1086    swc->commit(swc);
   1087    return PIPE_OK;
   1088 }
   1089 
   1090 enum pipe_error
   1091 SVGA3D_vgpu10_DestroyShader(struct svga_winsys_context *swc,
   1092                             SVGA3dShaderId shaderId)
   1093 {
   1094    SVGA3D_CREATE_COMMAND(DestroyShader, DESTROY_SHADER);
   1095 
   1096    cmd->shaderId = shaderId;
   1097 
   1098    swc->commit(swc);
   1099    return PIPE_OK;
   1100 }
   1101 
   1102 enum pipe_error
   1103 SVGA3D_vgpu10_DefineStreamOutput(struct svga_winsys_context *swc,
   1104        SVGA3dStreamOutputId soid,
   1105        uint32 numOutputStreamEntries,
   1106        uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS],
   1107        const SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_STREAMOUT_DECLS])
   1108 {
   1109    unsigned i;
   1110    SVGA3D_CREATE_COMMAND(DefineStreamOutput, DEFINE_STREAMOUTPUT);
   1111 
   1112    cmd->soid = soid;
   1113    cmd->numOutputStreamEntries = numOutputStreamEntries;
   1114 
   1115    for (i = 0; i < ARRAY_SIZE(cmd->streamOutputStrideInBytes); i++)
   1116       cmd->streamOutputStrideInBytes[i] = streamOutputStrideInBytes[i];
   1117 
   1118    memcpy(cmd->decl, decl,
   1119           sizeof(SVGA3dStreamOutputDeclarationEntry)
   1120           * SVGA3D_MAX_STREAMOUT_DECLS);
   1121 
   1122    swc->commit(swc);
   1123    return PIPE_OK;
   1124 }
   1125 
   1126 enum pipe_error
   1127 SVGA3D_vgpu10_DestroyStreamOutput(struct svga_winsys_context *swc,
   1128                                   SVGA3dStreamOutputId soid)
   1129 {
   1130    SVGA3D_CREATE_COMMAND(DestroyStreamOutput, DESTROY_STREAMOUTPUT);
   1131 
   1132    cmd->soid = soid;
   1133 
   1134    swc->commit(swc);
   1135    return PIPE_OK;
   1136 }
   1137 
   1138 enum pipe_error
   1139 SVGA3D_vgpu10_SetInputLayout(struct svga_winsys_context *swc,
   1140                              SVGA3dElementLayoutId elementLayoutId)
   1141 {
   1142    SVGA3D_CREATE_COMMAND(SetInputLayout, SET_INPUT_LAYOUT);
   1143 
   1144    cmd->elementLayoutId = elementLayoutId;
   1145 
   1146    swc->commit(swc);
   1147    return PIPE_OK;
   1148 }
   1149 
   1150 enum pipe_error
   1151 SVGA3D_vgpu10_SetVertexBuffers(struct svga_winsys_context *swc,
   1152                                unsigned count,
   1153                                uint32 startBuffer,
   1154                                const SVGA3dVertexBuffer *bufferInfo,
   1155                                struct svga_winsys_surface **surfaces)
   1156 {
   1157    SVGA3dCmdDXSetVertexBuffers *cmd;
   1158    SVGA3dVertexBuffer *bufs;
   1159    unsigned i;
   1160 
   1161    assert(count > 0);
   1162 
   1163    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS,
   1164                             sizeof(SVGA3dCmdDXSetVertexBuffers) +
   1165                             count * sizeof(SVGA3dVertexBuffer),
   1166                             count); /* 'count' relocations */
   1167    if (!cmd)
   1168       return PIPE_ERROR_OUT_OF_MEMORY;
   1169 
   1170    cmd->startBuffer = startBuffer;
   1171 
   1172    bufs = (SVGA3dVertexBuffer *) &cmd[1];
   1173    for (i = 0; i < count; i++) {
   1174       bufs[i].stride = bufferInfo[i].stride;
   1175       bufs[i].offset = bufferInfo[i].offset;
   1176       assert(bufs[i].stride % 4 == 0);
   1177       assert(bufs[i].offset % 4 == 0);
   1178       swc->surface_relocation(swc, &bufs[i].sid, NULL, surfaces[i],
   1179                               SVGA_RELOC_READ);
   1180    }
   1181 
   1182    swc->commit(swc);
   1183    return PIPE_OK;
   1184 }
   1185 
   1186 enum pipe_error
   1187 SVGA3D_vgpu10_SetTopology(struct svga_winsys_context *swc,
   1188                           SVGA3dPrimitiveType topology)
   1189 {
   1190    SVGA3D_CREATE_COMMAND(SetTopology, SET_TOPOLOGY);
   1191 
   1192    cmd->topology = topology;
   1193 
   1194    swc->commit(swc);
   1195    return PIPE_OK;
   1196 }
   1197 
   1198 enum pipe_error
   1199 SVGA3D_vgpu10_SetIndexBuffer(struct svga_winsys_context *swc,
   1200                              struct svga_winsys_surface *indexes,
   1201                              SVGA3dSurfaceFormat format,
   1202                              uint32 offset)
   1203 {
   1204    SVGA3dCmdDXSetIndexBuffer *cmd;
   1205 
   1206    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_INDEX_BUFFER,
   1207                             sizeof(SVGA3dCmdDXSetIndexBuffer),
   1208                             1); /* one relocations */
   1209    if (!cmd)
   1210       return PIPE_ERROR_OUT_OF_MEMORY;
   1211 
   1212    swc->surface_relocation(swc, &cmd->sid, NULL, indexes, SVGA_RELOC_READ);
   1213    SVGA3D_COPY_BASIC_2(format, offset);
   1214 
   1215    swc->commit(swc);
   1216    return PIPE_OK;
   1217 }
   1218 
   1219 enum pipe_error
   1220 SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
   1221                                       unsigned slot,
   1222                                       SVGA3dShaderType type,
   1223                                       struct svga_winsys_surface *surface,
   1224                                       uint32 offsetInBytes,
   1225                                       uint32 sizeInBytes)
   1226 {
   1227    SVGA3dCmdDXSetSingleConstantBuffer *cmd;
   1228 
   1229    assert(offsetInBytes % 256 == 0);
   1230    if (!surface)
   1231       assert(sizeInBytes == 0);
   1232    else
   1233       assert(sizeInBytes > 0);
   1234 
   1235    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER,
   1236                             sizeof(SVGA3dCmdDXSetSingleConstantBuffer),
   1237                             1);  /* one relocation */
   1238    if (!cmd)
   1239       return PIPE_ERROR_OUT_OF_MEMORY;
   1240 
   1241    cmd->slot = slot;
   1242    cmd->type = type;
   1243    swc->surface_relocation(swc, &cmd->sid, NULL, surface, SVGA_RELOC_READ);
   1244    cmd->offsetInBytes = offsetInBytes;
   1245    cmd->sizeInBytes = sizeInBytes;
   1246 
   1247    swc->commit(swc);
   1248 
   1249    return PIPE_OK;
   1250 }
   1251 
   1252 
   1253 enum pipe_error
   1254 SVGA3D_vgpu10_ReadbackSubResource(struct svga_winsys_context *swc,
   1255                                   struct svga_winsys_surface *surface,
   1256                                   unsigned subResource)
   1257 {
   1258    SVGA3dCmdDXReadbackSubResource *cmd;
   1259 
   1260    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_READBACK_SUBRESOURCE,
   1261                             sizeof(SVGA3dCmdDXReadbackSubResource),
   1262                             1);
   1263    if (!cmd)
   1264       return PIPE_ERROR_OUT_OF_MEMORY;
   1265 
   1266    swc->surface_relocation(swc, &cmd->sid, NULL, surface,
   1267                            SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
   1268    cmd->subResource = subResource;
   1269 
   1270    swc->commit(swc);
   1271    return PIPE_OK;
   1272 }
   1273 
   1274 enum pipe_error
   1275 SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
   1276                                 struct svga_winsys_surface *surface,
   1277                                 const SVGA3dBox *box,
   1278                                 unsigned subResource)
   1279 {
   1280    SVGA3dCmdDXUpdateSubResource *cmd;
   1281 
   1282    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE,
   1283                             sizeof(SVGA3dCmdDXUpdateSubResource),
   1284                             1);
   1285    if (!cmd)
   1286       return PIPE_ERROR_OUT_OF_MEMORY;
   1287 
   1288    swc->surface_relocation(swc, &cmd->sid, NULL, surface,
   1289                            SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
   1290    cmd->subResource = subResource;
   1291    cmd->box = *box;
   1292 
   1293    swc->commit(swc);
   1294    return PIPE_OK;
   1295 }
   1296 
   1297 enum pipe_error
   1298 SVGA3D_vgpu10_GenMips(struct svga_winsys_context *swc,
   1299                       SVGA3dShaderResourceViewId shaderResourceViewId,
   1300                       struct svga_winsys_surface *view)
   1301 {
   1302    SVGA3dCmdDXGenMips *cmd;
   1303 
   1304    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_GENMIPS,
   1305                             sizeof(SVGA3dCmdDXGenMips), 1);
   1306 
   1307    if (!cmd)
   1308       return PIPE_ERROR_OUT_OF_MEMORY;
   1309 
   1310    swc->surface_relocation(swc, &cmd->shaderResourceViewId, NULL, view,
   1311                            SVGA_RELOC_WRITE);
   1312    cmd->shaderResourceViewId = shaderResourceViewId;
   1313 
   1314    swc->commit(swc);
   1315    return PIPE_OK;
   1316 }
   1317 
   1318 
   1319 enum pipe_error
   1320 SVGA3D_vgpu10_BufferCopy(struct svga_winsys_context *swc,
   1321                           struct svga_winsys_surface *src,
   1322                           struct svga_winsys_surface *dst,
   1323                           unsigned srcx, unsigned dstx, unsigned width)
   1324 {
   1325    SVGA3dCmdDXBufferCopy *cmd;
   1326 
   1327    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_BUFFER_COPY, sizeof *cmd, 2);
   1328 
   1329    if (!cmd)
   1330       return PIPE_ERROR_OUT_OF_MEMORY;
   1331 
   1332    swc->surface_relocation(swc, &cmd->dest, NULL, dst, SVGA_RELOC_WRITE);
   1333    swc->surface_relocation(swc, &cmd->src, NULL, src, SVGA_RELOC_READ);
   1334    cmd->destX = dstx;
   1335    cmd->srcX = srcx;
   1336    cmd->width = width;
   1337 
   1338    swc->commit(swc);
   1339    return PIPE_OK;
   1340 }
   1341 
   1342 enum pipe_error
   1343 SVGA3D_vgpu10_TransferFromBuffer(struct svga_winsys_context *swc,
   1344                                  struct svga_winsys_surface *src,
   1345                                  unsigned srcOffset, unsigned srcPitch,
   1346                                  unsigned srcSlicePitch,
   1347                                  struct svga_winsys_surface *dst,
   1348                                  unsigned dstSubResource,
   1349                                  SVGA3dBox *dstBox)
   1350 {
   1351    SVGA3dCmdDXTransferFromBuffer *cmd;
   1352 
   1353    cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER,
   1354                             sizeof(SVGA3dCmdDXTransferFromBuffer), 2);
   1355 
   1356    if (!cmd)
   1357       return PIPE_ERROR_OUT_OF_MEMORY;
   1358 
   1359    swc->surface_relocation(swc, &cmd->srcSid, NULL, src, SVGA_RELOC_READ);
   1360    swc->surface_relocation(swc, &cmd->destSid, NULL, dst, SVGA_RELOC_WRITE);
   1361    cmd->srcOffset = srcOffset;
   1362    cmd->srcPitch = srcPitch;
   1363    cmd->srcSlicePitch = srcSlicePitch;
   1364    cmd->destSubResource = dstSubResource;
   1365    cmd->destBox = *dstBox;
   1366 
   1367    swc->commit(swc);
   1368    return PIPE_OK;
   1369 }
   1370