diff options
Diffstat (limited to 'src/gallium/drivers/r600/r600_buffer.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_buffer.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index be171f8850a..6df0d91a56c 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -27,6 +27,7 @@ #include "r600_pipe.h" #include "util/u_upload_mgr.h" #include "util/u_memory.h" +#include "util/u_surface.h" static void r600_buffer_destroy(struct pipe_screen *screen, struct pipe_resource *buf) @@ -179,13 +180,27 @@ static void r600_buffer_transfer_unmap(struct pipe_context *pipe, struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; if (rtransfer->staging) { - struct pipe_box box; - u_box_1d(rtransfer->offset + transfer->box.x % R600_MAP_BUFFER_ALIGNMENT, - transfer->box.width, &box); + struct pipe_resource *dst, *src; + unsigned soffset, doffset, size; + dst = transfer->resource; + src = &rtransfer->staging->b.b; + size = transfer->box.width; + doffset = transfer->box.x; + soffset = rtransfer->offset + transfer->box.x % R600_MAP_BUFFER_ALIGNMENT; /* Copy the staging buffer into the original one. */ - r600_copy_buffer(pipe, transfer->resource, transfer->box.x, - &rtransfer->staging->b.b, &box); + if (rctx->rings.dma.cs && !(size % 4) && !(doffset % 4) && !(soffset)) { + if (rctx->screen->chip_class >= EVERGREEN) { + evergreen_dma_copy(rctx, dst, src, doffset, soffset, size); + } else { + r600_dma_copy(rctx, dst, src, doffset, soffset, size); + } + } else { + struct pipe_box box; + + u_box_1d(soffset, size, &box); + r600_copy_buffer(pipe, dst, doffset, src, &box); + } pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL); } util_slab_free(&rctx->pool_transfers, transfer); |