From b1937296457ef5991de0275fa0dbf276a24be3a0 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Fri, 20 May 2022 15:26:47 +0200 Subject: [PATCH] nouveau/ws: add bo API Part-of: --- src/nouveau/winsys/meson.build | 2 ++ src/nouveau/winsys/nouveau_bo.c | 70 +++++++++++++++++++++++++++++++++++++ src/nouveau/winsys/nouveau_bo.h | 33 +++++++++++++++++ src/nouveau/winsys/nouveau_device.c | 5 +++ src/nouveau/winsys/nouveau_device.h | 1 + 5 files changed, 111 insertions(+) create mode 100644 src/nouveau/winsys/nouveau_bo.c create mode 100644 src/nouveau/winsys/nouveau_bo.h diff --git a/src/nouveau/winsys/meson.build b/src/nouveau/winsys/meson.build index 6204205..7ce1762 100644 --- a/src/nouveau/winsys/meson.build +++ b/src/nouveau/winsys/meson.build @@ -1,6 +1,8 @@ libnouveau_ws = static_library( 'nouveau_ws', [ + 'nouveau_bo.h', + 'nouveau_bo.c', 'nouveau_device.h', 'nouveau_device.c', 'nouveau_private.h', diff --git a/src/nouveau/winsys/nouveau_bo.c b/src/nouveau/winsys/nouveau_bo.c new file mode 100644 index 0000000..3387700 --- /dev/null +++ b/src/nouveau/winsys/nouveau_bo.c @@ -0,0 +1,70 @@ +#include "nouveau_bo.h" + +#include +#include +#include + +#include +#include + +struct nouveau_ws_bo * +nouveau_ws_bo_new(struct nouveau_ws_device *dev, uint64_t size, uint64_t align, enum nouveau_ws_bo_flags flags) +{ + struct nouveau_ws_device_priv *pdev = nouveau_ws_device(dev); + struct nouveau_ws_bo *bo = CALLOC_STRUCT(nouveau_ws_bo); + struct drm_nouveau_gem_new req = {}; + + /* if the caller doesn't care, use the GPU page size */ + if (align == 0) + align = 0x1000; + + req.info.domain = NOUVEAU_GEM_TILE_NONCONTIG; + if (flags & NOUVEAU_WS_BO_GART) + req.info.domain |= NOUVEAU_GEM_DOMAIN_GART; + else + req.info.domain |= pdev->local_mem_domain; + + if (flags & NOUVEAU_WS_BO_MAP) + req.info.domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; + + req.info.size = size; + req.align = align; + + int ret = drmCommandWriteRead(pdev->fd, DRM_NOUVEAU_GEM_NEW, &req, sizeof(req)); + if (ret) { + FREE(bo); + return NULL; + } + + bo->size = req.info.size; + bo->offset = req.info.offset; + bo->handle = req.info.handle; + bo->map_handle = req.info.map_handle; + bo->fd = pdev->fd; + + return bo; +} + +void +nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo) +{ + drmCloseBufferHandle(bo->fd, bo->handle); + FREE(bo); +} + +void * +nouveau_ws_bo_map(struct nouveau_ws_bo *bo, enum nouveau_ws_bo_map_flags flags) +{ + size_t prot = 0; + + if (flags & NOUVEAU_WS_BO_RD) + prot |= PROT_READ; + if (flags & NOUVEAU_WS_BO_WR) + prot |= PROT_WRITE; + + void *res = mmap64(NULL, bo->size, prot, MAP_SHARED, bo->fd, bo->map_handle); + if (res == MAP_FAILED) + return NULL; + + return res; +} diff --git a/src/nouveau/winsys/nouveau_bo.h b/src/nouveau/winsys/nouveau_bo.h new file mode 100644 index 0000000..e858d3b --- /dev/null +++ b/src/nouveau/winsys/nouveau_bo.h @@ -0,0 +1,33 @@ +#ifndef NOUVEAU_BO +#define NOUVEAU_BO 1 + +#include "nouveau_private.h" + +#include "nouveau_device.h" + +enum nouveau_ws_bo_flags { + /* vram or gart depending on GPU */ + NOUVEAU_WS_BO_LOCAL = 0 << 0, + NOUVEAU_WS_BO_GART = 1 << 0, + NOUVEAU_WS_BO_MAP = 1 << 1, +}; + +enum nouveau_ws_bo_map_flags { + NOUVEAU_WS_BO_RD = 1 << 0, + NOUVEAU_WS_BO_WR = 1 << 1, + NOUVEAU_WS_BO_RDWR = NOUVEAU_WS_BO_RD | NOUVEAU_WS_BO_WR, +}; + +struct nouveau_ws_bo { + uint64_t size; + uint64_t offset; + uint64_t map_handle; + int fd; + uint32_t handle; +}; + +struct nouveau_ws_bo *nouveau_ws_bo_new(struct nouveau_ws_device *, uint64_t size, uint64_t align, enum nouveau_ws_bo_flags); +void nouveau_ws_bo_destroy(struct nouveau_ws_bo *); +void *nouveau_ws_bo_map(struct nouveau_ws_bo *, enum nouveau_ws_bo_map_flags); + +#endif diff --git a/src/nouveau/winsys/nouveau_device.c b/src/nouveau/winsys/nouveau_device.c index 1d150de..6f4d621 100644 --- a/src/nouveau/winsys/nouveau_device.c +++ b/src/nouveau/winsys/nouveau_device.c @@ -103,6 +103,11 @@ nouveau_ws_device_new(int fd) device->dev = dev; device->fd = dup_fd; + if (dev->vram_size == 0) + device->local_mem_domain = NOUVEAU_GEM_DOMAIN_GART; + else + device->local_mem_domain = NOUVEAU_GEM_DOMAIN_VRAM; + return &device->base; out_dev: diff --git a/src/nouveau/winsys/nouveau_device.h b/src/nouveau/winsys/nouveau_device.h index 602e06b..cb78a20 100644 --- a/src/nouveau/winsys/nouveau_device.h +++ b/src/nouveau/winsys/nouveau_device.h @@ -22,6 +22,7 @@ struct nouveau_ws_device_priv { struct nouveau_drm *drm; struct nouveau_device *dev; int fd; + uint32_t local_mem_domain; }; static struct nouveau_ws_device_priv * -- 2.7.4