[Mesa-dev] [PATCH 06/14] winsys/amdgpu: add slab entry structures to amdgpu_winsys_bo

Marek Olšák maraeo at gmail.com
Sat Sep 17 15:06:58 UTC 2016


On Sat, Sep 17, 2016 at 4:46 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> On 17.09.2016 15:19, Marek Olšák wrote:
>>
>> On Tue, Sep 13, 2016 at 11:56 AM, Nicolai Hähnle <nhaehnle at gmail.com>
>> wrote:
>>>
>>> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>>>
>>> Already adjust amdgpu_bo_map/unmap accordingly.
>>> ---
>>>  src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 83
>>> ++++++++++++++++++++-----------
>>>  src/gallium/winsys/amdgpu/drm/amdgpu_bo.h | 25 +++++++---
>>>  src/gallium/winsys/amdgpu/drm/amdgpu_cs.c |  2 +-
>>>  3 files changed, 74 insertions(+), 36 deletions(-)
>>>
>>> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>>> b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>>> index 37a7ba1..f581d9b 100644
>>> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>>> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>>> @@ -144,64 +144,70 @@ static void amdgpu_bo_remove_fences(struct
>>> amdgpu_winsys_bo *bo)
>>>
>>>     FREE(bo->fences);
>>>     bo->num_fences = 0;
>>>     bo->max_fences = 0;
>>>  }
>>>
>>>  void amdgpu_bo_destroy(struct pb_buffer *_buf)
>>>  {
>>>     struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
>>>
>>> +   assert(bo->bo && "must not be called for slab entries");
>>> +
>>>     pipe_mutex_lock(bo->ws->global_bo_list_lock);
>>> -   LIST_DEL(&bo->global_list_item);
>>> +   LIST_DEL(&bo->u.real.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_va_range_free(bo->u.real.va_handle);
>>>     amdgpu_bo_free(bo->bo);
>>>
>>>     amdgpu_bo_remove_fences(bo);
>>>
>>>     if (bo->initial_domain & RADEON_DOMAIN_VRAM)
>>>        bo->ws->allocated_vram -= align64(bo->base.size,
>>> bo->ws->info.gart_page_size);
>>>     else if (bo->initial_domain & RADEON_DOMAIN_GTT)
>>>        bo->ws->allocated_gtt -= align64(bo->base.size,
>>> bo->ws->info.gart_page_size);
>>>
>>> -   if (bo->map_count >= 1) {
>>> +   if (bo->u.real.map_count >= 1) {
>>>        if (bo->initial_domain & RADEON_DOMAIN_VRAM)
>>>           bo->ws->mapped_vram -= bo->base.size;
>>>        else if (bo->initial_domain & RADEON_DOMAIN_GTT)
>>>           bo->ws->mapped_gtt -= bo->base.size;
>>>     }
>>>
>>>     FREE(bo);
>>>  }
>>>
>>>  static void amdgpu_bo_destroy_or_cache(struct pb_buffer *_buf)
>>>  {
>>>     struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
>>>
>>> -   if (bo->use_reusable_pool)
>>> -      pb_cache_add_buffer(&bo->cache_entry);
>>> +   assert(bo->bo); /* slab buffers have a separate vtbl */
>>> +
>>> +   if (bo->u.real.use_reusable_pool)
>>> +      pb_cache_add_buffer(&bo->u.real.cache_entry);
>>>     else
>>>        amdgpu_bo_destroy(_buf);
>>>  }
>>>
>>>  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;
>>>
>>>     /* 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
>>> @@ -265,68 +271,80 @@ static void *amdgpu_bo_map(struct pb_buffer *buf,
>>>              amdgpu_bo_wait((struct pb_buffer*)bo, PIPE_TIMEOUT_INFINITE,
>>>                             RADEON_USAGE_READWRITE);
>>>           }
>>>
>>>           bo->ws->buffer_wait_time += os_time_get_nano() - time;
>>>        }
>>>     }
>>>
>>>     /* If the buffer is created from user memory, return the user
>>> pointer. */
>>>     if (bo->user_ptr)
>>> -       return bo->user_ptr;
>>> +      return bo->user_ptr;
>>> +
>>> +   if (bo->bo) {
>>> +      real = bo;
>>> +   } else {
>>> +      real = bo->u.slab.real;
>>> +      offset = bo->va - real->va;
>>> +   }
>>>
>>> -   r = amdgpu_bo_cpu_map(bo->bo, &cpu);
>>> +   r = amdgpu_bo_cpu_map(real->bo, &cpu);
>>>     if (r) {
>>>        /* Clear the cache and try again. */
>>> -      pb_cache_release_all_buffers(&bo->ws->bo_cache);
>>> -      r = amdgpu_bo_cpu_map(bo->bo, &cpu);
>>> +      pb_cache_release_all_buffers(&real->ws->bo_cache);
>>> +      r = amdgpu_bo_cpu_map(real->bo, &cpu);
>>>        if (r)
>>>           return NULL;
>>>     }
>>>
>>> -   if (p_atomic_inc_return(&bo->map_count) == 1) {
>>> -      if (bo->initial_domain & RADEON_DOMAIN_VRAM)
>>> -         bo->ws->mapped_vram += bo->base.size;
>>> -      else if (bo->initial_domain & RADEON_DOMAIN_GTT)
>>> -         bo->ws->mapped_gtt += bo->base.size;
>>> +   if (p_atomic_inc_return(&real->u.real.map_count) == 1) {
>>> +      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;
>>>     }
>>> -   return cpu;
>>> +   return cpu + offset;
>>
>>
>> It should be: (uint8_t*)cpu + offset;
>
>
> Is there really a difference between void* and uint8_t* here?

Arithmetic on void pointers is illegal according to C and C++
standards. It's a GCC extension. I don't know if clang allows it.

Marek


More information about the mesa-dev mailing list