--- /dev/null
+/**********************************************************
+ * 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;
+}