svga: add new svga_cmd_vgpu10.c file
authorBrian Paul <brianp@vmware.com>
Fri, 7 Aug 2015 20:57:22 +0000 (14:57 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 2 Sep 2015 15:05:23 +0000 (09:05 -0600)
Signed-off-by: Brian Paul <brianp@vmware.com>
src/gallium/drivers/svga/svga_cmd_vgpu10.c [new file with mode: 0644]

diff --git a/src/gallium/drivers/svga/svga_cmd_vgpu10.c b/src/gallium/drivers/svga/svga_cmd_vgpu10.c
new file mode 100644 (file)
index 0000000..596ba95
--- /dev/null
@@ -0,0 +1,1289 @@
+/**********************************************************
+ * Copyright 2008-2013 VMware, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @file svga_cmd_vgpu10.c
+ *
+ * Command construction utility for the vgpu10 SVGA3D protocol.
+ *
+ * \author Mingcheng Chen
+ * \author Brian Paul
+ */
+
+
+#include "svga_winsys.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_surface.h"
+#include "svga_cmd.h"
+
+
+/**
+ * Emit a surface relocation for RenderTargetViewId
+ */
+static void
+view_relocation(struct svga_winsys_context *swc, // IN
+                struct pipe_surface *surface,    // IN
+                SVGA3dRenderTargetViewId *id,    // OUT
+                unsigned flags)
+{
+   if (surface) {
+      struct svga_surface *s = svga_surface(surface);
+      assert(s->handle);
+      swc->surface_relocation(swc, id, NULL, s->handle, flags);
+   }
+   else {
+      swc->surface_relocation(swc, id, NULL, NULL, flags);
+   }
+}
+
+
+/**
+ * Emit a surface relocation for a ResourceId.
+ */
+static void
+surface_to_resourceid(struct svga_winsys_context *swc, // IN
+                      struct svga_winsys_surface *surface,    // IN
+                      SVGA3dSurfaceId *sid,            // OUT
+                      unsigned flags)                  // IN
+{
+   if (surface) {
+      swc->surface_relocation(swc, sid, NULL, surface, flags);
+   }
+   else {
+      swc->surface_relocation(swc, sid, NULL, NULL, flags);
+   }
+}
+
+
+#define SVGA3D_CREATE_COMMAND(CommandName, CommandCode) \
+SVGA3dCmdDX##CommandName *cmd; \
+{ \
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_##CommandCode, \
+                            sizeof(SVGA3dCmdDX##CommandName), 0); \
+   if (!cmd) \
+      return PIPE_ERROR_OUT_OF_MEMORY; \
+}
+
+#define SVGA3D_CREATE_CMD_COUNT(CommandName, CommandCode, ElementClassName) \
+SVGA3dCmdDX##CommandName *cmd; \
+{ \
+   assert(count > 0); \
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_##CommandCode, \
+                            sizeof(SVGA3dCmdDX##CommandName) + \
+                            count * sizeof(ElementClassName), 0); \
+   if (!cmd) \
+      return PIPE_ERROR_OUT_OF_MEMORY; \
+}
+
+#define SVGA3D_COPY_BASIC(VariableName) \
+{ \
+   cmd->VariableName = VariableName; \
+}
+
+#define SVGA3D_COPY_BASIC_2(VariableName1, VariableName2) \
+{ \
+   SVGA3D_COPY_BASIC(VariableName1); \
+   SVGA3D_COPY_BASIC(VariableName2); \
+}
+
+#define SVGA3D_COPY_BASIC_3(VariableName1, VariableName2, VariableName3) \
+{ \
+   SVGA3D_COPY_BASIC_2(VariableName1, VariableName2); \
+   SVGA3D_COPY_BASIC(VariableName3); \
+}
+
+#define SVGA3D_COPY_BASIC_4(VariableName1, VariableName2, VariableName3, \
+                            VariableName4) \
+{ \
+   SVGA3D_COPY_BASIC_2(VariableName1, VariableName2); \
+   SVGA3D_COPY_BASIC_2(VariableName3, VariableName4); \
+}
+
+#define SVGA3D_COPY_BASIC_5(VariableName1, VariableName2, VariableName3, \
+                            VariableName4, VariableName5) \
+{\
+   SVGA3D_COPY_BASIC_3(VariableName1, VariableName2, VariableName3); \
+   SVGA3D_COPY_BASIC_2(VariableName4, VariableName5); \
+}
+
+#define SVGA3D_COPY_BASIC_6(VariableName1, VariableName2, VariableName3, \
+                            VariableName4, VariableName5, VariableName6) \
+{\
+   SVGA3D_COPY_BASIC_3(VariableName1, VariableName2, VariableName3); \
+   SVGA3D_COPY_BASIC_3(VariableName4, VariableName5, VariableName6); \
+}
+
+#define SVGA3D_COPY_BASIC_7(VariableName1, VariableName2, VariableName3, \
+                            VariableName4, VariableName5, VariableName6, \
+                            VariableName7) \
+{\
+   SVGA3D_COPY_BASIC_4(VariableName1, VariableName2, VariableName3, \
+                       VariableName4); \
+   SVGA3D_COPY_BASIC_3(VariableName5, VariableName6, VariableName7); \
+}
+
+#define SVGA3D_COPY_BASIC_8(VariableName1, VariableName2, VariableName3, \
+                            VariableName4, VariableName5, VariableName6, \
+                            VariableName7, VariableName8) \
+{\
+   SVGA3D_COPY_BASIC_4(VariableName1, VariableName2, VariableName3, \
+                       VariableName4); \
+   SVGA3D_COPY_BASIC_4(VariableName5, VariableName6, VariableName7, \
+                       VariableName8); \
+}
+
+#define SVGA3D_COPY_BASIC_9(VariableName1, VariableName2, VariableName3, \
+                            VariableName4, VariableName5, VariableName6, \
+                            VariableName7, VariableName8, VariableName9) \
+{\
+   SVGA3D_COPY_BASIC_5(VariableName1, VariableName2, VariableName3, \
+                       VariableName4, VariableName5); \
+   SVGA3D_COPY_BASIC_4(VariableName6, VariableName7, VariableName8, \
+                       VariableName9); \
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_PredCopyRegion(struct svga_winsys_context *swc,
+                             struct svga_winsys_surface *dstSurf,
+                             uint32 dstSubResource,
+                             struct svga_winsys_surface *srcSurf,
+                             uint32 srcSubResource,
+                             const SVGA3dCopyBox *box)
+{
+   SVGA3dCmdDXPredCopyRegion *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_DX_PRED_COPY_REGION,
+                         sizeof(SVGA3dCmdDXPredCopyRegion),
+                         2);  /* two relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->dstSid, NULL, dstSurf, SVGA_RELOC_WRITE);
+   swc->surface_relocation(swc, &cmd->srcSid, NULL, srcSurf, SVGA_RELOC_READ);
+   cmd->dstSubResource = dstSubResource;
+   cmd->srcSubResource = srcSubResource;
+   cmd->box = *box;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_PredCopy(struct svga_winsys_context *swc,
+                       struct svga_winsys_surface *dstSurf,
+                       struct svga_winsys_surface *srcSurf)
+{
+   SVGA3dCmdDXPredCopy *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_DX_PRED_COPY,
+                         sizeof(SVGA3dCmdDXPredCopy),
+                         2);  /* two relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->dstSid, NULL, dstSurf, SVGA_RELOC_WRITE);
+   swc->surface_relocation(swc, &cmd->srcSid, NULL, srcSurf, SVGA_RELOC_READ);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetViewports(struct svga_winsys_context *swc,
+                           unsigned count,
+                           const SVGA3dViewport *viewports)
+{
+   SVGA3D_CREATE_CMD_COUNT(SetViewports, SET_VIEWPORTS, SVGA3dViewport);
+
+   memcpy(cmd + 1, viewports, count * sizeof(SVGA3dViewport));
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_SetShader(struct svga_winsys_context *swc,
+                        SVGA3dShaderType type,
+                        struct svga_winsys_gb_shader *gbshader,
+                        SVGA3dShaderId shaderId)
+{
+   SVGA3dCmdDXSetShader *cmd = SVGA3D_FIFOReserve(swc,
+                                                  SVGA_3D_CMD_DX_SET_SHADER,
+                                                  sizeof *cmd,
+                                                  1);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->shader_relocation(swc, &cmd->shaderId, NULL, NULL, gbshader, 0);
+
+   cmd->type = type;
+   cmd->shaderId = shaderId;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_SetShaderResources(struct svga_winsys_context *swc,
+                                 SVGA3dShaderType type,
+                                 uint32 startView,
+                                 unsigned count,
+                                 const SVGA3dShaderResourceViewId ids[],
+                                 struct svga_winsys_surface **views)
+{
+   SVGA3dCmdDXSetShaderResources *cmd;
+   SVGA3dShaderResourceViewId *cmd_ids;
+   unsigned i;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_SET_SHADER_RESOURCES,
+                            sizeof(SVGA3dCmdDXSetShaderResources) +
+                            count * sizeof(SVGA3dShaderResourceViewId),
+                            count); /* 'count' relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+
+   cmd->type = type;
+   cmd->startView = startView;
+
+   cmd_ids = (SVGA3dShaderResourceViewId *) (cmd + 1);
+   for (i = 0; i < count; i++) {
+      swc->surface_relocation(swc, cmd_ids + i, NULL, views[i],
+                              SVGA_RELOC_READ);
+      cmd_ids[i] = ids[i];
+   }
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_SetSamplers(struct svga_winsys_context *swc,
+                          unsigned count,
+                          uint32 startSampler,
+                          SVGA3dShaderType type,
+                          const SVGA3dSamplerId *samplerIds)
+{
+   SVGA3D_CREATE_CMD_COUNT(SetSamplers, SET_SAMPLERS, SVGA3dSamplerId);
+
+   SVGA3D_COPY_BASIC_2(startSampler, type);
+   memcpy(cmd + 1, samplerIds, count * sizeof(SVGA3dSamplerId));
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_ClearRenderTargetView(struct svga_winsys_context *swc,
+                                    struct pipe_surface *color_surf,
+                                    const float *rgba)
+{
+   SVGA3dCmdDXClearRenderTargetView *cmd;
+   struct svga_surface *ss = svga_surface(color_surf);
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW,
+                            sizeof(SVGA3dCmdDXClearRenderTargetView),
+                            1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+
+   /* NOTE: The following is pretty tricky.  We need to emit a view/surface
+    * relocation and we have to provide a pointer to an ID which lies in
+    * the bounds of the command space which we just allocated.  However,
+    * we then need to overwrite it with the original RenderTargetViewId.
+    */
+   view_relocation(swc, color_surf, &cmd->renderTargetViewId,
+                   SVGA_RELOC_WRITE);
+   cmd->renderTargetViewId = ss->view_id;
+
+   COPY_4V(cmd->rgba.value, rgba);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_SetRenderTargets(struct svga_winsys_context *swc,
+                               unsigned color_count,
+                               struct pipe_surface **color_surfs,
+                               struct pipe_surface *depth_stencil_surf)
+{
+   const unsigned surf_count = color_count + 1;
+   SVGA3dCmdDXSetRenderTargets *cmd;
+   SVGA3dRenderTargetViewId *ctarget;
+   struct svga_surface *ss;
+   unsigned i;
+
+   assert(surf_count > 0);
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_SET_RENDERTARGETS,
+                            sizeof(SVGA3dCmdDXSetRenderTargets) +
+                            color_count * sizeof(SVGA3dRenderTargetViewId),
+                            surf_count); /* 'surf_count' relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   /* NOTE: See earlier comment about the tricky handling of the ViewIds.
+    */
+
+   /* Depth / Stencil buffer */
+   if (depth_stencil_surf) {
+      ss = svga_surface(depth_stencil_surf);
+      view_relocation(swc, depth_stencil_surf, &cmd->depthStencilViewId,
+                      SVGA_RELOC_WRITE);
+      cmd->depthStencilViewId = ss->view_id;
+   }
+   else {
+      /* no depth/stencil buffer - still need a relocation */
+      view_relocation(swc, NULL, &cmd->depthStencilViewId,
+                      SVGA_RELOC_WRITE);
+      cmd->depthStencilViewId = SVGA3D_INVALID_ID;
+   }
+
+   /* Color buffers */
+   ctarget = (SVGA3dRenderTargetViewId *) &cmd[1];
+   for (i = 0; i < color_count; i++) {
+      if (color_surfs[i]) {
+         ss = svga_surface(color_surfs[i]);
+         view_relocation(swc, color_surfs[i], ctarget + i, SVGA_RELOC_WRITE);
+         ctarget[i] = ss->view_id;
+      }
+      else {
+         view_relocation(swc, NULL, ctarget + i, SVGA_RELOC_WRITE);
+         ctarget[i] = SVGA3D_INVALID_ID;
+      }
+   }
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_SetBlendState(struct svga_winsys_context *swc,
+                            SVGA3dBlendStateId blendId,
+                            const float *blendFactor,
+                            uint32 sampleMask)
+{
+   SVGA3D_CREATE_COMMAND(SetBlendState, SET_BLEND_STATE);
+
+   SVGA3D_COPY_BASIC_2(blendId, sampleMask);
+   memcpy(cmd->blendFactor, blendFactor, sizeof(float) * 4);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetDepthStencilState(struct svga_winsys_context *swc,
+                                   SVGA3dDepthStencilStateId depthStencilId,
+                                   uint32 stencilRef)
+{
+   SVGA3D_CREATE_COMMAND(SetDepthStencilState, SET_DEPTHSTENCIL_STATE);
+
+   SVGA3D_COPY_BASIC_2(depthStencilId, stencilRef);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetRasterizerState(struct svga_winsys_context *swc,
+                                 SVGA3dRasterizerStateId rasterizerId)
+{
+   SVGA3D_CREATE_COMMAND(SetRasterizerState, SET_RASTERIZER_STATE);
+
+   cmd->rasterizerId = rasterizerId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetPredication(struct svga_winsys_context *swc,
+                             SVGA3dQueryId queryId,
+                             uint32 predicateValue)
+{
+   SVGA3dCmdDXSetPredication *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_PREDICATION,
+                            sizeof *cmd, 0);
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->queryId = queryId;
+   cmd->predicateValue = predicateValue;
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetSOTargets(struct svga_winsys_context *swc,
+                           unsigned count,
+                           const SVGA3dSoTarget *targets,
+                           struct svga_winsys_surface **surfaces)
+{
+   SVGA3dCmdDXSetSOTargets *cmd;
+   SVGA3dSoTarget *sot;
+   unsigned i;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_SET_SOTARGETS,
+                            sizeof(SVGA3dCmdDXSetSOTargets) +
+                            count * sizeof(SVGA3dSoTarget),
+                            count);
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->pad0 = 0;
+   sot = (SVGA3dSoTarget *)(cmd + 1);
+   for (i = 0; i < count; i++, sot++) {
+      if (surfaces[i]) {
+         sot->offset = targets[i].offset;
+         sot->sizeInBytes = targets[i].sizeInBytes;
+         swc->surface_relocation(swc, &sot->sid, NULL, surfaces[i],
+                                 SVGA_RELOC_WRITE);
+      }
+      else {
+         sot->offset = 0;
+         sot->sizeInBytes = ~0u;
+         swc->surface_relocation(swc, &sot->sid, NULL, NULL,
+                                 SVGA_RELOC_WRITE);
+      }
+   }
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetScissorRects(struct svga_winsys_context *swc,
+                              unsigned count,
+                              const SVGASignedRect *rects)
+{
+   SVGA3dCmdDXSetScissorRects *cmd;
+
+   assert(count > 0);
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_SCISSORRECTS,
+                            sizeof(SVGA3dCmdDXSetScissorRects) +
+                            count * sizeof(SVGASignedRect),
+                            0);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   memcpy(cmd + 1, rects, count * sizeof(SVGASignedRect));
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetStreamOutput(struct svga_winsys_context *swc,
+                              SVGA3dStreamOutputId soid)
+{
+   SVGA3D_CREATE_COMMAND(SetStreamOutput, SET_STREAMOUTPUT);
+
+   cmd->soid = soid;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_Draw(struct svga_winsys_context *swc,
+                   uint32 vertexCount,
+                   uint32 startVertexLocation)
+{
+   SVGA3D_CREATE_COMMAND(Draw, DRAW);
+
+   SVGA3D_COPY_BASIC_2(vertexCount, startVertexLocation);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DrawIndexed(struct svga_winsys_context *swc,
+                          uint32 indexCount,
+                          uint32 startIndexLocation,
+                          int32 baseVertexLocation)
+{
+   SVGA3D_CREATE_COMMAND(DrawIndexed, DRAW_INDEXED);
+
+   SVGA3D_COPY_BASIC_3(indexCount, startIndexLocation,
+                       baseVertexLocation);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DrawInstanced(struct svga_winsys_context *swc,
+                            uint32 vertexCountPerInstance,
+                            uint32 instanceCount,
+                            uint32 startVertexLocation,
+                            uint32 startInstanceLocation)
+{
+   SVGA3D_CREATE_COMMAND(DrawInstanced, DRAW_INSTANCED);
+
+   SVGA3D_COPY_BASIC_4(vertexCountPerInstance, instanceCount,
+                       startVertexLocation, startInstanceLocation);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DrawIndexedInstanced(struct svga_winsys_context *swc,
+                                   uint32 indexCountPerInstance,
+                                   uint32 instanceCount,
+                                   uint32 startIndexLocation,
+                                   int32  baseVertexLocation,
+                                   uint32 startInstanceLocation)
+{
+   SVGA3D_CREATE_COMMAND(DrawIndexedInstanced, DRAW_INDEXED_INSTANCED);
+
+   SVGA3D_COPY_BASIC_5(indexCountPerInstance, instanceCount,
+                       startIndexLocation, baseVertexLocation,
+                       startInstanceLocation);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DrawAuto(struct svga_winsys_context *swc)
+{
+   SVGA3D_CREATE_COMMAND(DrawAuto, DRAW_AUTO);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineQuery(struct svga_winsys_context *swc,
+                          SVGA3dQueryId queryId,
+                          SVGA3dQueryType type,
+                          SVGA3dDXQueryFlags flags)
+{
+   SVGA3D_CREATE_COMMAND(DefineQuery, DEFINE_QUERY);
+
+   SVGA3D_COPY_BASIC_3(queryId, type, flags);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyQuery(struct svga_winsys_context *swc,
+                           SVGA3dQueryId queryId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyQuery, DESTROY_QUERY);
+
+   cmd->queryId = queryId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_BindQuery(struct svga_winsys_context *swc,
+                        struct svga_winsys_gb_query *gbQuery,
+                        SVGA3dQueryId queryId)
+{
+   SVGA3dCmdDXBindQuery *cmd = SVGA3D_FIFOReserve(swc,
+                                                  SVGA_3D_CMD_DX_BIND_QUERY,
+                                                  sizeof *cmd,
+                                                  1);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->queryId = queryId;
+   swc->query_relocation(swc, &cmd->mobid, gbQuery);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetQueryOffset(struct svga_winsys_context *swc,
+                             SVGA3dQueryId queryId,
+                             uint32 mobOffset)
+{
+   SVGA3D_CREATE_COMMAND(SetQueryOffset, SET_QUERY_OFFSET);
+   SVGA3D_COPY_BASIC_2(queryId, mobOffset);
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_BeginQuery(struct svga_winsys_context *swc,
+                         SVGA3dQueryId queryId)
+{
+   SVGA3D_CREATE_COMMAND(BeginQuery, BEGIN_QUERY);
+   cmd->queryId = queryId;
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_EndQuery(struct svga_winsys_context *swc,
+                       SVGA3dQueryId queryId)
+{
+   SVGA3D_CREATE_COMMAND(EndQuery, END_QUERY);
+   cmd->queryId = queryId;
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_ClearDepthStencilView(struct svga_winsys_context *swc,
+                                    struct pipe_surface *ds_surf,
+                                    uint16 flags,
+                                    uint16 stencil,
+                                    float depth)
+{
+   SVGA3dCmdDXClearDepthStencilView *cmd;
+   struct svga_surface *ss = svga_surface(ds_surf);
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW,
+                            sizeof(SVGA3dCmdDXClearDepthStencilView),
+                            1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   /* NOTE: The following is pretty tricky.  We need to emit a view/surface
+    * relocation and we have to provide a pointer to an ID which lies in
+    * the bounds of the command space which we just allocated.  However,
+    * we then need to overwrite it with the original DepthStencilViewId.
+    */
+   view_relocation(swc, ds_surf, &cmd->depthStencilViewId,
+                   SVGA_RELOC_WRITE);
+   cmd->depthStencilViewId = ss->view_id;
+   cmd->flags = flags;
+   cmd->stencil = stencil;
+   cmd->depth = depth;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineShaderResourceView(struct svga_winsys_context *swc,
+                             SVGA3dShaderResourceViewId shaderResourceViewId,
+                             struct svga_winsys_surface *surface,
+                             SVGA3dSurfaceFormat format,
+                             SVGA3dResourceType resourceDimension,
+                             const SVGA3dShaderResourceViewDesc *desc)
+{
+   SVGA3dCmdDXDefineShaderResourceView *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW,
+                            sizeof(SVGA3dCmdDXDefineShaderResourceView),
+                            1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   SVGA3D_COPY_BASIC_3(shaderResourceViewId, format, resourceDimension);
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+                           SVGA_RELOC_READ);
+
+   cmd->desc = *desc;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyShaderResourceView(struct svga_winsys_context *swc,
+                             SVGA3dShaderResourceViewId shaderResourceViewId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyShaderResourceView,
+                       DESTROY_SHADERRESOURCE_VIEW);
+
+   cmd->shaderResourceViewId = shaderResourceViewId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_DefineRenderTargetView(struct svga_winsys_context *swc,
+                                  SVGA3dRenderTargetViewId renderTargetViewId,
+                                  struct svga_winsys_surface *surface,
+                                  SVGA3dSurfaceFormat format,
+                                  SVGA3dResourceType resourceDimension,
+                                  const SVGA3dRenderTargetViewDesc *desc)
+{
+   SVGA3dCmdDXDefineRenderTargetView *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW,
+                            sizeof(SVGA3dCmdDXDefineRenderTargetView),
+                            1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   SVGA3D_COPY_BASIC_3(renderTargetViewId, format, resourceDimension);
+   cmd->desc = *desc;
+
+   surface_to_resourceid(swc, surface,
+                         &cmd->sid,
+                         SVGA_RELOC_READ | SVGA_RELOC_WRITE);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyRenderTargetView(struct svga_winsys_context *swc,
+                                 SVGA3dRenderTargetViewId renderTargetViewId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyRenderTargetView, DESTROY_RENDERTARGET_VIEW);
+
+   cmd->renderTargetViewId = renderTargetViewId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_DefineDepthStencilView(struct svga_winsys_context *swc,
+                                  SVGA3dDepthStencilViewId depthStencilViewId,
+                                  struct svga_winsys_surface *surface,
+                                  SVGA3dSurfaceFormat format,
+                                  SVGA3dResourceType resourceDimension,
+                                  const SVGA3dRenderTargetViewDesc *desc)
+{
+   SVGA3dCmdDXDefineDepthStencilView *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW,
+                            sizeof(SVGA3dCmdDXDefineDepthStencilView),
+                            1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   SVGA3D_COPY_BASIC_3(depthStencilViewId, format, resourceDimension);
+   cmd->mipSlice = desc->tex.mipSlice;
+   cmd->firstArraySlice = desc->tex.firstArraySlice;
+   cmd->arraySize = desc->tex.arraySize;
+
+   surface_to_resourceid(swc, surface,
+                         &cmd->sid,
+                         SVGA_RELOC_READ | SVGA_RELOC_WRITE);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyDepthStencilView(struct svga_winsys_context *swc,
+                                 SVGA3dDepthStencilViewId depthStencilViewId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyDepthStencilView, DESTROY_DEPTHSTENCIL_VIEW);
+
+   cmd->depthStencilViewId = depthStencilViewId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineElementLayout(struct svga_winsys_context *swc,
+                                  unsigned count,
+                                  SVGA3dElementLayoutId elementLayoutId,
+                                  const SVGA3dInputElementDesc *elements)
+{
+   SVGA3dCmdDXDefineElementLayout *cmd;
+   unsigned i;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT,
+                            sizeof(SVGA3dCmdDXDefineElementLayout) +
+                            count * sizeof(SVGA3dInputElementDesc), 0);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   /* check that all offsets are multiples of four */
+   for (i = 0; i < count; i++) {
+      assert(elements[i].alignedByteOffset % 4 == 0);
+   }
+   (void) i; /* silence unused var in release build */
+
+   cmd->elementLayoutId = elementLayoutId;
+   memcpy(cmd + 1, elements, count * sizeof(SVGA3dInputElementDesc));
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyElementLayout(struct svga_winsys_context *swc,
+                                   SVGA3dElementLayoutId elementLayoutId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyElementLayout, DESTROY_ELEMENTLAYOUT);
+
+   cmd->elementLayoutId = elementLayoutId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineBlendState(struct svga_winsys_context *swc,
+                               SVGA3dBlendStateId blendId,
+                               uint8 alphaToCoverageEnable,
+                               uint8 independentBlendEnable,
+                               const SVGA3dDXBlendStatePerRT *perRT)
+{
+   SVGA3D_CREATE_COMMAND(DefineBlendState, DEFINE_BLEND_STATE);
+
+   cmd->blendId = blendId;
+   cmd->alphaToCoverageEnable = alphaToCoverageEnable;
+   cmd->independentBlendEnable = independentBlendEnable;
+   memcpy(cmd->perRT, perRT, sizeof(cmd->perRT));
+   cmd->pad0 = 0;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyBlendState(struct svga_winsys_context *swc,
+                                SVGA3dBlendStateId blendId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyBlendState, DESTROY_BLEND_STATE);
+
+   cmd->blendId = blendId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineDepthStencilState(struct svga_winsys_context *swc,
+                                      SVGA3dDepthStencilStateId depthStencilId,
+                                      uint8 depthEnable,
+                                      SVGA3dDepthWriteMask depthWriteMask,
+                                      SVGA3dComparisonFunc depthFunc,
+                                      uint8 stencilEnable,
+                                      uint8 frontEnable,
+                                      uint8 backEnable,
+                                      uint8 stencilReadMask,
+                                      uint8 stencilWriteMask,
+                                      uint8 frontStencilFailOp,
+                                      uint8 frontStencilDepthFailOp,
+                                      uint8 frontStencilPassOp,
+                                      SVGA3dComparisonFunc frontStencilFunc,
+                                      uint8 backStencilFailOp,
+                                      uint8 backStencilDepthFailOp,
+                                      uint8 backStencilPassOp,
+                                      SVGA3dComparisonFunc backStencilFunc)
+{
+   SVGA3D_CREATE_COMMAND(DefineDepthStencilState, DEFINE_DEPTHSTENCIL_STATE);
+
+   SVGA3D_COPY_BASIC_9(depthStencilId, depthEnable,
+                       depthWriteMask, depthFunc,
+                       stencilEnable, frontEnable,
+                       backEnable, stencilReadMask,
+                       stencilWriteMask);
+   SVGA3D_COPY_BASIC_8(frontStencilFailOp, frontStencilDepthFailOp,
+                       frontStencilPassOp, frontStencilFunc,
+                       backStencilFailOp, backStencilDepthFailOp,
+                       backStencilPassOp, backStencilFunc);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyDepthStencilState(struct svga_winsys_context *swc,
+                                    SVGA3dDepthStencilStateId depthStencilId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyDepthStencilState,
+                         DESTROY_DEPTHSTENCIL_STATE);
+
+   cmd->depthStencilId = depthStencilId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineRasterizerState(struct svga_winsys_context *swc,
+                                    SVGA3dRasterizerStateId rasterizerId,
+                                    uint8 fillMode,
+                                    SVGA3dCullMode cullMode,
+                                    uint8 frontCounterClockwise,
+                                    int32 depthBias,
+                                    float depthBiasClamp,
+                                    float slopeScaledDepthBias,
+                                    uint8 depthClipEnable,
+                                    uint8 scissorEnable,
+                                    uint8 multisampleEnable,
+                                    uint8 antialiasedLineEnable,
+                                    float lineWidth,
+                                    uint8 lineStippleEnable,
+                                    uint8 lineStippleFactor,
+                                    uint16 lineStipplePattern,
+                                    uint8 provokingVertexLast)
+{
+   SVGA3D_CREATE_COMMAND(DefineRasterizerState, DEFINE_RASTERIZER_STATE);
+
+   SVGA3D_COPY_BASIC_5(rasterizerId, fillMode,
+                       cullMode, frontCounterClockwise,
+                       depthBias);
+   SVGA3D_COPY_BASIC_6(depthBiasClamp, slopeScaledDepthBias,
+                       depthClipEnable, scissorEnable,
+                       multisampleEnable, antialiasedLineEnable);
+   cmd->lineWidth = lineWidth;
+   cmd->lineStippleEnable = lineStippleEnable;
+   cmd->lineStippleFactor = lineStippleFactor;
+   cmd->lineStipplePattern = lineStipplePattern;
+   cmd->provokingVertexLast = provokingVertexLast;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyRasterizerState(struct svga_winsys_context *swc,
+                                     SVGA3dRasterizerStateId rasterizerId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyRasterizerState, DESTROY_RASTERIZER_STATE);
+
+   cmd->rasterizerId = rasterizerId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineSamplerState(struct svga_winsys_context *swc,
+                                 SVGA3dSamplerId samplerId,
+                                 SVGA3dFilter filter,
+                                 uint8 addressU,
+                                 uint8 addressV,
+                                 uint8 addressW,
+                                 float mipLODBias,
+                                 uint8 maxAnisotropy,
+                                 uint8 comparisonFunc,
+                                 SVGA3dRGBAFloat borderColor,
+                                 float minLOD,
+                                 float maxLOD)
+{
+   SVGA3D_CREATE_COMMAND(DefineSamplerState, DEFINE_SAMPLER_STATE);
+
+   SVGA3D_COPY_BASIC_6(samplerId, filter,
+                       addressU, addressV,
+                       addressW, mipLODBias);
+   SVGA3D_COPY_BASIC_5(maxAnisotropy, comparisonFunc,
+                       borderColor, minLOD,
+                       maxLOD);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroySamplerState(struct svga_winsys_context *swc,
+                                  SVGA3dSamplerId samplerId)
+{
+   SVGA3D_CREATE_COMMAND(DestroySamplerState, DESTROY_SAMPLER_STATE);
+
+   cmd->samplerId = samplerId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_DefineAndBindShader(struct svga_winsys_context *swc,
+                                  struct svga_winsys_gb_shader *gbshader,
+                                  SVGA3dShaderId shaderId,
+                                  SVGA3dShaderType type,
+                                  uint32 sizeInBytes)
+{
+   SVGA3dCmdHeader *header;
+   SVGA3dCmdDXDefineShader *dcmd;
+   SVGA3dCmdDXBindShader *bcmd;
+   unsigned totalSize = 2 * sizeof(*header) +
+                        sizeof(*dcmd) + sizeof(*bcmd);
+
+   /* Make sure there is room for both commands */
+   header = swc->reserve(swc, totalSize, 2);
+   if (!header)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   /* DXDefineShader command */
+   header->id = SVGA_3D_CMD_DX_DEFINE_SHADER;
+   header->size = sizeof(*dcmd);
+   dcmd = (SVGA3dCmdDXDefineShader *)(header + 1);
+   dcmd->shaderId = shaderId;
+   dcmd->type = type;
+   dcmd->sizeInBytes = sizeInBytes;
+
+   /* DXBindShader command */
+   header = (SVGA3dCmdHeader *)(dcmd + 1);
+
+   header->id = SVGA_3D_CMD_DX_BIND_SHADER;
+   header->size = sizeof(*bcmd);
+   bcmd = (SVGA3dCmdDXBindShader *)(header + 1);
+
+   bcmd->cid = swc->cid;
+   swc->shader_relocation(swc, NULL, &bcmd->mobid,
+                          &bcmd->offsetInBytes, gbshader, 0);
+
+   bcmd->shid = shaderId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyShader(struct svga_winsys_context *swc,
+                            SVGA3dShaderId shaderId)
+{
+   SVGA3D_CREATE_COMMAND(DestroyShader, DESTROY_SHADER);
+
+   cmd->shaderId = shaderId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DefineStreamOutput(struct svga_winsys_context *swc,
+       SVGA3dStreamOutputId soid,
+       uint32 numOutputStreamEntries,
+       uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS],
+       const SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_STREAMOUT_DECLS])
+{
+   unsigned i;
+   SVGA3D_CREATE_COMMAND(DefineStreamOutput, DEFINE_STREAMOUTPUT);
+
+   cmd->soid = soid;
+   cmd->numOutputStreamEntries = numOutputStreamEntries;
+
+   for (i = 0; i < Elements(cmd->streamOutputStrideInBytes); i++)
+      cmd->streamOutputStrideInBytes[i] = streamOutputStrideInBytes[i];
+
+   memcpy(cmd->decl, decl,
+          sizeof(SVGA3dStreamOutputDeclarationEntry)
+          * SVGA3D_MAX_STREAMOUT_DECLS);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_DestroyStreamOutput(struct svga_winsys_context *swc,
+                                  SVGA3dStreamOutputId soid)
+{
+   SVGA3D_CREATE_COMMAND(DestroyStreamOutput, DESTROY_STREAMOUTPUT);
+
+   cmd->soid = soid;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetInputLayout(struct svga_winsys_context *swc,
+                             SVGA3dElementLayoutId elementLayoutId)
+{
+   SVGA3D_CREATE_COMMAND(SetInputLayout, SET_INPUT_LAYOUT);
+
+   cmd->elementLayoutId = elementLayoutId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetVertexBuffers(struct svga_winsys_context *swc,
+                               unsigned count,
+                               uint32 startBuffer,
+                               const SVGA3dVertexBuffer *bufferInfo,
+                               struct svga_winsys_surface **surfaces)
+{
+   SVGA3dCmdDXSetVertexBuffers *cmd;
+   SVGA3dVertexBuffer *bufs;
+   unsigned i;
+
+   assert(count > 0);
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS,
+                            sizeof(SVGA3dCmdDXSetVertexBuffers) +
+                            count * sizeof(SVGA3dVertexBuffer),
+                            count); /* 'count' relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->startBuffer = startBuffer;
+
+   bufs = (SVGA3dVertexBuffer *) &cmd[1];
+   for (i = 0; i < count; i++) {
+      bufs[i].stride = bufferInfo[i].stride;
+      bufs[i].offset = bufferInfo[i].offset;
+      assert(bufs[i].stride % 4 == 0);
+      assert(bufs[i].offset % 4 == 0);
+      swc->surface_relocation(swc, &bufs[i].sid, NULL, surfaces[i],
+                              SVGA_RELOC_READ);
+   }
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetTopology(struct svga_winsys_context *swc,
+                          SVGA3dPrimitiveType topology)
+{
+   SVGA3D_CREATE_COMMAND(SetTopology, SET_TOPOLOGY);
+
+   cmd->topology = topology;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetIndexBuffer(struct svga_winsys_context *swc,
+                             struct svga_winsys_surface *indexes,
+                             SVGA3dSurfaceFormat format,
+                             uint32 offset)
+{
+   SVGA3dCmdDXSetIndexBuffer *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_INDEX_BUFFER,
+                            sizeof(SVGA3dCmdDXSetIndexBuffer),
+                            1); /* one relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, indexes, SVGA_RELOC_READ);
+   SVGA3D_COPY_BASIC_2(format, offset);
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
+                                      unsigned slot,
+                                      SVGA3dShaderType type,
+                                      struct svga_winsys_surface *surface,
+                                      uint32 offsetInBytes,
+                                      uint32 sizeInBytes)
+{
+   SVGA3dCmdDXSetSingleConstantBuffer *cmd;
+
+   assert(offsetInBytes % 256 == 0);
+   if (!surface)
+      assert(sizeInBytes == 0);
+   else
+      assert(sizeInBytes > 0);
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER,
+                            sizeof(SVGA3dCmdDXSetSingleConstantBuffer),
+                            1);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->slot = slot;
+   cmd->type = type;
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface, SVGA_RELOC_READ);
+   cmd->offsetInBytes = offsetInBytes;
+   cmd->sizeInBytes = sizeInBytes;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_ReadbackSubResource(struct svga_winsys_context *swc,
+                                  struct svga_winsys_surface *surface,
+                                  unsigned subResource)
+{
+   SVGA3dCmdDXReadbackSubResource *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_READBACK_SUBRESOURCE,
+                            sizeof(SVGA3dCmdDXReadbackSubResource),
+                            1);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+   cmd->subResource = subResource;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
+                                struct svga_winsys_surface *surface,
+                                const SVGA3dBox *box,
+                                unsigned subResource)
+{
+   SVGA3dCmdDXUpdateSubResource *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE,
+                            sizeof(SVGA3dCmdDXUpdateSubResource),
+                            1);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
+   cmd->subResource = subResource;
+   cmd->box = *box;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}