Mesa (amdgpu): winsys/amdgpu: allocate IBs like normal buffers

Alex Deucher agd5f at kemper.freedesktop.org
Thu Jun 4 01:07:09 UTC 2015


Module: Mesa
Branch: amdgpu
Commit: 3e6c7a2892fc05a8e1e368878f35d7968d630742
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3e6c7a2892fc05a8e1e368878f35d7968d630742

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Fri May 29 12:58:17 2015 +0200

winsys/amdgpu: allocate IBs like normal buffers

There is a big IB buffer whose size is 256KB and normal IBs are allocated
from it. Each driver command stream (CS) has its own big IB buffer.

The maximum size of allocated IBs from the big buffer is 64KB.
(so there's a minimum of 4 IBs per buffer)

However, the size is determined when flushing, so if the used size is only
1KB, the next IB will start after the 1KB.

After the big IB buffer is all used, another one is allocated or reused.
The reusing is done by the buffer allocator itself.

Reviewed-by: Christian König <christian.koenig at amd.com>

---

 src/gallium/winsys/amdgpu/drm/amdgpu_cs.c |   54 +++++++++++++++++++++++------
 src/gallium/winsys/amdgpu/drm/amdgpu_cs.h |    9 +++++
 2 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
index 7064474..05720ef 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
@@ -179,17 +179,44 @@ amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx)
 static bool amdgpu_get_new_ib(struct amdgpu_cs *cs)
 {
    struct amdgpu_cs_context *cur_cs = cs->csc;
-   struct amdgpu_cs_ib_alloc_result ib;
-   int r;
-
-   r = amdgpu_cs_alloc_ib(cs->ctx->ctx, amdgpu_cs_ib_size_64K, &ib);
-   if (r)
-      return false;
+   unsigned max_ib_size = RADEON_MAX_CMDBUF_DWORDS * 4;
 
-   cs->base.buf = ib.cpu;
    cs->base.cdw = 0;
+   cs->base.buf = NULL;
+
+   /* Allocate a new buffer for IBs if the current buffer is all used. */
+   if (!cs->big_ib_buffer ||
+       cs->used_ib_space + max_ib_size > cs->big_ib_buffer->size) {
+      struct radeon_winsys *ws = &cs->ctx->ws->base;
+      struct radeon_winsys_cs_handle *winsys_bo;
+
+      pb_reference(&cs->big_ib_buffer, NULL);
+      cs->big_ib_winsys_buffer = NULL;
+      cs->ib_mapped = NULL;
+      cs->used_ib_space = 0;
+
+      cs->big_ib_buffer = ws->buffer_create(ws, 256 * 1024, 4096, true,
+                                            RADEON_DOMAIN_GTT,
+                                            RADEON_FLAG_CPU_ACCESS);
+      if (!cs->big_ib_buffer)
+         return false;
+
+      winsys_bo = ws->buffer_get_cs_handle(cs->big_ib_buffer);
+
+      cs->ib_mapped = ws->buffer_map(winsys_bo, NULL, PIPE_TRANSFER_WRITE);
+      if (!cs->ib_mapped) {
+         pb_reference(&cs->big_ib_buffer, NULL);
+         return false;
+      }
+
+      cs->big_ib_winsys_buffer = (struct amdgpu_winsys_bo*)winsys_bo;
+   }
 
-   cur_cs->ib.ib_handle = ib.handle;
+   pb_reference(&cur_cs->ib_buffer, cs->big_ib_buffer);
+   cur_cs->ib_winsys_buffer = cs->big_ib_winsys_buffer;
+   cur_cs->ib.bo_handle = cs->big_ib_winsys_buffer->bo;
+   cur_cs->ib.offset_dw = cs->used_ib_space / 4;
+   cs->base.buf = (uint32_t*)(cs->ib_mapped + cs->used_ib_space);
    return true;
 }
 
@@ -250,6 +277,7 @@ static void amdgpu_cs_context_cleanup(struct amdgpu_cs_context *csc)
 static void amdgpu_destroy_cs_context(struct amdgpu_cs_context *csc)
 {
    amdgpu_cs_context_cleanup(csc);
+   pb_reference(&csc->ib_buffer, NULL);
    FREE(csc->flags);
    FREE(csc->buffers);
    FREE(csc->handles);
@@ -451,15 +479,17 @@ void amdgpu_cs_emit_ioctl_oneshot(struct amdgpu_cs *cs, struct amdgpu_cs_context
       for (i = 0; i < csc->num_buffers; i++) {
          amdgpu_fence_reference(&csc->buffers[i].bo->fence, csc->fence);
       }
+      amdgpu_fence_reference(&csc->ib_winsys_buffer->fence, csc->fence);
    }
 
    /* Cleanup. */
-   if (cs->cst->request.resources)
-      amdgpu_bo_list_destroy(cs->cst->request.resources);
+   if (csc->request.resources)
+      amdgpu_bo_list_destroy(csc->request.resources);
 
    for (i = 0; i < csc->num_buffers; i++) {
       p_atomic_dec(&csc->buffers[i].bo->num_active_ioctls);
    }
+   p_atomic_dec(&csc->ib_winsys_buffer->num_active_ioctls);
    amdgpu_cs_context_cleanup(csc);
 }
 
@@ -545,11 +575,13 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
       }
 
       cs->cst->ib.size = cs->base.cdw;
+      cs->used_ib_space += cs->base.cdw * 4;
 
       for (i = 0; i < num_buffers; i++) {
          /* Update the number of active asynchronous CS ioctls for the buffer. */
          p_atomic_inc(&cs->cst->buffers[i].bo->num_active_ioctls);
       }
+      p_atomic_inc(&cs->cst->ib_winsys_buffer->num_active_ioctls);
 
       switch (cs->base.ring_type) {
       case RING_DMA:
@@ -608,9 +640,9 @@ static void amdgpu_cs_destroy(struct radeon_winsys_cs *rcs)
    amdgpu_cs_context_cleanup(&cs->csc1);
    amdgpu_cs_context_cleanup(&cs->csc2);
    p_atomic_dec(&cs->ctx->ws->num_cs);
-   amdgpu_cs_free_ib(cs->csc->ib.ib_handle);
    amdgpu_destroy_cs_context(&cs->csc1);
    amdgpu_destroy_cs_context(&cs->csc2);
+   pb_reference(&cs->big_ib_buffer, NULL);
    FREE(cs);
 }
 
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
index 781ad19..43ceec2 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
@@ -50,6 +50,9 @@ struct amdgpu_cs_buffer {
 struct amdgpu_cs_context {
    struct amdgpu_cs_request    request;
    struct amdgpu_cs_ib_info    ib;
+   /* just for holding the buffer reference during thread offloading */
+   struct pb_buffer            *ib_buffer;
+   struct amdgpu_winsys_bo     *ib_winsys_buffer;
 
    /* Relocs. */
    unsigned                    max_num_buffers;
@@ -86,6 +89,12 @@ struct amdgpu_cs {
    void *flush_data;
 
    pipe_semaphore flush_completed;
+
+   /* A buffer out of which new IBs are allocated. */
+   struct pb_buffer *big_ib_buffer; /* for holding the reference */
+   struct amdgpu_winsys_bo *big_ib_winsys_buffer;
+   uint8_t *ib_mapped;
+   unsigned used_ib_space;
 };
 
 struct amdgpu_fence {




More information about the mesa-commit mailing list