+ cmd = SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_SET_SHADER,
+ sizeof *cmd,
+ 2); /* two relocations */
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ cmd->cid = swc->cid;
+ cmd->type = type;
+ if (gbshader)
+ swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader, 0);
+ else
+ cmd->shid = SVGA_ID_INVALID;
+ swc->commit(swc);
+
+ return PIPE_OK;
+}
+
+
+/**
+ * \param flags mask of SVGA_RELOC_READ / _WRITE
+ */
+enum pipe_error
+SVGA3D_BindGBSurface(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface)
+{
+ SVGA3dCmdBindGBSurface *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_BIND_GB_SURFACE,
+ sizeof *cmd,
+ 2); /* two relocations */
+
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface,
+ SVGA_RELOC_READ);
+
+ swc->commit(swc);
+
+ return PIPE_OK;
+}
+
+
+/**
+ * Update an image in a guest-backed surface.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+enum pipe_error
+SVGA3D_UpdateGBImage(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface,
+ const SVGA3dBox *box,
+ unsigned face, unsigned mipLevel)
+
+{
+ SVGA3dCmdUpdateGBImage *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_UPDATE_GB_IMAGE,
+ sizeof *cmd,
+ 1); /* one relocation */
+
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+ SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
+ cmd->image.face = face;
+ cmd->image.mipmap = mipLevel;
+ cmd->box = *box;
+
+ swc->commit(swc);
+ swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+ return PIPE_OK;
+}
+
+
+/**
+ * Update an entire guest-backed surface.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+enum pipe_error
+SVGA3D_UpdateGBSurface(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface)
+{
+ SVGA3dCmdUpdateGBSurface *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_UPDATE_GB_SURFACE,
+ sizeof *cmd,
+ 1); /* one relocation */
+
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+ SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
+
+ swc->commit(swc);
+ swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+ return PIPE_OK;
+}
+
+
+/**
+ * Readback an image in a guest-backed surface.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+enum pipe_error
+SVGA3D_ReadbackGBImage(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface,
+ unsigned face, unsigned mipLevel)
+{
+ SVGA3dCmdReadbackGBImage *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_READBACK_GB_IMAGE,
+ sizeof *cmd,
+ 1); /* one relocation */
+
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+ SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+ cmd->image.face = face;
+ cmd->image.mipmap = mipLevel;
+
+ swc->commit(swc);
+ swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+ return PIPE_OK;
+}
+
+
+/**
+ * Readback an entire guest-backed surface.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+enum pipe_error
+SVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface)
+{
+ SVGA3dCmdReadbackGBSurface *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_READBACK_GB_SURFACE,
+ sizeof *cmd,
+ 1); /* one relocation */
+
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+ SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+
+ swc->commit(swc);
+ swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+ return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface,
+ unsigned face, unsigned mipLevel,
+ const SVGA3dBox *box,
+ bool invertBox)
+{
+ SVGA3dCmdReadbackGBImagePartial *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL,
+ sizeof *cmd,
+ 1); /* one relocation */
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+ SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+ cmd->image.face = face;
+ cmd->image.mipmap = mipLevel;
+ cmd->box = *box;
+ cmd->invertBox = invertBox;
+
+ swc->commit(swc);
+ swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+ return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface,
+ unsigned face, unsigned mipLevel,
+ const SVGA3dBox *box,
+ bool invertBox)
+{
+ SVGA3dCmdInvalidateGBImagePartial *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL,
+ sizeof *cmd,
+ 1); /* one relocation */
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+ SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+ cmd->image.face = face;
+ cmd->image.mipmap = mipLevel;
+ cmd->box = *box;
+ cmd->invertBox = invertBox;
+
+ swc->commit(swc);
+
+ return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_InvalidateGBSurface(struct svga_winsys_context *swc,
+ struct svga_winsys_surface *surface)
+{
+ SVGA3dCmdInvalidateGBSurface *cmd =
+ SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_INVALIDATE_GB_SURFACE,
+ sizeof *cmd,
+ 1); /* one relocation */
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+ SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+ swc->commit(swc);
+
+ return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,
+ unsigned regStart,
+ unsigned numRegs,
+ SVGA3dShaderType shaderType,
+ SVGA3dShaderConstType constType,
+ const void *values)
+{
+ SVGA3dCmdSetGBShaderConstInline *cmd;
+
+ assert(numRegs > 0);
+
+ cmd = SVGA3D_FIFOReserve(swc,
+ SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE,
+ sizeof *cmd + numRegs * sizeof(float[4]),
+ 0); /* no relocations */
+ if (!cmd)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ cmd->cid = swc->cid;
+ cmd->regStart = regStart;
+ cmd->shaderType = shaderType;
+ cmd->constType = constType;
+
+ memcpy(&cmd[1], values, numRegs * sizeof(float[4]));
+
+ swc->commit(swc);
+