[Mesa-dev] [PATCH v2 16/25] winsys/amdgpu: add sparse buffer data structures

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


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

v2:
- remove pipe_mutex_*
- use a simple page commitment array
---
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.c |  9 ++++++++
 src/gallium/winsys/amdgpu/drm/amdgpu_bo.h | 38 ++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index c7dd116..f6e47bb 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
@@ -31,20 +31,25 @@
 
 #include "amdgpu_cs.h"
 
 #include "os/os_time.h"
 #include "state_tracker/drm_driver.h"
 #include <amdgpu_drm.h>
 #include <xf86drm.h>
 #include <stdio.h>
 #include <inttypes.h>
 
+
+struct amdgpu_sparse_backing_chunk {
+   uint32_t begin, end;
+};
+
 static struct pb_buffer *
 amdgpu_bo_create(struct radeon_winsys *rws,
                  uint64_t size,
                  unsigned alignment,
                  enum radeon_bo_domain domain,
                  enum radeon_bo_flag flags);
 
 static bool amdgpu_bo_wait(struct pb_buffer *_buf, uint64_t timeout,
                            enum radeon_bo_usage usage)
 {
@@ -203,20 +208,22 @@ static void *amdgpu_bo_map(struct pb_buffer *buf,
                            struct radeon_winsys_cs *rcs,
                            enum pipe_transfer_usage usage)
 {
    struct amdgpu_winsys_bo *bo = (struct amdgpu_winsys_bo*)buf;
    struct amdgpu_winsys_bo *real;
    struct amdgpu_cs *cs = (struct amdgpu_cs*)rcs;
    int r;
    void *cpu = NULL;
    uint64_t offset = 0;
 
+   assert(!bo->sparse);
+
    /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */
    if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
       /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */
       if (usage & PIPE_TRANSFER_DONTBLOCK) {
          if (!(usage & PIPE_TRANSFER_WRITE)) {
             /* Mapping for read.
              *
              * Since we are mapping for read, we don't need to wait
              * if the GPU is using the buffer for read too
              * (neither one is changing it).
@@ -315,20 +322,22 @@ static void *amdgpu_bo_map(struct pb_buffer *buf,
       real->ws->num_mapped_buffers++;
    }
    return (uint8_t*)cpu + offset;
 }
 
 static void amdgpu_bo_unmap(struct pb_buffer *buf)
 {
    struct amdgpu_winsys_bo *bo = (struct amdgpu_winsys_bo*)buf;
    struct amdgpu_winsys_bo *real;
 
+   assert(!bo->sparse);
+
    if (bo->user_ptr)
       return;
 
    real = bo->bo ? bo : bo->u.slab.real;
 
    if (p_atomic_dec_zero(&real->u.real.map_count)) {
       if (real->initial_domain & RADEON_DOMAIN_VRAM)
          real->ws->mapped_vram -= real->base.size;
       else if (real->initial_domain & RADEON_DOMAIN_GTT)
          real->ws->mapped_gtt -= real->base.size;
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
index 1e25897..1311344 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.h
@@ -30,42 +30,78 @@
  *      Marek Olšák <maraeo at gmail.com>
  */
 
 #ifndef AMDGPU_BO_H
 #define AMDGPU_BO_H
 
 #include "amdgpu_winsys.h"
 
 #include "pipebuffer/pb_slab.h"
 
+struct amdgpu_sparse_backing_chunk;
+
+/*
+ * Sub-allocation information for a real buffer used as backing memory of a
+ * sparse buffer.
+ */
+struct amdgpu_sparse_backing {
+   struct list_head list;
+
+   struct amdgpu_winsys_bo *bo;
+
+   /* Sorted list of free chunks. */
+   struct amdgpu_sparse_backing_chunk *chunks;
+   uint32_t max_chunks;
+   uint32_t num_chunks;
+};
+
+struct amdgpu_sparse_commitment {
+   struct amdgpu_sparse_backing *backing;
+   uint32_t page;
+};
+
 struct amdgpu_winsys_bo {
    struct pb_buffer base;
    union {
       struct {
          struct pb_cache_entry cache_entry;
 
          amdgpu_va_handle va_handle;
          int map_count;
          bool use_reusable_pool;
 
          struct list_head global_list_item;
       } real;
       struct {
          struct pb_slab_entry entry;
          struct amdgpu_winsys_bo *real;
       } slab;
+      struct {
+         mtx_t commit_lock;
+         amdgpu_va_handle va_handle;
+         enum radeon_bo_flag flags;
+
+         uint32_t num_va_pages;
+         uint32_t num_backing_pages;
+
+         struct list_head backing;
+
+         /* Commitment information for each page of the virtual memory area. */
+         struct amdgpu_sparse_commitment *commitments;
+      } sparse;
    } u;
 
    struct amdgpu_winsys *ws;
    void *user_ptr; /* from buffer_from_ptr */
 
-   amdgpu_bo_handle bo; /* NULL for slab entries */
+   amdgpu_bo_handle bo; /* NULL for slab entries and sparse buffers */
+   bool sparse;
    uint32_t unique_id;
    uint64_t va;
    enum radeon_bo_domain initial_domain;
 
    /* how many command streams is this bo referenced in? */
    int num_cs_references;
 
    /* how many command streams, which are being emitted in a separate
     * thread, is this bo referenced in? */
    volatile int num_active_ioctls;
-- 
2.9.3



More information about the mesa-dev mailing list