From 1db57bb41424359569b195a93dc7269b1392ab26 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Sat, 6 Jul 2024 10:00:36 -0500 Subject: [PATCH] nvk/nvkmd: Rework memory placement flags Part-of: --- src/nouveau/vulkan/nvk_device_memory.c | 6 --- .../vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c | 45 ++++++++++++++----- src/nouveau/vulkan/nvkmd/nvkmd.h | 16 +++++-- src/nouveau/winsys/nouveau_bo.c | 20 +++------ src/nouveau/winsys/nouveau_bo.h | 2 +- src/nouveau/winsys/nouveau_device.c | 5 --- src/nouveau/winsys/nouveau_device.h | 1 - 7 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/nouveau/vulkan/nvk_device_memory.c b/src/nouveau/vulkan/nvk_device_memory.c index 8fec848e5d1..f4de756cfd0 100644 --- a/src/nouveau/vulkan/nvk_device_memory.c +++ b/src/nouveau/vulkan/nvk_device_memory.c @@ -52,12 +52,6 @@ nvk_memory_type_flags(const VkMemoryType *type, if (type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) flags |= NVKMD_MEM_CAN_MAP; - /* For dma-bufs, we have to allow them to live in GART because they might - * get forced there by the kernel if they're shared with another GPU. - */ - if (handle_types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) - flags |= NVKMD_MEM_GART; - if (handle_types != 0) flags |= NVKMD_MEM_SHARED; diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c index a7eb850ae52..a7cffb6a5af 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c @@ -82,15 +82,38 @@ nvkmd_nouveau_alloc_tiled_mem(struct nvkmd_dev *_dev, struct nvkmd_mem **mem_out) { struct nvkmd_nouveau_dev *dev = nvkmd_nouveau_dev(_dev); + const struct nv_device_info *dev_info = &dev->base.pdev->dev_info; - enum nouveau_ws_bo_flags nouveau_flags = 0; - if (flags & NVKMD_MEM_LOCAL) - nouveau_flags |= NOUVEAU_WS_BO_LOCAL; - if (flags & NVKMD_MEM_GART) - nouveau_flags |= NOUVEAU_WS_BO_GART; + /* Only one placement flag may be specified */ + assert(util_bitcount(flags & (NVKMD_MEM_LOCAL | + NVKMD_MEM_GART | + NVKMD_MEM_VRAM)) == 1); + enum nouveau_ws_bo_flags domains = 0; + if (flags & NVKMD_MEM_LOCAL) { + domains |= NOUVEAU_WS_BO_GART; + if (dev_info->vram_size_B > 0) + domains |= NOUVEAU_WS_BO_VRAM; + } else if (flags & NVKMD_MEM_GART) { + domains |= NOUVEAU_WS_BO_GART; + } else if (flags & NVKMD_MEM_VRAM) { + domains |= NOUVEAU_WS_BO_VRAM; + } + + /* TODO: + * + * VRAM maps on Kepler appear to be broken and we don't really know why. + * My NVIDIA contact doesn't remember them not working so they probably + * should but they don't today. Force everything that may be mapped to + * use GART for now. + */ + if (dev_info->chipset < 0x110 && (flags & NOUVEAU_WS_BO_MAP)) { + assert(domains & NOUVEAU_WS_BO_GART); + domains = NOUVEAU_WS_BO_GART; + } + + enum nouveau_ws_bo_flags nouveau_flags = domains; if (flags & NVKMD_MEM_CAN_MAP) nouveau_flags |= NOUVEAU_WS_BO_MAP; - if (!(flags & NVKMD_MEM_SHARED)) nouveau_flags |= NOUVEAU_WS_BO_NO_SHARE; @@ -117,10 +140,12 @@ nvkmd_nouveau_import_dma_buf(struct nvkmd_dev *_dev, return vk_errorf(log_obj, VK_ERROR_INVALID_EXTERNAL_HANDLE, "%m"); enum nvkmd_mem_flags flags = NVKMD_MEM_SHARED; - if (bo->flags & NOUVEAU_WS_BO_LOCAL) - flags |= NVKMD_MEM_LOCAL; - if (bo->flags & NOUVEAU_WS_BO_GART) - flags |= NVKMD_MEM_GART; + + /* We always set LOCAL for shared things because we don't know where the + * kernel will place it. The query only tells us where it is. + */ + flags |= NVKMD_MEM_LOCAL; + if (bo->flags & NOUVEAU_WS_BO_MAP) flags |= NVKMD_MEM_CAN_MAP; diff --git a/src/nouveau/vulkan/nvkmd/nvkmd.h b/src/nouveau/vulkan/nvkmd/nvkmd.h index ed551e73b88..ed5e426c0be 100644 --- a/src/nouveau/vulkan/nvkmd/nvkmd.h +++ b/src/nouveau/vulkan/nvkmd/nvkmd.h @@ -32,15 +32,25 @@ struct vk_sync_signal; */ enum nvkmd_mem_flags { - /** VRAM on discrete GPUs or GART on integrated */ + /** Place memory as local as possible. + * + * This should be the default for most memory allocations. On discrete + * GPUs, it will default to be placed in VRAM but may be paged out to GART, + * depending on system memory pressure. + */ NVKMD_MEM_LOCAL = 1 << 0, + + /** Place the memory in GART */ NVKMD_MEM_GART = 1 << 1, + /** Place the memory in VRAM */ + NVKMD_MEM_VRAM = 1 << 2, + /** This memory object may be mapped */ - NVKMD_MEM_CAN_MAP = 1 << 2, + NVKMD_MEM_CAN_MAP = 1 << 3, /** This memory object may be shared with other processes */ - NVKMD_MEM_SHARED = 1 << 3, + NVKMD_MEM_SHARED = 1 << 4, }; enum nvkmd_mem_map_flags { diff --git a/src/nouveau/winsys/nouveau_bo.c b/src/nouveau/winsys/nouveau_bo.c index 93f8994f07d..6ca33180045 100644 --- a/src/nouveau/winsys/nouveau_bo.c +++ b/src/nouveau/winsys/nouveau_bo.c @@ -100,24 +100,14 @@ nouveau_ws_bo_new_tiled_locked(struct nouveau_ws_device *dev, req.info.domain = 0; /* It needs to live somewhere */ - assert((flags & NOUVEAU_WS_BO_LOCAL) || (flags & NOUVEAU_WS_BO_GART)); + assert((flags & NOUVEAU_WS_BO_VRAM) || (flags & NOUVEAU_WS_BO_GART)); - if (flags & NOUVEAU_WS_BO_LOCAL) - req.info.domain |= dev->local_mem_domain; + if (flags & NOUVEAU_WS_BO_VRAM) + req.info.domain |= NOUVEAU_GEM_DOMAIN_VRAM; if (flags & NOUVEAU_WS_BO_GART) req.info.domain |= NOUVEAU_GEM_DOMAIN_GART; - /* TODO: - * - * VRAM maps on Kepler appear to be broken and we don't really know why. - * My NVIDIA contact doesn't remember them not working so they probably - * should but they don't today. Force everything that may be mapped to - * use GART for now. - */ - else if (dev->info.chipset < 0x110 && (flags & NOUVEAU_WS_BO_MAP)) - req.info.domain |= NOUVEAU_GEM_DOMAIN_GART; - if (flags & NOUVEAU_WS_BO_MAP) req.info.domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; @@ -201,8 +191,8 @@ nouveau_ws_bo_from_dma_buf_locked(struct nouveau_ws_device *dev, int fd) goto fail_fd_to_handle; enum nouveau_ws_bo_flags flags = 0; - if (info.domain & dev->local_mem_domain) - flags |= NOUVEAU_WS_BO_LOCAL; + if (info.domain & NOUVEAU_GEM_DOMAIN_VRAM) + flags |= NOUVEAU_WS_BO_VRAM; if (info.domain & NOUVEAU_GEM_DOMAIN_GART) flags |= NOUVEAU_WS_BO_GART; if (info.map_handle) diff --git a/src/nouveau/winsys/nouveau_bo.h b/src/nouveau/winsys/nouveau_bo.h index 7071128073a..fa444bffb54 100644 --- a/src/nouveau/winsys/nouveau_bo.h +++ b/src/nouveau/winsys/nouveau_bo.h @@ -20,7 +20,7 @@ extern "C" { enum nouveau_ws_bo_flags { /* vram or gart depending on GPU */ - NOUVEAU_WS_BO_LOCAL = 1 << 0, + NOUVEAU_WS_BO_VRAM = 1 << 0, NOUVEAU_WS_BO_GART = 1 << 1, NOUVEAU_WS_BO_MAP = 1 << 2, NOUVEAU_WS_BO_NO_SHARE = 1 << 3, diff --git a/src/nouveau/winsys/nouveau_device.c b/src/nouveau/winsys/nouveau_device.c index 25ccc64c98e..4d7d72f32da 100644 --- a/src/nouveau/winsys/nouveau_device.c +++ b/src/nouveau/winsys/nouveau_device.c @@ -337,11 +337,6 @@ nouveau_ws_device_new(drmDevicePtr drm_device) else device->max_push = value; - if (device->info.vram_size_B == 0) - device->local_mem_domain = NOUVEAU_GEM_DOMAIN_GART; - else - device->local_mem_domain = NOUVEAU_GEM_DOMAIN_VRAM; - if (drm_device->bustype == DRM_BUS_PCI && !nouveau_ws_param(fd, NOUVEAU_GETPARAM_VRAM_BAR_SIZE, &value)) device->info.bar_size_B = value; diff --git a/src/nouveau/winsys/nouveau_device.h b/src/nouveau/winsys/nouveau_device.h index b3824115dd4..e986b2cfab6 100644 --- a/src/nouveau/winsys/nouveau_device.h +++ b/src/nouveau/winsys/nouveau_device.h @@ -22,7 +22,6 @@ struct nouveau_ws_device { struct nv_device_info info; uint32_t max_push; - uint32_t local_mem_domain; simple_mtx_t bos_lock; struct hash_table *bos;