summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-03-30 15:55:20 +0100
committerChristoph Bumiller <[email protected]>2013-04-03 12:54:43 +0200
commit2a8145d36b0f04d0f26c1628222a8b5c4830f435 (patch)
tree7d298c6f8afc0071293b58fadc84d890efa0f06d
parent3ed4bbd76904983ca4b19a58afd2187f497b4ab0 (diff)
nouveau: accelerate buffer copies in resource_copy_region
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.c34
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.h7
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_surface.c6
5 files changed, 47 insertions, 11 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 5c9a44e368a..02bc6f04146 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -2,6 +2,7 @@
#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_surface.h"
#include "nouveau_screen.h"
#include "nouveau_context.h"
@@ -460,6 +461,39 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
}
+void
+nouveau_copy_buffer(struct nouveau_context *nv,
+ struct nv04_resource *dst, unsigned dstx,
+ struct nv04_resource *src, unsigned srcx, unsigned size)
+{
+ assert(dst->base.target == PIPE_BUFFER && src->base.target == PIPE_BUFFER);
+
+ if (likely(dst->domain) && likely(src->domain)) {
+ nv->copy_data(nv,
+ dst->bo, dst->offset + dstx, dst->domain,
+ src->bo, src->offset + srcx, src->domain, size);
+
+ dst->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+ nouveau_fence_ref(nv->screen->fence.current, &dst->fence);
+ nouveau_fence_ref(nv->screen->fence.current, &dst->fence_wr);
+
+ src->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+ nouveau_fence_ref(nv->screen->fence.current, &src->fence);
+ } else {
+ struct pipe_box src_box;
+ src_box.x = srcx;
+ src_box.y = 0;
+ src_box.z = 0;
+ src_box.width = size;
+ src_box.height = 1;
+ src_box.depth = 1;
+ util_resource_copy_region(&nv->pipe,
+ &dst->base, 0, dstx, 0, 0,
+ &src->base, 0, &src_box);
+ }
+}
+
+
void *
nouveau_resource_map_offset(struct nouveau_context *nv,
struct nv04_resource *res, uint32_t offset,
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h
index aafc84293a7..fd7a3f1287f 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.h
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.h
@@ -49,9 +49,10 @@ struct nv04_resource {
void
nouveau_buffer_release_gpu_storage(struct nv04_resource *);
-boolean
-nouveau_buffer_download(struct nouveau_context *, struct nv04_resource *,
- unsigned start, unsigned size);
+void
+nouveau_copy_buffer(struct nouveau_context *,
+ struct nv04_resource *dst, unsigned dst_pos,
+ struct nv04_resource *src, unsigned src_pos, unsigned size);
boolean
nouveau_buffer_migrate(struct nouveau_context *,
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index d4dcacb8506..f536287bbbb 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -130,8 +130,9 @@ nv30_resource_copy_region(struct pipe_context *pipe,
struct nv30_rect src, dst;
if (dstres->target == PIPE_BUFFER && srcres->target == PIPE_BUFFER) {
- util_resource_copy_region(pipe, dstres, dst_level, dstx, dsty, dstz,
- srcres, src_level, src_box);
+ nouveau_copy_buffer(&nv30->base,
+ nv04_resource(dstres), dstx,
+ nv04_resource(srcres), src_box->x, src_box->width);
return;
}
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index b29a736ae3c..51e702c7a3f 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -200,10 +200,10 @@ nv50_resource_copy_region(struct pipe_context *pipe,
boolean m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
- /* Fallback for buffers. */
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
- util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
- src, src_level, src_box);
+ nouveau_copy_buffer(&nv50->base,
+ nv04_resource(dst), dstx,
+ nv04_resource(src), src_box->x, src_box->width);
return;
}
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index 95f3ff43679..de71127072b 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -201,10 +201,10 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
boolean m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
- /* Fallback for buffers. */
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
- util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
- src, src_level, src_box);
+ nouveau_copy_buffer(&nvc0->base,
+ nv04_resource(dst), dstx,
+ nv04_resource(src), src_box->x, src_box->width);
NOUVEAU_DRV_STAT(&nvc0->screen->base, buf_copy_bytes, src_box->width);
return;
}