Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 void
  58. 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.    cmd->cid = swc->cid;
  583.    cmd->type = type;
  584.    surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
  585.    swc->commit(swc);
  586.  
  587.    return PIPE_OK;
  588. }
  589.  
  590.  
  591. /*
  592.  *----------------------------------------------------------------------
  593.  *
  594.  * SVGA3D_DefineShader --
  595.  *
  596.  *      Upload the bytecode for a new shader. The bytecode is "SVGA3D
  597.  *      format", which is theoretically a binary-compatible superset
  598.  *      of Microsoft's DirectX shader bytecode. In practice, the
  599.  *      SVGA3D bytecode doesn't yet have any extensions to DirectX's
  600.  *      bytecode format.
  601.  *
  602.  *      The SVGA3D device supports shader models 1.1 through 2.0.
  603.  *
  604.  *      The caller chooses a shader ID (small positive integer) by
  605.  *      which this shader will be identified in future commands. This
  606.  *      ID is in a namespace which is per-context and per-shader-type.
  607.  *
  608.  *      'bytecodeLen' is specified in bytes. It must be a multiple of 4.
  609.  *
  610.  * Results:
  611.  *      None.
  612.  *
  613.  * Side effects:
  614.  *      None.
  615.  *
  616.  *----------------------------------------------------------------------
  617.  */
  618.  
  619. enum pipe_error
  620. SVGA3D_DefineShader(struct svga_winsys_context *swc,
  621.                     uint32 shid,                  // IN
  622.                     SVGA3dShaderType type,        // IN
  623.                     const uint32 *bytecode,       // IN
  624.                     uint32 bytecodeLen)           // IN
  625. {
  626.    SVGA3dCmdDefineShader *cmd;
  627.  
  628.    assert(bytecodeLen % 4 == 0);
  629.  
  630.    cmd = SVGA3D_FIFOReserve(swc,
  631.                             SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,
  632.                             0);
  633.    if (!cmd)
  634.       return PIPE_ERROR_OUT_OF_MEMORY;
  635.  
  636.    cmd->cid = swc->cid;
  637.    cmd->shid = shid;
  638.    cmd->type = type;
  639.    memcpy(&cmd[1], bytecode, bytecodeLen);
  640.    swc->commit(swc);
  641.  
  642.    return PIPE_OK;
  643. }
  644.  
  645.  
  646. /*
  647.  *----------------------------------------------------------------------
  648.  *
  649.  * SVGA3D_DestroyShader --
  650.  *
  651.  *      Delete a shader that was created by SVGA3D_DefineShader. If
  652.  *      the shader was the current vertex or pixel shader for its
  653.  *      context, rendering results are undefined until a new shader is
  654.  *      bound.
  655.  *
  656.  * Results:
  657.  *      None.
  658.  *
  659.  * Side effects:
  660.  *      None.
  661.  *
  662.  *----------------------------------------------------------------------
  663.  */
  664.  
  665. enum pipe_error
  666. SVGA3D_DestroyShader(struct svga_winsys_context *swc,
  667.                      uint32 shid,            // IN
  668.                      SVGA3dShaderType type)  // IN
  669. {
  670.    SVGA3dCmdDestroyShader *cmd;
  671.  
  672.    cmd = SVGA3D_FIFOReserve(swc,
  673.                             SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,
  674.                             0);
  675.    if (!cmd)
  676.       return PIPE_ERROR_OUT_OF_MEMORY;
  677.  
  678.    cmd->cid = swc->cid;
  679.    cmd->shid = shid;
  680.    cmd->type = type;
  681.    swc->commit(swc);
  682.  
  683.    return PIPE_OK;
  684. }
  685.  
  686.  
  687. /*
  688.  *----------------------------------------------------------------------
  689.  *
  690.  * SVGA3D_SetShaderConst --
  691.  *
  692.  *      Set the value of a shader constant.
  693.  *
  694.  *      Shader constants are analogous to uniform variables in GLSL,
  695.  *      except that they belong to the render context rather than to
  696.  *      an individual shader.
  697.  *
  698.  *      Constants may have one of three types: A 4-vector of floats,
  699.  *      a 4-vector of integers, or a single boolean flag.
  700.  *
  701.  * Results:
  702.  *      None.
  703.  *
  704.  * Side effects:
  705.  *      None.
  706.  *
  707.  *----------------------------------------------------------------------
  708.  */
  709.  
  710. enum pipe_error
  711. SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
  712.                       uint32 reg,                   // IN
  713.                       SVGA3dShaderType type,        // IN
  714.                       SVGA3dShaderConstType ctype,  // IN
  715.                       const void *value)            // IN
  716. {
  717.    SVGA3dCmdSetShaderConst *cmd;
  718.  
  719.    cmd = SVGA3D_FIFOReserve(swc,
  720.                             SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,
  721.                             0);
  722.    if (!cmd)
  723.       return PIPE_ERROR_OUT_OF_MEMORY;
  724.  
  725.    cmd->cid = swc->cid;
  726.    cmd->reg = reg;
  727.    cmd->type = type;
  728.    cmd->ctype = ctype;
  729.  
  730.    switch (ctype) {
  731.  
  732.    case SVGA3D_CONST_TYPE_FLOAT:
  733.    case SVGA3D_CONST_TYPE_INT:
  734.       memcpy(&cmd->values, value, sizeof cmd->values);
  735.       break;
  736.  
  737.    case SVGA3D_CONST_TYPE_BOOL:
  738.       memset(&cmd->values, 0, sizeof cmd->values);
  739.       cmd->values[0] = *(uint32*)value;
  740.       break;
  741.  
  742.    default:
  743.       assert(0);
  744.       break;
  745.  
  746.    }
  747.    swc->commit(swc);
  748.  
  749.    return PIPE_OK;
  750. }
  751.  
  752.  
  753. /*
  754.  *----------------------------------------------------------------------
  755.  *
  756.  * SVGA3D_SetShaderConsts --
  757.  *
  758.  *      Set the value of successive shader constants.
  759.  *
  760.  *      Shader constants are analogous to uniform variables in GLSL,
  761.  *      except that they belong to the render context rather than to
  762.  *      an individual shader.
  763.  *
  764.  *      Constants may have one of three types: A 4-vector of floats,
  765.  *      a 4-vector of integers, or a single boolean flag.
  766.  *
  767.  * Results:
  768.  *      None.
  769.  *
  770.  * Side effects:
  771.  *      None.
  772.  *
  773.  *----------------------------------------------------------------------
  774.  */
  775.  
  776. enum pipe_error
  777. SVGA3D_SetShaderConsts(struct svga_winsys_context *swc,
  778.                         uint32 reg,                   // IN
  779.                         uint32 numRegs,               // IN
  780.                         SVGA3dShaderType type,        // IN
  781.                         SVGA3dShaderConstType ctype,  // IN
  782.                         const void *values)           // IN
  783. {
  784.    SVGA3dCmdSetShaderConst *cmd;
  785.  
  786.    cmd = SVGA3D_FIFOReserve(swc,
  787.                             SVGA_3D_CMD_SET_SHADER_CONST,
  788.                             sizeof *cmd + (numRegs - 1) * sizeof cmd->values,
  789.                             0);
  790.    if (!cmd)
  791.       return PIPE_ERROR_OUT_OF_MEMORY;
  792.  
  793.    cmd->cid = swc->cid;
  794.    cmd->reg = reg;
  795.    cmd->type = type;
  796.    cmd->ctype = ctype;
  797.  
  798.    memcpy(&cmd->values, values, numRegs * sizeof cmd->values);
  799.  
  800.    swc->commit(swc);
  801.  
  802.    return PIPE_OK;
  803. }
  804.  
  805.  
  806.  
  807.  
  808.  
  809. /*
  810.  *----------------------------------------------------------------------
  811.  *
  812.  * SVGA3D_SetShader --
  813.  *
  814.  *      Switch active shaders. This binds a new vertex or pixel shader
  815.  *      to the specified context.
  816.  *
  817.  *      A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
  818.  *      back to the fixed function vertex or pixel pipeline.
  819.  *
  820.  * Results:
  821.  *      None.
  822.  *
  823.  * Side effects:
  824.  *      None.
  825.  *
  826.  *----------------------------------------------------------------------
  827.  */
  828.  
  829. enum pipe_error
  830. SVGA3D_SetShader(struct svga_winsys_context *swc,
  831.                  SVGA3dShaderType type,  // IN
  832.                  uint32 shid)            // IN
  833. {
  834.    SVGA3dCmdSetShader *cmd;
  835.  
  836.    cmd = SVGA3D_FIFOReserve(swc,
  837.                             SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
  838.                             0);
  839.    if (!cmd)
  840.       return PIPE_ERROR_OUT_OF_MEMORY;
  841.  
  842.    cmd->cid = swc->cid;
  843.    cmd->type = type;
  844.    cmd->shid = shid;
  845.    swc->commit(swc);
  846.  
  847.    return PIPE_OK;
  848. }
  849.  
  850.  
  851. /*
  852.  *----------------------------------------------------------------------
  853.  *
  854.  * SVGA3D_BeginClear --
  855.  *
  856.  *      Begin a CLEAR command. This reserves space for it in the FIFO,
  857.  *      and returns a pointer to the command's rectangle array.  This
  858.  *      function must be paired with SVGA_FIFOCommitAll().
  859.  *
  860.  *      Clear is a rendering operation which fills a list of
  861.  *      rectangles with constant values on all render target types
  862.  *      indicated by 'flags'.
  863.  *
  864.  *      Clear is not affected by clipping, depth test, or other
  865.  *      render state which affects the fragment pipeline.
  866.  *
  867.  * Results:
  868.  *      None.
  869.  *
  870.  * Side effects:
  871.  *      May write to attached render target surfaces.
  872.  *
  873.  *----------------------------------------------------------------------
  874.  */
  875.  
  876. enum pipe_error
  877. SVGA3D_BeginClear(struct svga_winsys_context *swc,
  878.                   SVGA3dClearFlag flags,  // IN
  879.                   uint32 color,           // IN
  880.                   float depth,            // IN
  881.                   uint32 stencil,         // IN
  882.                   SVGA3dRect **rects,     // OUT
  883.                   uint32 numRects)        // IN
  884. {
  885.    SVGA3dCmdClear *cmd;
  886.  
  887.    cmd = SVGA3D_FIFOReserve(swc,
  888.                             SVGA_3D_CMD_CLEAR,
  889.                             sizeof *cmd + sizeof **rects * numRects,
  890.                             0);
  891.    if (!cmd)
  892.       return PIPE_ERROR_OUT_OF_MEMORY;
  893.  
  894.    cmd->cid = swc->cid;
  895.    cmd->clearFlag = flags;
  896.    cmd->color = color;
  897.    cmd->depth = depth;
  898.    cmd->stencil = stencil;
  899.    *rects = (SVGA3dRect*) &cmd[1];
  900.  
  901.    return PIPE_OK;
  902. }
  903.  
  904.  
  905. /*
  906.  *----------------------------------------------------------------------
  907.  *
  908.  * SVGA3D_ClearRect --
  909.  *
  910.  *      This is a simplified version of SVGA3D_BeginClear().
  911.  *
  912.  * Results:
  913.  *      None.
  914.  *
  915.  * Side effects:
  916.  *      None.
  917.  *
  918.  *----------------------------------------------------------------------
  919.  */
  920.  
  921. enum pipe_error
  922. SVGA3D_ClearRect(struct svga_winsys_context *swc,
  923.                  SVGA3dClearFlag flags,  // IN
  924.                  uint32 color,           // IN
  925.                  float depth,            // IN
  926.                  uint32 stencil,         // IN
  927.                  uint32 x,               // IN
  928.                  uint32 y,               // IN
  929.                  uint32 w,               // IN
  930.                  uint32 h)               // IN
  931. {
  932.    SVGA3dRect *rect;
  933.    enum pipe_error ret;
  934.  
  935.    ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
  936.    if (ret != PIPE_OK)
  937.       return PIPE_ERROR_OUT_OF_MEMORY;
  938.  
  939.    memset(rect, 0, sizeof *rect);
  940.    rect->x = x;
  941.    rect->y = y;
  942.    rect->w = w;
  943.    rect->h = h;
  944.    swc->commit(swc);
  945.  
  946.    return PIPE_OK;
  947. }
  948.  
  949.  
  950. /*
  951.  *----------------------------------------------------------------------
  952.  *
  953.  * SVGA3D_BeginDrawPrimitives --
  954.  *
  955.  *      Begin a DRAW_PRIMITIVES command. This reserves space for it in
  956.  *      the FIFO, and returns a pointer to the command's arrays.
  957.  *      This function must be paired with SVGA_FIFOCommitAll().
  958.  *
  959.  *      Drawing commands consist of two variable-length arrays:
  960.  *      SVGA3dVertexDecl elements declare a set of vertex buffers to
  961.  *      use while rendering, and SVGA3dPrimitiveRange elements specify
  962.  *      groups of primitives each with an optional index buffer.
  963.  *
  964.  *      The decls and ranges arrays are initialized to zero.
  965.  *
  966.  * Results:
  967.  *      None.
  968.  *
  969.  * Side effects:
  970.  *      May write to attached render target surfaces.
  971.  *
  972.  *----------------------------------------------------------------------
  973.  */
  974.  
  975. enum pipe_error
  976. SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
  977.                            SVGA3dVertexDecl **decls,      // OUT
  978.                            uint32 numVertexDecls,         // IN
  979.                            SVGA3dPrimitiveRange **ranges, // OUT
  980.                            uint32 numRanges)              // IN
  981. {
  982.    SVGA3dCmdDrawPrimitives *cmd;
  983.    SVGA3dVertexDecl *declArray;
  984.    SVGA3dPrimitiveRange *rangeArray;
  985.    uint32 declSize = sizeof **decls * numVertexDecls;
  986.    uint32 rangeSize = sizeof **ranges * numRanges;
  987.  
  988.    cmd = SVGA3D_FIFOReserve(swc,
  989.                             SVGA_3D_CMD_DRAW_PRIMITIVES,
  990.                             sizeof *cmd + declSize + rangeSize,
  991.                             numVertexDecls + numRanges);
  992.    if (!cmd)
  993.       return PIPE_ERROR_OUT_OF_MEMORY;
  994.  
  995.    cmd->cid = swc->cid;
  996.    cmd->numVertexDecls = numVertexDecls;
  997.    cmd->numRanges = numRanges;
  998.  
  999.    declArray = (SVGA3dVertexDecl*) &cmd[1];
  1000.    rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
  1001.  
  1002.    memset(declArray, 0, declSize);
  1003.    memset(rangeArray, 0, rangeSize);
  1004.  
  1005.    *decls = declArray;
  1006.    *ranges = rangeArray;
  1007.  
  1008.    return PIPE_OK;
  1009. }
  1010.  
  1011.  
  1012. /*
  1013.  *----------------------------------------------------------------------
  1014.  *
  1015.  * SVGA3D_BeginSurfaceCopy --
  1016.  *
  1017.  *      Begin a SURFACE_COPY command. This reserves space for it in
  1018.  *      the FIFO, and returns a pointer to the command's arrays.  This
  1019.  *      function must be paired with SVGA_FIFOCommitAll().
  1020.  *
  1021.  *      The box array is initialized with zeroes.
  1022.  *
  1023.  * Results:
  1024.  *      None.
  1025.  *
  1026.  * Side effects:
  1027.  *      Asynchronously copies a list of boxes from surface to surface.
  1028.  *
  1029.  *----------------------------------------------------------------------
  1030.  */
  1031.  
  1032. enum pipe_error
  1033. SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
  1034.                         struct pipe_surface *src,    // IN
  1035.                         struct pipe_surface *dest,   // IN
  1036.                         SVGA3dCopyBox **boxes,       // OUT
  1037.                         uint32 numBoxes)             // IN
  1038. {
  1039.    SVGA3dCmdSurfaceCopy *cmd;
  1040.    uint32 boxesSize = sizeof **boxes * numBoxes;
  1041.  
  1042.    cmd = SVGA3D_FIFOReserve(swc,
  1043.                             SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
  1044.                             2);
  1045.    if (!cmd)
  1046.       return PIPE_ERROR_OUT_OF_MEMORY;
  1047.  
  1048.    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
  1049.    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
  1050.    *boxes = (SVGA3dCopyBox*) &cmd[1];
  1051.  
  1052.    memset(*boxes, 0, boxesSize);
  1053.  
  1054.    return PIPE_OK;
  1055. }
  1056.  
  1057.  
  1058. /*
  1059.  *----------------------------------------------------------------------
  1060.  *
  1061.  * SVGA3D_SurfaceStretchBlt --
  1062.  *
  1063.  *      Issue a SURFACE_STRETCHBLT command: an asynchronous
  1064.  *      surface-to-surface blit, with scaling.
  1065.  *
  1066.  * Results:
  1067.  *      None.
  1068.  *
  1069.  * Side effects:
  1070.  *      Asynchronously copies one box from surface to surface.
  1071.  *
  1072.  *----------------------------------------------------------------------
  1073.  */
  1074.  
  1075. enum pipe_error
  1076. SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
  1077.                          struct pipe_surface *src,    // IN
  1078.                          struct pipe_surface *dest,   // IN
  1079.                          SVGA3dBox *boxSrc,           // IN
  1080.                          SVGA3dBox *boxDest,          // IN
  1081.                          SVGA3dStretchBltMode mode)   // IN
  1082. {
  1083.    SVGA3dCmdSurfaceStretchBlt *cmd;
  1084.  
  1085.    cmd = SVGA3D_FIFOReserve(swc,
  1086.                             SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
  1087.                             2);
  1088.    if (!cmd)
  1089.       return PIPE_ERROR_OUT_OF_MEMORY;
  1090.  
  1091.    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
  1092.    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
  1093.    cmd->boxSrc = *boxSrc;
  1094.    cmd->boxDest = *boxDest;
  1095.    cmd->mode = mode;
  1096.    swc->commit(swc);
  1097.  
  1098.    return PIPE_OK;
  1099. }
  1100.  
  1101.  
  1102. /*
  1103.  *----------------------------------------------------------------------
  1104.  *
  1105.  * SVGA3D_SetViewport --
  1106.  *
  1107.  *      Set the current context's viewport rectangle. The viewport
  1108.  *      is clipped to the dimensions of the current render target,
  1109.  *      then all rendering is clipped to the viewport.
  1110.  *
  1111.  * Results:
  1112.  *      None.
  1113.  *
  1114.  * Side effects:
  1115.  *      None.
  1116.  *
  1117.  *----------------------------------------------------------------------
  1118.  */
  1119.  
  1120. enum pipe_error
  1121. SVGA3D_SetViewport(struct svga_winsys_context *swc,
  1122.                    SVGA3dRect *rect)  // IN
  1123. {
  1124.    SVGA3dCmdSetViewport *cmd;
  1125.  
  1126.    cmd = SVGA3D_FIFOReserve(swc,
  1127.                             SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
  1128.                             0);
  1129.    if (!cmd)
  1130.       return PIPE_ERROR_OUT_OF_MEMORY;
  1131.  
  1132.    cmd->cid = swc->cid;
  1133.    cmd->rect = *rect;
  1134.    swc->commit(swc);
  1135.  
  1136.    return PIPE_OK;
  1137. }
  1138.  
  1139.  
  1140.  
  1141.  
  1142. /*
  1143.  *----------------------------------------------------------------------
  1144.  *
  1145.  * SVGA3D_SetScissorRect --
  1146.  *
  1147.  *      Set the current context's scissor rectangle. If scissoring
  1148.  *      is enabled then all rendering is clipped to the scissor bounds.
  1149.  *
  1150.  * Results:
  1151.  *      None.
  1152.  *
  1153.  * Side effects:
  1154.  *      None.
  1155.  *
  1156.  *----------------------------------------------------------------------
  1157.  */
  1158.  
  1159. enum pipe_error
  1160. SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
  1161.                       SVGA3dRect *rect)  // IN
  1162. {
  1163.    SVGA3dCmdSetScissorRect *cmd;
  1164.  
  1165.    cmd = SVGA3D_FIFOReserve(swc,
  1166.                             SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
  1167.                             0);
  1168.    if (!cmd)
  1169.       return PIPE_ERROR_OUT_OF_MEMORY;
  1170.  
  1171.    cmd->cid = swc->cid;
  1172.    cmd->rect = *rect;
  1173.    swc->commit(swc);
  1174.  
  1175.    return PIPE_OK;
  1176. }
  1177.  
  1178. /*
  1179.  *----------------------------------------------------------------------
  1180.  *
  1181.  * SVGA3D_SetClipPlane --
  1182.  *
  1183.  *      Set one of the current context's clip planes. If the clip
  1184.  *      plane is enabled then all 3d rendering is clipped against
  1185.  *      the plane.
  1186.  *
  1187.  * Results:
  1188.  *      None.
  1189.  *
  1190.  * Side effects:
  1191.  *      None.
  1192.  *
  1193.  *----------------------------------------------------------------------
  1194.  */
  1195.  
  1196. enum pipe_error
  1197. SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
  1198.                     uint32 index, const float *plane)
  1199. {
  1200.    SVGA3dCmdSetClipPlane *cmd;
  1201.  
  1202.    cmd = SVGA3D_FIFOReserve(swc,
  1203.                             SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
  1204.                             0);
  1205.    if (!cmd)
  1206.       return PIPE_ERROR_OUT_OF_MEMORY;
  1207.  
  1208.    cmd->cid = swc->cid;
  1209.    cmd->index = index;
  1210.    cmd->plane[0] = plane[0];
  1211.    cmd->plane[1] = plane[1];
  1212.    cmd->plane[2] = plane[2];
  1213.    cmd->plane[3] = plane[3];
  1214.    swc->commit(swc);
  1215.  
  1216.    return PIPE_OK;
  1217. }
  1218.  
  1219. /*
  1220.  *----------------------------------------------------------------------
  1221.  *
  1222.  * SVGA3D_SetZRange --
  1223.  *
  1224.  *      Set the range of the depth buffer to use. 'min' and 'max'
  1225.  *      are values between 0.0 and 1.0.
  1226.  *
  1227.  * Results:
  1228.  *      None.
  1229.  *
  1230.  * Side effects:
  1231.  *      None.
  1232.  *
  1233.  *----------------------------------------------------------------------
  1234.  */
  1235.  
  1236. enum pipe_error
  1237. SVGA3D_SetZRange(struct svga_winsys_context *swc,
  1238.                  float zMin,  // IN
  1239.                  float zMax)  // IN
  1240. {
  1241.    SVGA3dCmdSetZRange *cmd;
  1242.  
  1243.    cmd = SVGA3D_FIFOReserve(swc,
  1244.                             SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
  1245.                             0);
  1246.    if (!cmd)
  1247.       return PIPE_ERROR_OUT_OF_MEMORY;
  1248.  
  1249.    cmd->cid = swc->cid;
  1250.    cmd->zRange.min = zMin;
  1251.    cmd->zRange.max = zMax;
  1252.    swc->commit(swc);
  1253.  
  1254.    return PIPE_OK;
  1255. }
  1256.  
  1257.  
  1258. /*
  1259.  *----------------------------------------------------------------------
  1260.  *
  1261.  * SVGA3D_BeginSetTextureState --
  1262.  *
  1263.  *      Begin a SETTEXTURESTATE command. This reserves space for it in
  1264.  *      the FIFO, and returns a pointer to the command's texture state
  1265.  *      array.  This function must be paired with SVGA_FIFOCommitAll().
  1266.  *
  1267.  *      This command sets rendering state which is per-texture-unit.
  1268.  *
  1269.  *      XXX: Individual texture states need documentation. However,
  1270.  *           they are very similar to the texture states defined by
  1271.  *           Direct3D. The D3D documentation is a good starting point
  1272.  *           for understanding SVGA3D texture states.
  1273.  *
  1274.  * Results:
  1275.  *      None.
  1276.  *
  1277.  * Side effects:
  1278.  *      None.
  1279.  *
  1280.  *----------------------------------------------------------------------
  1281.  */
  1282.  
  1283. enum pipe_error
  1284. SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
  1285.                             SVGA3dTextureState **states,  // OUT
  1286.                             uint32 numStates)             // IN
  1287. {
  1288.    SVGA3dCmdSetTextureState *cmd;
  1289.  
  1290.    cmd = SVGA3D_FIFOReserve(swc,
  1291.                             SVGA_3D_CMD_SETTEXTURESTATE,
  1292.                             sizeof *cmd + sizeof **states * numStates,
  1293.                             numStates);
  1294.    if (!cmd)
  1295.       return PIPE_ERROR_OUT_OF_MEMORY;
  1296.  
  1297.    cmd->cid = swc->cid;
  1298.    *states = (SVGA3dTextureState*) &cmd[1];
  1299.  
  1300.    return PIPE_OK;
  1301. }
  1302.  
  1303.  
  1304. /*
  1305.  *----------------------------------------------------------------------
  1306.  *
  1307.  * SVGA3D_BeginSetRenderState --
  1308.  *
  1309.  *      Begin a SETRENDERSTATE command. This reserves space for it in
  1310.  *      the FIFO, and returns a pointer to the command's texture state
  1311.  *      array.  This function must be paired with SVGA_FIFOCommitAll().
  1312.  *
  1313.  *      This command sets rendering state which is global to the context.
  1314.  *
  1315.  *      XXX: Individual render states need documentation. However,
  1316.  *           they are very similar to the render states defined by
  1317.  *           Direct3D. The D3D documentation is a good starting point
  1318.  *           for understanding SVGA3D render states.
  1319.  *
  1320.  * Results:
  1321.  *      None.
  1322.  *
  1323.  * Side effects:
  1324.  *      None.
  1325.  *
  1326.  *----------------------------------------------------------------------
  1327.  */
  1328.  
  1329. enum pipe_error
  1330. SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
  1331.                            SVGA3dRenderState **states,  // OUT
  1332.                            uint32 numStates)            // IN
  1333. {
  1334.    SVGA3dCmdSetRenderState *cmd;
  1335.  
  1336.    cmd = SVGA3D_FIFOReserve(swc,
  1337.                             SVGA_3D_CMD_SETRENDERSTATE,
  1338.                             sizeof *cmd + sizeof **states * numStates,
  1339.                             0);
  1340.    if (!cmd)
  1341.       return PIPE_ERROR_OUT_OF_MEMORY;
  1342.  
  1343.    cmd->cid = swc->cid;
  1344.    *states = (SVGA3dRenderState*) &cmd[1];
  1345.  
  1346.    return PIPE_OK;
  1347. }
  1348.  
  1349.  
  1350. /*
  1351.  *----------------------------------------------------------------------
  1352.  *
  1353.  * SVGA3D_BeginQuery--
  1354.  *
  1355.  *      Issues a SVGA_3D_CMD_BEGIN_QUERY command.
  1356.  *
  1357.  * Results:
  1358.  *      None.
  1359.  *
  1360.  * Side effects:
  1361.  *      Commits space in the FIFO memory.
  1362.  *
  1363.  *----------------------------------------------------------------------
  1364.  */
  1365.  
  1366. enum pipe_error
  1367. SVGA3D_BeginQuery(struct svga_winsys_context *swc,
  1368.                   SVGA3dQueryType type) // IN
  1369. {
  1370.    SVGA3dCmdBeginQuery *cmd;
  1371.  
  1372.    cmd = SVGA3D_FIFOReserve(swc,
  1373.                             SVGA_3D_CMD_BEGIN_QUERY,
  1374.                             sizeof *cmd,
  1375.                             0);
  1376.    if (!cmd)
  1377.       return PIPE_ERROR_OUT_OF_MEMORY;
  1378.  
  1379.    cmd->cid = swc->cid;
  1380.    cmd->type = type;
  1381.  
  1382.    swc->commit(swc);
  1383.  
  1384.    return PIPE_OK;
  1385. }
  1386.  
  1387.  
  1388. /*
  1389.  *----------------------------------------------------------------------
  1390.  *
  1391.  * SVGA3D_EndQuery--
  1392.  *
  1393.  *      Issues a SVGA_3D_CMD_END_QUERY command.
  1394.  *
  1395.  * Results:
  1396.  *      None.
  1397.  *
  1398.  * Side effects:
  1399.  *      Commits space in the FIFO memory.
  1400.  *
  1401.  *----------------------------------------------------------------------
  1402.  */
  1403.  
  1404. enum pipe_error
  1405. SVGA3D_EndQuery(struct svga_winsys_context *swc,
  1406.                 SVGA3dQueryType type,              // IN
  1407.                 struct svga_winsys_buffer *buffer) // IN/OUT
  1408. {
  1409.    SVGA3dCmdEndQuery *cmd;
  1410.  
  1411.    cmd = SVGA3D_FIFOReserve(swc,
  1412.                             SVGA_3D_CMD_END_QUERY,
  1413.                             sizeof *cmd,
  1414.                             1);
  1415.    if (!cmd)
  1416.       return PIPE_ERROR_OUT_OF_MEMORY;
  1417.  
  1418.    cmd->cid = swc->cid;
  1419.    cmd->type = type;
  1420.  
  1421.    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
  1422.                           SVGA_RELOC_WRITE);
  1423.  
  1424.    swc->commit(swc);
  1425.  
  1426.    return PIPE_OK;
  1427. }
  1428.  
  1429.  
  1430. /*
  1431.  *----------------------------------------------------------------------
  1432.  *
  1433.  * SVGA3D_WaitForQuery--
  1434.  *
  1435.  *      Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command.  This reserves space
  1436.  *      for it in the FIFO.  This doesn't actually wait for the query to
  1437.  *      finish but instead tells the host to start a wait at the driver
  1438.  *      level.  The caller can wait on the status variable in the
  1439.  *      guestPtr memory or send an insert fence instruction after this
  1440.  *      command and wait on the fence.
  1441.  *
  1442.  * Results:
  1443.  *      None.
  1444.  *
  1445.  * Side effects:
  1446.  *      Commits space in the FIFO memory.
  1447.  *
  1448.  *----------------------------------------------------------------------
  1449.  */
  1450.  
  1451. enum pipe_error
  1452. SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
  1453.                     SVGA3dQueryType type,              // IN
  1454.                     struct svga_winsys_buffer *buffer) // IN/OUT
  1455. {
  1456.    SVGA3dCmdWaitForQuery *cmd;
  1457.  
  1458.    cmd = SVGA3D_FIFOReserve(swc,
  1459.                             SVGA_3D_CMD_WAIT_FOR_QUERY,
  1460.                             sizeof *cmd,
  1461.                             1);
  1462.    if (!cmd)
  1463.       return PIPE_ERROR_OUT_OF_MEMORY;
  1464.  
  1465.    cmd->cid = swc->cid;
  1466.    cmd->type = type;
  1467.  
  1468.    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
  1469.                           SVGA_RELOC_WRITE);
  1470.  
  1471.    swc->commit(swc);
  1472.  
  1473.    return PIPE_OK;
  1474. }
  1475.