winsys/amdgpu: optionally use buffer lists with all allocated buffers
authorMarek Olšák <marek.olsak@amd.com>
Thu, 14 Jan 2016 18:31:18 +0000 (19:31 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 23 Jan 2016 16:01:54 +0000 (17:01 +0100)
Set RADEON_ALL_BOS=1 to use it.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h

index 82c803b564d5149dbe6efa478d24e2194984db72..30a1aa8d6ba35d187bc8a06f4ffef8d533b11d4d 100644 (file)
@@ -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:
index 12cb920b38730d78067afd836a395fbbdb0295b0..54f5dbdc4592640a8112a68abfa8aab2e26a070a 100644 (file)
@@ -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);
index 10f112d01b321c60cf135dad925babe14bbb0a2c..83da740f649f94a98bdba6fba54e08e85bd67b79 100644 (file)
@@ -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);
index 69df363b6d64fae46cbc6c741d8ba12c309829ef..7393a1d1eb409451752216d41e13782c2fe291e0 100644 (file)
@@ -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
index 615f55411f8c8d9d6f853ead2ebd04614f9864e5..91b9be4bb3222ef926b7c000bc48ec9584228092 100644 (file)
@@ -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 *