14a49301eSmrg/**********************************************************
24a49301eSmrg * Copyright 2008-2009 VMware, Inc.  All rights reserved.
34a49301eSmrg *
44a49301eSmrg * Permission is hereby granted, free of charge, to any person
54a49301eSmrg * obtaining a copy of this software and associated documentation
64a49301eSmrg * files (the "Software"), to deal in the Software without
74a49301eSmrg * restriction, including without limitation the rights to use, copy,
84a49301eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies
94a49301eSmrg * of the Software, and to permit persons to whom the Software is
104a49301eSmrg * furnished to do so, subject to the following conditions:
114a49301eSmrg *
124a49301eSmrg * The above copyright notice and this permission notice shall be
134a49301eSmrg * included in all copies or substantial portions of the Software.
144a49301eSmrg *
154a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
164a49301eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
174a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
184a49301eSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
194a49301eSmrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
204a49301eSmrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
214a49301eSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
224a49301eSmrg * SOFTWARE.
234a49301eSmrg *
244a49301eSmrg **********************************************************/
254a49301eSmrg
264a49301eSmrg/**
274a49301eSmrg * svga_cmd.c --
284a49301eSmrg *
294a49301eSmrg *      Command construction utility for the SVGA3D protocol used by
304a49301eSmrg *      the VMware SVGA device, based on the svgautil library.
314a49301eSmrg */
324a49301eSmrg
334a49301eSmrg#include "svga_winsys.h"
343464ebd5Sriastradh#include "svga_resource_buffer.h"
353464ebd5Sriastradh#include "svga_resource_texture.h"
363464ebd5Sriastradh#include "svga_surface.h"
374a49301eSmrg#include "svga_cmd.h"
384a49301eSmrg
394a49301eSmrg/*
404a49301eSmrg *----------------------------------------------------------------------
414a49301eSmrg *
424a49301eSmrg * surface_to_surfaceid --
434a49301eSmrg *
444a49301eSmrg *      Utility function for surface ids.
454a49301eSmrg *      Can handle null surface. Does a surface_reallocation so you need
464a49301eSmrg *      to have allocated the fifo space before converting.
474a49301eSmrg *
48af69d88dSmrg *
49af69d88dSmrg * param flags  mask of SVGA_RELOC_READ / _WRITE
50af69d88dSmrg *
514a49301eSmrg * Results:
523464ebd5Sriastradh *      id is filled out.
534a49301eSmrg *
544a49301eSmrg * Side effects:
553464ebd5Sriastradh *      One surface relocation is performed for texture handle.
564a49301eSmrg *
574a49301eSmrg *----------------------------------------------------------------------
584a49301eSmrg */
594a49301eSmrg
6001e04c3fSmrgstatic inline void
61af69d88dSmrgsurface_to_surfaceid(struct svga_winsys_context *swc, // IN
62af69d88dSmrg                     struct pipe_surface *surface,    // IN
63af69d88dSmrg                     SVGA3dSurfaceImageId *id,        // OUT
64af69d88dSmrg                     unsigned flags)                  // IN
654a49301eSmrg{
66af69d88dSmrg   if (surface) {
674a49301eSmrg      struct svga_surface *s = svga_surface(surface);
68af69d88dSmrg      swc->surface_relocation(swc, &id->sid, NULL, s->handle, flags);
6901e04c3fSmrg      id->face = s->real_layer; /* faces have the same order */
704a49301eSmrg      id->mipmap = s->real_level;
714a49301eSmrg   }
724a49301eSmrg   else {
73af69d88dSmrg      swc->surface_relocation(swc, &id->sid, NULL, NULL, flags);
744a49301eSmrg      id->face = 0;
754a49301eSmrg      id->mipmap = 0;
764a49301eSmrg   }
774a49301eSmrg}
784a49301eSmrg
794a49301eSmrg
804a49301eSmrg/*
814a49301eSmrg *----------------------------------------------------------------------
824a49301eSmrg *
834a49301eSmrg * SVGA3D_FIFOReserve --
844a49301eSmrg *
854a49301eSmrg *      Reserve space for an SVGA3D FIFO command.
864a49301eSmrg *
874a49301eSmrg *      The 2D SVGA commands have been around for a while, so they
884a49301eSmrg *      have a rather asymmetric structure. The SVGA3D protocol is
894a49301eSmrg *      more uniform: each command begins with a header containing the
904a49301eSmrg *      command number and the full size.
914a49301eSmrg *
924a49301eSmrg *      This is a convenience wrapper around SVGA_FIFOReserve. We
934a49301eSmrg *      reserve space for the whole command, and write the header.
944a49301eSmrg *
954a49301eSmrg *      This function must be paired with SVGA_FIFOCommitAll().
964a49301eSmrg *
974a49301eSmrg * Results:
984a49301eSmrg *      Returns a pointer to the space reserved for command-specific
994a49301eSmrg *      data. It must be 'cmdSize' bytes long.
1004a49301eSmrg *
1014a49301eSmrg * Side effects:
1024a49301eSmrg *      Begins a FIFO reservation.
1034a49301eSmrg *
1044a49301eSmrg *----------------------------------------------------------------------
1054a49301eSmrg */
1064a49301eSmrg
1074a49301eSmrgvoid *
1084a49301eSmrgSVGA3D_FIFOReserve(struct svga_winsys_context *swc,
1094a49301eSmrg                   uint32 cmd,       // IN
1104a49301eSmrg                   uint32 cmdSize,   // IN
1114a49301eSmrg                   uint32 nr_relocs) // IN
1124a49301eSmrg{
1134a49301eSmrg   SVGA3dCmdHeader *header;
1144a49301eSmrg
1154a49301eSmrg   header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs);
116af69d88dSmrg   if (!header)
1174a49301eSmrg      return NULL;
1184a49301eSmrg
1194a49301eSmrg   header->id = cmd;
1204a49301eSmrg   header->size = cmdSize;
1214a49301eSmrg
12201e04c3fSmrg   swc->last_command = cmd;
12301e04c3fSmrg
12401e04c3fSmrg   swc->num_commands++;
12501e04c3fSmrg
1264a49301eSmrg   return &header[1];
1274a49301eSmrg}
1284a49301eSmrg
1294a49301eSmrg
1304a49301eSmrgvoid
1314a49301eSmrgSVGA_FIFOCommitAll(struct svga_winsys_context *swc)
1324a49301eSmrg{
1334a49301eSmrg   swc->commit(swc);
1344a49301eSmrg}
1354a49301eSmrg
1364a49301eSmrg
1374a49301eSmrg/*
1384a49301eSmrg *----------------------------------------------------------------------
1394a49301eSmrg *
1404a49301eSmrg * SVGA3D_DefineContext --
1414a49301eSmrg *
1424a49301eSmrg *      Create a new context, to be referred to with the provided ID.
1434a49301eSmrg *
1444a49301eSmrg *      Context objects encapsulate all render state, and shader
1454a49301eSmrg *      objects are per-context.
1464a49301eSmrg *
1474a49301eSmrg *      Surfaces are not per-context. The same surface can be shared
1484a49301eSmrg *      between multiple contexts, and surface operations can occur
1494a49301eSmrg *      without a context.
1504a49301eSmrg *
1514a49301eSmrg *      If the provided context ID already existed, it is redefined.
1524a49301eSmrg *
1534a49301eSmrg *      Context IDs are arbitrary small non-negative integers,
1544a49301eSmrg *      global to the entire SVGA device.
1554a49301eSmrg *
1564a49301eSmrg * Results:
1574a49301eSmrg *      None.
1584a49301eSmrg *
1594a49301eSmrg * Side effects:
1604a49301eSmrg *      None.
1614a49301eSmrg *
1624a49301eSmrg *----------------------------------------------------------------------
1634a49301eSmrg */
1644a49301eSmrg
1654a49301eSmrgenum pipe_error
1664a49301eSmrgSVGA3D_DefineContext(struct svga_winsys_context *swc)  // IN
1674a49301eSmrg{
1684a49301eSmrg   SVGA3dCmdDefineContext *cmd;
1694a49301eSmrg
1704a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
1714a49301eSmrg                            SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0);
172af69d88dSmrg   if (!cmd)
1734a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1744a49301eSmrg
1754a49301eSmrg   cmd->cid = swc->cid;
1764a49301eSmrg
1774a49301eSmrg   swc->commit(swc);
178af69d88dSmrg
1794a49301eSmrg   return PIPE_OK;
1804a49301eSmrg}
1814a49301eSmrg
1824a49301eSmrg
1834a49301eSmrg/*
1844a49301eSmrg *----------------------------------------------------------------------
1854a49301eSmrg *
1864a49301eSmrg * SVGA3D_DestroyContext --
1874a49301eSmrg *
1884a49301eSmrg *      Delete a context created with SVGA3D_DefineContext.
1894a49301eSmrg *
1904a49301eSmrg * Results:
1914a49301eSmrg *      None.
1924a49301eSmrg *
1934a49301eSmrg * Side effects:
1944a49301eSmrg *      None.
1954a49301eSmrg *
1964a49301eSmrg *----------------------------------------------------------------------
1974a49301eSmrg */
1984a49301eSmrg
1994a49301eSmrgenum pipe_error
2004a49301eSmrgSVGA3D_DestroyContext(struct svga_winsys_context *swc)  // IN
2014a49301eSmrg{
2024a49301eSmrg   SVGA3dCmdDestroyContext *cmd;
203af69d88dSmrg
2044a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
2054a49301eSmrg                            SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0);
206af69d88dSmrg   if (!cmd)
2074a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
208af69d88dSmrg
2094a49301eSmrg   cmd->cid = swc->cid;
210af69d88dSmrg
2114a49301eSmrg   swc->commit(swc);
212af69d88dSmrg
2134a49301eSmrg   return PIPE_OK;
2144a49301eSmrg}
2154a49301eSmrg
2164a49301eSmrg
2174a49301eSmrg/*
2184a49301eSmrg *----------------------------------------------------------------------
2194a49301eSmrg *
2204a49301eSmrg * SVGA3D_BeginDefineSurface --
2214a49301eSmrg *
2224a49301eSmrg *      Begin a SURFACE_DEFINE command. This reserves space for it in
2234a49301eSmrg *      the FIFO, and returns pointers to the command's faces and
2244a49301eSmrg *      mipsizes arrays.
2254a49301eSmrg *
2264a49301eSmrg *      This function must be paired with SVGA_FIFOCommitAll().
2274a49301eSmrg *      The faces and mipSizes arrays are initialized to zero.
2284a49301eSmrg *
2294a49301eSmrg *      This creates a "surface" object in the SVGA3D device,
2304a49301eSmrg *      with the provided surface ID (sid). Surfaces are generic
2314a49301eSmrg *      containers for host VRAM objects like textures, vertex
2324a49301eSmrg *      buffers, and depth/stencil buffers.
2334a49301eSmrg *
2343464ebd5Sriastradh *      Surfaces are hierarchical:
2354a49301eSmrg *
2364a49301eSmrg *        - Surface may have multiple faces (for cube maps)
2374a49301eSmrg *
2384a49301eSmrg *          - Each face has a list of mipmap levels
2394a49301eSmrg *
2404a49301eSmrg *             - Each mipmap image may have multiple volume
2414a49301eSmrg *               slices, if the image is three dimensional.
2424a49301eSmrg *
2434a49301eSmrg *                - Each slice is a 2D array of 'blocks'
2444a49301eSmrg *
2454a49301eSmrg *                   - Each block may be one or more pixels.
2464a49301eSmrg *                     (Usually 1, more for DXT or YUV formats.)
2474a49301eSmrg *
2484a49301eSmrg *      Surfaces are generic host VRAM objects. The SVGA3D device
2494a49301eSmrg *      may optimize surfaces according to the format they were
2504a49301eSmrg *      created with, but this format does not limit the ways in
2514a49301eSmrg *      which the surface may be used. For example, a depth surface
2524a49301eSmrg *      can be used as a texture, or a floating point image may
2534a49301eSmrg *      be used as a vertex buffer. Some surface usages may be
2544a49301eSmrg *      lower performance, due to software emulation, but any
2554a49301eSmrg *      usage should work with any surface.
2564a49301eSmrg *
2574a49301eSmrg *      If 'sid' is already defined, the old surface is deleted
2584a49301eSmrg *      and this new surface replaces it.
2594a49301eSmrg *
2604a49301eSmrg *      Surface IDs are arbitrary small non-negative integers,
2614a49301eSmrg *      global to the entire SVGA device.
2624a49301eSmrg *
2634a49301eSmrg * Results:
2644a49301eSmrg *      Returns pointers to arrays allocated in the FIFO for 'faces'
2654a49301eSmrg *      and 'mipSizes'.
2664a49301eSmrg *
2674a49301eSmrg * Side effects:
2684a49301eSmrg *      Begins a FIFO reservation.
2694a49301eSmrg *
2704a49301eSmrg *----------------------------------------------------------------------
2714a49301eSmrg */
2724a49301eSmrg
2734a49301eSmrgenum pipe_error
2744a49301eSmrgSVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
2754a49301eSmrg                          struct svga_winsys_surface *sid, // IN
27601e04c3fSmrg                          SVGA3dSurface1Flags flags,    // IN
2774a49301eSmrg                          SVGA3dSurfaceFormat format,  // IN
2784a49301eSmrg                          SVGA3dSurfaceFace **faces,   // OUT
2794a49301eSmrg                          SVGA3dSize **mipSizes,       // OUT
2804a49301eSmrg                          uint32 numMipSizes)          // IN
2814a49301eSmrg{
2824a49301eSmrg   SVGA3dCmdDefineSurface *cmd;
2834a49301eSmrg
2844a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
2854a49301eSmrg                            SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +
2864a49301eSmrg                            sizeof **mipSizes * numMipSizes, 1);
287af69d88dSmrg   if (!cmd)
2884a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
2894a49301eSmrg
290af69d88dSmrg   swc->surface_relocation(swc, &cmd->sid, NULL, sid,
291af69d88dSmrg                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
2924a49301eSmrg   cmd->surfaceFlags = flags;
2934a49301eSmrg   cmd->format = format;
2944a49301eSmrg
2954a49301eSmrg   *faces = &cmd->face[0];
2964a49301eSmrg   *mipSizes = (SVGA3dSize*) &cmd[1];
2974a49301eSmrg
2984a49301eSmrg   memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);
2994a49301eSmrg   memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);
300af69d88dSmrg
3014a49301eSmrg   return PIPE_OK;
3024a49301eSmrg}
3034a49301eSmrg
3044a49301eSmrg
3054a49301eSmrg/*
3064a49301eSmrg *----------------------------------------------------------------------
3074a49301eSmrg *
3084a49301eSmrg * SVGA3D_DefineSurface2D --
3094a49301eSmrg *
3104a49301eSmrg *      This is a simplified version of SVGA3D_BeginDefineSurface(),
3114a49301eSmrg *      which does not support cube maps, mipmaps, or volume textures.
3124a49301eSmrg *
3134a49301eSmrg * Results:
3144a49301eSmrg *      None.
3154a49301eSmrg *
3164a49301eSmrg * Side effects:
3174a49301eSmrg *      None.
3184a49301eSmrg *
3194a49301eSmrg *----------------------------------------------------------------------
3204a49301eSmrg */
3214a49301eSmrg
3224a49301eSmrgenum pipe_error
3234a49301eSmrgSVGA3D_DefineSurface2D(struct svga_winsys_context *swc,    // IN
3244a49301eSmrg                       struct svga_winsys_surface *sid, // IN
3254a49301eSmrg                       uint32 width,                // IN
3264a49301eSmrg                       uint32 height,               // IN
3274a49301eSmrg                       SVGA3dSurfaceFormat format)  // IN
3284a49301eSmrg{
3294a49301eSmrg   SVGA3dSize *mipSizes;
3304a49301eSmrg   SVGA3dSurfaceFace *faces;
3314a49301eSmrg   enum pipe_error ret;
3324a49301eSmrg
3334a49301eSmrg   ret = SVGA3D_BeginDefineSurface(swc,
3344a49301eSmrg                                   sid, 0, format, &faces, &mipSizes, 1);
335af69d88dSmrg   if (ret != PIPE_OK)
3364a49301eSmrg      return ret;
3374a49301eSmrg
3384a49301eSmrg   faces[0].numMipLevels = 1;
3394a49301eSmrg
3404a49301eSmrg   mipSizes[0].width = width;
3414a49301eSmrg   mipSizes[0].height = height;
3424a49301eSmrg   mipSizes[0].depth = 1;
343af69d88dSmrg
34401e04c3fSmrg   swc->commit(swc);
345af69d88dSmrg
3464a49301eSmrg   return PIPE_OK;
3474a49301eSmrg}
3484a49301eSmrg
3494a49301eSmrg
3504a49301eSmrg/*
3514a49301eSmrg *----------------------------------------------------------------------
3524a49301eSmrg *
3534a49301eSmrg * SVGA3D_DestroySurface --
3544a49301eSmrg *
3554a49301eSmrg *      Release the host VRAM encapsulated by a particular surface ID.
3564a49301eSmrg *
3574a49301eSmrg * Results:
3584a49301eSmrg *      None.
3594a49301eSmrg *
3604a49301eSmrg * Side effects:
3614a49301eSmrg *      None.
3624a49301eSmrg *
3634a49301eSmrg *----------------------------------------------------------------------
3644a49301eSmrg */
3654a49301eSmrg
3664a49301eSmrgenum pipe_error
3674a49301eSmrgSVGA3D_DestroySurface(struct svga_winsys_context *swc,
3684a49301eSmrg                      struct svga_winsys_surface *sid)  // IN
3694a49301eSmrg{
3704a49301eSmrg   SVGA3dCmdDestroySurface *cmd;
371af69d88dSmrg
3724a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
3734a49301eSmrg                            SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);
374af69d88dSmrg   if (!cmd)
3754a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
3764a49301eSmrg
377af69d88dSmrg   swc->surface_relocation(swc, &cmd->sid, NULL, sid,
378af69d88dSmrg                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
37901e04c3fSmrg   swc->commit(swc);
380af69d88dSmrg
3814a49301eSmrg   return PIPE_OK;
3824a49301eSmrg}
3834a49301eSmrg
3844a49301eSmrg
3854a49301eSmrg/*
3864a49301eSmrg *----------------------------------------------------------------------
3874a49301eSmrg *
3883464ebd5Sriastradh * SVGA3D_SurfaceDMA--
3894a49301eSmrg *
3903464ebd5Sriastradh *      Emit a SURFACE_DMA command.
3914a49301eSmrg *
3924a49301eSmrg *      When the SVGA3D device asynchronously processes this FIFO
3934a49301eSmrg *      command, a DMA operation is performed between host VRAM and
3944a49301eSmrg *      a generic SVGAGuestPtr. The guest pointer may refer to guest
3954a49301eSmrg *      VRAM (provided by the SVGA PCI device) or to guest system
3964a49301eSmrg *      memory that has been set up as a Guest Memory Region (GMR)
3974a49301eSmrg *      by the SVGA device.
3984a49301eSmrg *
3994a49301eSmrg *      The guest's DMA buffer must remain valid (not freed, paged out,
4004a49301eSmrg *      or overwritten) until the host has finished processing this
4014a49301eSmrg *      command. The guest can determine that the host has finished
4024a49301eSmrg *      by using the SVGA device's FIFO Fence mechanism.
4034a49301eSmrg *
4044a49301eSmrg *      The guest's image buffer can be an arbitrary size and shape.
4054a49301eSmrg *      Guest image data is interpreted according to the SVGA3D surface
4064a49301eSmrg *      format specified when the surface was defined.
4074a49301eSmrg *
4084a49301eSmrg *      The caller may optionally define the guest image's pitch.
4094a49301eSmrg *      guestImage->pitch can either be zero (assume image is tightly
4104a49301eSmrg *      packed) or it must be the number of bytes between vertically
4114a49301eSmrg *      adjacent image blocks.
4124a49301eSmrg *
4134a49301eSmrg *      The provided copybox list specifies which regions of the source
4144a49301eSmrg *      image are to be copied, and where they appear on the destination.
4154a49301eSmrg *
4164a49301eSmrg *      NOTE: srcx/srcy are always on the guest image and x/y are
4174a49301eSmrg *      always on the host image, regardless of the actual transfer
4184a49301eSmrg *      direction!
4194a49301eSmrg *
4204a49301eSmrg *      For efficiency, the SVGA3D device is free to copy more data
4214a49301eSmrg *      than specified. For example, it may round copy boxes outwards
4224a49301eSmrg *      such that they lie on particular alignment boundaries.
4234a49301eSmrg *
4244a49301eSmrg *----------------------------------------------------------------------
4254a49301eSmrg */
4264a49301eSmrg
4274a49301eSmrgenum pipe_error
4284a49301eSmrgSVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
4294a49301eSmrg                  struct svga_transfer *st,         // IN
4304a49301eSmrg                  SVGA3dTransferType transfer,      // IN
4314a49301eSmrg                  const SVGA3dCopyBox *boxes,       // IN
4323464ebd5Sriastradh                  uint32 numBoxes,                  // IN
4333464ebd5Sriastradh                  SVGA3dSurfaceDMAFlags flags)      // IN
4344a49301eSmrg{
435af69d88dSmrg   struct svga_texture *texture = svga_texture(st->base.resource);
4364a49301eSmrg   SVGA3dCmdSurfaceDMA *cmd;
4374a49301eSmrg   SVGA3dCmdSurfaceDMASuffix *pSuffix;
4384a49301eSmrg   uint32 boxesSize = sizeof *boxes * numBoxes;
4394a49301eSmrg   unsigned region_flags;
4404a49301eSmrg   unsigned surface_flags;
441af69d88dSmrg
442af69d88dSmrg   if (transfer == SVGA3D_WRITE_HOST_VRAM) {
4433464ebd5Sriastradh      region_flags = SVGA_RELOC_READ;
4443464ebd5Sriastradh      surface_flags = SVGA_RELOC_WRITE;
4454a49301eSmrg   }
446af69d88dSmrg   else if (transfer == SVGA3D_READ_HOST_VRAM) {
4473464ebd5Sriastradh      region_flags = SVGA_RELOC_WRITE;
4483464ebd5Sriastradh      surface_flags = SVGA_RELOC_READ;
4494a49301eSmrg   }
4504a49301eSmrg   else {
4514a49301eSmrg      assert(0);
4524a49301eSmrg      return PIPE_ERROR_BAD_INPUT;
4534a49301eSmrg   }
454af69d88dSmrg
4554a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
4564a49301eSmrg                            SVGA_3D_CMD_SURFACE_DMA,
4574a49301eSmrg                            sizeof *cmd + boxesSize + sizeof *pSuffix,
4584a49301eSmrg                            2);
459af69d88dSmrg   if (!cmd)
4604a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
4614a49301eSmrg
4624a49301eSmrg   swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
4634a49301eSmrg   cmd->guest.pitch = st->base.stride;
4644a49301eSmrg
465af69d88dSmrg   swc->surface_relocation(swc, &cmd->host.sid, NULL,
466af69d88dSmrg                           texture->handle, surface_flags);
46701e04c3fSmrg   cmd->host.face = st->slice; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
4684a49301eSmrg   cmd->host.mipmap = st->base.level;
4694a49301eSmrg
4704a49301eSmrg   cmd->transfer = transfer;
4714a49301eSmrg
4724a49301eSmrg   memcpy(&cmd[1], boxes, boxesSize);
473af69d88dSmrg
4744a49301eSmrg   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
4754a49301eSmrg   pSuffix->suffixSize = sizeof *pSuffix;
4764a49301eSmrg   pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
4773464ebd5Sriastradh   pSuffix->flags = flags;
4784a49301eSmrg
4794a49301eSmrg   swc->commit(swc);
48001e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
4814a49301eSmrg
4824a49301eSmrg   return PIPE_OK;
4834a49301eSmrg}
4844a49301eSmrg
4854a49301eSmrg
4864a49301eSmrgenum pipe_error
4874a49301eSmrgSVGA3D_BufferDMA(struct svga_winsys_context *swc,
4884a49301eSmrg                 struct svga_winsys_buffer *guest,
4894a49301eSmrg                 struct svga_winsys_surface *host,
4904a49301eSmrg                 SVGA3dTransferType transfer,      // IN
4914a49301eSmrg                 uint32 size,                      // IN
4924a49301eSmrg                 uint32 guest_offset,              // IN
4934a49301eSmrg                 uint32 host_offset,               // IN
4944a49301eSmrg                 SVGA3dSurfaceDMAFlags flags)      // IN
4954a49301eSmrg{
4964a49301eSmrg   SVGA3dCmdSurfaceDMA *cmd;
4974a49301eSmrg   SVGA3dCopyBox *box;
4984a49301eSmrg   SVGA3dCmdSurfaceDMASuffix *pSuffix;
4994a49301eSmrg   unsigned region_flags;
5004a49301eSmrg   unsigned surface_flags;
5014a49301eSmrg
502af69d88dSmrg   assert(!swc->have_gb_objects);
503af69d88dSmrg
504af69d88dSmrg   if (transfer == SVGA3D_WRITE_HOST_VRAM) {
5053464ebd5Sriastradh      region_flags = SVGA_RELOC_READ;
5063464ebd5Sriastradh      surface_flags = SVGA_RELOC_WRITE;
5074a49301eSmrg   }
508af69d88dSmrg   else if (transfer == SVGA3D_READ_HOST_VRAM) {
5093464ebd5Sriastradh      region_flags = SVGA_RELOC_WRITE;
5103464ebd5Sriastradh      surface_flags = SVGA_RELOC_READ;
5114a49301eSmrg   }
5124a49301eSmrg   else {
5134a49301eSmrg      assert(0);
5144a49301eSmrg      return PIPE_ERROR_BAD_INPUT;
5154a49301eSmrg   }
516af69d88dSmrg
5174a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
5184a49301eSmrg                            SVGA_3D_CMD_SURFACE_DMA,
5194a49301eSmrg                            sizeof *cmd + sizeof *box + sizeof *pSuffix,
5204a49301eSmrg                            2);
521af69d88dSmrg   if (!cmd)
5224a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
5234a49301eSmrg
5244a49301eSmrg   swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
5254a49301eSmrg   cmd->guest.pitch = 0;
5264a49301eSmrg
527af69d88dSmrg   swc->surface_relocation(swc, &cmd->host.sid,
528af69d88dSmrg                           NULL, host, surface_flags);
5294a49301eSmrg   cmd->host.face = 0;
5304a49301eSmrg   cmd->host.mipmap = 0;
5314a49301eSmrg
5324a49301eSmrg   cmd->transfer = transfer;
5334a49301eSmrg
5344a49301eSmrg   box = (SVGA3dCopyBox *)&cmd[1];
5354a49301eSmrg   box->x = host_offset;
5364a49301eSmrg   box->y = 0;
5374a49301eSmrg   box->z = 0;
5384a49301eSmrg   box->w = size;
5394a49301eSmrg   box->h = 1;
5404a49301eSmrg   box->d = 1;
5414a49301eSmrg   box->srcx = guest_offset;
5424a49301eSmrg   box->srcy = 0;
5434a49301eSmrg   box->srcz = 0;
544af69d88dSmrg
5454a49301eSmrg   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
5464a49301eSmrg   pSuffix->suffixSize = sizeof *pSuffix;
5474a49301eSmrg   pSuffix->maximumOffset = guest_offset + size;
5484a49301eSmrg   pSuffix->flags = flags;
5494a49301eSmrg
5504a49301eSmrg   swc->commit(swc);
55101e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
5524a49301eSmrg
5534a49301eSmrg   return PIPE_OK;
5544a49301eSmrg}
5554a49301eSmrg
5564a49301eSmrg
5574a49301eSmrg/*
5584a49301eSmrg *----------------------------------------------------------------------
5594a49301eSmrg *
5604a49301eSmrg * SVGA3D_SetRenderTarget --
5614a49301eSmrg *
5624a49301eSmrg *      Bind a surface object to a particular render target attachment
5634a49301eSmrg *      point on the current context. Render target attachment points
5644a49301eSmrg *      exist for color buffers, a depth buffer, and a stencil buffer.
5654a49301eSmrg *
5664a49301eSmrg *      The SVGA3D device is quite lenient about the types of surfaces
5674a49301eSmrg *      that may be used as render targets. The color buffers must
5684a49301eSmrg *      all be the same size, but the depth and stencil buffers do not
5694a49301eSmrg *      have to be the same size as the color buffer. All attachments
5704a49301eSmrg *      are optional.
5714a49301eSmrg *
5724a49301eSmrg *      Some combinations of render target formats may require software
5734a49301eSmrg *      emulation, depending on the capabilities of the host graphics
5744a49301eSmrg *      API and graphics hardware.
5754a49301eSmrg *
5764a49301eSmrg * Results:
5774a49301eSmrg *      None.
5784a49301eSmrg *
5794a49301eSmrg * Side effects:
5804a49301eSmrg *      None.
5814a49301eSmrg *
5824a49301eSmrg *----------------------------------------------------------------------
5834a49301eSmrg */
5844a49301eSmrg
5854a49301eSmrgenum pipe_error
5864a49301eSmrgSVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
5874a49301eSmrg                       SVGA3dRenderTargetType type,   // IN
5884a49301eSmrg                       struct pipe_surface *surface)  // IN
5894a49301eSmrg{
5904a49301eSmrg   SVGA3dCmdSetRenderTarget *cmd;
591af69d88dSmrg
5924a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
5934a49301eSmrg                            SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);
594af69d88dSmrg   if (!cmd)
5954a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
5964a49301eSmrg
5974a49301eSmrg   cmd->cid = swc->cid;
5984a49301eSmrg   cmd->type = type;
5993464ebd5Sriastradh   surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
6004a49301eSmrg   swc->commit(swc);
6014a49301eSmrg
6024a49301eSmrg   return PIPE_OK;
6034a49301eSmrg}
6044a49301eSmrg
6054a49301eSmrg
6064a49301eSmrg/*
6074a49301eSmrg *----------------------------------------------------------------------
6084a49301eSmrg *
6094a49301eSmrg * SVGA3D_DefineShader --
6104a49301eSmrg *
6114a49301eSmrg *      Upload the bytecode for a new shader. The bytecode is "SVGA3D
6124a49301eSmrg *      format", which is theoretically a binary-compatible superset
6134a49301eSmrg *      of Microsoft's DirectX shader bytecode. In practice, the
6144a49301eSmrg *      SVGA3D bytecode doesn't yet have any extensions to DirectX's
6154a49301eSmrg *      bytecode format.
6164a49301eSmrg *
6174a49301eSmrg *      The SVGA3D device supports shader models 1.1 through 2.0.
6184a49301eSmrg *
6194a49301eSmrg *      The caller chooses a shader ID (small positive integer) by
6204a49301eSmrg *      which this shader will be identified in future commands. This
6214a49301eSmrg *      ID is in a namespace which is per-context and per-shader-type.
6224a49301eSmrg *
6234a49301eSmrg *      'bytecodeLen' is specified in bytes. It must be a multiple of 4.
6244a49301eSmrg *
6254a49301eSmrg * Results:
6264a49301eSmrg *      None.
6274a49301eSmrg *
6284a49301eSmrg * Side effects:
6294a49301eSmrg *      None.
6304a49301eSmrg *
6314a49301eSmrg *----------------------------------------------------------------------
6324a49301eSmrg */
6334a49301eSmrg
6344a49301eSmrgenum pipe_error
6354a49301eSmrgSVGA3D_DefineShader(struct svga_winsys_context *swc,
6364a49301eSmrg                    uint32 shid,                  // IN
6374a49301eSmrg                    SVGA3dShaderType type,        // IN
6384a49301eSmrg                    const uint32 *bytecode,       // IN
6394a49301eSmrg                    uint32 bytecodeLen)           // IN
6404a49301eSmrg{
6414a49301eSmrg   SVGA3dCmdDefineShader *cmd;
6424a49301eSmrg
6434a49301eSmrg   assert(bytecodeLen % 4 == 0);
6444a49301eSmrg
6454a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
6464a49301eSmrg                            SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,
6474a49301eSmrg                            0);
648af69d88dSmrg   if (!cmd)
6494a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
6504a49301eSmrg
6514a49301eSmrg   cmd->cid = swc->cid;
6524a49301eSmrg   cmd->shid = shid;
6534a49301eSmrg   cmd->type = type;
6544a49301eSmrg   memcpy(&cmd[1], bytecode, bytecodeLen);
6554a49301eSmrg   swc->commit(swc);
6564a49301eSmrg
6574a49301eSmrg   return PIPE_OK;
6584a49301eSmrg}
6594a49301eSmrg
6604a49301eSmrg
6614a49301eSmrg/*
6624a49301eSmrg *----------------------------------------------------------------------
6634a49301eSmrg *
6644a49301eSmrg * SVGA3D_DestroyShader --
6654a49301eSmrg *
6664a49301eSmrg *      Delete a shader that was created by SVGA3D_DefineShader. If
6674a49301eSmrg *      the shader was the current vertex or pixel shader for its
6684a49301eSmrg *      context, rendering results are undefined until a new shader is
6694a49301eSmrg *      bound.
6704a49301eSmrg *
6714a49301eSmrg * Results:
6724a49301eSmrg *      None.
6734a49301eSmrg *
6744a49301eSmrg * Side effects:
6754a49301eSmrg *      None.
6764a49301eSmrg *
6774a49301eSmrg *----------------------------------------------------------------------
6784a49301eSmrg */
6794a49301eSmrg
6804a49301eSmrgenum pipe_error
6814a49301eSmrgSVGA3D_DestroyShader(struct svga_winsys_context *swc,
6824a49301eSmrg                     uint32 shid,            // IN
6834a49301eSmrg                     SVGA3dShaderType type)  // IN
6844a49301eSmrg{
6854a49301eSmrg   SVGA3dCmdDestroyShader *cmd;
686af69d88dSmrg
6874a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
6884a49301eSmrg                            SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,
6894a49301eSmrg                            0);
690af69d88dSmrg   if (!cmd)
6914a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
6924a49301eSmrg
6934a49301eSmrg   cmd->cid = swc->cid;
6944a49301eSmrg   cmd->shid = shid;
6954a49301eSmrg   cmd->type = type;
6964a49301eSmrg   swc->commit(swc);
6974a49301eSmrg
6984a49301eSmrg   return PIPE_OK;
6994a49301eSmrg}
7004a49301eSmrg
7014a49301eSmrg
7024a49301eSmrg/*
7034a49301eSmrg *----------------------------------------------------------------------
7044a49301eSmrg *
7054a49301eSmrg * SVGA3D_SetShaderConst --
7064a49301eSmrg *
7074a49301eSmrg *      Set the value of a shader constant.
7084a49301eSmrg *
7094a49301eSmrg *      Shader constants are analogous to uniform variables in GLSL,
7104a49301eSmrg *      except that they belong to the render context rather than to
7114a49301eSmrg *      an individual shader.
7124a49301eSmrg *
7134a49301eSmrg *      Constants may have one of three types: A 4-vector of floats,
7144a49301eSmrg *      a 4-vector of integers, or a single boolean flag.
7154a49301eSmrg *
7164a49301eSmrg * Results:
7174a49301eSmrg *      None.
7184a49301eSmrg *
7194a49301eSmrg * Side effects:
7204a49301eSmrg *      None.
7214a49301eSmrg *
7224a49301eSmrg *----------------------------------------------------------------------
7234a49301eSmrg */
7244a49301eSmrg
7254a49301eSmrgenum pipe_error
7264a49301eSmrgSVGA3D_SetShaderConst(struct svga_winsys_context *swc,
7274a49301eSmrg                      uint32 reg,                   // IN
7284a49301eSmrg                      SVGA3dShaderType type,        // IN
7294a49301eSmrg                      SVGA3dShaderConstType ctype,  // IN
7304a49301eSmrg                      const void *value)            // IN
7314a49301eSmrg{
7324a49301eSmrg   SVGA3dCmdSetShaderConst *cmd;
733af69d88dSmrg
7344a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
7354a49301eSmrg                            SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,
7364a49301eSmrg                            0);
737af69d88dSmrg   if (!cmd)
7384a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
7394a49301eSmrg
7404a49301eSmrg   cmd->cid = swc->cid;
7414a49301eSmrg   cmd->reg = reg;
7424a49301eSmrg   cmd->type = type;
7434a49301eSmrg   cmd->ctype = ctype;
7444a49301eSmrg
7454a49301eSmrg   switch (ctype) {
7464a49301eSmrg
7474a49301eSmrg   case SVGA3D_CONST_TYPE_FLOAT:
7484a49301eSmrg   case SVGA3D_CONST_TYPE_INT:
7494a49301eSmrg      memcpy(&cmd->values, value, sizeof cmd->values);
7504a49301eSmrg      break;
7514a49301eSmrg
7524a49301eSmrg   case SVGA3D_CONST_TYPE_BOOL:
7534a49301eSmrg      memset(&cmd->values, 0, sizeof cmd->values);
7544a49301eSmrg      cmd->values[0] = *(uint32*)value;
7554a49301eSmrg      break;
7564a49301eSmrg
7574a49301eSmrg   default:
7584a49301eSmrg      assert(0);
7594a49301eSmrg      break;
7604a49301eSmrg
7614a49301eSmrg   }
7624a49301eSmrg   swc->commit(swc);
7634a49301eSmrg
7644a49301eSmrg   return PIPE_OK;
7654a49301eSmrg}
7664a49301eSmrg
7674a49301eSmrg
768af69d88dSmrg/*
769af69d88dSmrg *----------------------------------------------------------------------
770af69d88dSmrg *
771af69d88dSmrg * SVGA3D_SetShaderConsts --
772af69d88dSmrg *
773af69d88dSmrg *      Set the value of successive shader constants.
774af69d88dSmrg *
775af69d88dSmrg *      Shader constants are analogous to uniform variables in GLSL,
776af69d88dSmrg *      except that they belong to the render context rather than to
777af69d88dSmrg *      an individual shader.
778af69d88dSmrg *
779af69d88dSmrg *      Constants may have one of three types: A 4-vector of floats,
780af69d88dSmrg *      a 4-vector of integers, or a single boolean flag.
781af69d88dSmrg *
782af69d88dSmrg * Results:
783af69d88dSmrg *      None.
784af69d88dSmrg *
785af69d88dSmrg * Side effects:
786af69d88dSmrg *      None.
787af69d88dSmrg *
788af69d88dSmrg *----------------------------------------------------------------------
789af69d88dSmrg */
790af69d88dSmrg
791af69d88dSmrgenum pipe_error
792af69d88dSmrgSVGA3D_SetShaderConsts(struct svga_winsys_context *swc,
793af69d88dSmrg                        uint32 reg,                   // IN
794af69d88dSmrg                        uint32 numRegs,               // IN
795af69d88dSmrg                        SVGA3dShaderType type,        // IN
796af69d88dSmrg                        SVGA3dShaderConstType ctype,  // IN
797af69d88dSmrg                        const void *values)           // IN
798af69d88dSmrg{
799af69d88dSmrg   SVGA3dCmdSetShaderConst *cmd;
800af69d88dSmrg
801af69d88dSmrg   cmd = SVGA3D_FIFOReserve(swc,
802af69d88dSmrg                            SVGA_3D_CMD_SET_SHADER_CONST,
803af69d88dSmrg                            sizeof *cmd + (numRegs - 1) * sizeof cmd->values,
804af69d88dSmrg                            0);
805af69d88dSmrg   if (!cmd)
806af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
807af69d88dSmrg
808af69d88dSmrg   cmd->cid = swc->cid;
809af69d88dSmrg   cmd->reg = reg;
810af69d88dSmrg   cmd->type = type;
811af69d88dSmrg   cmd->ctype = ctype;
812af69d88dSmrg
813af69d88dSmrg   memcpy(&cmd->values, values, numRegs * sizeof cmd->values);
814af69d88dSmrg
815af69d88dSmrg   swc->commit(swc);
816af69d88dSmrg
817af69d88dSmrg   return PIPE_OK;
818af69d88dSmrg}
819af69d88dSmrg
820af69d88dSmrg
8214a49301eSmrg
8224a49301eSmrg
8234a49301eSmrg
8244a49301eSmrg/*
8254a49301eSmrg *----------------------------------------------------------------------
8264a49301eSmrg *
8274a49301eSmrg * SVGA3D_SetShader --
8284a49301eSmrg *
8294a49301eSmrg *      Switch active shaders. This binds a new vertex or pixel shader
8304a49301eSmrg *      to the specified context.
8314a49301eSmrg *
8324a49301eSmrg *      A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
8334a49301eSmrg *      back to the fixed function vertex or pixel pipeline.
8344a49301eSmrg *
8354a49301eSmrg * Results:
8364a49301eSmrg *      None.
8374a49301eSmrg *
8384a49301eSmrg * Side effects:
8394a49301eSmrg *      None.
8404a49301eSmrg *
8414a49301eSmrg *----------------------------------------------------------------------
8424a49301eSmrg */
8434a49301eSmrg
8444a49301eSmrgenum pipe_error
8454a49301eSmrgSVGA3D_SetShader(struct svga_winsys_context *swc,
8464a49301eSmrg                 SVGA3dShaderType type,  // IN
8474a49301eSmrg                 uint32 shid)            // IN
8484a49301eSmrg{
8494a49301eSmrg   SVGA3dCmdSetShader *cmd;
850af69d88dSmrg
85101e04c3fSmrg   assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS);
85201e04c3fSmrg
8534a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
8544a49301eSmrg                            SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
8554a49301eSmrg                            0);
856af69d88dSmrg   if (!cmd)
8574a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
858af69d88dSmrg
8594a49301eSmrg   cmd->cid = swc->cid;
8604a49301eSmrg   cmd->type = type;
8614a49301eSmrg   cmd->shid = shid;
8624a49301eSmrg   swc->commit(swc);
8634a49301eSmrg
8644a49301eSmrg   return PIPE_OK;
8654a49301eSmrg}
8664a49301eSmrg
8674a49301eSmrg
8684a49301eSmrg/*
8694a49301eSmrg *----------------------------------------------------------------------
8704a49301eSmrg *
8714a49301eSmrg * SVGA3D_BeginClear --
8724a49301eSmrg *
8734a49301eSmrg *      Begin a CLEAR command. This reserves space for it in the FIFO,
8744a49301eSmrg *      and returns a pointer to the command's rectangle array.  This
8754a49301eSmrg *      function must be paired with SVGA_FIFOCommitAll().
8764a49301eSmrg *
8774a49301eSmrg *      Clear is a rendering operation which fills a list of
8784a49301eSmrg *      rectangles with constant values on all render target types
8794a49301eSmrg *      indicated by 'flags'.
8804a49301eSmrg *
8814a49301eSmrg *      Clear is not affected by clipping, depth test, or other
8824a49301eSmrg *      render state which affects the fragment pipeline.
8834a49301eSmrg *
8844a49301eSmrg * Results:
8854a49301eSmrg *      None.
8864a49301eSmrg *
8874a49301eSmrg * Side effects:
8884a49301eSmrg *      May write to attached render target surfaces.
8894a49301eSmrg *
8904a49301eSmrg *----------------------------------------------------------------------
8914a49301eSmrg */
8924a49301eSmrg
8934a49301eSmrgenum pipe_error
8944a49301eSmrgSVGA3D_BeginClear(struct svga_winsys_context *swc,
8954a49301eSmrg                  SVGA3dClearFlag flags,  // IN
8964a49301eSmrg                  uint32 color,           // IN
8974a49301eSmrg                  float depth,            // IN
8984a49301eSmrg                  uint32 stencil,         // IN
8994a49301eSmrg                  SVGA3dRect **rects,     // OUT
9004a49301eSmrg                  uint32 numRects)        // IN
9014a49301eSmrg{
9024a49301eSmrg   SVGA3dCmdClear *cmd;
903af69d88dSmrg
9044a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
905af69d88dSmrg                            SVGA_3D_CMD_CLEAR,
9064a49301eSmrg                            sizeof *cmd + sizeof **rects * numRects,
9074a49301eSmrg                            0);
908af69d88dSmrg   if (!cmd)
9094a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
9104a49301eSmrg
9114a49301eSmrg   cmd->cid = swc->cid;
9124a49301eSmrg   cmd->clearFlag = flags;
9134a49301eSmrg   cmd->color = color;
9144a49301eSmrg   cmd->depth = depth;
9154a49301eSmrg   cmd->stencil = stencil;
9164a49301eSmrg   *rects = (SVGA3dRect*) &cmd[1];
9174a49301eSmrg
9184a49301eSmrg   return PIPE_OK;
9194a49301eSmrg}
9204a49301eSmrg
9214a49301eSmrg
9224a49301eSmrg/*
9234a49301eSmrg *----------------------------------------------------------------------
9244a49301eSmrg *
9254a49301eSmrg * SVGA3D_ClearRect --
9264a49301eSmrg *
9274a49301eSmrg *      This is a simplified version of SVGA3D_BeginClear().
9284a49301eSmrg *
9294a49301eSmrg * Results:
9304a49301eSmrg *      None.
9314a49301eSmrg *
9324a49301eSmrg * Side effects:
9334a49301eSmrg *      None.
9344a49301eSmrg *
9354a49301eSmrg *----------------------------------------------------------------------
9364a49301eSmrg */
9374a49301eSmrg
9384a49301eSmrgenum pipe_error
9394a49301eSmrgSVGA3D_ClearRect(struct svga_winsys_context *swc,
9404a49301eSmrg                 SVGA3dClearFlag flags,  // IN
9414a49301eSmrg                 uint32 color,           // IN
9424a49301eSmrg                 float depth,            // IN
9434a49301eSmrg                 uint32 stencil,         // IN
9444a49301eSmrg                 uint32 x,               // IN
9454a49301eSmrg                 uint32 y,               // IN
9464a49301eSmrg                 uint32 w,               // IN
9474a49301eSmrg                 uint32 h)               // IN
9484a49301eSmrg{
9494a49301eSmrg   SVGA3dRect *rect;
9504a49301eSmrg   enum pipe_error ret;
9514a49301eSmrg
9524a49301eSmrg   ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
953af69d88dSmrg   if (ret != PIPE_OK)
9544a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
9554a49301eSmrg
9564a49301eSmrg   memset(rect, 0, sizeof *rect);
9574a49301eSmrg   rect->x = x;
9584a49301eSmrg   rect->y = y;
9594a49301eSmrg   rect->w = w;
9604a49301eSmrg   rect->h = h;
9614a49301eSmrg   swc->commit(swc);
9624a49301eSmrg
9634a49301eSmrg   return PIPE_OK;
9644a49301eSmrg}
9654a49301eSmrg
9664a49301eSmrg
9674a49301eSmrg/*
9684a49301eSmrg *----------------------------------------------------------------------
9694a49301eSmrg *
9704a49301eSmrg * SVGA3D_BeginDrawPrimitives --
9714a49301eSmrg *
9724a49301eSmrg *      Begin a DRAW_PRIMITIVES command. This reserves space for it in
9734a49301eSmrg *      the FIFO, and returns a pointer to the command's arrays.
9744a49301eSmrg *      This function must be paired with SVGA_FIFOCommitAll().
9754a49301eSmrg *
9764a49301eSmrg *      Drawing commands consist of two variable-length arrays:
9774a49301eSmrg *      SVGA3dVertexDecl elements declare a set of vertex buffers to
9784a49301eSmrg *      use while rendering, and SVGA3dPrimitiveRange elements specify
9794a49301eSmrg *      groups of primitives each with an optional index buffer.
9804a49301eSmrg *
9814a49301eSmrg *      The decls and ranges arrays are initialized to zero.
9824a49301eSmrg *
9834a49301eSmrg * Results:
9844a49301eSmrg *      None.
9854a49301eSmrg *
9864a49301eSmrg * Side effects:
9874a49301eSmrg *      May write to attached render target surfaces.
9884a49301eSmrg *
9894a49301eSmrg *----------------------------------------------------------------------
9904a49301eSmrg */
9914a49301eSmrg
9924a49301eSmrgenum pipe_error
9934a49301eSmrgSVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
9944a49301eSmrg                           SVGA3dVertexDecl **decls,      // OUT
9954a49301eSmrg                           uint32 numVertexDecls,         // IN
9964a49301eSmrg                           SVGA3dPrimitiveRange **ranges, // OUT
9974a49301eSmrg                           uint32 numRanges)              // IN
9984a49301eSmrg{
9994a49301eSmrg   SVGA3dCmdDrawPrimitives *cmd;
10004a49301eSmrg   SVGA3dVertexDecl *declArray;
10014a49301eSmrg   SVGA3dPrimitiveRange *rangeArray;
10024a49301eSmrg   uint32 declSize = sizeof **decls * numVertexDecls;
10034a49301eSmrg   uint32 rangeSize = sizeof **ranges * numRanges;
10044a49301eSmrg
10054a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
1006af69d88dSmrg                            SVGA_3D_CMD_DRAW_PRIMITIVES,
10074a49301eSmrg                            sizeof *cmd + declSize + rangeSize,
10084a49301eSmrg                            numVertexDecls + numRanges);
1009af69d88dSmrg   if (!cmd)
10104a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
10114a49301eSmrg
10124a49301eSmrg   cmd->cid = swc->cid;
10134a49301eSmrg   cmd->numVertexDecls = numVertexDecls;
10144a49301eSmrg   cmd->numRanges = numRanges;
10154a49301eSmrg
10164a49301eSmrg   declArray = (SVGA3dVertexDecl*) &cmd[1];
10174a49301eSmrg   rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
10184a49301eSmrg
10194a49301eSmrg   memset(declArray, 0, declSize);
10204a49301eSmrg   memset(rangeArray, 0, rangeSize);
10214a49301eSmrg
10224a49301eSmrg   *decls = declArray;
10234a49301eSmrg   *ranges = rangeArray;
10244a49301eSmrg
102501e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
102601e04c3fSmrg
102701e04c3fSmrg   swc->num_draw_commands++;
102801e04c3fSmrg
10294a49301eSmrg   return PIPE_OK;
10304a49301eSmrg}
10314a49301eSmrg
10324a49301eSmrg
10334a49301eSmrg/*
10344a49301eSmrg *----------------------------------------------------------------------
10354a49301eSmrg *
10364a49301eSmrg * SVGA3D_BeginSurfaceCopy --
10374a49301eSmrg *
10384a49301eSmrg *      Begin a SURFACE_COPY command. This reserves space for it in
10394a49301eSmrg *      the FIFO, and returns a pointer to the command's arrays.  This
10404a49301eSmrg *      function must be paired with SVGA_FIFOCommitAll().
10414a49301eSmrg *
10424a49301eSmrg *      The box array is initialized with zeroes.
10434a49301eSmrg *
10444a49301eSmrg * Results:
10454a49301eSmrg *      None.
10464a49301eSmrg *
10474a49301eSmrg * Side effects:
10484a49301eSmrg *      Asynchronously copies a list of boxes from surface to surface.
10494a49301eSmrg *
10504a49301eSmrg *----------------------------------------------------------------------
10514a49301eSmrg */
10524a49301eSmrg
10534a49301eSmrgenum pipe_error
10544a49301eSmrgSVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
10554a49301eSmrg                        struct pipe_surface *src,    // IN
10564a49301eSmrg                        struct pipe_surface *dest,   // IN
10574a49301eSmrg                        SVGA3dCopyBox **boxes,       // OUT
10584a49301eSmrg                        uint32 numBoxes)             // IN
10594a49301eSmrg{
10604a49301eSmrg   SVGA3dCmdSurfaceCopy *cmd;
10614a49301eSmrg   uint32 boxesSize = sizeof **boxes * numBoxes;
10624a49301eSmrg
10634a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
10644a49301eSmrg                            SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
10654a49301eSmrg                            2);
1066af69d88dSmrg   if (!cmd)
10674a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
10684a49301eSmrg
10693464ebd5Sriastradh   surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
10703464ebd5Sriastradh   surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
10714a49301eSmrg   *boxes = (SVGA3dCopyBox*) &cmd[1];
10724a49301eSmrg
10734a49301eSmrg   memset(*boxes, 0, boxesSize);
10744a49301eSmrg
10754a49301eSmrg   return PIPE_OK;
10764a49301eSmrg}
10774a49301eSmrg
10784a49301eSmrg
10794a49301eSmrg/*
10804a49301eSmrg *----------------------------------------------------------------------
10814a49301eSmrg *
10824a49301eSmrg * SVGA3D_SurfaceStretchBlt --
10834a49301eSmrg *
10844a49301eSmrg *      Issue a SURFACE_STRETCHBLT command: an asynchronous
10854a49301eSmrg *      surface-to-surface blit, with scaling.
10864a49301eSmrg *
10874a49301eSmrg * Results:
10884a49301eSmrg *      None.
10894a49301eSmrg *
10904a49301eSmrg * Side effects:
10914a49301eSmrg *      Asynchronously copies one box from surface to surface.
10924a49301eSmrg *
10934a49301eSmrg *----------------------------------------------------------------------
10944a49301eSmrg */
10954a49301eSmrg
10964a49301eSmrgenum pipe_error
10974a49301eSmrgSVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
10984a49301eSmrg                         struct pipe_surface *src,    // IN
10994a49301eSmrg                         struct pipe_surface *dest,   // IN
11004a49301eSmrg                         SVGA3dBox *boxSrc,           // IN
11014a49301eSmrg                         SVGA3dBox *boxDest,          // IN
11024a49301eSmrg                         SVGA3dStretchBltMode mode)   // IN
11034a49301eSmrg{
11044a49301eSmrg   SVGA3dCmdSurfaceStretchBlt *cmd;
1105af69d88dSmrg
11064a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
11074a49301eSmrg                            SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
11084a49301eSmrg                            2);
1109af69d88dSmrg   if (!cmd)
11104a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
11114a49301eSmrg
11123464ebd5Sriastradh   surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
11133464ebd5Sriastradh   surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
11144a49301eSmrg   cmd->boxSrc = *boxSrc;
11154a49301eSmrg   cmd->boxDest = *boxDest;
11164a49301eSmrg   cmd->mode = mode;
11174a49301eSmrg   swc->commit(swc);
11184a49301eSmrg
11194a49301eSmrg   return PIPE_OK;
11204a49301eSmrg}
11214a49301eSmrg
11224a49301eSmrg
11234a49301eSmrg/*
11244a49301eSmrg *----------------------------------------------------------------------
11254a49301eSmrg *
11264a49301eSmrg * SVGA3D_SetViewport --
11274a49301eSmrg *
11284a49301eSmrg *      Set the current context's viewport rectangle. The viewport
11294a49301eSmrg *      is clipped to the dimensions of the current render target,
11304a49301eSmrg *      then all rendering is clipped to the viewport.
11314a49301eSmrg *
11324a49301eSmrg * Results:
11334a49301eSmrg *      None.
11344a49301eSmrg *
11354a49301eSmrg * Side effects:
11364a49301eSmrg *      None.
11374a49301eSmrg *
11384a49301eSmrg *----------------------------------------------------------------------
11394a49301eSmrg */
11404a49301eSmrg
11414a49301eSmrgenum pipe_error
11424a49301eSmrgSVGA3D_SetViewport(struct svga_winsys_context *swc,
11434a49301eSmrg                   SVGA3dRect *rect)  // IN
11444a49301eSmrg{
11454a49301eSmrg   SVGA3dCmdSetViewport *cmd;
1146af69d88dSmrg
11474a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
11484a49301eSmrg                            SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
11494a49301eSmrg                            0);
1150af69d88dSmrg   if (!cmd)
11514a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
11524a49301eSmrg
11534a49301eSmrg   cmd->cid = swc->cid;
11544a49301eSmrg   cmd->rect = *rect;
11554a49301eSmrg   swc->commit(swc);
11564a49301eSmrg
11574a49301eSmrg   return PIPE_OK;
11584a49301eSmrg}
11594a49301eSmrg
11604a49301eSmrg
11614a49301eSmrg
11624a49301eSmrg
11634a49301eSmrg/*
11644a49301eSmrg *----------------------------------------------------------------------
11654a49301eSmrg *
11664a49301eSmrg * SVGA3D_SetScissorRect --
11674a49301eSmrg *
1168af69d88dSmrg *      Set the current context's scissor rectangle. If scissoring
1169af69d88dSmrg *      is enabled then all rendering is clipped to the scissor bounds.
11704a49301eSmrg *
11714a49301eSmrg * Results:
11724a49301eSmrg *      None.
11734a49301eSmrg *
11744a49301eSmrg * Side effects:
11754a49301eSmrg *      None.
11764a49301eSmrg *
11774a49301eSmrg *----------------------------------------------------------------------
11784a49301eSmrg */
11794a49301eSmrg
11804a49301eSmrgenum pipe_error
11814a49301eSmrgSVGA3D_SetScissorRect(struct svga_winsys_context *swc,
11824a49301eSmrg                      SVGA3dRect *rect)  // IN
11834a49301eSmrg{
11844a49301eSmrg   SVGA3dCmdSetScissorRect *cmd;
1185af69d88dSmrg
11864a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
11874a49301eSmrg                            SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
11884a49301eSmrg                            0);
1189af69d88dSmrg   if (!cmd)
11904a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
11914a49301eSmrg
11924a49301eSmrg   cmd->cid = swc->cid;
11934a49301eSmrg   cmd->rect = *rect;
11944a49301eSmrg   swc->commit(swc);
11954a49301eSmrg
11964a49301eSmrg   return PIPE_OK;
11974a49301eSmrg}
11984a49301eSmrg
11994a49301eSmrg/*
12004a49301eSmrg *----------------------------------------------------------------------
12014a49301eSmrg *
12024a49301eSmrg * SVGA3D_SetClipPlane --
12034a49301eSmrg *
12044a49301eSmrg *      Set one of the current context's clip planes. If the clip
1205af69d88dSmrg *      plane is enabled then all 3d rendering is clipped against
12064a49301eSmrg *      the plane.
12074a49301eSmrg *
12084a49301eSmrg * Results:
12094a49301eSmrg *      None.
12104a49301eSmrg *
12114a49301eSmrg * Side effects:
12124a49301eSmrg *      None.
12134a49301eSmrg *
12144a49301eSmrg *----------------------------------------------------------------------
12154a49301eSmrg */
12164a49301eSmrg
1217af69d88dSmrgenum pipe_error
1218af69d88dSmrgSVGA3D_SetClipPlane(struct svga_winsys_context *swc,
1219af69d88dSmrg                    uint32 index, const float *plane)
12204a49301eSmrg{
12214a49301eSmrg   SVGA3dCmdSetClipPlane *cmd;
1222af69d88dSmrg
12234a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
12244a49301eSmrg                            SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
12254a49301eSmrg                            0);
1226af69d88dSmrg   if (!cmd)
12274a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
12284a49301eSmrg
12294a49301eSmrg   cmd->cid = swc->cid;
12304a49301eSmrg   cmd->index = index;
12314a49301eSmrg   cmd->plane[0] = plane[0];
12324a49301eSmrg   cmd->plane[1] = plane[1];
12334a49301eSmrg   cmd->plane[2] = plane[2];
12344a49301eSmrg   cmd->plane[3] = plane[3];
12354a49301eSmrg   swc->commit(swc);
12364a49301eSmrg
12374a49301eSmrg   return PIPE_OK;
12384a49301eSmrg}
12394a49301eSmrg
12404a49301eSmrg/*
12414a49301eSmrg *----------------------------------------------------------------------
12424a49301eSmrg *
12434a49301eSmrg * SVGA3D_SetZRange --
12444a49301eSmrg *
12454a49301eSmrg *      Set the range of the depth buffer to use. 'min' and 'max'
12464a49301eSmrg *      are values between 0.0 and 1.0.
12474a49301eSmrg *
12484a49301eSmrg * Results:
12494a49301eSmrg *      None.
12504a49301eSmrg *
12514a49301eSmrg * Side effects:
12524a49301eSmrg *      None.
12534a49301eSmrg *
12544a49301eSmrg *----------------------------------------------------------------------
12554a49301eSmrg */
12564a49301eSmrg
12574a49301eSmrgenum pipe_error
12584a49301eSmrgSVGA3D_SetZRange(struct svga_winsys_context *swc,
12594a49301eSmrg                 float zMin,  // IN
12604a49301eSmrg                 float zMax)  // IN
12614a49301eSmrg{
12624a49301eSmrg   SVGA3dCmdSetZRange *cmd;
1263af69d88dSmrg
12644a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
12654a49301eSmrg                            SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
12664a49301eSmrg                            0);
1267af69d88dSmrg   if (!cmd)
12684a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
12694a49301eSmrg
12704a49301eSmrg   cmd->cid = swc->cid;
12714a49301eSmrg   cmd->zRange.min = zMin;
12724a49301eSmrg   cmd->zRange.max = zMax;
12734a49301eSmrg   swc->commit(swc);
12744a49301eSmrg
12754a49301eSmrg   return PIPE_OK;
12764a49301eSmrg}
12774a49301eSmrg
12784a49301eSmrg
12794a49301eSmrg/*
12804a49301eSmrg *----------------------------------------------------------------------
12814a49301eSmrg *
12824a49301eSmrg * SVGA3D_BeginSetTextureState --
12834a49301eSmrg *
12844a49301eSmrg *      Begin a SETTEXTURESTATE command. This reserves space for it in
12854a49301eSmrg *      the FIFO, and returns a pointer to the command's texture state
12864a49301eSmrg *      array.  This function must be paired with SVGA_FIFOCommitAll().
12874a49301eSmrg *
12884a49301eSmrg *      This command sets rendering state which is per-texture-unit.
12894a49301eSmrg *
12904a49301eSmrg *      XXX: Individual texture states need documentation. However,
12914a49301eSmrg *           they are very similar to the texture states defined by
12924a49301eSmrg *           Direct3D. The D3D documentation is a good starting point
12934a49301eSmrg *           for understanding SVGA3D texture states.
12944a49301eSmrg *
12954a49301eSmrg * Results:
12964a49301eSmrg *      None.
12974a49301eSmrg *
12984a49301eSmrg * Side effects:
12994a49301eSmrg *      None.
13004a49301eSmrg *
13014a49301eSmrg *----------------------------------------------------------------------
13024a49301eSmrg */
13034a49301eSmrg
13044a49301eSmrgenum pipe_error
13054a49301eSmrgSVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
13064a49301eSmrg                            SVGA3dTextureState **states,  // OUT
13074a49301eSmrg                            uint32 numStates)             // IN
13084a49301eSmrg{
13094a49301eSmrg   SVGA3dCmdSetTextureState *cmd;
1310af69d88dSmrg
13114a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
1312af69d88dSmrg                            SVGA_3D_CMD_SETTEXTURESTATE,
13134a49301eSmrg                            sizeof *cmd + sizeof **states * numStates,
13144a49301eSmrg                            numStates);
1315af69d88dSmrg   if (!cmd)
13164a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
13174a49301eSmrg
13184a49301eSmrg   cmd->cid = swc->cid;
13194a49301eSmrg   *states = (SVGA3dTextureState*) &cmd[1];
13204a49301eSmrg
13214a49301eSmrg   return PIPE_OK;
13224a49301eSmrg}
13234a49301eSmrg
13244a49301eSmrg
13254a49301eSmrg/*
13264a49301eSmrg *----------------------------------------------------------------------
13274a49301eSmrg *
13284a49301eSmrg * SVGA3D_BeginSetRenderState --
13294a49301eSmrg *
13304a49301eSmrg *      Begin a SETRENDERSTATE command. This reserves space for it in
13314a49301eSmrg *      the FIFO, and returns a pointer to the command's texture state
13324a49301eSmrg *      array.  This function must be paired with SVGA_FIFOCommitAll().
13334a49301eSmrg *
13344a49301eSmrg *      This command sets rendering state which is global to the context.
13354a49301eSmrg *
13364a49301eSmrg *      XXX: Individual render states need documentation. However,
13374a49301eSmrg *           they are very similar to the render states defined by
13384a49301eSmrg *           Direct3D. The D3D documentation is a good starting point
13394a49301eSmrg *           for understanding SVGA3D render states.
13404a49301eSmrg *
13414a49301eSmrg * Results:
13424a49301eSmrg *      None.
13434a49301eSmrg *
13444a49301eSmrg * Side effects:
13454a49301eSmrg *      None.
13464a49301eSmrg *
13474a49301eSmrg *----------------------------------------------------------------------
13484a49301eSmrg */
13494a49301eSmrg
13504a49301eSmrgenum pipe_error
13514a49301eSmrgSVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
13524a49301eSmrg                           SVGA3dRenderState **states,  // OUT
13534a49301eSmrg                           uint32 numStates)            // IN
13544a49301eSmrg{
13554a49301eSmrg   SVGA3dCmdSetRenderState *cmd;
1356af69d88dSmrg
13574a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
1358af69d88dSmrg                            SVGA_3D_CMD_SETRENDERSTATE,
13594a49301eSmrg                            sizeof *cmd + sizeof **states * numStates,
13604a49301eSmrg                            0);
1361af69d88dSmrg   if (!cmd)
13624a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
13634a49301eSmrg
13644a49301eSmrg   cmd->cid = swc->cid;
13654a49301eSmrg   *states = (SVGA3dRenderState*) &cmd[1];
13664a49301eSmrg
13674a49301eSmrg   return PIPE_OK;
13684a49301eSmrg}
13694a49301eSmrg
13704a49301eSmrg
1371af69d88dSmrg/*
1372af69d88dSmrg *----------------------------------------------------------------------
1373af69d88dSmrg *
1374af69d88dSmrg * SVGA3D_BeginGBQuery--
1375af69d88dSmrg *
1376af69d88dSmrg *      GB resource version of SVGA3D_BeginQuery.
1377af69d88dSmrg *
1378af69d88dSmrg * Results:
1379af69d88dSmrg *      None.
1380af69d88dSmrg *
1381af69d88dSmrg * Side effects:
1382af69d88dSmrg *      Commits space in the FIFO memory.
1383af69d88dSmrg *
1384af69d88dSmrg *----------------------------------------------------------------------
1385af69d88dSmrg */
1386af69d88dSmrg
1387af69d88dSmrgstatic enum pipe_error
1388af69d88dSmrgSVGA3D_BeginGBQuery(struct svga_winsys_context *swc,
1389af69d88dSmrg		    SVGA3dQueryType type) // IN
1390af69d88dSmrg{
1391af69d88dSmrg   SVGA3dCmdBeginGBQuery *cmd;
1392af69d88dSmrg
1393af69d88dSmrg   cmd = SVGA3D_FIFOReserve(swc,
1394af69d88dSmrg                            SVGA_3D_CMD_BEGIN_GB_QUERY,
1395af69d88dSmrg                            sizeof *cmd,
1396af69d88dSmrg                            1);
139701e04c3fSmrg   if (!cmd)
1398af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1399af69d88dSmrg
140001e04c3fSmrg   cmd->cid = swc->cid;
1401af69d88dSmrg   cmd->type = type;
1402af69d88dSmrg
1403af69d88dSmrg   swc->commit(swc);
1404af69d88dSmrg
1405af69d88dSmrg   return PIPE_OK;
1406af69d88dSmrg}
1407af69d88dSmrg
1408af69d88dSmrg
14094a49301eSmrg/*
14104a49301eSmrg *----------------------------------------------------------------------
14114a49301eSmrg *
14124a49301eSmrg * SVGA3D_BeginQuery--
14134a49301eSmrg *
14144a49301eSmrg *      Issues a SVGA_3D_CMD_BEGIN_QUERY command.
14154a49301eSmrg *
14164a49301eSmrg * Results:
14174a49301eSmrg *      None.
14184a49301eSmrg *
14194a49301eSmrg * Side effects:
14204a49301eSmrg *      Commits space in the FIFO memory.
14214a49301eSmrg *
14224a49301eSmrg *----------------------------------------------------------------------
14234a49301eSmrg */
14244a49301eSmrg
14254a49301eSmrgenum pipe_error
14264a49301eSmrgSVGA3D_BeginQuery(struct svga_winsys_context *swc,
14274a49301eSmrg                  SVGA3dQueryType type) // IN
14284a49301eSmrg{
14294a49301eSmrg   SVGA3dCmdBeginQuery *cmd;
14304a49301eSmrg
1431af69d88dSmrg   if (swc->have_gb_objects)
1432af69d88dSmrg      return SVGA3D_BeginGBQuery(swc, type);
1433af69d88dSmrg
14344a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
14354a49301eSmrg                            SVGA_3D_CMD_BEGIN_QUERY,
14364a49301eSmrg                            sizeof *cmd,
14374a49301eSmrg                            0);
1438af69d88dSmrg   if (!cmd)
14394a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
14404a49301eSmrg
14414a49301eSmrg   cmd->cid = swc->cid;
14424a49301eSmrg   cmd->type = type;
14434a49301eSmrg
14444a49301eSmrg   swc->commit(swc);
1445af69d88dSmrg
1446af69d88dSmrg   return PIPE_OK;
1447af69d88dSmrg}
1448af69d88dSmrg
1449af69d88dSmrg
1450af69d88dSmrg/*
1451af69d88dSmrg *----------------------------------------------------------------------
1452af69d88dSmrg *
1453af69d88dSmrg * SVGA3D_EndGBQuery--
1454af69d88dSmrg *
1455af69d88dSmrg *      GB resource version of SVGA3D_EndQuery.
1456af69d88dSmrg *
1457af69d88dSmrg * Results:
1458af69d88dSmrg *      None.
1459af69d88dSmrg *
1460af69d88dSmrg * Side effects:
1461af69d88dSmrg *      Commits space in the FIFO memory.
1462af69d88dSmrg *
1463af69d88dSmrg *----------------------------------------------------------------------
1464af69d88dSmrg */
1465af69d88dSmrg
1466af69d88dSmrgstatic enum pipe_error
1467af69d88dSmrgSVGA3D_EndGBQuery(struct svga_winsys_context *swc,
1468af69d88dSmrg		  SVGA3dQueryType type,              // IN
1469af69d88dSmrg		  struct svga_winsys_buffer *buffer) // IN/OUT
1470af69d88dSmrg{
1471af69d88dSmrg   SVGA3dCmdEndGBQuery *cmd;
1472af69d88dSmrg
1473af69d88dSmrg   cmd = SVGA3D_FIFOReserve(swc,
1474af69d88dSmrg                            SVGA_3D_CMD_END_GB_QUERY,
1475af69d88dSmrg                            sizeof *cmd,
1476af69d88dSmrg                            2);
147701e04c3fSmrg   if (!cmd)
1478af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1479af69d88dSmrg
148001e04c3fSmrg   cmd->cid = swc->cid;
1481af69d88dSmrg   cmd->type = type;
1482af69d88dSmrg
1483af69d88dSmrg   swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
1484af69d88dSmrg		       0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1485af69d88dSmrg
1486af69d88dSmrg   swc->commit(swc);
14874a49301eSmrg
14884a49301eSmrg   return PIPE_OK;
14894a49301eSmrg}
14904a49301eSmrg
14914a49301eSmrg
14924a49301eSmrg/*
14934a49301eSmrg *----------------------------------------------------------------------
14944a49301eSmrg *
14954a49301eSmrg * SVGA3D_EndQuery--
14964a49301eSmrg *
14974a49301eSmrg *      Issues a SVGA_3D_CMD_END_QUERY command.
14984a49301eSmrg *
14994a49301eSmrg * Results:
15004a49301eSmrg *      None.
15014a49301eSmrg *
15024a49301eSmrg * Side effects:
15034a49301eSmrg *      Commits space in the FIFO memory.
15044a49301eSmrg *
15054a49301eSmrg *----------------------------------------------------------------------
15064a49301eSmrg */
15074a49301eSmrg
15084a49301eSmrgenum pipe_error
15094a49301eSmrgSVGA3D_EndQuery(struct svga_winsys_context *swc,
15104a49301eSmrg                SVGA3dQueryType type,              // IN
15114a49301eSmrg                struct svga_winsys_buffer *buffer) // IN/OUT
15124a49301eSmrg{
15134a49301eSmrg   SVGA3dCmdEndQuery *cmd;
15144a49301eSmrg
1515af69d88dSmrg   if (swc->have_gb_objects)
1516af69d88dSmrg      return SVGA3D_EndGBQuery(swc, type, buffer);
1517af69d88dSmrg
15184a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
1519af69d88dSmrg                            SVGA_3D_CMD_END_QUERY,
15204a49301eSmrg                            sizeof *cmd,
15214a49301eSmrg                            1);
1522af69d88dSmrg   if (!cmd)
15234a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
15244a49301eSmrg
15254a49301eSmrg   cmd->cid = swc->cid;
15264a49301eSmrg   cmd->type = type;
15274a49301eSmrg
15284a49301eSmrg   swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1529af69d88dSmrg                          SVGA_RELOC_READ | SVGA_RELOC_WRITE);
15304a49301eSmrg
15314a49301eSmrg   swc->commit(swc);
1532af69d88dSmrg
1533af69d88dSmrg   return PIPE_OK;
1534af69d88dSmrg}
1535af69d88dSmrg
1536af69d88dSmrg
1537af69d88dSmrg/*
1538af69d88dSmrg *----------------------------------------------------------------------
1539af69d88dSmrg *
1540af69d88dSmrg * SVGA3D_WaitForGBQuery--
1541af69d88dSmrg *
1542af69d88dSmrg *      GB resource version of SVGA3D_WaitForQuery.
1543af69d88dSmrg *
1544af69d88dSmrg * Results:
1545af69d88dSmrg *      None.
1546af69d88dSmrg *
1547af69d88dSmrg * Side effects:
1548af69d88dSmrg *      Commits space in the FIFO memory.
1549af69d88dSmrg *
1550af69d88dSmrg *----------------------------------------------------------------------
1551af69d88dSmrg */
1552af69d88dSmrg
1553af69d88dSmrgstatic enum pipe_error
1554af69d88dSmrgSVGA3D_WaitForGBQuery(struct svga_winsys_context *swc,
1555af69d88dSmrg		      SVGA3dQueryType type,              // IN
1556af69d88dSmrg		      struct svga_winsys_buffer *buffer) // IN/OUT
1557af69d88dSmrg{
1558af69d88dSmrg   SVGA3dCmdWaitForGBQuery *cmd;
1559af69d88dSmrg
1560af69d88dSmrg   cmd = SVGA3D_FIFOReserve(swc,
1561af69d88dSmrg                            SVGA_3D_CMD_WAIT_FOR_GB_QUERY,
1562af69d88dSmrg                            sizeof *cmd,
1563af69d88dSmrg                            2);
156401e04c3fSmrg   if (!cmd)
1565af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1566af69d88dSmrg
156701e04c3fSmrg   cmd->cid = swc->cid;
1568af69d88dSmrg   cmd->type = type;
1569af69d88dSmrg
1570af69d88dSmrg   swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
1571af69d88dSmrg		       0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1572af69d88dSmrg
1573af69d88dSmrg   swc->commit(swc);
1574af69d88dSmrg
15754a49301eSmrg   return PIPE_OK;
15764a49301eSmrg}
15774a49301eSmrg
15784a49301eSmrg
15794a49301eSmrg/*
15804a49301eSmrg *----------------------------------------------------------------------
15814a49301eSmrg *
15824a49301eSmrg * SVGA3D_WaitForQuery--
15834a49301eSmrg *
15844a49301eSmrg *      Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command.  This reserves space
15854a49301eSmrg *      for it in the FIFO.  This doesn't actually wait for the query to
15864a49301eSmrg *      finish but instead tells the host to start a wait at the driver
15874a49301eSmrg *      level.  The caller can wait on the status variable in the
15884a49301eSmrg *      guestPtr memory or send an insert fence instruction after this
15894a49301eSmrg *      command and wait on the fence.
15904a49301eSmrg *
15914a49301eSmrg * Results:
15924a49301eSmrg *      None.
15934a49301eSmrg *
15944a49301eSmrg * Side effects:
15954a49301eSmrg *      Commits space in the FIFO memory.
15964a49301eSmrg *
15974a49301eSmrg *----------------------------------------------------------------------
15984a49301eSmrg */
15994a49301eSmrg
16004a49301eSmrgenum pipe_error
16014a49301eSmrgSVGA3D_WaitForQuery(struct svga_winsys_context *swc,
16024a49301eSmrg                    SVGA3dQueryType type,              // IN
16034a49301eSmrg                    struct svga_winsys_buffer *buffer) // IN/OUT
16044a49301eSmrg{
16054a49301eSmrg   SVGA3dCmdWaitForQuery *cmd;
16064a49301eSmrg
1607af69d88dSmrg   if (swc->have_gb_objects)
1608af69d88dSmrg      return SVGA3D_WaitForGBQuery(swc, type, buffer);
1609af69d88dSmrg
16104a49301eSmrg   cmd = SVGA3D_FIFOReserve(swc,
1611af69d88dSmrg                            SVGA_3D_CMD_WAIT_FOR_QUERY,
16124a49301eSmrg                            sizeof *cmd,
16134a49301eSmrg                            1);
1614af69d88dSmrg   if (!cmd)
16154a49301eSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
16164a49301eSmrg
16174a49301eSmrg   cmd->cid = swc->cid;
16184a49301eSmrg   cmd->type = type;
1619af69d88dSmrg
16204a49301eSmrg   swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1621af69d88dSmrg                          SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1622af69d88dSmrg
1623af69d88dSmrg   swc->commit(swc);
1624af69d88dSmrg
1625af69d88dSmrg   return PIPE_OK;
1626af69d88dSmrg}
1627af69d88dSmrg
1628af69d88dSmrg
1629af69d88dSmrgenum pipe_error
1630af69d88dSmrgSVGA3D_BindGBShader(struct svga_winsys_context *swc,
1631af69d88dSmrg                    struct svga_winsys_gb_shader *gbshader)
1632af69d88dSmrg{
1633af69d88dSmrg   SVGA3dCmdBindGBShader *cmd =
1634af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1635af69d88dSmrg                         SVGA_3D_CMD_BIND_GB_SHADER,
1636af69d88dSmrg                         sizeof *cmd,
1637af69d88dSmrg                         2);  /* two relocations */
1638af69d88dSmrg
1639af69d88dSmrg   if (!cmd)
1640af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1641af69d88dSmrg
1642af69d88dSmrg   swc->shader_relocation(swc, &cmd->shid, &cmd->mobid,
164301e04c3fSmrg			  &cmd->offsetInBytes, gbshader, 0);
16444a49301eSmrg
16454a49301eSmrg   swc->commit(swc);
1646af69d88dSmrg
1647af69d88dSmrg   return PIPE_OK;
1648af69d88dSmrg}
1649af69d88dSmrg
1650af69d88dSmrg
1651af69d88dSmrgenum pipe_error
1652af69d88dSmrgSVGA3D_SetGBShader(struct svga_winsys_context *swc,
1653af69d88dSmrg                   SVGA3dShaderType type,  // IN
1654af69d88dSmrg                   struct svga_winsys_gb_shader *gbshader)
1655af69d88dSmrg{
1656af69d88dSmrg   SVGA3dCmdSetShader *cmd;
165701e04c3fSmrg
165801e04c3fSmrg   assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS);
1659af69d88dSmrg
1660af69d88dSmrg   cmd = SVGA3D_FIFOReserve(swc,
1661af69d88dSmrg                            SVGA_3D_CMD_SET_SHADER,
1662af69d88dSmrg                            sizeof *cmd,
1663af69d88dSmrg                            2);  /* two relocations */
1664af69d88dSmrg   if (!cmd)
1665af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
16664a49301eSmrg
166701e04c3fSmrg   cmd->cid = swc->cid;
1668af69d88dSmrg   cmd->type = type;
1669af69d88dSmrg   if (gbshader)
167001e04c3fSmrg      swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader, 0);
1671af69d88dSmrg   else
1672af69d88dSmrg      cmd->shid = SVGA_ID_INVALID;
1673af69d88dSmrg   swc->commit(swc);
1674af69d88dSmrg
1675af69d88dSmrg   return PIPE_OK;
1676af69d88dSmrg}
1677af69d88dSmrg
1678af69d88dSmrg
1679af69d88dSmrg/**
1680af69d88dSmrg * \param flags  mask of SVGA_RELOC_READ / _WRITE
1681af69d88dSmrg */
1682af69d88dSmrgenum pipe_error
1683af69d88dSmrgSVGA3D_BindGBSurface(struct svga_winsys_context *swc,
1684af69d88dSmrg                     struct svga_winsys_surface *surface)
1685af69d88dSmrg{
1686af69d88dSmrg   SVGA3dCmdBindGBSurface *cmd =
1687af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1688af69d88dSmrg                         SVGA_3D_CMD_BIND_GB_SURFACE,
1689af69d88dSmrg                         sizeof *cmd,
1690af69d88dSmrg                         2);  /* two relocations */
1691af69d88dSmrg
1692af69d88dSmrg   if (!cmd)
1693af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1694af69d88dSmrg
1695af69d88dSmrg   swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface,
16969f464c52Smaya                           SVGA_RELOC_READ);
1697af69d88dSmrg
1698af69d88dSmrg   swc->commit(swc);
1699af69d88dSmrg
1700af69d88dSmrg   return PIPE_OK;
1701af69d88dSmrg}
1702af69d88dSmrg
1703af69d88dSmrg
1704af69d88dSmrg/**
1705af69d88dSmrg * Update an image in a guest-backed surface.
1706af69d88dSmrg * (Inform the device that the guest-contents have been updated.)
1707af69d88dSmrg */
1708af69d88dSmrgenum pipe_error
1709af69d88dSmrgSVGA3D_UpdateGBImage(struct svga_winsys_context *swc,
1710af69d88dSmrg                     struct svga_winsys_surface *surface,
1711af69d88dSmrg                     const SVGA3dBox *box,
1712af69d88dSmrg                     unsigned face, unsigned mipLevel)
1713af69d88dSmrg
1714af69d88dSmrg{
1715af69d88dSmrg   SVGA3dCmdUpdateGBImage *cmd =
1716af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1717af69d88dSmrg                         SVGA_3D_CMD_UPDATE_GB_IMAGE,
1718af69d88dSmrg                         sizeof *cmd,
1719af69d88dSmrg                         1);  /* one relocation */
1720af69d88dSmrg
1721af69d88dSmrg   if (!cmd)
1722af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1723af69d88dSmrg
1724af69d88dSmrg   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1725af69d88dSmrg                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
1726af69d88dSmrg   cmd->image.face = face;
1727af69d88dSmrg   cmd->image.mipmap = mipLevel;
1728af69d88dSmrg   cmd->box = *box;
1729af69d88dSmrg
1730af69d88dSmrg   swc->commit(swc);
173101e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
1732af69d88dSmrg
1733af69d88dSmrg   return PIPE_OK;
1734af69d88dSmrg}
1735af69d88dSmrg
1736af69d88dSmrg
1737af69d88dSmrg/**
1738af69d88dSmrg * Update an entire guest-backed surface.
1739af69d88dSmrg * (Inform the device that the guest-contents have been updated.)
1740af69d88dSmrg */
1741af69d88dSmrgenum pipe_error
1742af69d88dSmrgSVGA3D_UpdateGBSurface(struct svga_winsys_context *swc,
1743af69d88dSmrg                       struct svga_winsys_surface *surface)
1744af69d88dSmrg{
1745af69d88dSmrg   SVGA3dCmdUpdateGBSurface *cmd =
1746af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1747af69d88dSmrg                         SVGA_3D_CMD_UPDATE_GB_SURFACE,
1748af69d88dSmrg                         sizeof *cmd,
1749af69d88dSmrg                         1);  /* one relocation */
1750af69d88dSmrg
1751af69d88dSmrg   if (!cmd)
1752af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1753af69d88dSmrg
1754af69d88dSmrg   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
1755af69d88dSmrg                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
1756af69d88dSmrg
1757af69d88dSmrg   swc->commit(swc);
175801e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
1759af69d88dSmrg
1760af69d88dSmrg   return PIPE_OK;
1761af69d88dSmrg}
1762af69d88dSmrg
1763af69d88dSmrg
1764af69d88dSmrg/**
1765af69d88dSmrg * Readback an image in a guest-backed surface.
1766af69d88dSmrg * (Request the device to flush the dirty contents into the guest.)
1767af69d88dSmrg */
1768af69d88dSmrgenum pipe_error
1769af69d88dSmrgSVGA3D_ReadbackGBImage(struct svga_winsys_context *swc,
1770af69d88dSmrg                       struct svga_winsys_surface *surface,
1771af69d88dSmrg                       unsigned face, unsigned mipLevel)
1772af69d88dSmrg{
1773af69d88dSmrg   SVGA3dCmdReadbackGBImage *cmd =
1774af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1775af69d88dSmrg                         SVGA_3D_CMD_READBACK_GB_IMAGE,
1776af69d88dSmrg                         sizeof *cmd,
1777af69d88dSmrg                         1);  /* one relocation */
1778af69d88dSmrg
1779af69d88dSmrg   if (!cmd)
1780af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1781af69d88dSmrg
1782af69d88dSmrg   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1783af69d88dSmrg                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1784af69d88dSmrg   cmd->image.face = face;
1785af69d88dSmrg   cmd->image.mipmap = mipLevel;
1786af69d88dSmrg
1787af69d88dSmrg   swc->commit(swc);
178801e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
1789af69d88dSmrg
1790af69d88dSmrg   return PIPE_OK;
1791af69d88dSmrg}
1792af69d88dSmrg
1793af69d88dSmrg
1794af69d88dSmrg/**
1795af69d88dSmrg * Readback an entire guest-backed surface.
1796af69d88dSmrg * (Request the device to flush the dirty contents into the guest.)
1797af69d88dSmrg */
1798af69d88dSmrgenum pipe_error
1799af69d88dSmrgSVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc,
1800af69d88dSmrg                         struct svga_winsys_surface *surface)
1801af69d88dSmrg{
1802af69d88dSmrg   SVGA3dCmdReadbackGBSurface *cmd =
1803af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1804af69d88dSmrg                         SVGA_3D_CMD_READBACK_GB_SURFACE,
1805af69d88dSmrg                         sizeof *cmd,
1806af69d88dSmrg                         1);  /* one relocation */
1807af69d88dSmrg
1808af69d88dSmrg   if (!cmd)
1809af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1810af69d88dSmrg
1811af69d88dSmrg   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
1812af69d88dSmrg                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1813af69d88dSmrg
1814af69d88dSmrg   swc->commit(swc);
181501e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
1816af69d88dSmrg
1817af69d88dSmrg   return PIPE_OK;
1818af69d88dSmrg}
1819af69d88dSmrg
1820af69d88dSmrg
1821af69d88dSmrgenum pipe_error
1822af69d88dSmrgSVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc,
1823af69d88dSmrg                              struct svga_winsys_surface *surface,
1824af69d88dSmrg                              unsigned face, unsigned mipLevel,
1825af69d88dSmrg                              const SVGA3dBox *box,
1826af69d88dSmrg                              bool invertBox)
1827af69d88dSmrg{
1828af69d88dSmrg   SVGA3dCmdReadbackGBImagePartial *cmd =
1829af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1830af69d88dSmrg                         SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL,
1831af69d88dSmrg                         sizeof *cmd,
1832af69d88dSmrg                         1);  /* one relocation */
1833af69d88dSmrg   if (!cmd)
1834af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1835af69d88dSmrg
1836af69d88dSmrg   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1837af69d88dSmrg                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1838af69d88dSmrg   cmd->image.face = face;
1839af69d88dSmrg   cmd->image.mipmap = mipLevel;
1840af69d88dSmrg   cmd->box = *box;
1841af69d88dSmrg   cmd->invertBox = invertBox;
1842af69d88dSmrg
1843af69d88dSmrg   swc->commit(swc);
184401e04c3fSmrg   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
1845af69d88dSmrg
1846af69d88dSmrg   return PIPE_OK;
1847af69d88dSmrg}
1848af69d88dSmrg
1849af69d88dSmrg
1850af69d88dSmrgenum pipe_error
1851af69d88dSmrgSVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc,
1852af69d88dSmrg                                struct svga_winsys_surface *surface,
1853af69d88dSmrg                                unsigned face, unsigned mipLevel,
1854af69d88dSmrg                                const SVGA3dBox *box,
1855af69d88dSmrg                                bool invertBox)
1856af69d88dSmrg{
1857af69d88dSmrg   SVGA3dCmdInvalidateGBImagePartial *cmd =
1858af69d88dSmrg      SVGA3D_FIFOReserve(swc,
1859af69d88dSmrg                         SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL,
1860af69d88dSmrg                         sizeof *cmd,
1861af69d88dSmrg                         1);  /* one relocation */
1862af69d88dSmrg   if (!cmd)
1863af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1864af69d88dSmrg
1865af69d88dSmrg   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1866af69d88dSmrg                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1867af69d88dSmrg   cmd->image.face = face;
1868af69d88dSmrg   cmd->image.mipmap = mipLevel;
1869af69d88dSmrg   cmd->box = *box;
1870af69d88dSmrg   cmd->invertBox = invertBox;
1871af69d88dSmrg
1872af69d88dSmrg   swc->commit(swc);
1873af69d88dSmrg
1874af69d88dSmrg   return PIPE_OK;
1875af69d88dSmrg}
1876af69d88dSmrg
187701e04c3fSmrgenum pipe_error
187801e04c3fSmrgSVGA3D_InvalidateGBSurface(struct svga_winsys_context *swc,
187901e04c3fSmrg                           struct svga_winsys_surface *surface)
188001e04c3fSmrg{
188101e04c3fSmrg   SVGA3dCmdInvalidateGBSurface *cmd =
188201e04c3fSmrg      SVGA3D_FIFOReserve(swc,
188301e04c3fSmrg                         SVGA_3D_CMD_INVALIDATE_GB_SURFACE,
188401e04c3fSmrg                         sizeof *cmd,
188501e04c3fSmrg                         1);  /* one relocation */
188601e04c3fSmrg   if (!cmd)
188701e04c3fSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
188801e04c3fSmrg
188901e04c3fSmrg   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
189001e04c3fSmrg                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
189101e04c3fSmrg   swc->commit(swc);
189201e04c3fSmrg
189301e04c3fSmrg   return PIPE_OK;
189401e04c3fSmrg}
1895af69d88dSmrg
1896af69d88dSmrgenum pipe_error
1897af69d88dSmrgSVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,
1898af69d88dSmrg                              unsigned regStart,
1899af69d88dSmrg                              unsigned numRegs,
1900af69d88dSmrg                              SVGA3dShaderType shaderType,
1901af69d88dSmrg                              SVGA3dShaderConstType constType,
1902af69d88dSmrg                              const void *values)
1903af69d88dSmrg{
1904af69d88dSmrg   SVGA3dCmdSetGBShaderConstInline *cmd;
1905af69d88dSmrg
1906af69d88dSmrg   assert(numRegs > 0);
1907af69d88dSmrg
1908af69d88dSmrg   cmd = SVGA3D_FIFOReserve(swc,
1909af69d88dSmrg                            SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE,
1910af69d88dSmrg                            sizeof *cmd + numRegs * sizeof(float[4]),
1911af69d88dSmrg                            0); /* no relocations */
1912af69d88dSmrg   if (!cmd)
1913af69d88dSmrg      return PIPE_ERROR_OUT_OF_MEMORY;
1914af69d88dSmrg
1915af69d88dSmrg   cmd->cid = swc->cid;
1916af69d88dSmrg   cmd->regStart = regStart;
1917af69d88dSmrg   cmd->shaderType = shaderType;
1918af69d88dSmrg   cmd->constType = constType;
1919af69d88dSmrg
1920af69d88dSmrg   memcpy(&cmd[1], values, numRegs * sizeof(float[4]));
1921af69d88dSmrg
1922af69d88dSmrg   swc->commit(swc);
1923af69d88dSmrg
19244a49301eSmrg   return PIPE_OK;
19254a49301eSmrg}
1926