From: Marek Olšák <marek.ol...@amd.com>

This is a rework of "r600g,radeonsi: force VRAM placement for DRI2 buffers".
It mainly consolidates the code determining resource placements. It also takes
Prime into account.
---
 src/gallium/drivers/r600/r600_state_common.c    |  4 +-
 src/gallium/drivers/radeon/r600_buffer_common.c | 72 +++++++++++++++----------
 src/gallium/drivers/radeon/r600_pipe_common.h   |  3 +-
 src/gallium/drivers/radeon/r600_texture.c       | 11 ++--
 src/gallium/drivers/radeonsi/si_descriptors.c   |  4 +-
 5 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index d8fab10..c1d7e29 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -2082,8 +2082,8 @@ static void r600_invalidate_buffer(struct pipe_context 
*ctx, struct pipe_resourc
        pb_reference(&rbuffer->buf, NULL);
 
        /* Create a new one in the same pipe_resource. */
-       r600_init_resource(&rctx->screen->b, rbuffer, rbuffer->b.b.width0, 
alignment,
-                          TRUE, rbuffer->b.b.usage);
+       r600_init_resource(&rctx->screen->b, rbuffer, rbuffer->b.b.width0,
+                          alignment, TRUE);
 
        /* We changed the buffer, now we need to bind it where the old one was 
bound. */
        /* Vertex buffers. */
diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c 
b/src/gallium/drivers/radeon/r600_buffer_common.c
index 2077228..466630e 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -100,45 +100,56 @@ void *r600_buffer_map_sync_with_rings(struct 
r600_common_context *ctx,
        return ctx->ws->buffer_map(resource->cs_buf, NULL, usage);
 }
 
+void r600_set_resource_placement(struct r600_resource *res)
+{
+       if (res->b.b.target == PIPE_BUFFER) {
+               /* Buffer placement is determined from the usage flag directly. 
*/
+               switch (res->b.b.usage) {
+               case PIPE_USAGE_IMMUTABLE:
+               case PIPE_USAGE_DEFAULT:
+               case PIPE_USAGE_STATIC:
+               default:
+                       /* Not listing GTT here improves performance in some 
apps. */
+                       res->domains = RADEON_DOMAIN_VRAM;
+                       break;
+               case PIPE_USAGE_DYNAMIC:
+               case PIPE_USAGE_STREAM:
+               case PIPE_USAGE_STAGING:
+                       /* These resources participate in transfers, i.e. are 
used
+                        * for uploads and downloads from regular resources. */
+                       res->domains = RADEON_DOMAIN_GTT;
+                       break;
+               }
+       } else {
+               /* Texture placement is determined from the tiling mode,
+                * which was determined from the usage flags. */
+               struct r600_texture *rtex = (struct r600_texture*)rtex;
+
+               if (rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D) {
+                       /* Tiled textures are unmappable. Always put them in 
VRAM. */
+                       res->domains = RADEON_DOMAIN_VRAM;
+               } else {
+                       /* Linear textures should be in GTT for Prime and 
texture
+                        * transfers. Also, why would anyone want to have a 
linear
+                        * texture in VRAM? */
+                       res->domains = RADEON_DOMAIN_GTT;
+               }
+       }
+}
+
 bool r600_init_resource(struct r600_common_screen *rscreen,
                        struct r600_resource *res,
                        unsigned size, unsigned alignment,
-                       bool use_reusable_pool, unsigned usage)
+                       bool use_reusable_pool)
 {
-       uint32_t initial_domain, domains;
-
-       switch(usage) {
-       case PIPE_USAGE_STAGING:
-       case PIPE_USAGE_DYNAMIC:
-       case PIPE_USAGE_STREAM:
-               /* These resources participate in transfers, i.e. are used
-                * for uploads and downloads from regular resources.
-                * We generate them internally for some transfers.
-                */
-               initial_domain = RADEON_DOMAIN_GTT;
-               domains = RADEON_DOMAIN_GTT;
-               break;
-       case PIPE_USAGE_DEFAULT:
-       case PIPE_USAGE_STATIC:
-       case PIPE_USAGE_IMMUTABLE:
-       default:
-               /* Don't list GTT here, because the memory manager would put 
some
-                * resources to GTT no matter what the initial domain is.
-                * Not listing GTT in the domains improves performance a lot. */
-               initial_domain = RADEON_DOMAIN_VRAM;
-               domains = RADEON_DOMAIN_VRAM;
-               break;
-       }
-
        res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment,
                                               use_reusable_pool,
-                                              initial_domain);
+                                              res->domains);
        if (!res->buf) {
                return false;
        }
 
        res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf);
