[Mesa-dev] [PATCH] winsys/amdgpu: optionally use buffer lists with all allocated buffers

Marek Olšák maraeo at gmail.com
Fri Jan 22 12:19:59 PST 2016


From: Marek Olšák <marek.olsak at amd.com>

Set RADEON_ALL_BOS=1 to use it.
---
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.c     | 21 +++++++++++++++++
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.h     |  2 ++
 src/gallium/winsys/amdgpu/drm/amdgpu_cs.c     | 33 ++++++++++++++++++++++++---
 src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c |  3 +++
 src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h |  5 ++++
 5 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index 82c803b..30a1aa8 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
@@ -128,6 +128,11 @@ void amdgpu_bo_destroy(struct pb_buffer *_buf)
    struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
    int i;
 
+   pipe_mutex_lock(bo->ws->global_bo_list_lock);
+   LIST_DEL(&bo->global_list_item);
+   bo->ws->num_buffers--;
+   pipe_mutex_unlock(bo->ws->global_bo_list_lock);
+
    amdgpu_bo_va_op(bo->bo, 0, bo->base.size, bo->va, 0, AMDGPU_VA_OP_UNMAP);
    amdgpu_va_range_free(bo->va_handle);
    amdgpu_bo_free(bo->bo);
@@ -249,6 +254,16 @@ static const struct pb_vtbl amdgpu_winsys_bo_vtbl = {
    /* other functions are never called */
 };
 
+static void amdgpu_add_buffer_to_global_list(struct amdgpu_winsys_bo *bo)
+{
+   struct amdgpu_winsys *ws = bo->ws;
+
+   pipe_mutex_lock(ws->global_bo_list_lock);
+   LIST_ADDTAIL(&bo->global_list_item, &ws->global_bo_list);
+   ws->num_buffers++;
+   pipe_mutex_unlock(ws->global_bo_list_lock);
+}
+
 static struct amdgpu_winsys_bo *amdgpu_create_bo(struct amdgpu_winsys *ws,
                                                  unsigned size,
                                                  unsigned alignment,
@@ -319,6 +334,8 @@ static struct amdgpu_winsys_bo *amdgpu_create_bo(struct amdgpu_winsys *ws,
    else if (initial_domain & RADEON_DOMAIN_GTT)
       ws->allocated_gtt += align(size, ws->gart_page_size);
 
+   amdgpu_add_buffer_to_global_list(bo);
+
    return bo;
 
 error_va_map:
@@ -588,6 +605,8 @@ static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws,
    else if (bo->initial_domain & RADEON_DOMAIN_GTT)
       ws->allocated_gtt += align(bo->base.size, ws->gart_page_size);
 
+   amdgpu_add_buffer_to_global_list(bo);
+
    return &bo->base;
 
 error_va_map:
@@ -673,6 +692,8 @@ static struct pb_buffer *amdgpu_bo_from_ptr(struct radeon_winsys *rws,
 
     ws->allocated_gtt += align(bo->base.size, ws->gart_page_size);
 
+    amdgpu_add_buffer_to_global_list(bo);
+
     return (struct pb_buffer*)bo;
 
 error_va_map:
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
index 12cb920..54f5dbd 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
@@ -60,6 +60,8 @@ struct amdgpu_winsys_bo {
 
    /* Fences for buffer synchronization. */
    struct pipe_fence_handle *fence[RING_LAST];
+
+   struct list_head global_list_item;
 };
 
 bool amdgpu_bo_can_reclaim(struct pb_buffer *_buf);
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
index 10f112d..83da740 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
@@ -605,6 +605,7 @@ static void amdgpu_cs_sync_flush(struct radeon_winsys_cs *rcs)
 }
 
 DEBUG_GET_ONCE_BOOL_OPTION(noop, "RADEON_NOOP", FALSE)
+DEBUG_GET_ONCE_BOOL_OPTION(all_bos, "RADEON_ALL_BOS", FALSE)
 
 static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
                             unsigned flags,
@@ -644,9 +645,35 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
    if (cs->base.cdw && cs->base.cdw <= cs->base.max_dw && !debug_get_option_noop()) {
       int r;
 
-      r = amdgpu_bo_list_create(ws->dev, cs->num_buffers,
-                                cs->handles, cs->flags,
-                                &cs->request.resources);
+      /* Use a buffer list containing all allocated buffers if requested. */
+      if (debug_get_option_all_bos()) {
+         struct amdgpu_winsys_bo *bo;
+         amdgpu_bo_handle *handles;
+         unsigned num = 0;
+
+         pipe_mutex_lock(ws->global_bo_list_lock);
+
+         handles = malloc(sizeof(handles[0]) * ws->num_buffers);
+         if (!handles) {
+            pipe_mutex_unlock(ws->global_bo_list_lock);
+            goto cleanup;
+         }
+
+         LIST_FOR_EACH_ENTRY(bo, &ws->global_bo_list, global_list_item) {
+            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);
+         pipe_mutex_unlock(ws->global_bo_list_lock);
+      } else {
+         r = amdgpu_bo_list_create(ws->dev, cs->num_buffers,
+                                   cs->handles, cs->flags,
+                                   &cs->request.resources);
+      }
 
       if (r) {
          fprintf(stderr, "amdgpu: resource list creation failed (%d)\n", r);
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
index 69df363..7393a1d 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
@@ -300,6 +300,7 @@ static void amdgpu_winsys_destroy(struct radeon_winsys *rws)
 
    pipe_mutex_destroy(ws->bo_fence_lock);
    pb_cache_deinit(&ws->bo_cache);
+   pipe_mutex_destroy(ws->global_bo_list_lock);
    AddrDestroy(ws->addrlib);
    amdgpu_device_deinitialize(ws->dev);
    FREE(rws);
@@ -472,6 +473,8 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create)
    amdgpu_cs_init_functions(ws);
    amdgpu_surface_init_functions(ws);
 
+   LIST_INITHEAD(&ws->global_bo_list);
+   pipe_mutex_init(ws->global_bo_list_lock);
    pipe_mutex_init(ws->bo_fence_lock);
 
    /* Create the screen at the end. The winsys must be initialized
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h
index 615f554..91b9be4 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h
@@ -63,6 +63,11 @@ struct amdgpu_winsys {
    ADDR_HANDLE addrlib;
    uint32_t rev_id;
    unsigned family;
+
+   /* List of all allocated buffers */
+   pipe_mutex global_bo_list_lock;
+   struct list_head global_bo_list;
+   unsigned num_buffers;
 };
 
 static inline struct amdgpu_winsys *
-- 
2.1.4



More information about the mesa-dev mailing list