r600g: let radeon_winsys maintain the list of relocations
authorMarek Olšák <maraeo@gmail.com>
Wed, 3 Aug 2011 02:31:02 +0000 (04:31 +0200)
committerMarek Olšák <maraeo@gmail.com>
Tue, 16 Aug 2011 07:15:10 +0000 (09:15 +0200)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/drivers/r600/r600.h
src/gallium/winsys/r600/drm/evergreen_hw_context.c
src/gallium/winsys/r600/drm/r600_hw_context.c
src/gallium/winsys/r600/drm/r600_priv.h
src/gallium/winsys/r600/drm/radeon_bo.c
src/gallium/winsys/radeon/drm/radeon_drm_cs.c
src/gallium/winsys/radeon/drm/radeon_winsys.h

index 043215b3ec77e13a354ea1fd558a78ad90829b2d..3ac60bce6111fc71e32e396b6a8700d4a627863a 100644 (file)
@@ -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;
index df89047ebc52899a52d66a61cefe268923c8462b..3f6f8b5368b5b64f2ba7a18cc6ec989ee05e788b 100644 (file)
@@ -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 */
index 4d8bb184cbd49e3121e40af9227e30c3cfb050b1..bba55d682677dba14e935ac9b6af8611ab7699b1 100644 (file)
@@ -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);
        }
index 49d3060bbf2a7acc8d69e91679eb938538cb93ec..baf7c98d5780e652fe3e5ef9e2bf9fa9291f69c8 100644 (file)
@@ -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;
index 63dc44ddb446f3c2f74b3e6d5180a810ca1a22e4..536bbe45bffcee1ede04e51682c9e6f976b61c4e 100644 (file)
@@ -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;
index 1b30b95a318eed67303a2103861a96e02324fe24..9a1e16957d20a8309ffda2b3411202255bb79e13 100644 (file)
@@ -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;
 }
index 2e5000702e032fef72abb051cb8a3b6ed2a9c59d..8e81fa1e3017e877bd133d555b89d0b43de31e70 100644 (file)
@@ -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