nvk/nvkmd: Rework memory placement flags

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30033>
This commit is contained in:
Faith Ekstrand 2024-07-06 10:00:36 -05:00 committed by Marge Bot
parent e04bb3dffa
commit 1db57bb414
7 changed files with 54 additions and 41 deletions

View file

@ -52,12 +52,6 @@ nvk_memory_type_flags(const VkMemoryType *type,
if (type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) if (type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
flags |= NVKMD_MEM_CAN_MAP; 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) if (handle_types != 0)
flags |= NVKMD_MEM_SHARED; flags |= NVKMD_MEM_SHARED;

View file

@ -82,15 +82,38 @@ nvkmd_nouveau_alloc_tiled_mem(struct nvkmd_dev *_dev,
struct nvkmd_mem **mem_out) struct nvkmd_mem **mem_out)
{ {
struct nvkmd_nouveau_dev *dev = nvkmd_nouveau_dev(_dev); 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; /* Only one placement flag may be specified */
if (flags & NVKMD_MEM_LOCAL) assert(util_bitcount(flags & (NVKMD_MEM_LOCAL |
nouveau_flags |= NOUVEAU_WS_BO_LOCAL; NVKMD_MEM_GART |
if (flags & NVKMD_MEM_GART) NVKMD_MEM_VRAM)) == 1);
nouveau_flags |= NOUVEAU_WS_BO_GART; 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) if (flags & NVKMD_MEM_CAN_MAP)
nouveau_flags |= NOUVEAU_WS_BO_MAP; nouveau_flags |= NOUVEAU_WS_BO_MAP;
if (!(flags & NVKMD_MEM_SHARED)) if (!(flags & NVKMD_MEM_SHARED))
nouveau_flags |= NOUVEAU_WS_BO_NO_SHARE; 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"); return vk_errorf(log_obj, VK_ERROR_INVALID_EXTERNAL_HANDLE, "%m");
enum nvkmd_mem_flags flags = NVKMD_MEM_SHARED; enum nvkmd_mem_flags flags = NVKMD_MEM_SHARED;
if (bo->flags & NOUVEAU_WS_BO_LOCAL)
flags |= NVKMD_MEM_LOCAL; /* We always set LOCAL for shared things because we don't know where the
if (bo->flags & NOUVEAU_WS_BO_GART) * kernel will place it. The query only tells us where it is.
flags |= NVKMD_MEM_GART; */
flags |= NVKMD_MEM_LOCAL;
if (bo->flags & NOUVEAU_WS_BO_MAP) if (bo->flags & NOUVEAU_WS_BO_MAP)
flags |= NVKMD_MEM_CAN_MAP; flags |= NVKMD_MEM_CAN_MAP;

View file

@ -32,15 +32,25 @@ struct vk_sync_signal;
*/ */
enum nvkmd_mem_flags { 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, NVKMD_MEM_LOCAL = 1 << 0,
/** Place the memory in GART */
NVKMD_MEM_GART = 1 << 1, NVKMD_MEM_GART = 1 << 1,
/** Place the memory in VRAM */
NVKMD_MEM_VRAM = 1 << 2,
/** This memory object may be mapped */ /** 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 */ /** This memory object may be shared with other processes */
NVKMD_MEM_SHARED = 1 << 3, NVKMD_MEM_SHARED = 1 << 4,
}; };
enum nvkmd_mem_map_flags { enum nvkmd_mem_map_flags {

View file

@ -100,24 +100,14 @@ nouveau_ws_bo_new_tiled_locked(struct nouveau_ws_device *dev,
req.info.domain = 0; req.info.domain = 0;
/* It needs to live somewhere */ /* 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) if (flags & NOUVEAU_WS_BO_VRAM)
req.info.domain |= dev->local_mem_domain; req.info.domain |= NOUVEAU_GEM_DOMAIN_VRAM;
if (flags & NOUVEAU_WS_BO_GART) if (flags & NOUVEAU_WS_BO_GART)
req.info.domain |= NOUVEAU_GEM_DOMAIN_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) if (flags & NOUVEAU_WS_BO_MAP)
req.info.domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; 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; goto fail_fd_to_handle;
enum nouveau_ws_bo_flags flags = 0; enum nouveau_ws_bo_flags flags = 0;
if (info.domain & dev->local_mem_domain) if (info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
flags |= NOUVEAU_WS_BO_LOCAL; flags |= NOUVEAU_WS_BO_VRAM;
if (info.domain & NOUVEAU_GEM_DOMAIN_GART) if (info.domain & NOUVEAU_GEM_DOMAIN_GART)
flags |= NOUVEAU_WS_BO_GART; flags |= NOUVEAU_WS_BO_GART;
if (info.map_handle) if (info.map_handle)

View file

@ -20,7 +20,7 @@ extern "C" {
enum nouveau_ws_bo_flags { enum nouveau_ws_bo_flags {
/* vram or gart depending on GPU */ /* 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_GART = 1 << 1,
NOUVEAU_WS_BO_MAP = 1 << 2, NOUVEAU_WS_BO_MAP = 1 << 2,
NOUVEAU_WS_BO_NO_SHARE = 1 << 3, NOUVEAU_WS_BO_NO_SHARE = 1 << 3,

View file

@ -337,11 +337,6 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
else else
device->max_push = value; 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 && if (drm_device->bustype == DRM_BUS_PCI &&
!nouveau_ws_param(fd, NOUVEAU_GETPARAM_VRAM_BAR_SIZE, &value)) !nouveau_ws_param(fd, NOUVEAU_GETPARAM_VRAM_BAR_SIZE, &value))
device->info.bar_size_B = value; device->info.bar_size_B = value;

View file

@ -22,7 +22,6 @@ struct nouveau_ws_device {
struct nv_device_info info; struct nv_device_info info;
uint32_t max_push; uint32_t max_push;
uint32_t local_mem_domain;
simple_mtx_t bos_lock; simple_mtx_t bos_lock;
struct hash_table *bos; struct hash_table *bos;