mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 17:40:11 +01:00
nouveau/winsys: Add dma-buf import support
This requires a lock and a buffer cache on the nouveau_ws_device. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
parent
10ffe8e709
commit
c370260a8f
5 changed files with 84 additions and 9 deletions
|
|
@ -18,6 +18,7 @@ libnouveau_ws = static_library(
|
|||
dependencies : [
|
||||
dep_libdrm,
|
||||
dep_libdrm_nouveau,
|
||||
dep_valgrind,
|
||||
idep_nvidia_headers,
|
||||
],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "nouveau_bo.h"
|
||||
|
||||
#include <util/hash_table.h>
|
||||
|
||||
#include <nouveau_drm.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
|
|
@ -67,19 +69,71 @@ nouveau_ws_bo_new_tiled(struct nouveau_ws_device *dev,
|
|||
req.info.size = size;
|
||||
req.align = align;
|
||||
|
||||
simple_mtx_lock(&dev->bos_lock);
|
||||
|
||||
int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW, &req, sizeof(req));
|
||||
if (ret) {
|
||||
if (ret == 0) {
|
||||
bo->size = req.info.size;
|
||||
bo->offset = req.info.offset;
|
||||
bo->handle = req.info.handle;
|
||||
bo->map_handle = req.info.map_handle;
|
||||
bo->dev = dev;
|
||||
bo->flags = flags;
|
||||
bo->refcnt = 1;
|
||||
|
||||
_mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)bo->handle, bo);
|
||||
} else {
|
||||
FREE(bo);
|
||||
return NULL;
|
||||
bo = NULL;
|
||||
}
|
||||
|
||||
bo->size = req.info.size;
|
||||
bo->offset = req.info.offset;
|
||||
bo->handle = req.info.handle;
|
||||
bo->map_handle = req.info.map_handle;
|
||||
bo->dev = dev;
|
||||
bo->flags = flags;
|
||||
bo->refcnt = 1;
|
||||
simple_mtx_unlock(&dev->bos_lock);
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
||||
struct nouveau_ws_bo *
|
||||
nouveau_ws_bo_from_dma_buf(struct nouveau_ws_device *dev, int fd)
|
||||
{
|
||||
struct nouveau_ws_bo *bo = NULL;
|
||||
|
||||
simple_mtx_lock(&dev->bos_lock);
|
||||
|
||||
uint32_t handle;
|
||||
int ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
|
||||
if (ret == 0) {
|
||||
struct hash_entry *entry =
|
||||
_mesa_hash_table_search(dev->bos, (void *)(uintptr_t)handle);
|
||||
if (entry != NULL) {
|
||||
bo = entry->data;
|
||||
} else {
|
||||
struct drm_nouveau_gem_info info = {
|
||||
.handle = handle
|
||||
};
|
||||
ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO,
|
||||
&info, sizeof(info));
|
||||
if (ret == 0) {
|
||||
enum nouveau_ws_bo_flags flags = 0;
|
||||
if (info.domain & NOUVEAU_GEM_DOMAIN_GART)
|
||||
flags |= NOUVEAU_WS_BO_GART;
|
||||
if (info.map_handle)
|
||||
flags |= NOUVEAU_WS_BO_MAP;
|
||||
|
||||
bo = CALLOC_STRUCT(nouveau_ws_bo);
|
||||
bo->size = info.size;
|
||||
bo->offset = info.offset;
|
||||
bo->handle = info.handle;
|
||||
bo->map_handle = info.map_handle;
|
||||
bo->dev = dev;
|
||||
bo->flags = flags;
|
||||
bo->refcnt = 1;
|
||||
|
||||
_mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)handle, bo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&dev->bos_lock);
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
|
@ -90,8 +144,15 @@ nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo)
|
|||
if (--bo->refcnt)
|
||||
return;
|
||||
|
||||
struct nouveau_ws_device *dev = bo->dev;
|
||||
|
||||
simple_mtx_lock(&dev->bos_lock);
|
||||
|
||||
_mesa_hash_table_remove_key(dev->bos, (void *)(uintptr_t)bo->handle);
|
||||
drmCloseBufferHandle(bo->dev->fd, bo->handle);
|
||||
FREE(bo);
|
||||
|
||||
simple_mtx_unlock(&dev->bos_lock);
|
||||
}
|
||||
|
||||
void *
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ struct nouveau_ws_bo *nouveau_ws_bo_new_tiled(struct nouveau_ws_device *,
|
|||
uint8_t pte_kind,
|
||||
uint16_t tile_mode,
|
||||
enum nouveau_ws_bo_flags);
|
||||
struct nouveau_ws_bo *nouveau_ws_bo_from_dma_buf(struct nouveau_ws_device *,
|
||||
int fd);
|
||||
void nouveau_ws_bo_destroy(struct nouveau_ws_bo *);
|
||||
void *nouveau_ws_bo_map(struct nouveau_ws_bo *, enum nouveau_ws_bo_map_flags);
|
||||
bool nouveau_ws_bo_wait(struct nouveau_ws_bo *, enum nouveau_ws_bo_map_flags flags);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <nouveau/nvif/ioctl.h>
|
||||
#include <nvif/cl0080.h>
|
||||
#include <nvif/class.h>
|
||||
#include <util/hash_table.h>
|
||||
|
||||
#include "nouveau_context.h"
|
||||
|
||||
|
|
@ -266,6 +267,9 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
|
|||
|
||||
nouveau_ws_context_destroy(tmp_ctx);
|
||||
|
||||
simple_mtx_init(&device->bos_lock, mtx_plain);
|
||||
device->bos = _mesa_pointer_hash_table_create(NULL);
|
||||
|
||||
return device;
|
||||
|
||||
out_err:
|
||||
|
|
@ -282,6 +286,8 @@ nouveau_ws_device_destroy(struct nouveau_ws_device *device)
|
|||
if (!device)
|
||||
return;
|
||||
|
||||
_mesa_hash_table_destroy(device->bos, NULL);
|
||||
simple_mtx_destroy(&device->bos_lock);
|
||||
close(device->fd);
|
||||
FREE(device->chipset_name);
|
||||
FREE(device->device_name);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
#include "nouveau_private.h"
|
||||
#include "nv_device_info.h"
|
||||
#include "util/simple_mtx.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct _drmDevice;
|
||||
struct hash_table;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -52,6 +54,9 @@ struct nouveau_ws_device {
|
|||
uint16_t mp_count;
|
||||
|
||||
enum nvk_debug debug_flags;
|
||||
|
||||
simple_mtx_t bos_lock;
|
||||
struct hash_table *bos;
|
||||
};
|
||||
|
||||
struct nouveau_ws_device *nouveau_ws_device_new(struct _drmDevice *drm_device);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue