mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +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 : [
|
dependencies : [
|
||||||
dep_libdrm,
|
dep_libdrm,
|
||||||
dep_libdrm_nouveau,
|
dep_libdrm_nouveau,
|
||||||
|
dep_valgrind,
|
||||||
idep_nvidia_headers,
|
idep_nvidia_headers,
|
||||||
],
|
],
|
||||||
gnu_symbol_visibility : 'hidden',
|
gnu_symbol_visibility : 'hidden',
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#include "nouveau_bo.h"
|
#include "nouveau_bo.h"
|
||||||
|
|
||||||
|
#include <util/hash_table.h>
|
||||||
|
|
||||||
#include <nouveau_drm.h>
|
#include <nouveau_drm.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
|
||||||
|
|
@ -67,19 +69,71 @@ nouveau_ws_bo_new_tiled(struct nouveau_ws_device *dev,
|
||||||
req.info.size = size;
|
req.info.size = size;
|
||||||
req.align = align;
|
req.align = align;
|
||||||
|
|
||||||
|
simple_mtx_lock(&dev->bos_lock);
|
||||||
|
|
||||||
int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW, &req, sizeof(req));
|
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);
|
FREE(bo);
|
||||||
return NULL;
|
bo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bo->size = req.info.size;
|
simple_mtx_unlock(&dev->bos_lock);
|
||||||
bo->offset = req.info.offset;
|
|
||||||
bo->handle = req.info.handle;
|
return bo;
|
||||||
bo->map_handle = req.info.map_handle;
|
}
|
||||||
bo->dev = dev;
|
|
||||||
bo->flags = flags;
|
struct nouveau_ws_bo *
|
||||||
bo->refcnt = 1;
|
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;
|
return bo;
|
||||||
}
|
}
|
||||||
|
|
@ -90,8 +144,15 @@ nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo)
|
||||||
if (--bo->refcnt)
|
if (--bo->refcnt)
|
||||||
return;
|
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);
|
drmCloseBufferHandle(bo->dev->fd, bo->handle);
|
||||||
FREE(bo);
|
FREE(bo);
|
||||||
|
|
||||||
|
simple_mtx_unlock(&dev->bos_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ struct nouveau_ws_bo *nouveau_ws_bo_new_tiled(struct nouveau_ws_device *,
|
||||||
uint8_t pte_kind,
|
uint8_t pte_kind,
|
||||||
uint16_t tile_mode,
|
uint16_t tile_mode,
|
||||||
enum nouveau_ws_bo_flags);
|
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_destroy(struct nouveau_ws_bo *);
|
||||||
void *nouveau_ws_bo_map(struct nouveau_ws_bo *, enum nouveau_ws_bo_map_flags);
|
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);
|
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 <nouveau/nvif/ioctl.h>
|
||||||
#include <nvif/cl0080.h>
|
#include <nvif/cl0080.h>
|
||||||
#include <nvif/class.h>
|
#include <nvif/class.h>
|
||||||
|
#include <util/hash_table.h>
|
||||||
|
|
||||||
#include "nouveau_context.h"
|
#include "nouveau_context.h"
|
||||||
|
|
||||||
|
|
@ -266,6 +267,9 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
|
||||||
|
|
||||||
nouveau_ws_context_destroy(tmp_ctx);
|
nouveau_ws_context_destroy(tmp_ctx);
|
||||||
|
|
||||||
|
simple_mtx_init(&device->bos_lock, mtx_plain);
|
||||||
|
device->bos = _mesa_pointer_hash_table_create(NULL);
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
|
|
@ -282,6 +286,8 @@ nouveau_ws_device_destroy(struct nouveau_ws_device *device)
|
||||||
if (!device)
|
if (!device)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_mesa_hash_table_destroy(device->bos, NULL);
|
||||||
|
simple_mtx_destroy(&device->bos_lock);
|
||||||
close(device->fd);
|
close(device->fd);
|
||||||
FREE(device->chipset_name);
|
FREE(device->chipset_name);
|
||||||
FREE(device->device_name);
|
FREE(device->device_name);
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
#include "nouveau_private.h"
|
#include "nouveau_private.h"
|
||||||
#include "nv_device_info.h"
|
#include "nv_device_info.h"
|
||||||
|
#include "util/simple_mtx.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct _drmDevice;
|
struct _drmDevice;
|
||||||
|
struct hash_table;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -52,6 +54,9 @@ struct nouveau_ws_device {
|
||||||
uint16_t mp_count;
|
uint16_t mp_count;
|
||||||
|
|
||||||
enum nvk_debug debug_flags;
|
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);
|
struct nouveau_ws_device *nouveau_ws_device_new(struct _drmDevice *drm_device);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue