From 638d75185e66727faaba5dc2df1b6e14c7c0c075 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 3 Aug 2011 04:31:02 +0200 Subject: [PATCH] r600g: let radeon_winsys maintain the list of relocations Reviewed-by: Alex Deucher --- src/gallium/drivers/r600/r600.h | 3 +- .../winsys/r600/drm/evergreen_hw_context.c | 14 ++----- src/gallium/winsys/r600/drm/r600_hw_context.c | 37 +++++++---------- src/gallium/winsys/r600/drm/r600_priv.h | 1 + src/gallium/winsys/r600/drm/radeon_bo.c | 1 + src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 40 +++++++++++++++---- src/gallium/winsys/radeon/drm/radeon_winsys.h | 5 +++ 7 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 043215b3ec7..3ac60bce611 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -239,6 +239,7 @@ struct r600_query { struct r600_context { struct radeon *radeon; + struct radeon_winsys_cs *cs; struct r600_range *range; unsigned nblocks; struct r600_block **blocks; @@ -250,7 +251,7 @@ struct r600_context { unsigned pm4_dirty_cdwords; unsigned ctx_pm4_ndwords; unsigned init_dwords; - unsigned nreloc; + unsigned creloc; struct r600_reloc *reloc; struct radeon_bo **bo; diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c index df89047ebc5..3f6f8b5368b 100644 --- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c +++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c @@ -986,14 +986,10 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) if (r) goto out_err; + ctx->cs = radeon->ws->cs_create(radeon->ws); + /* allocate cs variables */ - ctx->nreloc = RADEON_CTX_MAX_PM4; - ctx->reloc = calloc(ctx->nreloc, sizeof(struct r600_reloc)); - if (ctx->reloc == NULL) { - r = -ENOMEM; - goto out_err; - } - ctx->bo = calloc(ctx->nreloc, sizeof(void *)); + ctx->bo = calloc(RADEON_CTX_MAX_PM4, sizeof(void *)); if (ctx->bo == NULL) { r = -ENOMEM; goto out_err; @@ -1146,10 +1142,6 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr if (draw->indices) { ndwords = 11; - /* make sure there is enough relocation space before scheduling draw */ - if (ctx->creloc >= (ctx->nreloc - 1)) { - r600_context_flush(ctx); - } } /* queries need some special values */ diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 4d8bb184cbd..bba55d68267 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -776,9 +776,9 @@ void r600_context_fini(struct r600_context *ctx) r600_free_resource_range(ctx, &ctx->fs_resources, ctx->num_fs_resources); free(ctx->range); free(ctx->blocks); - free(ctx->reloc); free(ctx->bo); free(ctx->pm4); + ctx->radeon->ws->cs_destroy(ctx->cs); memset(ctx, 0, sizeof(struct r600_context)); } @@ -912,14 +912,10 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) if (r) goto out_err; + ctx->cs = radeon->ws->cs_create(radeon->ws); + /* allocate cs variables */ - ctx->nreloc = RADEON_CTX_MAX_PM4; - ctx->reloc = calloc(ctx->nreloc, sizeof(struct r600_reloc)); - if (ctx->reloc == NULL) { - r = -ENOMEM; - goto out_err; - } - ctx->bo = calloc(ctx->nreloc, sizeof(void *)); + ctx->bo = calloc(RADEON_CTX_MAX_PM4, sizeof(void *)); if (ctx->bo == NULL) { r = -ENOMEM; goto out_err; @@ -1009,14 +1005,15 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, void r600_context_get_reloc(struct r600_context *ctx, struct r600_bo *rbo) { struct radeon_bo *bo = rbo->bo; - 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 = 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++; + + unsigned reloc_index = ctx->radeon->ws->trans_add_reloc(ctx->cs, bo->cs_buf, + rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM), + rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM), + (void**)&ctx->reloc, &ctx->creloc); + + bo->reloc = (void*)1; + bo->reloc_id = reloc_index * 4; + radeon_bo_reference(ctx->radeon, &ctx->bo[reloc_index], bo); } void r600_context_reg(struct r600_context *ctx, @@ -1444,10 +1441,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) if (draw->indices) { ndwords = 11; - /* make sure there is enough relocation space before scheduling draw */ - if (ctx->creloc >= (ctx->nreloc - 1)) { - r600_context_flush(ctx); - } } /* queries need some special values */ @@ -1570,6 +1563,7 @@ void r600_context_flush(struct r600_context *ctx) ctx->pm4_dirty_cdwords = 0; ctx->pm4_cdwords = 0; ctx->flags = 0; + ctx->radeon->ws->cs_flush(ctx->cs, 0); r600_init_cs(ctx); @@ -1601,8 +1595,7 @@ void r600_context_emit_fence(struct r600_context *ctx, struct r600_bo *fence_bo, { unsigned ndwords = 10; - if (((ctx->pm4_dirty_cdwords + ndwords + ctx->pm4_cdwords) > ctx->pm4_ndwords) || - (ctx->creloc >= (ctx->nreloc - 1))) { + if ((ctx->pm4_dirty_cdwords + ndwords + ctx->pm4_cdwords) > ctx->pm4_ndwords) { /* need to flush */ r600_context_flush(ctx); } diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 49d3060bbf2..baf7c98d578 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -65,6 +65,7 @@ struct r600_reg { struct radeon_bo { struct pipe_reference reference; struct pb_buffer *buf; + struct radeon_winsys_cs_handle *cs_buf; unsigned handle; unsigned size; int map_count; diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c index 63dc44ddb44..536bbe45bff 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo.c +++ b/src/gallium/winsys/r600/drm/radeon_bo.c @@ -94,6 +94,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, FREE(bo); return NULL; } + bo->cs_buf = radeon->ws->buffer_get_cs_handle(bo->buf); bo->handle = radeon->ws->trans_get_buffer_handle(bo->buf); bo->size = size; return bo; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 1b30b95a318..9a1e16957d2 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -219,11 +219,11 @@ int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo) return -1; } -static void radeon_add_reloc(struct radeon_cs_context *csc, - struct radeon_bo *bo, - enum radeon_bo_domain rd, - enum radeon_bo_domain wd, - enum radeon_bo_domain *added_domains) +static unsigned radeon_add_reloc(struct radeon_cs_context *csc, + struct radeon_bo *bo, + enum radeon_bo_domain rd, + enum radeon_bo_domain wd, + enum radeon_bo_domain *added_domains) { struct drm_radeon_cs_reloc *reloc; unsigned i; @@ -233,7 +233,7 @@ static void radeon_add_reloc(struct radeon_cs_context *csc, reloc = csc->relocs_hashlist[hash]; if (reloc->handle == bo->handle) { update_domains(reloc, rd, wd, added_domains); - return; + return csc->reloc_indices_hashlist[hash]; } /* Hash collision, look for the BO in the list of relocs linearly. */ @@ -246,7 +246,7 @@ static void radeon_add_reloc(struct radeon_cs_context *csc, csc->relocs_hashlist[hash] = reloc; csc->reloc_indices_hashlist[hash] = i; /*printf("write_reloc collision, hash: %i, handle: %i\n", hash, bo->handle);*/ - return; + return i; } } } @@ -280,9 +280,9 @@ static void radeon_add_reloc(struct radeon_cs_context *csc, csc->reloc_indices_hashlist[hash] = csc->crelocs; csc->chunks[1].length_dw += RELOC_DWORDS; - csc->crelocs++; *added_domains = rd | wd; + return csc->crelocs++; } static void radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs, @@ -470,6 +470,28 @@ static boolean radeon_bo_is_referenced(struct radeon_winsys_cs *rcs, return radeon_bo_is_referenced_by_cs(cs, bo); } +static unsigned trans_add_reloc(struct radeon_winsys_cs *rcs, + struct radeon_winsys_cs_handle *buf, + enum radeon_bo_domain rd, + enum radeon_bo_domain wd, + void **reloc_list, unsigned *reloc_count) +{ + struct radeon_drm_cs *cs = radeon_drm_cs(rcs); + struct radeon_bo *bo = (struct radeon_bo*)buf; + enum radeon_bo_domain added_domains; + + unsigned index = radeon_add_reloc(cs->csc, bo, rd, wd, &added_domains); + + if (added_domains & RADEON_DOMAIN_GTT) + cs->csc->used_gart += bo->size; + if (added_domains & RADEON_DOMAIN_VRAM) + cs->csc->used_vram += bo->size; + + *reloc_list = cs->csc->relocs; + *reloc_count = cs->csc->crelocs; + return index; +} + void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) { ws->base.cs_create = radeon_drm_cs_create; @@ -480,4 +502,6 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) ws->base.cs_flush = radeon_drm_cs_flush; ws->base.cs_set_flush = radeon_drm_cs_set_flush; ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced; + + ws->base.trans_add_reloc = trans_add_reloc; } diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 2e5000702e0..8e81fa1e301 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -329,6 +329,11 @@ struct radeon_winsys { /* Transitional functions for r600g when moving to winsys/radeon */ unsigned (*trans_get_buffer_handle)(struct pb_buffer *buf); + unsigned (*trans_add_reloc)(struct radeon_winsys_cs *cs, + struct radeon_winsys_cs_handle *buf, + enum radeon_bo_domain rd, + enum radeon_bo_domain wd, + void **reloc_list, unsigned *reloc_count); }; #endif -- 2.30.2