[Mesa-dev] [PATCH 06/12] winsys/amdgpu: extract adding a new buffer list entry into its own function

Nicolai Hähnle nhaehnle at gmail.com
Fri Sep 9 17:34:08 UTC 2016


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

While at it, try to be a little more robust in the face of memory allocation
failure.
---
 src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 113 ++++++++++++++++++------------
 1 file changed, 70 insertions(+), 43 deletions(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
index 7cbf19b..638c2d5 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
@@ -284,77 +284,104 @@ int amdgpu_lookup_buffer(struct amdgpu_cs_context *cs, struct amdgpu_winsys_bo *
           *         AAAAAAAAAAABBBBBBBBBBBBBBCCCCCCCC
           * will collide here: ^ and here:   ^,
           * meaning that we should get very few collisions in the end. */
          cs->buffer_indices_hashlist[hash] = i;
          return i;
       }
    }
    return -1;
 }
 
-static unsigned amdgpu_add_buffer(struct amdgpu_cs *acs,
-                                 struct amdgpu_winsys_bo *bo,
-                                 enum radeon_bo_usage usage,
-                                 enum radeon_bo_domain domains,
-                                 unsigned priority,
-                                 enum radeon_bo_domain *added_domains)
+static int
+amdgpu_lookup_or_add_buffer(struct amdgpu_cs_context *cs, struct amdgpu_winsys_bo *bo)
 {
-   struct amdgpu_cs_context *cs = acs->csc;
    struct amdgpu_cs_buffer *buffer;
-   unsigned hash = bo->unique_id & (ARRAY_SIZE(cs->buffer_indices_hashlist)-1);
-   int i = -1;
+   unsigned hash;
+   int idx = amdgpu_lookup_buffer(cs, bo);
 
-   assert(priority < 64);
-   *added_domains = 0;
-
-   i = amdgpu_lookup_buffer(cs, bo);
-
-   if (i >= 0) {
-      buffer = &cs->buffers[i];
-      buffer->priority_usage |= 1llu << priority;
-      buffer->usage |= usage;
-      *added_domains = domains & ~buffer->domains;
-      buffer->domains |= domains;
-      cs->flags[i] = MAX2(cs->flags[i], priority / 4);
-      return i;
-   }
+   if (idx >= 0)
+      return idx;
 
    /* New buffer, check if the backing array is large enough. */
    if (cs->num_buffers >= cs->max_num_buffers) {
-      uint32_t size;
-      cs->max_num_buffers += 10;
+      unsigned new_max =
+         MAX2(cs->max_num_buffers + 16, (unsigned)(cs->max_num_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) {
+         fprintf(stderr, "amdgpu_lookup_or_add_buffer: allocation failed\n");
+         FREE(new_buffers);
+         FREE(new_handles);
+         FREE(new_flags);
+         return -1;
+      }
 
-      size = cs->max_num_buffers * sizeof(struct amdgpu_cs_buffer);
-      cs->buffers = realloc(cs->buffers, size);
+      memcpy(new_buffers, cs->buffers, cs->num_buffers * sizeof(*new_buffers));
+      memcpy(new_handles, cs->handles, cs->num_buffers * sizeof(*new_handles));
+      memcpy(new_flags, cs->flags, cs->num_buffers * sizeof(*new_flags));
 
-      size = cs->max_num_buffers * sizeof(amdgpu_bo_handle);
-      cs->handles = realloc(cs->handles, size);
+      FREE(cs->buffers);
+      FREE(cs->handles);
+      FREE(cs->flags);
 
-      cs->flags = realloc(cs->flags, cs->max_num_buffers);
+      cs->max_num_buffers = new_max;
+      cs->buffers = new_buffers;
+      cs->handles = new_handles;
+      cs->flags = new_flags;
    }
 
-   /* Initialize the new buffer. */
-   cs->buffers[cs->num_buffers].bo = NULL;
-   amdgpu_winsys_bo_reference(&cs->buffers[cs->num_buffers].bo, bo);
-   cs->handles[cs->num_buffers] = bo->bo;
-   cs->flags[cs->num_buffers] = priority / 4;
+   idx = cs->num_buffers;
+   buffer = &cs->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);
-   buffer = &cs->buffers[cs->num_buffers];
-   buffer->bo = bo;
-   buffer->priority_usage = 1llu << priority;
-   buffer->usage = usage;
-   buffer->domains = domains;
+   cs->num_buffers++;
 
-   cs->buffer_indices_hashlist[hash] = cs->num_buffers;
+   hash = bo->unique_id & (ARRAY_SIZE(cs->buffer_indices_hashlist)-1);
+   cs->buffer_indices_hashlist[hash] = idx;
+
+   return idx;
+}
+
+static unsigned amdgpu_add_buffer(struct amdgpu_cs *acs,
+                                 struct amdgpu_winsys_bo *bo,
+                                 enum radeon_bo_usage usage,
+                                 enum radeon_bo_domain domains,
+                                 unsigned priority,
+                                 enum radeon_bo_domain *added_domains)
+{
+   struct amdgpu_cs_context *cs = acs->csc;
+   struct amdgpu_cs_buffer *buffer;
+   int i = amdgpu_lookup_or_add_buffer(cs, bo);
+
+   assert(priority < 64);
+
+   if (i < 0) {
+      *added_domains = 0;
+      return ~0;
+   }
 
-   *added_domains = domains;
-   return cs->num_buffers++;
+   buffer = &cs->buffers[i];
+   buffer->priority_usage |= 1llu << priority;
+   buffer->usage |= usage;
+   *added_domains = domains & ~buffer->domains;
+   buffer->domains |= domains;
+   cs->flags[i] = MAX2(cs->flags[i], priority / 4);
+   return i;
 }
 
 static unsigned amdgpu_cs_add_buffer(struct radeon_winsys_cs *rcs,
                                     struct pb_buffer *buf,
                                     enum radeon_bo_usage usage,
                                     enum radeon_bo_domain domains,
                                     enum radeon_bo_priority priority)
 {
    /* Don't use the "domains" parameter. Amdgpu doesn't support changing
     * the buffer placement during command submission.
-- 
2.7.4



More information about the mesa-dev mailing list