Subversion Repositories Kolibri OS

Rev

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.  *
  49.  * param flags  mask of SVGA_RELOC_READ / _WRITE
  50.  *
  51.  * Results:
  52.  *      id is filled out.
  53.  *
  54.  * Side effects:
  55.  *      One surface relocation is performed for texture handle.
  56.  *
  57.  *----------------------------------------------------------------------
  58.  */
  59.  
  60. static INLINE void
  61. surface_to_surfaceid(struct svga_winsys_context *swc, // IN
  62.                      struct pipe_surface *surface,    // IN
  63.                      SVGA3dSurfaceImageId *id,        // OUT
  64.                      unsigned flags)                  // IN
  65. {
  66.    if (surface) {
  67.       struct svga_surface *s = svga_surface(surface);
  68.       swc->surface_relocation(swc, &id->sid, NULL, s->handle, flags);
  69.       id->face = s->real_face; /* faces have the same order */
  70.       id->mipmap = s->real_level;
  71.    }
  72.    else {
  73.       swc->surface_relocation(swc, &id->sid, NULL, NULL, flags);
  74.       id->face = 0;
  75.       id->mipmap = 0;
  76.    }
  77. }
  78.  
  79.  
  80. /*
  81.  *----------------------------------------------------------------------
  82.  *
  83.  * SVGA3D_FIFOReserve --
  84.  *
  85.  *      Reserve space for an SVGA3D FIFO command.
  86.  *
  87.  *      The 2D SVGA commands have been around for a while, so they
  88.  *      have a rather asymmetric structure. The SVGA3D protocol is
  89.  *      more uniform: each command begins with a header containing the
  90.  *      command number and the full size.
  91.  *
  92.  *      This is a convenience wrapper around SVGA_FIFOReserve. We
  93.  *      reserve space for the whole command, and write the header.
  94.  *
  95.  *      This function must be paired with SVGA_FIFOCommitAll().
  96.  *
  97.  * Results:
  98.  *      Returns a pointer to the space reserved for command-specific
  99.  *      data. It must be 'cmdSize' bytes long.
  100.  *
  101.  * Side effects:
  102.  *      Begins a FIFO reservation.
  103.  *
  104.  *----------------------------------------------------------------------
  105.  */
  106.  
  107. void *
  108. SVGA3D_FIFOReserve(struct svga_winsys_context *swc,
  109.                    uint32 cmd,       // IN
  110.                    uint32 cmdSize,   // IN
  111.                    uint32 nr_relocs) // IN
  112. {
  113.    SVGA3dCmdHeader *header;
  114.  
  115.    header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs);
  116.    if (!header)
  117.       return NULL;
  118.  
  119.    header->id = cmd;
  120.    header->size = cmdSize;
  121.  
  122.    return &header[1];
  123. }
  124.  
  125.  
  126. void
  127. SVGA_FIFOCommitAll(struct svga_winsys_context *swc)
  128. {
  129.    swc->commit(swc);
  130. }
  131.  
  132.  
  133. /*
  134.  *----------------------------------------------------------------------
  135.  *
  136.  * SVGA3D_DefineContext --
  137.  *
  138.  *      Create a new context, to be referred to with the provided ID.
  139.  *
  140.  *      Context objects encapsulate all render state, and shader
  141.  *      objects are per-context.
  142.  *
  143.  *      Surfaces are not per-context. The same surface can be shared
  144.  *      between multiple contexts, and surface operations can occur
  145.  *      without a context.
  146.  *
  147.  *      If the provided context ID already existed, it is redefined.
  148.  *
  149.  *      Context IDs are arbitrary small non-negative integers,
  150.  *      global to the entire SVGA device.
  151.  *
  152.  * Results:
  153.  *      None.
  154.  *
  155.  * Side effects:
  156.  *      None.
  157.  *
  158.  *----------------------------------------------------------------------
  159.  */
  160.  
  161. enum pipe_error
  162. SVGA3D_DefineContext(struct svga_winsys_context *swc)  // IN
  163. {
  164.    SVGA3dCmdDefineContext *cmd;
  165.  
  166.    cmd = SVGA3D_FIFOReserve(swc,
  167.                             SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0);
  168.    if (!cmd)
  169.       return PIPE_ERROR_OUT_OF_MEMORY;
  170.  
  171.    cmd->cid = swc->cid;
  172.  
  173.    swc->commit(swc);
  174.  
  175.    return PIPE_OK;
  176. }
  177.  
  178.  
  179. /*
  180.  *----------------------------------------------------------------------
  181.  *
  182.  * SVGA3D_DestroyContext --
  183.  *
  184.  *      Delete a context created with SVGA3D_DefineContext.
  185.  *
  186.  * Results:
  187.  *      None.
  188.  *
  189.  * Side effects:
  190.  *      None.
  191.  *
  192.  *----------------------------------------------------------------------
  193.  */
  194.  
  195. enum pipe_error
  196. SVGA3D_DestroyContext(struct svga_winsys_context *swc)  // IN
  197. {
  198.    SVGA3dCmdDestroyContext *cmd;
  199.  
  200.    cmd = SVGA3D_FIFOReserve(swc,
  201.                             SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0);
  202.    if (!cmd)
  203.       return PIPE_ERROR_OUT_OF_MEMORY;
  204.  
  205.    cmd->cid = swc->cid;
  206.  
  207.    swc->commit(swc);
  208.  
  209.    return PIPE_OK;
  210. }
  211.  
  212.  
  213. /*
  214.  *----------------------------------------------------------------------
  215.  *
  216.  * SVGA3D_BeginDefineSurface --
  217.  *
  218.  *      Begin a SURFACE_DEFINE command. This reserves space for it in
  219.  *      the FIFO, and returns pointers to the command's faces and
  220.  *      mipsizes arrays.
  221.  *
  222.  *      This function must be paired with SVGA_FIFOCommitAll().
  223.  *      The faces and mipSizes arrays are initialized to zero.
  224.  *
  225.  *      This creates a "surface" object in the SVGA3D device,
  226.  *      with the provided surface ID (sid). Surfaces are generic
  227.  *      containers for host VRAM objects like textures, vertex
  228.  *      buffers, and depth/stencil buffers.
  229.  *
  230.  *      Surfaces are hierarchical:
  231.  *
  232.  *        - Surface may have multiple faces (for cube maps)
  233.  *
  234.  *          - Each face has a list of mipmap levels
  235.  *
  236.  *             - Each mipmap image may have multiple volume
  237.  *               slices, if the image is three dimensional.
  238.  *
  239.  *                - Each slice is a 2D array of 'blocks'
  240.  *
  241.  *                   - Each block may be one or more pixels.
  242.  *                     (Usually 1, more for DXT or YUV formats.)
  243.  *
  244.  *      Surfaces are generic host VRAM objects. The SVGA3D device
  245.  *      may optimize surfaces according to the format they were
  246.  *      created with, but this format does not limit the ways in
  247.  *      which the surface may be used. For example, a depth surface
  248.  *      can be used as a texture, or a floating point image may
  249.  *      be used as a vertex buffer. Some surface usages may be
  250.  *      lower performance, due to software emulation, but any
  251.  *      usage should work with any surface.
  252.  *
  253.  *      If 'sid' is already defined, the old surface is deleted
  254.  *      and this new surface replaces it.
  255.  *
  256.  *      Surface IDs are arbitrary small non-negative integers,
  257.  *      global to the entire SVGA device.
  258.  *
  259.  * Results:
  260.  *      Returns pointers to arrays allocated in the FIFO for 'faces'
  261.  *      and 'mipSizes'.
  262.  *
  263.  * Side effects:
  264.  *      Begins a FIFO reservation.
  265.  *
  266.  *----------------------------------------------------------------------
  267.  */
  268.  
  269. enum pipe_error
  270. SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
  271.                           struct svga_winsys_surface *sid, // IN
  272.                           SVGA3dSurfaceFlags flags,    // IN
  273.                           SVGA3dSurfaceFormat format,  // IN
  274.                           SVGA3dSurfaceFace **faces,   // OUT
  275.                           SVGA3dSize **mipSizes,       // OUT
  276.                           uint32 numMipSizes)          // IN
  277. {
  278.    SVGA3dCmdDefineSurface *cmd;
  279.  
  280.    cmd = SVGA3D_FIFOReserve(swc,
  281.                             SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +
  282.                             sizeof **mipSizes * numMipSizes, 1);
  283.    if (!cmd)
  284.       return PIPE_ERROR_OUT_OF_MEMORY;
  285.  
  286.    swc->surface_relocation(swc, &cmd->sid, NULL, sid,
  287.                            SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
  288.    cmd->surfaceFlags = flags;
  289.    cmd->format = format;
  290.  
  291.    *faces = &cmd->face[0];
  292.    *mipSizes = (SVGA3dSize*) &cmd[1];
  293.  
  294.    memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);
  295.    memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);
  296.  
  297.    return PIPE_OK;
  298. }
  299.  
  300.  
  301. /*
  302.  *----------------------------------------------------------------------
  303.  *
  304.  * SVGA3D_DefineSurface2D --
  305.  *
  306.  *      This is a simplified version of SVGA3D_BeginDefineSurface(),
  307.  *      which does not support cube maps, mipmaps, or volume textures.
  308.  *
  309.  * Results:
  310.  *      None.
  311.  *
  312.  * Side effects:
  313.  *      None.
  314.  *
  315.  *----------------------------------------------------------------------
  316.  */
  317.  
  318. enum pipe_error
  319. SVGA3D_DefineSurface2D(struct svga_winsys_context *swc,    // IN
  320.                        struct svga_winsys_surface *sid, // IN
  321.                        uint32 width,                // IN
  322.                        uint32 height,               // IN
  323.                        SVGA3dSurfaceFormat format)  // IN
  324. {
  325.    SVGA3dSize *mipSizes;
  326.    SVGA3dSurfaceFace *faces;
  327.    enum pipe_error ret;
  328.  
  329.    ret = SVGA3D_BeginDefineSurface(swc,
  330.                                    sid, 0, format, &faces, &mipSizes, 1);
  331.    if (ret != PIPE_OK)
  332.       return ret;
  333.  
  334.    faces[0].numMipLevels = 1;
  335.  
  336.    mipSizes[0].width = width;
  337.    mipSizes[0].height = height;
  338.    mipSizes[0].depth = 1;
  339.  
  340.    swc->commit(swc);;
  341.  
  342.    return PIPE_OK;
  343. }
  344.  
  345.  
  346. /*
  347.  *----------------------------------------------------------------------
  348.  *
  349.  * SVGA3D_DestroySurface --
  350.  *
  351.  *      Release the host VRAM encapsulated by a particular surface ID.
  352.  *
  353.  * Results:
  354.  *      None.
  355.  *
  356.  * Side effects:
  357.  *      None.
  358.  *
  359.  *----------------------------------------------------------------------
  360.  */
  361.  
  362. enum pipe_error
  363. SVGA3D_DestroySurface(struct svga_winsys_context *swc,
  364.                       struct svga_winsys_surface *sid)  // IN
  365. {
  366.    SVGA3dCmdDestroySurface *cmd;
  367.  
  368.    cmd = SVGA3D_FIFOReserve(swc,
  369.                             SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);
  370.    if (!cmd)
  371.       return PIPE_ERROR_OUT_OF_MEMORY;
  372.    
  373.    swc->surface_relocation(swc, &cmd->sid, NULL, sid,
  374.                            SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
  375.    swc->commit(swc);;
  376.  
  377.    return PIPE_OK;
  378. }
  379.  
  380.  
  381. /*
  382.  *----------------------------------------------------------------------
  383.  *
  384.  * SVGA3D_SurfaceDMA--
  385.  *
  386.  *      Emit a SURFACE_DMA command.
  387.  *
  388.  *      When the SVGA3D device asynchronously processes this FIFO
  389.  *      command, a DMA operation is performed between host VRAM and
  390.  *      a generic SVGAGuestPtr. The guest pointer may refer to guest
  391.  *      VRAM (provided by the SVGA PCI device) or to guest system
  392.  *      memory that has been set up as a Guest Memory Region (GMR)
  393.  *      by the SVGA device.
  394.  *
  395.  *      The guest's DMA buffer must remain valid (not freed, paged out,
  396.  *      or overwritten) until the host has finished processing this
  397.  *      command. The guest can determine that the host has finished
  398.  *      by using the SVGA device's FIFO Fence mechanism.
  399.  *
  400.  *      The guest's image buffer can be an arbitrary size and shape.
  401.  *      Guest image data is interpreted according to the SVGA3D surface
  402.  *      format specified when the surface was defined.
  403.  *
  404.  *      The caller may optionally define the guest image's pitch.
  405.  *      guestImage->pitch can either be zero (assume image is tightly
  406.  *      packed) or it must be the number of bytes between vertically
  407.  *      adjacent image blocks.
  408.  *
  409.  *      The provided copybox list specifies which regions of the source
  410.  *      image are to be copied, and where they appear on the destination.
  411.  *
  412.  *      NOTE: srcx/srcy are always on the guest image and x/y are
  413.  *      always on the host image, regardless of the actual transfer
  414.  *      direction!
  415.  *
  416.  *      For efficiency, the SVGA3D device is free to copy more data
  417.  *      than specified. For example, it may round copy boxes outwards
  418.  *      such that they lie on particular alignment boundaries.
  419.  *
  420.  *----------------------------------------------------------------------
  421.  */
  422.  
  423. enum pipe_error
  424. SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
  425.                   struct svga_transfer *st,         // IN
  426.                   SVGA3dTransferType transfer,      // IN
  427.                   const SVGA3dCopyBox *boxes,       // IN
  428.                   uint32 numBoxes,                  // IN
  429.                   SVGA3dSurfaceDMAFlags flags)      // IN
  430. {
  431.    struct svga_texture *texture = svga_texture(st->base.resource);
  432.    SVGA3dCmdSurfaceDMA *cmd;
  433.    SVGA3dCmdSurfaceDMASuffix *pSuffix;
  434.    uint32 boxesSize = sizeof *boxes * numBoxes;
  435.    unsigned region_flags;
  436.    unsigned surface_flags;
  437.  
  438.    if (transfer == SVGA3D_WRITE_HOST_VRAM) {
  439.       region_flags = SVGA_RELOC_READ;
  440.       surface_flags = SVGA_RELOC_WRITE;
  441.    }
  442.    else if (transfer == SVGA3D_READ_HOST_VRAM) {
  443.       region_flags = SVGA_RELOC_WRITE;
  444.       surface_flags = SVGA_RELOC_READ;
  445.    }
  446.    else {
  447.       assert(0);
  448.       return PIPE_ERROR_BAD_INPUT;
  449.    }
  450.  
  451.    cmd = SVGA3D_FIFOReserve(swc,
  452.                             SVGA_3D_CMD_SURFACE_DMA,
  453.                             sizeof *cmd + boxesSize + sizeof *pSuffix,
  454.                             2);
  455.    if (!cmd)
  456.       return PIPE_ERROR_OUT_OF_MEMORY;
  457.  
  458.    swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
  459.    cmd->guest.pitch = st->base.stride;
  460.  
  461.    swc->surface_relocation(swc, &cmd->host.sid, NULL,
  462.                            texture->handle, surface_flags);
  463.    cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
  464.    cmd->host.mipmap = st->base.level;
  465.  
  466.    cmd->transfer = transfer;
  467.  
  468.    memcpy(&cmd[1], boxes, boxesSize);
  469.  
  470.    pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
  471.    pSuffix->suffixSize = sizeof *pSuffix;
  472.    pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
  473.    pSuffix->flags = flags;
  474.  
  475.    swc->commit(swc);
  476.  
  477.    return PIPE_OK;
  478. }
  479.  
  480.  
  481. enum pipe_error
  482. SVGA3D_BufferDMA(struct svga_winsys_context *swc,
  483.                  struct svga_winsys_buffer *guest,
  484.                  struct svga_winsys_surface *host,
  485.                  SVGA3dTransferType transfer,      // IN
  486.                  uint32 size,                      // IN
  487.                  uint32 guest_offset,              // IN
  488.                  uint32 host_offset,               // IN
  489.                  SVGA3dSurfaceDMAFlags flags)      // IN
  490. {
  491.    SVGA3dCmdSurfaceDMA *cmd;
  492.    SVGA3dCopyBox *box;
  493.    SVGA3dCmdSurfaceDMASuffix *pSuffix;
  494.    unsigned region_flags;
  495.    unsigned surface_flags;
  496.    
  497.    assert(!swc->have_gb_objects);
  498.  
  499.    if (transfer == SVGA3D_WRITE_HOST_VRAM) {
  500.       region_flags = SVGA_RELOC_READ;
  501.       surface_flags = SVGA_RELOC_WRITE;
  502.    }
  503.    else if (transfer == SVGA3D_READ_HOST_VRAM) {
  504.       region_flags = SVGA_RELOC_WRITE;
  505.       surface_flags = SVGA_RELOC_READ;
  506.    }
  507.    else {
  508.       assert(0);
  509.       return PIPE_ERROR_BAD_INPUT;
  510.    }
  511.  
  512.    cmd = SVGA3D_FIFOReserve(swc,
  513.                             SVGA_3D_CMD_SURFACE_DMA,
  514.                             sizeof *cmd + sizeof *box + sizeof *pSuffix,
  515.                             2);
  516.    if (!cmd)
  517.       return PIPE_ERROR_OUT_OF_MEMORY;
  518.  
  519.    swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
  520.    cmd->guest.pitch = 0;
  521.  
  522.    swc->surface_relocation(swc, &cmd->host.sid,
  523.                            NULL, host, surface_flags);
  524.    cmd->host.face = 0;
  525.    cmd->host.mipmap = 0;
  526.  
  527.    cmd->transfer = transfer;
  528.  
  529.    box = (SVGA3dCopyBox *)&cmd[1];
  530.    box->x = host_offset;
  531.    box->y = 0;
  532.    box->z = 0;
  533.    box->w = size;
  534.    box->h = 1;
  535.    box->d = 1;
  536.    box->srcx = guest_offset;
  537.    box->srcy = 0;
  538.    box->srcz = 0;
  539.  
  540.    pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
  541.    pSuffix->suffixSize = sizeof *pSuffix;
  542.    pSuffix->maximumOffset = guest_offset + size;
  543.    pSuffix->flags = flags;
  544.  
  545.    swc->commit(swc);
  546.  
  547.    return PIPE_OK;
  548. }
  549.  
  550.  
  551. /*
  552.  *----------------------------------------------------------------------
  553.  *
  554.  * SVGA3D_SetRenderTarget --
  555.  *
  556.  *      Bind a surface object to a particular render target attachment
  557.  *      point on the current context. Render target attachment points
  558.  *      exist for color buffers, a depth buffer, and a stencil buffer.
  559.  *
  560.  *      The SVGA3D device is quite lenient about the types of surfaces
  561.  *      that may be used as render targets. The color buffers must
  562.  *      all be the same size, but the depth and stencil buffers do not
  563.  *      have to be the same size as the color buffer. All attachments
  564.  *      are optional.
  565.  *
  566.  *      Some combinations of render target formats may require software
  567.  *      emulation, depending on the capabilities of the host graphics
  568.  *      API and graphics hardware.
  569.  *
  570.  * Results:
  571.  *      None.
  572.  *
  573.  * Side effects:
  574.  *      None.
  575.  *
  576.  *----------------------------------------------------------------------
  577.  */
  578.  
  579. enum pipe_error
  580. SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
  581.                        SVGA3dRenderTargetType type,   // IN
  582.                        struct pipe_surface *surface)  // IN
  583. {
  584.    SVGA3dCmdSetRenderTarget *cmd;
  585.  
  586.    cmd = SVGA3D_FIFOReserve(swc,
  587.                             SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);
  588.    if (!cmd)
  589.       return PIPE_ERROR_OUT_OF_MEMORY;
  590.  
  591.    cmd->cid = swc->cid;
  592.    cmd->type = type;
  593.    surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
  594.    swc->commit(swc);
  595.  
  596.    return PIPE_OK;
  597. }
  598.  
  599.  
  600. /*
  601.  *----------------------------------------------------------------------
  602.  *
  603.  * SVGA3D_DefineShader --
  604.  *
  605.  *      Upload the bytecode for a new shader. The bytecode is "SVGA3D
  606.  *      format", which is theoretically a binary-compatible superset
  607.  *      of Microsoft's DirectX shader bytecode. In practice, the
  608.  *      SVGA3D bytecode doesn't yet have any extensions to DirectX's
  609.  *      bytecode format.
  610.  *
  611.  *      The SVGA3D device supports shader models 1.1 through 2.0.
  612.  *
  613.  *      The caller chooses a shader ID (small positive integer) by
  614.  *      which this shader will be identified in future commands. This
  615.  *      ID is in a namespace which is per-context and per-shader-type.
  616.  *
  617.  *      'bytecodeLen' is specified in bytes. It must be a multiple of 4.
  618.  *
  619.  * Results:
  620.  *      None.
  621.  *
  622.  * Side effects:
  623.  *      None.
  624.  *
  625.  *----------------------------------------------------------------------
  626.  */
  627.  
  628. enum pipe_error
  629. SVGA3D_DefineShader(struct svga_winsys_context *swc,
  630.                     uint32 shid,                  // IN
  631.                     SVGA3dShaderType type,        // IN
  632.                     const uint32 *bytecode,       // IN
  633.                     uint32 bytecodeLen)           // IN
  634. {
  635.    SVGA3dCmdDefineShader *cmd;
  636.  
  637.    assert(bytecodeLen % 4 == 0);
  638.  
  639.    cmd = SVGA3D_FIFOReserve(swc,
  640.                             SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,
  641.                             0);
  642.    if (!cmd)
  643.       return PIPE_ERROR_OUT_OF_MEMORY;
  644.  
  645.    cmd->cid = swc->cid;
  646.    cmd->shid = shid;
  647.    cmd->type = type;
  648.    memcpy(&cmd[1], bytecode, bytecodeLen);
  649.    swc->commit(swc);
  650.  
  651.    return PIPE_OK;
  652. }
  653.  
  654.  
  655. /*
  656.  *----------------------------------------------------------------------
  657.  *
  658.  * SVGA3D_DestroyShader --
  659.  *
  660.  *      Delete a shader that was created by SVGA3D_DefineShader. If
  661.  *      the shader was the current vertex or pixel shader for its
  662.  *      context, rendering results are undefined until a new shader is
  663.  *      bound.
  664.  *
  665.  * Results:
  666.  *      None.
  667.  *
  668.  * Side effects:
  669.  *      None.
  670.  *
  671.  *----------------------------------------------------------------------
  672.  */
  673.  
  674. enum pipe_error
  675. SVGA3D_DestroyShader(struct svga_winsys_context *swc,
  676.                      uint32 shid,            // IN
  677.                      SVGA3dShaderType type)  // IN
  678. {
  679.    SVGA3dCmdDestroyShader *cmd;
  680.  
  681.    cmd = SVGA3D_FIFOReserve(swc,
  682.                             SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,
  683.                             0);
  684.    if (!cmd)
  685.       return PIPE_ERROR_OUT_OF_MEMORY;
  686.  
  687.    cmd->cid = swc->cid;
  688.    cmd->shid = shid;
  689.    cmd->type = type;
  690.    swc->commit(swc);
  691.  
  692.    return PIPE_OK;
  693. }
  694.  
  695.  
  696. /*
  697.  *----------------------------------------------------------------------
  698.  *
  699.  * SVGA3D_SetShaderConst --
  700.  *
  701.  *      Set the value of a shader constant.
  702.  *
  703.  *      Shader constants are analogous to uniform variables in GLSL,
  704.  *      except that they belong to the render context rather than to
  705.  *      an individual shader.
  706.  *
  707.  *      Constants may have one of three types: A 4-vector of floats,
  708.  *      a 4-vector of integers, or a single boolean flag.
  709.  *
  710.  * Results:
  711.  *      None.
  712.  *
  713.  * Side effects:
  714.  *      None.
  715.  *
  716.  *----------------------------------------------------------------------
  717.  */
  718.  
  719. enum pipe_error
  720. SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
  721.                       uint32 reg,                   // IN
  722.                       SVGA3dShaderType type,        // IN
  723.                       SVGA3dShaderConstType ctype,  // IN
  724.                       const void *value)            // IN
  725. {
  726.    SVGA3dCmdSetShaderConst *cmd;
  727.  
  728.    cmd = SVGA3D_FIFOReserve(swc,
  729.                             SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,
  730.                             0);
  731.    if (!cmd)
  732.       return PIPE_ERROR_OUT_OF_MEMORY;
  733.  
  734.    cmd->cid = swc->cid;
  735.    cmd->reg = reg;
  736.    cmd->type = type;
  737.    cmd->ctype = ctype;
  738.  
  739.    switch (ctype) {
  740.  
  741.    case SVGA3D_CONST_TYPE_FLOAT:
  742.    case SVGA3D_CONST_TYPE_INT:
  743.       memcpy(&cmd->values, value, sizeof cmd->values);
  744.       break;
  745.  
  746.    case SVGA3D_CONST_TYPE_BOOL:
  747.       memset(&cmd->values, 0, sizeof cmd->values);
  748.       cmd->values[0] = *(uint32*)value;
  749.       break;
  750.  
  751.    default:
  752.       assert(0);
  753.       break;
  754.  
  755.    }
  756.    swc->commit(swc);
  757.  
  758.    return PIPE_OK;
  759. }
  760.  
  761.  
  762. /*
  763.  *----------------------------------------------------------------------
  764.  *
  765.  * SVGA3D_SetShaderConsts --
  766.  *
  767.  *      Set the value of successive shader constants.
  768.  *
  769.  *      Shader constants are analogous to uniform variables in GLSL,
  770.  *      except that they belong to the render context rather than to
  771.  *      an individual shader.
  772.  *
  773.  *      Constants may have one of three types: A 4-vector of floats,
  774.  *      a 4-vector of integers, or a single boolean flag.
  775.  *
  776.  * Results:
  777.  *      None.
  778.  *
  779.  * Side effects:
  780.  *      None.
  781.  *
  782.  *----------------------------------------------------------------------
  783.  */
  784.  
  785. enum pipe_error
  786. SVGA3D_SetShaderConsts(struct svga_winsys_context *swc,
  787.                         uint32 reg,                   // IN
  788.                         uint32 numRegs,               // IN
  789.                         SVGA3dShaderType type,        // IN
  790.                         SVGA3dShaderConstType ctype,  // IN
  791.                         const void *values)           // IN
  792. {
  793.    SVGA3dCmdSetShaderConst *cmd;
  794.  
  795.    cmd = SVGA3D_FIFOReserve(swc,
  796.                             SVGA_3D_CMD_SET_SHADER_CONST,
  797.                             sizeof *cmd + (numRegs - 1) * sizeof cmd->values,
  798.                             0);
  799.    if (!cmd)
  800.       return PIPE_ERROR_OUT_OF_MEMORY;
  801.  
  802.    cmd->cid = swc->cid;
  803.    cmd->reg = reg;
  804.    cmd->type = type;
  805.    cmd->ctype = ctype;
  806.  
  807.    memcpy(&cmd->values, values, numRegs * sizeof cmd->values);
  808.  
  809.    swc->commit(swc);
  810.  
  811.    return PIPE_OK;
  812. }
  813.  
  814.  
  815.  
  816.  
  817.  
  818. /*
  819.  *----------------------------------------------------------------------
  820.  *
  821.  * SVGA3D_SetShader --
  822.  *
  823.  *      Switch active shaders. This binds a new vertex or pixel shader
  824.  *      to the specified context.
  825.  *
  826.  *      A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
  827.  *      back to the fixed function vertex or pixel pipeline.
  828.  *
  829.  * Results:
  830.  *      None.
  831.  *
  832.  * Side effects:
  833.  *      None.
  834.  *
  835.  *----------------------------------------------------------------------
  836.  */
  837.  
  838. enum pipe_error
  839. SVGA3D_SetShader(struct svga_winsys_context *swc,
  840.                  SVGA3dShaderType type,  // IN
  841.                  uint32 shid)            // IN
  842. {
  843.    SVGA3dCmdSetShader *cmd;
  844.  
  845.    cmd = SVGA3D_FIFOReserve(swc,
  846.                             SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
  847.                             0);
  848.    if (!cmd)
  849.       return PIPE_ERROR_OUT_OF_MEMORY;
  850.  
  851.    cmd->cid = swc->cid;
  852.    cmd->type = type;
  853.    cmd->shid = shid;
  854.    swc->commit(swc);
  855.  
  856.    return PIPE_OK;
  857. }
  858.  
  859.  
  860. /*
  861.  *----------------------------------------------------------------------
  862.  *
  863.  * SVGA3D_BeginClear --
  864.  *
  865.  *      Begin a CLEAR command. This reserves space for it in the FIFO,
  866.  *      and returns a pointer to the command's rectangle array.  This
  867.  *      function must be paired with SVGA_FIFOCommitAll().
  868.  *
  869.  *      Clear is a rendering operation which fills a list of
  870.  *      rectangles with constant values on all render target types
  871.  *      indicated by 'flags'.
  872.  *
  873.  *      Clear is not affected by clipping, depth test, or other
  874.  *      render state which affects the fragment pipeline.
  875.  *
  876.  * Results:
  877.  *      None.
  878.  *
  879.  * Side effects:
  880.  *      May write to attached render target surfaces.
  881.  *
  882.  *----------------------------------------------------------------------
  883.  */
  884.  
  885. enum pipe_error
  886. SVGA3D_BeginClear(struct svga_winsys_context *swc,
  887.                   SVGA3dClearFlag flags,  // IN
  888.                   uint32 color,           // IN
  889.                   float depth,            // IN
  890.                   uint32 stencil,         // IN
  891.                   SVGA3dRect **rects,     // OUT
  892.                   uint32 numRects)        // IN
  893. {
  894.    SVGA3dCmdClear *cmd;
  895.  
  896.    cmd = SVGA3D_FIFOReserve(swc,
  897.                             SVGA_3D_CMD_CLEAR,
  898.                             sizeof *cmd + sizeof **rects * numRects,
  899.                             0);
  900.    if (!cmd)
  901.       return PIPE_ERROR_OUT_OF_MEMORY;
  902.  
  903.    cmd->cid = swc->cid;
  904.    cmd->clearFlag = flags;
  905.    cmd->color = color;
  906.    cmd->depth = depth;
  907.    cmd->stencil = stencil;
  908.    *rects = (SVGA3dRect*) &cmd[1];
  909.  
  910.    return PIPE_OK;
  911. }
  912.  
  913.  
  914. /*
  915.  *----------------------------------------------------------------------
  916.  *
  917.  * SVGA3D_ClearRect --
  918.  *
  919.  *      This is a simplified version of SVGA3D_BeginClear().
  920.  *
  921.  * Results:
  922.  *      None.
  923.  *
  924.  * Side effects:
  925.  *      None.
  926.  *
  927.  *----------------------------------------------------------------------
  928.  */
  929.  
  930. enum pipe_error
  931. SVGA3D_ClearRect(struct svga_winsys_context *swc,
  932.                  SVGA3dClearFlag flags,  // IN
  933.                  uint32 color,           // IN
  934.                  float depth,            // IN
  935.                  uint32 stencil,         // IN
  936.                  uint32 x,               // IN
  937.                  uint32 y,               // IN
  938.                  uint32 w,               // IN
  939.                  uint32 h)               // IN
  940. {
  941.    SVGA3dRect *rect;
  942.    enum pipe_error ret;
  943.  
  944.    ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
  945.    if (ret != PIPE_OK)
  946.       return PIPE_ERROR_OUT_OF_MEMORY;
  947.  
  948.    memset(rect, 0, sizeof *rect);
  949.    rect->x = x;
  950.    rect->y = y;
  951.    rect->w = w;
  952.    rect->h = h;
  953.    swc->commit(swc);
  954.  
  955.    return PIPE_OK;
  956. }
  957.  
  958.  
  959. /*
  960.  *----------------------------------------------------------------------
  961.  *
  962.  * SVGA3D_BeginDrawPrimitives --
  963.  *
  964.  *      Begin a DRAW_PRIMITIVES command. This reserves space for it in
  965.  *      the FIFO, and returns a pointer to the command's arrays.
  966.  *      This function must be paired with SVGA_FIFOCommitAll().
  967.  *
  968.  *      Drawing commands consist of two variable-length arrays:
  969.  *      SVGA3dVertexDecl elements declare a set of vertex buffers to
  970.  *      use while rendering, and SVGA3dPrimitiveRange elements specify
  971.  *      groups of primitives each with an optional index buffer.
  972.  *
  973.  *      The decls and ranges arrays are initialized to zero.
  974.  *
  975.  * Results:
  976.  *      None.
  977.  *
  978.  * Side effects:
  979.  *      May write to attached render target surfaces.
  980.  *
  981.  *----------------------------------------------------------------------
  982.  */
  983.  
  984. enum pipe_error
  985. SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
  986.                            SVGA3dVertexDecl **decls,      // OUT
  987.                            uint32 numVertexDecls,         // IN
  988.                            SVGA3dPrimitiveRange **ranges, // OUT
  989.                            uint32 numRanges)              // IN
  990. {
  991.    SVGA3dCmdDrawPrimitives *cmd;
  992.    SVGA3dVertexDecl *declArray;
  993.    SVGA3dPrimitiveRange *rangeArray;
  994.    uint32 declSize = sizeof **decls * numVertexDecls;
  995.    uint32 rangeSize = sizeof **ranges * numRanges;
  996.  
  997.    cmd = SVGA3D_FIFOReserve(swc,
  998.                             SVGA_3D_CMD_DRAW_PRIMITIVES,
  999.                             sizeof *cmd + declSize + rangeSize,
  1000.                             numVertexDecls + numRanges);
  1001.    if (!cmd)
  1002.       return PIPE_ERROR_OUT_OF_MEMORY;
  1003.  
  1004.    cmd->cid = swc->cid;
  1005.    cmd->numVertexDecls = numVertexDecls;
  1006.    cmd->numRanges = numRanges;
  1007.  
  1008.    declArray = (SVGA3dVertexDecl*) &cmd[1];
  1009.    rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
  1010.  
  1011.    memset(declArray, 0, declSize);
  1012.    memset(rangeArray, 0, rangeSize);
  1013.  
  1014.    *decls = declArray;
  1015.    *ranges = rangeArray;
  1016.  
  1017.    return PIPE_OK;
  1018. }
  1019.  
  1020.  
  1021. /*
  1022.  *----------------------------------------------------------------------
  1023.  *
  1024.  * SVGA3D_BeginSurfaceCopy --
  1025.  *
  1026.  *      Begin a SURFACE_COPY command. This reserves space for it in
  1027.  *      the FIFO, and returns a pointer to the command's arrays.  This
  1028.  *      function must be paired with SVGA_FIFOCommitAll().
  1029.  *
  1030.  *      The box array is initialized with zeroes.
  1031.  *
  1032.  * Results:
  1033.  *      None.
  1034.  *
  1035.  * Side effects:
  1036.  *      Asynchronously copies a list of boxes from surface to surface.
  1037.  *
  1038.  *----------------------------------------------------------------------
  1039.  */
  1040.  
  1041. enum pipe_error
  1042. SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
  1043.                         struct pipe_surface *src,    // IN
  1044.                         struct pipe_surface *dest,   // IN
  1045.                         SVGA3dCopyBox **boxes,       // OUT
  1046.                         uint32 numBoxes)             // IN
  1047. {
  1048.    SVGA3dCmdSurfaceCopy *cmd;
  1049.    uint32 boxesSize = sizeof **boxes * numBoxes;
  1050.  
  1051.    cmd = SVGA3D_FIFOReserve(swc,
  1052.                             SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
  1053.                             2);
  1054.    if (!cmd)
  1055.       return PIPE_ERROR_OUT_OF_MEMORY;
  1056.  
  1057.    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
  1058.    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
  1059.    *boxes = (SVGA3dCopyBox*) &cmd[1];
  1060.  
  1061.    memset(*boxes, 0, boxesSize);
  1062.  
  1063.    return PIPE_OK;
  1064. }
  1065.  
  1066.  
  1067. /*
  1068.  *----------------------------------------------------------------------
  1069.  *
  1070.  * SVGA3D_SurfaceStretchBlt --
  1071.  *
  1072.  *      Issue a SURFACE_STRETCHBLT command: an asynchronous
  1073.  *      surface-to-surface blit, with scaling.
  1074.  *
  1075.  * Results:
  1076.  *      None.
  1077.  *
  1078.  * Side effects:
  1079.  *      Asynchronously copies one box from surface to surface.
  1080.  *
  1081.  *----------------------------------------------------------------------
  1082.  */
  1083.  
  1084. enum pipe_error
  1085. SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
  1086.                          struct pipe_surface *src,    // IN
  1087.                          struct pipe_surface *dest,   // IN
  1088.                          SVGA3dBox *boxSrc,           // IN
  1089.                          SVGA3dBox *boxDest,          // IN
  1090.                          SVGA3dStretchBltMode mode)   // IN
  1091. {
  1092.    SVGA3dCmdSurfaceStretchBlt *cmd;
  1093.  
  1094.    cmd = SVGA3D_FIFOReserve(swc,
  1095.                             SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
  1096.                             2);
  1097.    if (!cmd)
  1098.       return PIPE_ERROR_OUT_OF_MEMORY;
  1099.  
  1100.    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
  1101.    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
  1102.    cmd->boxSrc = *boxSrc;
  1103.    cmd->boxDest = *boxDest;
  1104.    cmd->mode = mode;
  1105.    swc->commit(swc);
  1106.  
  1107.    return PIPE_OK;
  1108. }
  1109.  
  1110.  
  1111. /*
  1112.  *----------------------------------------------------------------------
  1113.  *
  1114.  * SVGA3D_SetViewport --
  1115.  *
  1116.  *      Set the current context's viewport rectangle. The viewport
  1117.  *      is clipped to the dimensions of the current render target,
  1118.  *      then all rendering is clipped to the viewport.
  1119.  *
  1120.  * Results:
  1121.  *      None.
  1122.  *
  1123.  * Side effects:
  1124.  *      None.
  1125.  *
  1126.  *----------------------------------------------------------------------
  1127.  */
  1128.  
  1129. enum pipe_error
  1130. SVGA3D_SetViewport(struct svga_winsys_context *swc,
  1131.                    SVGA3dRect *rect)  // IN
  1132. {
  1133.    SVGA3dCmdSetViewport *cmd;
  1134.  
  1135.    cmd = SVGA3D_FIFOReserve(swc,
  1136.                             SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
  1137.                             0);
  1138.    if (!cmd)
  1139.       return PIPE_ERROR_OUT_OF_MEMORY;
  1140.  
  1141.    cmd->cid = swc->cid;
  1142.    cmd->rect = *rect;
  1143.    swc->commit(swc);
  1144.  
  1145.    return PIPE_OK;
  1146. }
  1147.  
  1148.  
  1149.  
  1150.  
  1151. /*
  1152.  *----------------------------------------------------------------------
  1153.  *
  1154.  * SVGA3D_SetScissorRect --
  1155.  *
  1156.  *      Set the current context's scissor rectangle. If scissoring
  1157.  *      is enabled then all rendering is clipped to the scissor bounds.
  1158.  *
  1159.  * Results:
  1160.  *      None.
  1161.  *
  1162.  * Side effects:
  1163.  *      None.
  1164.  *
  1165.  *----------------------------------------------------------------------
  1166.  */
  1167.  
  1168. enum pipe_error
  1169. SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
  1170.                       SVGA3dRect *rect)  // IN
  1171. {
  1172.    SVGA3dCmdSetScissorRect *cmd;
  1173.  
  1174.    cmd = SVGA3D_FIFOReserve(swc,
  1175.                             SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
  1176.                             0);
  1177.    if (!cmd)
  1178.       return PIPE_ERROR_OUT_OF_MEMORY;
  1179.  
  1180.    cmd->cid = swc->cid;
  1181.    cmd->rect = *rect;
  1182.    swc->commit(swc);
  1183.  
  1184.    return PIPE_OK;
  1185. }
  1186.  
  1187. /*
  1188.  *----------------------------------------------------------------------
  1189.  *
  1190.  * SVGA3D_SetClipPlane --
  1191.  *
  1192.  *      Set one of the current context's clip planes. If the clip
  1193.  *      plane is enabled then all 3d rendering is clipped against
  1194.  *      the plane.
  1195.  *
  1196.  * Results:
  1197.  *      None.
  1198.  *
  1199.  * Side effects:
  1200.  *      None.
  1201.  *
  1202.  *----------------------------------------------------------------------
  1203.  */
  1204.  
  1205. enum pipe_error
  1206. SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
  1207.                     uint32 index, const float *plane)
  1208. {
  1209.    SVGA3dCmdSetClipPlane *cmd;
  1210.  
  1211.    cmd = SVGA3D_FIFOReserve(swc,
  1212.                             SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
  1213.                             0);
  1214.    if (!cmd)
  1215.       return PIPE_ERROR_OUT_OF_MEMORY;
  1216.  
  1217.    cmd->cid = swc->cid;
  1218.    cmd->index = index;
  1219.    cmd->plane[0] = plane[0];
  1220.    cmd->plane[1] = plane[1];
  1221.    cmd->plane[2] = plane[2];
  1222.    cmd->plane[3] = plane[3];
  1223.    swc->commit(swc);
  1224.  
  1225.    return PIPE_OK;
  1226. }
  1227.  
  1228. /*
  1229.  *----------------------------------------------------------------------
  1230.  *
  1231.  * SVGA3D_SetZRange --
  1232.  *
  1233.  *      Set the range of the depth buffer to use. 'min' and 'max'
  1234.  *      are values between 0.0 and 1.0.
  1235.  *
  1236.  * Results:
  1237.  *      None.
  1238.  *
  1239.  * Side effects:
  1240.  *      None.
  1241.  *
  1242.  *----------------------------------------------------------------------
  1243.  */
  1244.  
  1245. enum pipe_error
  1246. SVGA3D_SetZRange(struct svga_winsys_context *swc,
  1247.                  float zMin,  // IN
  1248.                  float zMax)  // IN
  1249. {
  1250.    SVGA3dCmdSetZRange *cmd;
  1251.  
  1252.    cmd = SVGA3D_FIFOReserve(swc,
  1253.                             SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
  1254.                             0);
  1255.    if (!cmd)
  1256.       return PIPE_ERROR_OUT_OF_MEMORY;
  1257.  
  1258.    cmd->cid = swc->cid;
  1259.    cmd->zRange.min = zMin;
  1260.    cmd->zRange.max = zMax;
  1261.    swc->commit(swc);
  1262.  
  1263.    return PIPE_OK;
  1264. }
  1265.  
  1266.  
  1267. /*
  1268.  *----------------------------------------------------------------------
  1269.  *
  1270.  * SVGA3D_BeginSetTextureState --
  1271.  *
  1272.  *      Begin a SETTEXTURESTATE command. This reserves space for it in
  1273.  *      the FIFO, and returns a pointer to the command's texture state
  1274.  *      array.  This function must be paired with SVGA_FIFOCommitAll().
  1275.  *
  1276.  *      This command sets rendering state which is per-texture-unit.
  1277.  *
  1278.  *      XXX: Individual texture states need documentation. However,
  1279.  *           they are very similar to the texture states defined by
  1280.  *           Direct3D. The D3D documentation is a good starting point
  1281.  *           for understanding SVGA3D texture states.
  1282.  *
  1283.  * Results:
  1284.  *      None.
  1285.  *
  1286.  * Side effects:
  1287.  *      None.
  1288.  *
  1289.  *----------------------------------------------------------------------
  1290.  */
  1291.  
  1292. enum pipe_error
  1293. SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
  1294.                             SVGA3dTextureState **states,  // OUT
  1295.                             uint32 numStates)             // IN
  1296. {
  1297.    SVGA3dCmdSetTextureState *cmd;
  1298.  
  1299.    cmd = SVGA3D_FIFOReserve(swc,
  1300.                             SVGA_3D_CMD_SETTEXTURESTATE,
  1301.                             sizeof *cmd + sizeof **states * numStates,
  1302.                             numStates);
  1303.    if (!cmd)
  1304.       return PIPE_ERROR_OUT_OF_MEMORY;
  1305.  
  1306.    cmd->cid = swc->cid;
  1307.    *states = (SVGA3dTextureState*) &cmd[1];
  1308.  
  1309.    return PIPE_OK;
  1310. }
  1311.  
  1312.  
  1313. /*
  1314.  *----------------------------------------------------------------------
  1315.  *
  1316.  * SVGA3D_BeginSetRenderState --
  1317.  *
  1318.  *      Begin a SETRENDERSTATE command. This reserves space for it in
  1319.  *      the FIFO, and returns a pointer to the command's texture state
  1320.  *      array.  This function must be paired with SVGA_FIFOCommitAll().
  1321.  *
  1322.  *      This command sets rendering state which is global to the context.
  1323.  *
  1324.  *      XXX: Individual render states need documentation. However,
  1325.  *           they are very similar to the render states defined by
  1326.  *           Direct3D. The D3D documentation is a good starting point
  1327.  *           for understanding SVGA3D render states.
  1328.  *
  1329.  * Results:
  1330.  *      None.
  1331.  *
  1332.  * Side effects:
  1333.  *      None.
  1334.  *
  1335.  *----------------------------------------------------------------------
  1336.  */
  1337.  
  1338. enum pipe_error
  1339. SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
  1340.                            SVGA3dRenderState **states,  // OUT
  1341.                            uint32 numStates)            // IN
  1342. {
  1343.    SVGA3dCmdSetRenderState *cmd;
  1344.  
  1345.    cmd = SVGA3D_FIFOReserve(swc,
  1346.                             SVGA_3D_CMD_SETRENDERSTATE,
  1347.                             sizeof *cmd + sizeof **states * numStates,
  1348.                             0);
  1349.    if (!cmd)
  1350.       return PIPE_ERROR_OUT_OF_MEMORY;
  1351.  
  1352.    cmd->cid = swc->cid;
  1353.    *states = (SVGA3dRenderState*) &cmd[1];
  1354.  
  1355.    return PIPE_OK;
  1356. }
  1357.  
  1358.  
  1359. /*
  1360.  *----------------------------------------------------------------------
  1361.  *
  1362.  * SVGA3D_BeginGBQuery--
  1363.  *
  1364.  *      GB resource version of SVGA3D_BeginQuery.
  1365.  *
  1366.  * Results:
  1367.  *      None.
  1368.  *
  1369.  * Side effects:
  1370.  *      Commits space in the FIFO memory.
  1371.  *
  1372.  *----------------------------------------------------------------------
  1373.  */
  1374.  
  1375. static enum pipe_error
  1376. SVGA3D_BeginGBQuery(struct svga_winsys_context *swc,
  1377.                     SVGA3dQueryType type) // IN
  1378. {
  1379.    SVGA3dCmdBeginGBQuery *cmd;
  1380.  
  1381.    cmd = SVGA3D_FIFOReserve(swc,
  1382.                             SVGA_3D_CMD_BEGIN_GB_QUERY,
  1383.                             sizeof *cmd,
  1384.                             1);
  1385.    if(!cmd)
  1386.       return PIPE_ERROR_OUT_OF_MEMORY;
  1387.  
  1388.    swc->context_relocation(swc, &cmd->cid);
  1389.    cmd->type = type;
  1390.  
  1391.    swc->commit(swc);
  1392.  
  1393.    return PIPE_OK;
  1394. }
  1395.  
  1396.  
  1397. /*
  1398.  *----------------------------------------------------------------------
  1399.  *
  1400.  * SVGA3D_BeginQuery--
  1401.  *
  1402.  *      Issues a SVGA_3D_CMD_BEGIN_QUERY command.
  1403.  *
  1404.  * Results:
  1405.  *      None.
  1406.  *
  1407.  * Side effects:
  1408.  *      Commits space in the FIFO memory.
  1409.  *
  1410.  *----------------------------------------------------------------------
  1411.  */
  1412.  
  1413. enum pipe_error
  1414. SVGA3D_BeginQuery(struct svga_winsys_context *swc,
  1415.                   SVGA3dQueryType type) // IN
  1416. {
  1417.    SVGA3dCmdBeginQuery *cmd;
  1418.  
  1419.    if (swc->have_gb_objects)
  1420.       return SVGA3D_BeginGBQuery(swc, type);
  1421.  
  1422.    cmd = SVGA3D_FIFOReserve(swc,
  1423.                             SVGA_3D_CMD_BEGIN_QUERY,
  1424.                             sizeof *cmd,
  1425.                             0);
  1426.    if (!cmd)
  1427.       return PIPE_ERROR_OUT_OF_MEMORY;
  1428.  
  1429.    cmd->cid = swc->cid;
  1430.    cmd->type = type;
  1431.  
  1432.    swc->commit(swc);
  1433.  
  1434.    return PIPE_OK;
  1435. }
  1436.  
  1437.  
  1438. /*
  1439.  *----------------------------------------------------------------------
  1440.  *
  1441.  * SVGA3D_EndGBQuery--
  1442.  *
  1443.  *      GB resource version of SVGA3D_EndQuery.
  1444.  *
  1445.  * Results:
  1446.  *      None.
  1447.  *
  1448.  * Side effects:
  1449.  *      Commits space in the FIFO memory.
  1450.  *
  1451.  *----------------------------------------------------------------------
  1452.  */
  1453.  
  1454. static enum pipe_error
  1455. SVGA3D_EndGBQuery(struct svga_winsys_context *swc,
  1456.                   SVGA3dQueryType type,              // IN
  1457.                   struct svga_winsys_buffer *buffer) // IN/OUT
  1458. {
  1459.    SVGA3dCmdEndGBQuery *cmd;
  1460.  
  1461.    cmd = SVGA3D_FIFOReserve(swc,
  1462.                             SVGA_3D_CMD_END_GB_QUERY,
  1463.                             sizeof *cmd,
  1464.                             2);
  1465.    if(!cmd)
  1466.       return PIPE_ERROR_OUT_OF_MEMORY;
  1467.  
  1468.    swc->context_relocation(swc, &cmd->cid);
  1469.    cmd->type = type;
  1470.  
  1471.    swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
  1472.                        0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
  1473.  
  1474.    swc->commit(swc);
  1475.    
  1476.    return PIPE_OK;
  1477. }
  1478.  
  1479.  
  1480. /*
  1481.  *----------------------------------------------------------------------
  1482.  *
  1483.  * SVGA3D_EndQuery--
  1484.  *
  1485.  *      Issues a SVGA_3D_CMD_END_QUERY command.
  1486.  *
  1487.  * Results:
  1488.  *      None.
  1489.  *
  1490.  * Side effects:
  1491.  *      Commits space in the FIFO memory.
  1492.  *
  1493.  *----------------------------------------------------------------------
  1494.  */
  1495.  
  1496. enum pipe_error
  1497. SVGA3D_EndQuery(struct svga_winsys_context *swc,
  1498.                 SVGA3dQueryType type,              // IN
  1499.                 struct svga_winsys_buffer *buffer) // IN/OUT
  1500. {
  1501.    SVGA3dCmdEndQuery *cmd;
  1502.  
  1503.    if (swc->have_gb_objects)
  1504.       return SVGA3D_EndGBQuery(swc, type, buffer);
  1505.  
  1506.    cmd = SVGA3D_FIFOReserve(swc,
  1507.                             SVGA_3D_CMD_END_QUERY,
  1508.                             sizeof *cmd,
  1509.                             1);
  1510.    if (!cmd)
  1511.       return PIPE_ERROR_OUT_OF_MEMORY;
  1512.  
  1513.    cmd->cid = swc->cid;
  1514.    cmd->type = type;
  1515.  
  1516.    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
  1517.                           SVGA_RELOC_READ | SVGA_RELOC_WRITE);
  1518.  
  1519.    swc->commit(swc);
  1520.  
  1521.    return PIPE_OK;
  1522. }
  1523.  
  1524.  
  1525. /*
  1526.  *----------------------------------------------------------------------
  1527.  *
  1528.  * SVGA3D_WaitForGBQuery--
  1529.  *
  1530.  *      GB resource version of SVGA3D_WaitForQuery.
  1531.  *
  1532.  * Results:
  1533.  *      None.
  1534.  *
  1535.  * Side effects:
  1536.  *      Commits space in the FIFO memory.
  1537.  *
  1538.  *----------------------------------------------------------------------
  1539.  */
  1540.  
  1541. static enum pipe_error
  1542. SVGA3D_WaitForGBQuery(struct svga_winsys_context *swc,
  1543.                       SVGA3dQueryType type,              // IN
  1544.                       struct svga_winsys_buffer *buffer) // IN/OUT
  1545. {
  1546.    SVGA3dCmdWaitForGBQuery *cmd;
  1547.  
  1548.    cmd = SVGA3D_FIFOReserve(swc,
  1549.                             SVGA_3D_CMD_WAIT_FOR_GB_QUERY,
  1550.                             sizeof *cmd,
  1551.                             2);
  1552.    if(!cmd)
  1553.       return PIPE_ERROR_OUT_OF_MEMORY;
  1554.  
  1555.    swc->context_relocation(swc, &cmd->cid);
  1556.    cmd->type = type;
  1557.  
  1558.    swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
  1559.                        0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
  1560.  
  1561.    swc->commit(swc);
  1562.  
  1563.    return PIPE_OK;
  1564. }
  1565.  
  1566.  
  1567. /*
  1568.  *----------------------------------------------------------------------
  1569.  *
  1570.  * SVGA3D_WaitForQuery--
  1571.  *
  1572.  *      Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command.  This reserves space
  1573.  *      for it in the FIFO.  This doesn't actually wait for the query to
  1574.  *      finish but instead tells the host to start a wait at the driver
  1575.  *      level.  The caller can wait on the status variable in the
  1576.  *      guestPtr memory or send an insert fence instruction after this
  1577.  *      command and wait on the fence.
  1578.  *
  1579.  * Results:
  1580.  *      None.
  1581.  *
  1582.  * Side effects:
  1583.  *      Commits space in the FIFO memory.
  1584.  *
  1585.  *----------------------------------------------------------------------
  1586.  */
  1587.  
  1588. enum pipe_error
  1589. SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
  1590.                     SVGA3dQueryType type,              // IN
  1591.                     struct svga_winsys_buffer *buffer) // IN/OUT
  1592. {
  1593.    SVGA3dCmdWaitForQuery *cmd;
  1594.  
  1595.    if (swc->have_gb_objects)
  1596.       return SVGA3D_WaitForGBQuery(swc, type, buffer);
  1597.  
  1598.    cmd = SVGA3D_FIFOReserve(swc,
  1599.                             SVGA_3D_CMD_WAIT_FOR_QUERY,
  1600.                             sizeof *cmd,
  1601.                             1);
  1602.    if (!cmd)
  1603.       return PIPE_ERROR_OUT_OF_MEMORY;
  1604.  
  1605.    cmd->cid = swc->cid;
  1606.    cmd->type = type;
  1607.  
  1608.    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
  1609.                           SVGA_RELOC_READ | SVGA_RELOC_WRITE);
  1610.  
  1611.    swc->commit(swc);
  1612.  
  1613.    return PIPE_OK;
  1614. }
  1615.  
  1616.  
  1617. enum pipe_error
  1618. SVGA3D_DefineGBShader(struct svga_winsys_context *swc,
  1619.                       struct svga_winsys_gb_shader *gbshader,
  1620.                       SVGA3dShaderType type,
  1621.                       uint32 sizeInBytes)
  1622. {
  1623.    SVGA3dCmdDefineGBShader *cmd;
  1624.  
  1625.    assert(sizeInBytes % 4 == 0);
  1626.    assert(type == SVGA3D_SHADERTYPE_VS ||
  1627.           type == SVGA3D_SHADERTYPE_PS);
  1628.  
  1629.    cmd = SVGA3D_FIFOReserve(swc,
  1630.                             SVGA_3D_CMD_DEFINE_GB_SHADER,
  1631.                             sizeof *cmd,
  1632.                             1); /* one relocation */
  1633.  
  1634.    if (!cmd)
  1635.       return PIPE_ERROR_OUT_OF_MEMORY;
  1636.  
  1637.    swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader);
  1638.    cmd->type = type;
  1639.    cmd->sizeInBytes = sizeInBytes;
  1640.  
  1641.    swc->commit(swc);
  1642.    
  1643.    return PIPE_OK;
  1644. }
  1645.  
  1646.  
  1647. enum pipe_error
  1648. SVGA3D_BindGBShader(struct svga_winsys_context *swc,
  1649.                     struct svga_winsys_gb_shader *gbshader)
  1650. {
  1651.    SVGA3dCmdBindGBShader *cmd =
  1652.       SVGA3D_FIFOReserve(swc,
  1653.                          SVGA_3D_CMD_BIND_GB_SHADER,
  1654.                          sizeof *cmd,
  1655.                          2);  /* two relocations */
  1656.  
  1657.    if (!cmd)
  1658.       return PIPE_ERROR_OUT_OF_MEMORY;
  1659.  
  1660.    swc->shader_relocation(swc, &cmd->shid, &cmd->mobid,
  1661.                           &cmd->offsetInBytes, gbshader);
  1662.  
  1663.    swc->commit(swc);
  1664.  
  1665.    return PIPE_OK;
  1666. }
  1667.  
  1668.  
  1669. enum pipe_error
  1670. SVGA3D_SetGBShader(struct svga_winsys_context *swc,
  1671.                    SVGA3dShaderType type,  // IN
  1672.                    struct svga_winsys_gb_shader *gbshader)
  1673. {
  1674.    SVGA3dCmdSetShader *cmd;
  1675.    
  1676.    cmd = SVGA3D_FIFOReserve(swc,
  1677.                             SVGA_3D_CMD_SET_SHADER,
  1678.                             sizeof *cmd,
  1679.                             2);  /* two relocations */
  1680.    if (!cmd)
  1681.       return PIPE_ERROR_OUT_OF_MEMORY;
  1682.    
  1683.    swc->context_relocation(swc, &cmd->cid);
  1684.    cmd->type = type;
  1685.    if (gbshader)
  1686.       swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader);
  1687.    else
  1688.       cmd->shid = SVGA_ID_INVALID;
  1689.    swc->commit(swc);
  1690.  
  1691.    return PIPE_OK;
  1692. }
  1693.  
  1694.  
  1695. enum pipe_error
  1696. SVGA3D_DestroyGBShader(struct svga_winsys_context *swc,
  1697.                        struct svga_winsys_gb_shader *gbshader)
  1698. {
  1699.    SVGA3dCmdDestroyGBShader *cmd =
  1700.       SVGA3D_FIFOReserve(swc,
  1701.                          SVGA_3D_CMD_DESTROY_GB_SHADER,
  1702.                          sizeof *cmd,
  1703.                          1); /* one relocation */
  1704.  
  1705.    if (!cmd)
  1706.       return PIPE_ERROR_OUT_OF_MEMORY;
  1707.  
  1708.    swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader);
  1709.  
  1710.    swc->commit(swc);
  1711.  
  1712.    return PIPE_OK;
  1713. }
  1714.  
  1715.  
  1716. /**
  1717.  * \param flags  mask of SVGA_RELOC_READ / _WRITE
  1718.  */
  1719. enum pipe_error
  1720. SVGA3D_BindGBSurface(struct svga_winsys_context *swc,
  1721.                      struct svga_winsys_surface *surface)
  1722. {
  1723.    SVGA3dCmdBindGBSurface *cmd =
  1724.       SVGA3D_FIFOReserve(swc,
  1725.                          SVGA_3D_CMD_BIND_GB_SURFACE,
  1726.                          sizeof *cmd,
  1727.                          2);  /* two relocations */
  1728.  
  1729.    if (!cmd)
  1730.       return PIPE_ERROR_OUT_OF_MEMORY;
  1731.  
  1732.    swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface,
  1733.                            SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
  1734.  
  1735.    swc->commit(swc);
  1736.  
  1737.    return PIPE_OK;
  1738. }
  1739.  
  1740.  
  1741. enum pipe_error
  1742. SVGA3D_DefineGBContext(struct svga_winsys_context *swc)
  1743. {
  1744.    SVGA3dCmdDefineGBContext *cmd =
  1745.       SVGA3D_FIFOReserve(swc,
  1746.                          SVGA_3D_CMD_DEFINE_GB_CONTEXT,
  1747.                          sizeof *cmd,
  1748.                          1);  /* one relocation */
  1749.  
  1750.    if (!cmd)
  1751.       return PIPE_ERROR_OUT_OF_MEMORY;
  1752.  
  1753.    swc->context_relocation(swc, &cmd->cid);
  1754.  
  1755.    swc->commit(swc);
  1756.  
  1757.    return PIPE_OK;
  1758. }
  1759.  
  1760.  
  1761. enum pipe_error
  1762. SVGA3D_DestroyGBContext(struct svga_winsys_context *swc)
  1763. {
  1764.    SVGA3dCmdDestroyGBContext *cmd =
  1765.       SVGA3D_FIFOReserve(swc,
  1766.                          SVGA_3D_CMD_DESTROY_GB_CONTEXT,
  1767.                          sizeof *cmd,
  1768.                          1);  /* one relocation */
  1769.  
  1770.    if (!cmd)
  1771.       return PIPE_ERROR_OUT_OF_MEMORY;
  1772.  
  1773.    swc->context_relocation(swc, &cmd->cid);
  1774.  
  1775.    swc->commit(swc);
  1776.  
  1777.    return PIPE_OK;
  1778. }
  1779.  
  1780.  
  1781. enum pipe_error
  1782. SVGA3D_BindGBContext(struct svga_winsys_context *swc)
  1783. {
  1784.    SVGA3dCmdBindGBContext *cmd =
  1785.       SVGA3D_FIFOReserve(swc,
  1786.                          SVGA_3D_CMD_BIND_GB_CONTEXT,
  1787.                          sizeof *cmd,
  1788.                          2);  /* two relocations */
  1789.  
  1790.    if (!cmd)
  1791.       return PIPE_ERROR_OUT_OF_MEMORY;
  1792.  
  1793.    swc->context_relocation(swc, &cmd->cid);
  1794.    swc->context_relocation(swc, &cmd->mobid);
  1795.    cmd->validContents = 0;  /* XXX pass as a parameter? */
  1796.  
  1797.    swc->commit(swc);
  1798.  
  1799.    return PIPE_OK;
  1800. }
  1801.  
  1802.  
  1803. enum pipe_error
  1804. SVGA3D_InvalidateGBContext(struct svga_winsys_context *swc)
  1805. {
  1806.    SVGA3dCmdInvalidateGBContext *cmd =
  1807.       SVGA3D_FIFOReserve(swc,
  1808.                          SVGA_3D_CMD_INVALIDATE_GB_CONTEXT,
  1809.                          sizeof *cmd,
  1810.                          1);  /* one relocation */
  1811.  
  1812.    if (!cmd)
  1813.       return PIPE_ERROR_OUT_OF_MEMORY;
  1814.  
  1815.    swc->context_relocation(swc, &cmd->cid);
  1816.  
  1817.    swc->commit(swc);
  1818.  
  1819.    return PIPE_OK;
  1820. }
  1821.  
  1822.  
  1823.  
  1824. /**
  1825.  * Update an image in a guest-backed surface.
  1826.  * (Inform the device that the guest-contents have been updated.)
  1827.  */
  1828. enum pipe_error
  1829. SVGA3D_UpdateGBImage(struct svga_winsys_context *swc,
  1830.                      struct svga_winsys_surface *surface,
  1831.                      const SVGA3dBox *box,
  1832.                      unsigned face, unsigned mipLevel)
  1833.  
  1834. {
  1835.    SVGA3dCmdUpdateGBImage *cmd =
  1836.       SVGA3D_FIFOReserve(swc,
  1837.                          SVGA_3D_CMD_UPDATE_GB_IMAGE,
  1838.                          sizeof *cmd,
  1839.                          1);  /* one relocation */
  1840.  
  1841.    if (!cmd)
  1842.       return PIPE_ERROR_OUT_OF_MEMORY;
  1843.  
  1844.    swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
  1845.                            SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
  1846.    cmd->image.face = face;
  1847.    cmd->image.mipmap = mipLevel;
  1848.    cmd->box = *box;
  1849.  
  1850.    swc->commit(swc);
  1851.  
  1852.    return PIPE_OK;
  1853. }
  1854.  
  1855.  
  1856. /**
  1857.  * Update an entire guest-backed surface.
  1858.  * (Inform the device that the guest-contents have been updated.)
  1859.  */
  1860. enum pipe_error
  1861. SVGA3D_UpdateGBSurface(struct svga_winsys_context *swc,
  1862.                        struct svga_winsys_surface *surface)
  1863. {
  1864.    SVGA3dCmdUpdateGBSurface *cmd =
  1865.       SVGA3D_FIFOReserve(swc,
  1866.                          SVGA_3D_CMD_UPDATE_GB_SURFACE,
  1867.                          sizeof *cmd,
  1868.                          1);  /* one relocation */
  1869.  
  1870.    if (!cmd)
  1871.       return PIPE_ERROR_OUT_OF_MEMORY;
  1872.  
  1873.    swc->surface_relocation(swc, &cmd->sid, NULL, surface,
  1874.                            SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
  1875.  
  1876.    swc->commit(swc);
  1877.  
  1878.    return PIPE_OK;
  1879. }
  1880.  
  1881.  
  1882. /**
  1883.  * Readback an image in a guest-backed surface.
  1884.  * (Request the device to flush the dirty contents into the guest.)
  1885.  */
  1886. enum pipe_error
  1887. SVGA3D_ReadbackGBImage(struct svga_winsys_context *swc,
  1888.                        struct svga_winsys_surface *surface,
  1889.                        unsigned face, unsigned mipLevel)
  1890. {
  1891.    SVGA3dCmdReadbackGBImage *cmd =
  1892.       SVGA3D_FIFOReserve(swc,
  1893.                          SVGA_3D_CMD_READBACK_GB_IMAGE,
  1894.                          sizeof *cmd,
  1895.                          1);  /* one relocation */
  1896.  
  1897.    if (!cmd)
  1898.       return PIPE_ERROR_OUT_OF_MEMORY;
  1899.  
  1900.    swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
  1901.                            SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
  1902.    cmd->image.face = face;
  1903.    cmd->image.mipmap = mipLevel;
  1904.  
  1905.    swc->commit(swc);
  1906.  
  1907.    return PIPE_OK;
  1908. }
  1909.  
  1910.  
  1911. /**
  1912.  * Readback an entire guest-backed surface.
  1913.  * (Request the device to flush the dirty contents into the guest.)
  1914.  */
  1915. enum pipe_error
  1916. SVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc,
  1917.                          struct svga_winsys_surface *surface)
  1918. {
  1919.    SVGA3dCmdReadbackGBSurface *cmd =
  1920.       SVGA3D_FIFOReserve(swc,
  1921.                          SVGA_3D_CMD_READBACK_GB_SURFACE,
  1922.                          sizeof *cmd,
  1923.                          1);  /* one relocation */
  1924.  
  1925.    if (!cmd)
  1926.       return PIPE_ERROR_OUT_OF_MEMORY;
  1927.  
  1928.    swc->surface_relocation(swc, &cmd->sid, NULL, surface,
  1929.                            SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
  1930.  
  1931.    swc->commit(swc);
  1932.  
  1933.    return PIPE_OK;
  1934. }
  1935.  
  1936.  
  1937. enum pipe_error
  1938. SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc,
  1939.                               struct svga_winsys_surface *surface,
  1940.                               unsigned face, unsigned mipLevel,
  1941.                               const SVGA3dBox *box,
  1942.                               bool invertBox)
  1943. {
  1944.    SVGA3dCmdReadbackGBImagePartial *cmd =
  1945.       SVGA3D_FIFOReserve(swc,
  1946.                          SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL,
  1947.                          sizeof *cmd,
  1948.                          1);  /* one relocation */
  1949.    if (!cmd)
  1950.       return PIPE_ERROR_OUT_OF_MEMORY;
  1951.  
  1952.    swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
  1953.                            SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
  1954.    cmd->image.face = face;
  1955.    cmd->image.mipmap = mipLevel;
  1956.    cmd->box = *box;
  1957.    cmd->invertBox = invertBox;
  1958.  
  1959.    swc->commit(swc);
  1960.  
  1961.    return PIPE_OK;
  1962. }
  1963.  
  1964.  
  1965. enum pipe_error
  1966. SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc,
  1967.                                 struct svga_winsys_surface *surface,
  1968.                                 unsigned face, unsigned mipLevel,
  1969.                                 const SVGA3dBox *box,
  1970.                                 bool invertBox)
  1971. {
  1972.    SVGA3dCmdInvalidateGBImagePartial *cmd =
  1973.       SVGA3D_FIFOReserve(swc,
  1974.                          SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL,
  1975.                          sizeof *cmd,
  1976.                          1);  /* one relocation */
  1977.    if (!cmd)
  1978.       return PIPE_ERROR_OUT_OF_MEMORY;
  1979.  
  1980.    swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
  1981.                            SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
  1982.    cmd->image.face = face;
  1983.    cmd->image.mipmap = mipLevel;
  1984.    cmd->box = *box;
  1985.    cmd->invertBox = invertBox;
  1986.  
  1987.    swc->commit(swc);
  1988.  
  1989.    return PIPE_OK;
  1990. }
  1991.  
  1992.  
  1993. enum pipe_error
  1994. SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,
  1995.                               unsigned regStart,
  1996.                               unsigned numRegs,
  1997.                               SVGA3dShaderType shaderType,
  1998.                               SVGA3dShaderConstType constType,
  1999.                               const void *values)
  2000. {
  2001.    SVGA3dCmdSetGBShaderConstInline *cmd;
  2002.  
  2003.    assert(numRegs > 0);
  2004.  
  2005.    cmd = SVGA3D_FIFOReserve(swc,
  2006.                             SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE,
  2007.                             sizeof *cmd + numRegs * sizeof(float[4]),
  2008.                             0); /* no relocations */
  2009.    if (!cmd)
  2010.       return PIPE_ERROR_OUT_OF_MEMORY;
  2011.  
  2012.    cmd->cid = swc->cid;
  2013.    cmd->regStart = regStart;
  2014.    cmd->shaderType = shaderType;
  2015.    cmd->constType = constType;
  2016.  
  2017.    memcpy(&cmd[1], values, numRegs * sizeof(float[4]));
  2018.  
  2019.    swc->commit(swc);
  2020.  
  2021.    return PIPE_OK;
  2022. }
  2023.