#include "nouveau_bo.h"
+#include <util/hash_table.h>
+
#include <nouveau_drm.h>
#include <xf86drm.h>
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;
+ }
+
+ 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);
+ }
+ }
}
- 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;
}
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 *
#include <nouveau/nvif/ioctl.h>
#include <nvif/cl0080.h>
#include <nvif/class.h>
+#include <util/hash_table.h>
#include "nouveau_context.h"
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:
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);