[Mesa-dev] [PATCH 4/4] winsys/amdgpu: fix VDPAU interop by having one amdgpu_winsys_bo per BO

Leo Liu leo.liu at amd.com
Wed Jul 18 13:36:06 UTC 2018


The series are

Acked-by: Leo Liu <leo.liu at amd.com>


On 07/16/2018 06:03 PM, Leo Liu wrote:
>
>
> On 2018-07-16 04:01 PM, Marek Olšák wrote:
>> From: Marek Olšák <marek.olsak at amd.com>
>>
>> Dependencies between rings are inserted correctly if a buffer is
>> represented by only one unique amdgpu_winsys_bo instance.
>> Use a hash table keyed by amdgpu_bo_handle to have exactly one
>> amdgpu_winsys_bo per amdgpu_bo_handle.
> The series are:
> Tested-by: Leo Liu <leo.liu at amd.com>
>
>>
>> v2: return offset and stride properly
>> ---
>>   src/gallium/winsys/amdgpu/drm/amdgpu_bo.c     | 36 ++++++++++++++++---
>>   src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c |  5 +++
>>   src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h |  5 +++
>>   3 files changed, 41 insertions(+), 5 deletions(-)
>>
>> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c 
>> b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>> index d9192c209e2..80563d3df98 100644
>> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
>> @@ -21,20 +21,21 @@
>>    * USE OR OTHER DEALINGS IN THE SOFTWARE.
>>    *
>>    * The above copyright notice and this permission notice (including 
>> the
>>    * next paragraph) shall be included in all copies or substantial 
>> portions
>>    * of the Software.
>>    */
>>     #include "amdgpu_cs.h"
>>     #include "util/os_time.h"
>> +#include "util/u_hash_table.h"
>>   #include "state_tracker/drm_driver.h"
>>   #include <amdgpu_drm.h>
>>   #include <xf86drm.h>
>>   #include <stdio.h>
>>   #include <inttypes.h>
>>     #ifndef AMDGPU_GEM_CREATE_VM_ALWAYS_VALID
>>   #define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6)
>>   #endif
>>   @@ -172,20 +173,24 @@ void amdgpu_bo_destroy(struct pb_buffer *_buf)
>>        assert(bo->bo && "must not be called for slab entries");
>>        if (ws->debug_all_bos) {
>>         simple_mtx_lock(&ws->global_bo_list_lock);
>>         LIST_DEL(&bo->u.real.global_list_item);
>>         ws->num_buffers--;
>>         simple_mtx_unlock(&ws->global_bo_list_lock);
>>      }
>>   +   simple_mtx_lock(&ws->bo_export_table_lock);
>> +   util_hash_table_remove(ws->bo_export_table, bo->bo);
>> +   simple_mtx_unlock(&ws->bo_export_table_lock);
>> +
>>      amdgpu_bo_va_op(bo->bo, 0, bo->base.size, bo->va, 0, 
>> AMDGPU_VA_OP_UNMAP);
>>      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)
>>         ws->allocated_vram -= align64(bo->base.size, 
>> ws->info.gart_page_size);
>>      else if (bo->initial_domain & RADEON_DOMAIN_GTT)
>>         ws->allocated_gtt -= align64(bo->base.size, 
>> ws->info.gart_page_size);
>> @@ -1278,24 +1283,41 @@ static struct pb_buffer 
>> *amdgpu_bo_from_handle(struct radeon_winsys *rws,
>>      case WINSYS_HANDLE_TYPE_SHARED:
>>         type = amdgpu_bo_handle_type_gem_flink_name;
>>         break;
>>      case WINSYS_HANDLE_TYPE_FD:
>>         type = amdgpu_bo_handle_type_dma_buf_fd;
>>         break;
>>      default:
>>         return NULL;
>>      }
>>   +   if (stride)
>> +      *stride = whandle->stride;
>> +   if (offset)
>> +      *offset = whandle->offset;
>> +
>>      r = amdgpu_bo_import(ws->dev, type, whandle->handle, &result);
>>      if (r)
>>         return NULL;
>>   +   simple_mtx_lock(&ws->bo_export_table_lock);
>> +   bo = util_hash_table_get(ws->bo_export_table, result.buf_handle);
>> +
>> +   /* If the amdgpu_winsys_bo instance already exists, bump the 
>> reference
>> +    * counter and return it.
>> +    */
>> +   if (bo) {
>> +      p_atomic_inc(&bo->base.reference.count);
>> +      simple_mtx_unlock(&ws->bo_export_table_lock);
>> +      return &bo->base;
>> +   }
>> +
>>      /* Get initial domains. */
>>      r = amdgpu_bo_query_info(result.buf_handle, &info);
>>      if (r)
>>         goto error;
>>        r = amdgpu_va_range_alloc(ws->dev, amdgpu_gpu_va_range_general,
>>                                result.alloc_size, 1 << 20, 0, &va, 
>> &va_handle,
>>                    AMDGPU_VA_RANGE_HIGH);
>>      if (r)
>>         goto error;
>> @@ -1319,49 +1341,49 @@ static struct pb_buffer 
>> *amdgpu_bo_from_handle(struct radeon_winsys *rws,
>>      bo->bo = result.buf_handle;
>>      bo->base.size = result.alloc_size;
>>      bo->base.vtbl = &amdgpu_winsys_bo_vtbl;
>>      bo->ws = ws;
>>      bo->va = va;
>>      bo->u.real.va_handle = va_handle;
>>      bo->initial_domain = initial;
>>      bo->unique_id = __sync_fetch_and_add(&ws->next_bo_unique_id, 1);
>>      bo->is_shared = true;
>>   -   if (stride)
>> -      *stride = whandle->stride;
>> -   if (offset)
>> -      *offset = whandle->offset;
>> -
>>      if (bo->initial_domain & RADEON_DOMAIN_VRAM)
>>         ws->allocated_vram += align64(bo->base.size, 
>> ws->info.gart_page_size);
>>      else if (bo->initial_domain & RADEON_DOMAIN_GTT)
>>         ws->allocated_gtt += align64(bo->base.size, 
>> ws->info.gart_page_size);
>>        amdgpu_add_buffer_to_global_list(bo);
>>   +   util_hash_table_set(ws->bo_export_table, bo->bo, bo);
>> +   simple_mtx_unlock(&ws->bo_export_table_lock);
>> +
>>      return &bo->base;
>>     error:
>> +   simple_mtx_unlock(&ws->bo_export_table_lock);
>>      if (bo)
>>         FREE(bo);
>>      if (va_handle)
>>         amdgpu_va_range_free(va_handle);
>>      amdgpu_bo_free(result.buf_handle);
>>      return NULL;
>>   }
>>     static bool amdgpu_bo_get_handle(struct pb_buffer *buffer,
>>                                    unsigned stride, unsigned offset,
>>                                    unsigned slice_size,
>>                                    struct winsys_handle *whandle)
>>   {
>>      struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(buffer);
>> +   struct amdgpu_winsys *ws = bo->ws;
>>      enum amdgpu_bo_handle_type type;
>>      int r;
>>        /* Don't allow exports of slab entries and sparse buffers. */
>>      if (!bo->bo)
>>         return false;
>>        bo->u.real.use_reusable_pool = false;
>>        switch (whandle->type) {
>> @@ -1375,20 +1397,24 @@ static bool amdgpu_bo_get_handle(struct 
>> pb_buffer *buffer,
>>         type = amdgpu_bo_handle_type_kms;
>>         break;
>>      default:
>>         return false;
>>      }
>>        r = amdgpu_bo_export(bo->bo, type, &whandle->handle);
>>      if (r)
>>         return false;
>>   +   simple_mtx_lock(&ws->bo_export_table_lock);
>> +   util_hash_table_set(ws->bo_export_table, bo->bo, bo);
>> +   simple_mtx_unlock(&ws->bo_export_table_lock);
>> +
>>      whandle->stride = stride;
>>      whandle->offset = offset;
>>      whandle->offset += slice_size * whandle->layer;
>>      bo->is_shared = true;
>>      return true;
>>   }
>>     static struct pb_buffer *amdgpu_bo_from_ptr(struct radeon_winsys 
>> *rws,
>>                           void *pointer, uint64_t size)
>>   {
>> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c 
>> b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
>> index db7a4d7033c..882f500bc69 100644
>> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
>> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
>> @@ -85,21 +85,23 @@ static void amdgpu_winsys_destroy(struct 
>> radeon_winsys *rws)
>>        if (ws->reserve_vmid)
>>         amdgpu_vm_unreserve_vmid(ws->dev, 0);
>>        if (util_queue_is_initialized(&ws->cs_queue))
>>         util_queue_destroy(&ws->cs_queue);
>>        simple_mtx_destroy(&ws->bo_fence_lock);
>>      pb_slabs_deinit(&ws->bo_slabs);
>>      pb_cache_deinit(&ws->bo_cache);
>> +   util_hash_table_destroy(ws->bo_export_table);
>>      simple_mtx_destroy(&ws->global_bo_list_lock);
>> +   simple_mtx_destroy(&ws->bo_export_table_lock);
>>      do_winsys_deinit(ws);
>>      FREE(rws);
>>   }
>>     static void amdgpu_winsys_query_info(struct radeon_winsys *rws,
>>                                        struct radeon_info *info)
>>   {
>>      *info = ((struct amdgpu_winsys *)rws)->info;
>>   }
>>   @@ -307,22 +309,25 @@ amdgpu_winsys_create(int fd, const struct 
>> pipe_screen_config *config,
>>      ws->base.cs_request_feature = amdgpu_cs_request_feature;
>>      ws->base.query_value = amdgpu_query_value;
>>      ws->base.read_registers = amdgpu_read_registers;
>>      ws->base.get_chip_name = amdgpu_get_chip_name;
>>        amdgpu_bo_init_functions(ws);
>>      amdgpu_cs_init_functions(ws);
>>      amdgpu_surface_init_functions(ws);
>>        LIST_INITHEAD(&ws->global_bo_list);
>> +   ws->bo_export_table = util_hash_table_create(hash_pointer, 
>> compare_pointers);
>> +
>>      (void) simple_mtx_init(&ws->global_bo_list_lock, mtx_plain);
>>      (void) simple_mtx_init(&ws->bo_fence_lock, mtx_plain);
>> +   (void) simple_mtx_init(&ws->bo_export_table_lock, mtx_plain);
>>        if (!util_queue_init(&ws->cs_queue, "cs", 8, 1,
>>                           UTIL_QUEUE_INIT_RESIZE_IF_FULL)) {
>>         amdgpu_winsys_destroy(&ws->base);
>>         simple_mtx_unlock(&dev_tab_mutex);
>>         return NULL;
>>      }
>>        /* Create the screen at the end. The winsys must be initialized
>>       * completely.
>> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h 
>> b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h
>> index 8079255e4cf..c355eff5262 100644
>> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h
>> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h
>> @@ -78,20 +78,25 @@ struct amdgpu_winsys {
>>        bool check_vm;
>>      bool debug_all_bos;
>>      bool reserve_vmid;
>>      bool zero_all_vram_allocs;
>>        /* List of all allocated buffers */
>>      simple_mtx_t global_bo_list_lock;
>>      struct list_head global_bo_list;
>>      unsigned num_buffers;
>> +
>> +   /* For returning the same amdgpu_winsys_bo instance for exported
>> +    * and re-imported buffers. */
>> +   struct util_hash_table *bo_export_table;
>> +   simple_mtx_t bo_export_table_lock;
>>   };
>>     static inline struct amdgpu_winsys *
>>   amdgpu_winsys(struct radeon_winsys *base)
>>   {
>>      return (struct amdgpu_winsys*)base;
>>   }
>>     void amdgpu_surface_init_functions(struct amdgpu_winsys *ws);
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev



More information about the mesa-dev mailing list