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