/** * Issue commands to transfer guest memory to the host. */ static enum pipe_error svga_buffer_upload_command(struct svga_context *svga, struct svga_buffer *sbuf) { if (svga_have_gb_objects(svga)) { return svga_buffer_upload_gb_command(svga, sbuf); } else { return svga_buffer_upload_hb_command(svga, sbuf); } }
/** * Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank. */ static enum pipe_error svga_buffer_upload_command(struct svga_context *svga, struct svga_buffer *sbuf) { struct svga_winsys_context *swc = svga->swc; struct svga_winsys_buffer *guest = sbuf->hwbuf; struct svga_winsys_surface *host = sbuf->handle; SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM; SVGA3dCmdSurfaceDMA *cmd; uint32 numBoxes = sbuf->map.num_ranges; SVGA3dCopyBox *boxes; SVGA3dCmdSurfaceDMASuffix *pSuffix; unsigned region_flags; unsigned surface_flags; struct pipe_resource *dummy; if (svga_have_gb_objects(svga)) return svga_buffer_upload_gb_command(svga, sbuf); if (transfer == SVGA3D_WRITE_HOST_VRAM) { region_flags = SVGA_RELOC_READ; surface_flags = SVGA_RELOC_WRITE; } else if (transfer == SVGA3D_READ_HOST_VRAM) { region_flags = SVGA_RELOC_WRITE; surface_flags = SVGA_RELOC_READ; } else { assert(0); return PIPE_ERROR_BAD_INPUT; } assert(numBoxes); cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_SURFACE_DMA, sizeof *cmd + numBoxes * sizeof *boxes + sizeof *pSuffix, 2); if (!cmd) return PIPE_ERROR_OUT_OF_MEMORY; swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags); cmd->guest.pitch = 0; swc->surface_relocation(swc, &cmd->host.sid, NULL, host, surface_flags); cmd->host.face = 0; cmd->host.mipmap = 0; cmd->transfer = transfer; sbuf->dma.boxes = (SVGA3dCopyBox *)&cmd[1]; sbuf->dma.svga = svga; /* Increment reference count */ dummy = NULL; pipe_resource_reference(&dummy, &sbuf->b.b); pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes); pSuffix->suffixSize = sizeof *pSuffix; pSuffix->maximumOffset = sbuf->b.b.width0; pSuffix->flags = sbuf->dma.flags; SVGA_FIFOCommitAll(swc); sbuf->dma.flags.discard = FALSE; return PIPE_OK; }