[Mesa-dev] [PATCH] r600g,radeonsi: set domains in one place; put DRI2 tiled textures in VRAM
Marek Olšák
maraeo at gmail.com
Tue Feb 4 20:42:18 CET 2014
From: Marek Olšák <marek.olsak at 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
More information about the mesa-dev
mailing list