summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/r600_buffer.c')
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c25
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);