-       res->domains = domains;
        util_range_set_empty(&res->valid_buffer_range);
 
        if (rscreen->debug_flags & DBG_VM && res->b.b.target == PIPE_BUFFER) {
@@ -327,7 +338,10 @@ struct pipe_resource *r600_buffer_create(struct 
pipe_screen *screen,
        rbuffer->b.vtbl = &r600_buffer_vtbl;
        util_range_init(&rbuffer->valid_buffer_range);
 
-       if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, 
TRUE, templ->usage)) {
+       /* Must be set before creating the buffer. */
+       r600_set_resource_placement(rbuffer);
+
+       if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, 
TRUE)) {
                FREE(rbuffer);
                return NULL;
        }
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h 
b/src/gallium/drivers/radeon/r600_pipe_common.h
index 9fdfdfd..97c5d6e 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -318,10 +318,11 @@ boolean r600_rings_is_buffer_referenced(struct 
r600_common_context *ctx,
 void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
                                       struct r600_resource *resource,
                                       unsigned usage);
+void r600_set_resource_placement(struct r600_resource *res);
 bool r600_init_resource(struct r600_common_screen *rscreen,
                        struct r600_resource *res,
                        unsigned size, unsigned alignment,
-                       bool use_reusable_pool, unsigned usage);
+                       bool use_reusable_pool);
 struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
                                         const struct pipe_resource *templ,
                                         unsigned alignment);
diff --git a/src/gallium/drivers/radeon/r600_texture.c 
b/src/gallium/drivers/radeon/r600_texture.c
index 878b26f..e05375d 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -614,20 +614,19 @@ r600_texture_create_object(struct pipe_screen *screen,
                }
        }
 
+       /* Must be set before creating the buffer. */
+       r600_set_resource_placement(resource);
+
        /* Now create the backing buffer. */
        if (!buf) {
-               unsigned base_align = rtex->surface.bo_alignment;
-               unsigned usage = rtex->surface.level[0].mode >= 
RADEON_SURF_MODE_1D ?
-                                        PIPE_USAGE_STATIC : base->usage;
-
-               if (!r600_init_resource(rscreen, resource, rtex->size, 
base_align, FALSE, usage)) {
+               if (!r600_init_resource(rscreen, resource, rtex->size,
+                                       rtex->surface.bo_alignment, FALSE)) {
                        FREE(rtex);
                        return NULL;
                }
        } else {
                resource->buf = buf;
                resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
-               resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
        }
 
        if (rtex->cmask.size) {
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c 
b/src/gallium/drivers/radeonsi/si_descriptors.c
index 9078c6c..f717371 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -706,8 +706,8 @@ static void si_invalidate_buffer(struct pipe_context *ctx, 
struct pipe_resource
        pb_reference(&rbuffer->buf, NULL);
 
        /* Create a new one in the same pipe_resource. */
-       r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0, 
alignment,
-                          TRUE, rbuffer->b.b.usage);
+       r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0,
+                          alignment, TRUE);
 
        /* We changed the buffer, now we need to bind it where the old one
         * was bound. This consists of 2 things:
-- 
1.8.3.2

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

Reply via email to