From: Nicolai Hähnle <nicolai.haeh...@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 <mar...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev