/** * unmap direct map transfer request */ static void svga_texture_transfer_unmap_direct(struct svga_context *svga, struct svga_transfer *st) { struct pipe_transfer *transfer = &st->base; struct svga_texture *tex = svga_texture(transfer->resource); svga_texture_surface_unmap(svga, transfer); /* Now send an update command to update the content in the backend. */ if (st->base.usage & PIPE_TRANSFER_WRITE) { struct svga_winsys_surface *surf = tex->handle; enum pipe_error ret; assert(svga_have_gb_objects(svga)); /* update the effected region */ SVGA3dBox box = st->box; unsigned nlayers; switch (tex->b.b.target) { case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_1D_ARRAY: nlayers = box.d; box.d = 1; break; default: nlayers = 1; break; } if (0) debug_printf("%s %d, %d, %d %d x %d x %d\n", __FUNCTION__, box.x, box.y, box.z, box.w, box.h, box.d); if (svga_have_vgpu10(svga)) { unsigned i; for (i = 0; i < nlayers; i++) { ret = update_image_vgpu10(svga, surf, &box, st->slice + i, transfer->level, tex->b.b.last_level + 1); assert(ret == PIPE_OK); } } else { assert(nlayers == 1); ret = update_image_vgpu9(svga, surf, &box, st->slice, transfer->level); assert(ret == PIPE_OK); } (void) ret; } }
static void svga_texture_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct svga_context *svga = svga_context(pipe); struct svga_screen *ss = svga_screen(pipe->screen); struct svga_winsys_screen *sws = ss->sws; struct svga_transfer *st = svga_transfer(transfer); struct svga_texture *tex = svga_texture(transfer->resource); if (!st->swbuf) { if (st->use_direct_map) { svga_texture_surface_unmap(svga, transfer); } else { sws->buffer_unmap(sws, st->hwbuf); } } if (!st->use_direct_map && (st->base.usage & PIPE_TRANSFER_WRITE)) { /* Use DMA to transfer texture data */ SVGA3dSurfaceDMAFlags flags; memset(&flags, 0, sizeof flags); if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { flags.discard = TRUE; } if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) { flags.unsynchronized = TRUE; } svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags); } else if (transfer->usage & PIPE_TRANSFER_WRITE) { struct svga_winsys_surface *surf = svga_texture(transfer->resource)->handle; SVGA3dBox box; enum pipe_error ret; assert(svga_have_gb_objects(svga)); /* update the effected region */ box.x = transfer->box.x; box.y = transfer->box.y; switch (tex->b.b.target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_2D_ARRAY: box.z = 0; break; case PIPE_TEXTURE_1D_ARRAY: box.y = box.z = 0; break; default: box.z = transfer->box.z; break; } box.w = transfer->box.width; box.h = transfer->box.height; box.d = transfer->box.depth; if (0) debug_printf("%s %d, %d, %d %d x %d x %d\n", __FUNCTION__, box.x, box.y, box.z, box.w, box.h, box.d); if (svga_have_vgpu10(svga)) { ret = update_image_vgpu10(svga, surf, &box, st->slice, transfer->level, tex->b.b.last_level + 1); } else { ret = update_image_vgpu9(svga, surf, &box, st->slice, transfer->level); } assert(ret == PIPE_OK); (void) ret; } ss->texture_timestamp++; svga_age_texture_view(tex, transfer->level); if (transfer->resource->target == PIPE_TEXTURE_CUBE) svga_define_texture_level(tex, st->slice, transfer->level); else svga_define_texture_level(tex, 0, transfer->level); pipe_resource_reference(&st->base.resource, NULL); FREE(st->swbuf); if (!st->use_direct_map) { sws->buffer_destroy(sws, st->hwbuf); } FREE(st); }