[Mesa-dev] [PATCH v2 14/25] winsys/amdgpu: build handles and flags list late on submit thread

Nicolai Hähnle nhaehnle at gmail.com
Tue Mar 28 09:12:04 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

This probably has only minor performance effects, but it simplifies some
subsequent code slightly.

Ideally, it could also be used to simplify the handling of slab buffers
in the same way, but unfortunately that's not possible as long as we need
indices for relocations.
---
 src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 41 +++++++++++++++++++------------
 src/gallium/winsys/amdgpu/drm/amdgpu_cs.h |  4 ++-
 2 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
index 2520aff..e2d3a45 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
@@ -318,56 +318,42 @@ static int
 amdgpu_do_add_real_buffer(struct amdgpu_cs_context *cs, struct amdgpu_winsys_bo *bo)
 {
    struct amdgpu_cs_buffer *buffer;
    int idx;
 
    /* New buffer, check if the backing array is large enough. */
    if (cs->num_real_buffers >= cs->max_real_buffers) {
       unsigned new_max =
          MAX2(cs->max_real_buffers + 16, (unsigned)(cs->max_real_buffers * 1.3));
       struct amdgpu_cs_buffer *new_buffers;
-      amdgpu_bo_handle *new_handles;
-      uint8_t *new_flags;
 
       new_buffers = MALLOC(new_max * sizeof(*new_buffers));
-      new_handles = MALLOC(new_max * sizeof(*new_handles));
-      new_flags = MALLOC(new_max * sizeof(*new_flags));
 
-      if (!new_buffers || !new_handles || !new_flags) {
+      if (!new_buffers) {
          fprintf(stderr, "amdgpu_do_add_buffer: allocation failed\n");
          FREE(new_buffers);
-         FREE(new_handles);
-         FREE(new_flags);
          return -1;
       }
 
       memcpy(new_buffers, cs->real_buffers, cs->num_real_buffers * sizeof(*new_buffers));
-      memcpy(new_handles, cs->handles, cs->num_real_buffers * sizeof(*new_handles));
-      memcpy(new_flags, cs->flags, cs->num_real_buffers * sizeof(*new_flags));
 
       FREE(cs->real_buffers);
-      FREE(cs->handles);
-      FREE(cs->flags);
 
       cs->max_real_buffers = new_max;
       cs->real_buffers = new_buffers;
-      cs->handles = new_handles;
-      cs->flags = new_flags;
    }
 
    idx = cs->num_real_buffers;
    buffer = &cs->real_buffers[idx];
 
    memset(buffer, 0, sizeof(*buffer));
    amdgpu_winsys_bo_reference(&buffer->bo, bo);
-   cs->handles[idx] = bo->bo;
-   cs->flags[idx] = 0;
    p_atomic_inc(&bo->num_cs_references);
    cs->num_real_buffers++;
 
    return idx;
 }
 
 static int
 amdgpu_lookup_or_add_real_buffer(struct amdgpu_cs *acs, struct amdgpu_winsys_bo *bo)
 {
    struct amdgpu_cs_context *cs = acs->csc;
@@ -475,21 +461,20 @@ static unsigned amdgpu_cs_add_buffer(struct radeon_winsys_cs *rcs,
       index = buffer->u.slab.real_idx;
    } else {
       index = amdgpu_lookup_or_add_real_buffer(acs, bo);
       if (index < 0)
          return 0;
    }
 
    buffer = &cs->real_buffers[index];
    buffer->u.real.priority_usage |= 1llu << priority;
    buffer->usage |= usage;
-   cs->flags[index] = MAX2(cs->flags[index], priority / 4);
 
    cs->last_added_bo = bo;
    cs->last_added_bo_index = index;
    cs->last_added_bo_usage = buffer->usage;
    cs->last_added_bo_priority_usage = buffer->u.real.priority_usage;
    return index;
 }
 
 static bool amdgpu_ib_new_buffer(struct amdgpu_winsys *ws, struct amdgpu_ib *ib)
 {
@@ -1057,24 +1042,48 @@ void amdgpu_cs_submit_ib(void *job, int thread_index)
          assert(num < ws->num_buffers);
          handles[num++] = bo->bo;
       }
 
       r = amdgpu_bo_list_create(ws->dev, ws->num_buffers,
                                 handles, NULL,
                                 &cs->request.resources);
       free(handles);
       mtx_unlock(&ws->global_bo_list_lock);
    } else {
+      if (cs->max_real_submit < cs->num_real_buffers) {
+         FREE(cs->handles);
+         FREE(cs->flags);
+
+         cs->handles = MALLOC(sizeof(*cs->handles) * cs->num_real_buffers);
+         cs->flags = MALLOC(sizeof(*cs->flags) * cs->num_real_buffers);
+
+         if (!cs->handles || !cs->flags) {
+            cs->max_real_submit = 0;
+            r = -ENOMEM;
+            goto bo_list_error;
+         }
+      }
+
+      for (i = 0; i < cs->num_real_buffers; ++i) {
+         struct amdgpu_cs_buffer *buffer = &cs->real_buffers[i];
+
+         assert(buffer->u.real.priority_usage != 0);
+
+         cs->handles[i] = buffer->bo->bo;
+         cs->flags[i] = (util_last_bit64(buffer->u.real.priority_usage) - 1) / 4;
+      }
+
       r = amdgpu_bo_list_create(ws->dev, cs->num_real_buffers,
                                 cs->handles, cs->flags,
                                 &cs->request.resources);
    }
+bo_list_error:
 
    if (r) {
       fprintf(stderr, "amdgpu: buffer list creation failed (%d)\n", r);
       cs->request.resources = NULL;
       amdgpu_fence_signalled(cs->fence);
       cs->error_code = r;
       goto cleanup;
    }
 
    if (acs->ctx->num_rejected_cs)
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
index 495d55b..bdf7cb2 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
@@ -77,23 +77,25 @@ struct amdgpu_ib {
    enum ib_type            ib_type;
 };
 
 struct amdgpu_cs_context {
    struct amdgpu_cs_request    request;
    struct amdgpu_cs_ib_info    ib[IB_NUM];
 
    /* Buffers. */
    unsigned                    max_real_buffers;
    unsigned                    num_real_buffers;
+   struct amdgpu_cs_buffer     *real_buffers;
+
+   unsigned                    max_real_submit;
    amdgpu_bo_handle            *handles;
    uint8_t                     *flags;
-   struct amdgpu_cs_buffer     *real_buffers;
 
    unsigned                    num_slab_buffers;
    unsigned                    max_slab_buffers;
    struct amdgpu_cs_buffer     *slab_buffers;
 
    int                         buffer_indices_hashlist[4096];
 
    struct amdgpu_winsys_bo     *last_added_bo;
    unsigned                    last_added_bo_index;
    unsigned                    last_added_bo_usage;
-- 
2.9.3



More information about the mesa-dev mailing list