This opens the question of what interface the winsys layer should
really have for talking about these concepts.

For now I'm using the existing gallium resource usage concept, but
there is no reason not use terms closer to what the hardware
understands - eg. the domains themselves.
---
 src/gallium/drivers/r600/r600.h               |    3 ++-
 src/gallium/drivers/r600/r600_buffer.c        |    7 ++++---
 src/gallium/drivers/r600/r600_shader.c        |    2 +-
 src/gallium/drivers/r600/r600_texture.c       |    2 +-
 src/gallium/winsys/r600/drm/r600_bo.c         |   20 +++++++++++++++++---
 src/gallium/winsys/r600/drm/r600_hw_context.c |   13 +++++++++----
 src/gallium/winsys/r600/drm/r600_priv.h       |    1 +
 7 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 62d9832..5ec607b 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -112,7 +112,8 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon 
*radeon);
 /* r600_bo.c */
 struct r600_bo;
 struct r600_bo *r600_bo(struct radeon *radeon,
-                                 unsigned size, unsigned alignment, unsigned 
usage);
+                        unsigned size, unsigned alignment,
+                        unsigned binding, unsigned usage);
 struct r600_bo *r600_bo_handle(struct radeon *radeon,
                               unsigned handle, unsigned *array_mode);
 void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, 
void *ctx);
diff --git a/src/gallium/drivers/r600/r600_buffer.c 
b/src/gallium/drivers/r600/r600_buffer.c
index 455aa2e..3c45d78 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -86,7 +86,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen 
*screen,
        rbuffer->r.base.vtbl = &r600_buffer_vtbl;
        rbuffer->r.size = rbuffer->r.base.b.width0;
        rbuffer->r.domain = r600_domain_from_usage(rbuffer->r.base.b.bind);
-       bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, 
alignment, rbuffer->r.base.b.bind);
+       bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, 
alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage);
        if (bo == NULL) {
                FREE(rbuffer);
                return NULL;
@@ -156,8 +156,9 @@ static void *r600_buffer_transfer_map(struct pipe_context 
*pipe,
                                r600_bo_reference((struct radeon*)pipe->winsys, 
&rbuffer->r.bo, NULL);
                                rbuffer->num_ranges = 0;
                                rbuffer->r.bo = r600_bo((struct 
radeon*)pipe->winsys,
-                                                            
rbuffer->r.base.b.width0, 0,
-                                                            
rbuffer->r.base.b.bind);
+                                                        
rbuffer->r.base.b.width0, 0,
+                                                        rbuffer->r.base.b.bind,
+                                                        
rbuffer->r.base.b.usage);
                                break;
                        }
                }
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 4106587..1a0b35d 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -218,7 +218,7 @@ static int r600_pipe_shader(struct pipe_context *ctx, 
struct r600_pipe_shader *s
 
        /* copy new shader */
        if (shader->bo == NULL) {
-               shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 
0);
+               shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 
0, 0);
                if (shader->bo == NULL) {
                        return -ENOMEM;
                }
diff --git a/src/gallium/drivers/r600/r600_texture.c 
b/src/gallium/drivers/r600/r600_texture.c
index 7222b43..9a52cfa 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -294,7 +294,7 @@ r600_texture_create_object(struct pipe_screen *screen,
        resource->size = rtex->size;
 
        if (!resource->bo) {
-               resource->bo = r600_bo(radeon, rtex->size, 4096, 0);
+               resource->bo = r600_bo(radeon, rtex->size, 4096, base->bind, 
base->usage);
                if (!resource->bo) {
                        FREE(rtex);
                        return NULL;
diff --git a/src/gallium/winsys/r600/drm/r600_bo.c 
b/src/gallium/winsys/r600/drm/r600_bo.c
index 7d54ff1..de46d50 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -29,23 +29,37 @@
 #include "radeon_drm.h"
 #include "r600_priv.h"
 #include "r600d.h"
+#include "radeon_drm.h"
 
 struct r600_bo *r600_bo(struct radeon *radeon,
-                                 unsigned size, unsigned alignment, unsigned 
usage)
+                       unsigned size, unsigned alignment,
+                       unsigned binding, unsigned usage)
 {
        struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo));
        struct pb_desc desc;
        struct pb_manager *man;
 
        desc.alignment = alignment;
-       desc.usage = usage;
+       desc.usage = (PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_READ_WRITE);
        ws_bo->size = size;
 
-       if (usage & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | 
PIPE_BIND_INDEX_BUFFER))
+       if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | 
PIPE_BIND_INDEX_BUFFER))
                man = radeon->cman;
        else
                man = radeon->kman;
 
+       /* Staging resources particpate in transfers and blits only
+        * and are used for uploads and downloads from regular
+        * resources.  We generate them internally for some transfers.
+        */
+       if (usage == PIPE_USAGE_STAGING)
+                ws_bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
+        else
+                ws_bo->domains = (RADEON_GEM_DOMAIN_CPU |
+                                  RADEON_GEM_DOMAIN_GTT |
+                                  RADEON_GEM_DOMAIN_VRAM);
+
+
        ws_bo->pb = man->create_buffer(man, size, &desc);
        if (ws_bo->pb == NULL) {
                free(ws_bo);
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c 
b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 2521ff9..effb228 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -44,7 +44,7 @@
 int r600_context_init_fence(struct r600_context *ctx)
 {
        ctx->fence = 1;
-       ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0);
+       ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0, 0);
        if (ctx->fence_bo == NULL) {
                return -ENOMEM;
        }
@@ -785,8 +785,8 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 
*pm4, struct r600_bo *r
        bo->reloc = &ctx->reloc[ctx->creloc];
        bo->reloc_id = ctx->creloc * sizeof(struct r600_reloc) / 4;
        ctx->reloc[ctx->creloc].handle = bo->handle;
-       ctx->reloc[ctx->creloc].read_domain = RADEON_GEM_DOMAIN_GTT | 
RADEON_GEM_DOMAIN_VRAM;
-       ctx->reloc[ctx->creloc].write_domain = RADEON_GEM_DOMAIN_GTT | 
RADEON_GEM_DOMAIN_VRAM;
+       ctx->reloc[ctx->creloc].read_domain = rbo->domains & 
(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM);
+       ctx->reloc[ctx->creloc].write_domain = rbo->domains & 
(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM);
        ctx->reloc[ctx->creloc].flags = 0;
        radeon_bo_reference(ctx->radeon, &ctx->bo[ctx->creloc], bo);
        ctx->creloc++;
@@ -1304,7 +1304,12 @@ struct r600_query *r600_context_query_create(struct 
r600_context *ctx, unsigned
        query->type = query_type;
        query->buffer_size = 4096;
 
-       query->buffer = r600_bo(ctx->radeon, query->buffer_size, 1, 0);
+       /* As of GL4, query buffers are normally read by the CPU after
+        * being written by the gpu, hence staging is probably a good
+        * usage pattern.
+        */
+       query->buffer = r600_bo(ctx->radeon, query->buffer_size, 1, 0,
+                               PIPE_USAGE_STAGING);
        if (!query->buffer) {
                free(query);
                return NULL;
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h 
b/src/gallium/winsys/r600/drm/r600_priv.h
index b5bd7bd..996ac0f 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -79,6 +79,7 @@ struct r600_bo {
        unsigned                        size;
        unsigned                        tiling_flags;
        unsigned                        kernel_pitch;
+       unsigned                        domains;
 };
 
 
-- 
1.7.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to