nvk/nvkmd: Add memory and virtual address interfaces
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30033>
This commit is contained in:
committed by
Marge Bot
parent
4323d2ac54
commit
0b93c42ba1
@@ -15,3 +15,44 @@ nvkmd_try_create_pdev_for_drm(struct _drmDevice *drm_device,
|
||||
return nvkmd_nouveau_try_create_pdev(drm_device, log_obj,
|
||||
debug_flags, pdev_out);
|
||||
}
|
||||
|
||||
VkResult
|
||||
nvkmd_dev_alloc_mapped_mem(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
enum nvkmd_mem_flags flags,
|
||||
enum nvkmd_mem_map_flags map_flags,
|
||||
struct nvkmd_mem **mem_out)
|
||||
{
|
||||
struct nvkmd_mem *mem;
|
||||
VkResult result;
|
||||
|
||||
result = nvkmd_dev_alloc_mem(dev, log_obj, size_B, align_B,
|
||||
flags | NVKMD_MEM_CAN_MAP, &mem);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
assert(!(map_flags & NVKMD_MEM_MAP_FIXED));
|
||||
result = mem->ops->map(mem, log_obj, map_flags, NULL);
|
||||
if (result != VK_SUCCESS) {
|
||||
mem->ops->free(mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
*mem_out = mem;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
nvkmd_mem_unref(struct nvkmd_mem *mem)
|
||||
{
|
||||
assert(p_atomic_read(&mem->refcnt) > 0);
|
||||
if (!p_atomic_dec_zero(&mem->refcnt))
|
||||
return;
|
||||
|
||||
if (mem->map != NULL)
|
||||
mem->ops->unmap(mem);
|
||||
|
||||
mem->ops->free(mem);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#define NVKMD_H 1
|
||||
|
||||
#include "nv_device_info.h"
|
||||
#include "util/u_atomic.h"
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
#include "nouveau_device.h"
|
||||
|
||||
@@ -27,11 +29,38 @@ struct vk_object_base;
|
||||
* Enums
|
||||
*/
|
||||
|
||||
enum nvkmd_mem_flags {
|
||||
/** VRAM on discrete GPUs or GART on integrated */
|
||||
NVKMD_MEM_LOCAL = 1 << 0,
|
||||
NVKMD_MEM_GART = 1 << 1,
|
||||
NVKMD_MEM_CAN_MAP = 1 << 2,
|
||||
NVKMD_MEM_NO_SHARE = 1 << 3,
|
||||
};
|
||||
|
||||
enum nvkmd_mem_map_flags {
|
||||
NVKMD_MEM_MAP_RD = 1 << 0,
|
||||
NVKMD_MEM_MAP_WR = 1 << 1,
|
||||
NVKMD_MEM_MAP_RDWR = NVKMD_MEM_MAP_RD | NVKMD_MEM_MAP_WR,
|
||||
NVKMD_MEM_MAP_FIXED = 1 << 2,
|
||||
};
|
||||
|
||||
enum nvkmd_va_flags {
|
||||
/** This VA should be configured for sparse (soft faults) */
|
||||
NVKMD_VA_SPARSE = 1 << 0,
|
||||
|
||||
/** This VA should come from the capture/replay pool */
|
||||
NVKMD_VA_REPLAY = 1 << 1,
|
||||
|
||||
/** Attempt to place this VA at the requested address and fail otherwise */
|
||||
NVKMD_VA_ALLOC_FIXED = 1 << 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* Structs
|
||||
*/
|
||||
|
||||
struct nvkmd_info {
|
||||
bool has_dma_buf;
|
||||
bool has_get_vram_used;
|
||||
bool has_alloc_tiled;
|
||||
bool has_map_fixed;
|
||||
@@ -70,12 +99,89 @@ struct nvkmd_dev_ops {
|
||||
uint64_t (*get_gpu_timestamp)(struct nvkmd_dev *dev);
|
||||
|
||||
int (*get_drm_fd)(struct nvkmd_dev *dev);
|
||||
|
||||
VkResult (*alloc_mem)(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
enum nvkmd_mem_flags flags,
|
||||
struct nvkmd_mem **mem_out);
|
||||
|
||||
VkResult (*alloc_tiled_mem)(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
uint8_t pte_kind, uint16_t tile_mode,
|
||||
enum nvkmd_mem_flags flags,
|
||||
struct nvkmd_mem **mem_out);
|
||||
|
||||
VkResult (*import_dma_buf)(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
int fd, struct nvkmd_mem **mem_out);
|
||||
|
||||
VkResult (*alloc_va)(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
enum nvkmd_va_flags flags, uint8_t pte_kind,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
uint64_t fixed_addr, struct nvkmd_va **va_out);
|
||||
};
|
||||
|
||||
struct nvkmd_dev {
|
||||
const struct nvkmd_dev_ops *ops;
|
||||
};
|
||||
|
||||
struct nvkmd_mem_ops {
|
||||
void (*free)(struct nvkmd_mem *mem);
|
||||
|
||||
VkResult (*map)(struct nvkmd_mem *mem,
|
||||
struct vk_object_base *log_obj,
|
||||
enum nvkmd_mem_map_flags flags,
|
||||
void *fixed_addr);
|
||||
|
||||
void (*unmap)(struct nvkmd_mem *mem);
|
||||
|
||||
VkResult (*overmap)(struct nvkmd_mem *mem,
|
||||
struct vk_object_base *log_obj);
|
||||
|
||||
VkResult (*export_dma_buf)(struct nvkmd_mem *mem,
|
||||
struct vk_object_base *log_obj,
|
||||
int *fd_out);
|
||||
};
|
||||
|
||||
struct nvkmd_mem {
|
||||
const struct nvkmd_mem_ops *ops;
|
||||
|
||||
uint32_t refcnt;
|
||||
|
||||
enum nvkmd_mem_flags flags;
|
||||
|
||||
uint64_t size_B;
|
||||
const struct nvkmd_va *va;
|
||||
void *map;
|
||||
};
|
||||
|
||||
struct nvkmd_va_ops {
|
||||
void (*free)(struct nvkmd_va *va);
|
||||
|
||||
VkResult (*bind_mem)(struct nvkmd_va *va,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t va_offset_B,
|
||||
struct nvkmd_mem *mem,
|
||||
uint64_t mem_offset_B,
|
||||
uint64_t range_B);
|
||||
|
||||
VkResult (*unbind)(struct nvkmd_va *va,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t va_offset_B,
|
||||
uint64_t range_B);
|
||||
};
|
||||
|
||||
struct nvkmd_va {
|
||||
const struct nvkmd_va_ops *ops;
|
||||
enum nvkmd_va_flags flags;
|
||||
uint8_t pte_kind;
|
||||
uint64_t addr;
|
||||
uint64_t size_B;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros
|
||||
*
|
||||
@@ -155,4 +261,141 @@ nvkmd_dev_get_drm_fd(struct nvkmd_dev *dev)
|
||||
return dev->ops->get_drm_fd(dev);
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_dev_alloc_mem(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
enum nvkmd_mem_flags flags,
|
||||
struct nvkmd_mem **mem_out)
|
||||
{
|
||||
return dev->ops->alloc_mem(dev, log_obj, size_B, align_B, flags, mem_out);
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_dev_alloc_tiled_mem(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
uint8_t pte_kind, uint16_t tile_mode,
|
||||
enum nvkmd_mem_flags flags,
|
||||
struct nvkmd_mem **mem_out)
|
||||
{
|
||||
return dev->ops->alloc_tiled_mem(dev, log_obj, size_B, align_B,
|
||||
pte_kind, tile_mode, flags, mem_out);
|
||||
}
|
||||
|
||||
/* Implies NVKMD_MEM_CAN_MAP */
|
||||
VkResult MUST_CHECK
|
||||
nvkmd_dev_alloc_mapped_mem(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
enum nvkmd_mem_flags flags,
|
||||
enum nvkmd_mem_map_flags map_flags,
|
||||
struct nvkmd_mem **mem_out);
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_dev_import_dma_buf(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
int fd, struct nvkmd_mem **mem_out)
|
||||
{
|
||||
return dev->ops->import_dma_buf(dev, log_obj, fd, mem_out);
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_dev_alloc_va(struct nvkmd_dev *dev,
|
||||
struct vk_object_base *log_obj,
|
||||
enum nvkmd_va_flags flags, uint8_t pte_kind,
|
||||
uint64_t size_B, uint64_t align_B,
|
||||
uint64_t fixed_addr, struct nvkmd_va **va_out)
|
||||
{
|
||||
return dev->ops->alloc_va(dev, log_obj, flags, pte_kind, size_B, align_B,
|
||||
fixed_addr, va_out);
|
||||
}
|
||||
|
||||
static inline struct nvkmd_mem *
|
||||
nvkmd_mem_ref(struct nvkmd_mem *mem)
|
||||
{
|
||||
p_atomic_inc(&mem->refcnt);
|
||||
return mem;
|
||||
}
|
||||
|
||||
void nvkmd_mem_unref(struct nvkmd_mem *mem);
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_mem_map(struct nvkmd_mem *mem, struct vk_object_base *log_obj,
|
||||
enum nvkmd_mem_map_flags flags, void *fixed_addr,
|
||||
void **map_out)
|
||||
{
|
||||
assert(mem->map == NULL);
|
||||
|
||||
VkResult result = mem->ops->map(mem, log_obj, flags, fixed_addr);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
*map_out = mem->map;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void
|
||||
nvkmd_mem_unmap(struct nvkmd_mem *mem)
|
||||
{
|
||||
assert(mem->map != NULL);
|
||||
mem->ops->unmap(mem);
|
||||
assert(mem->map == NULL);
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_mem_overmap(struct nvkmd_mem *mem, struct vk_object_base *log_obj)
|
||||
{
|
||||
assert(mem->map != NULL);
|
||||
VkResult result = mem->ops->overmap(mem, log_obj);
|
||||
assert(mem->map == NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_mem_export_dma_buf(struct nvkmd_mem *mem,
|
||||
struct vk_object_base *log_obj,
|
||||
int *fd_out)
|
||||
{
|
||||
assert(!(mem->flags & NVKMD_MEM_NO_SHARE));
|
||||
|
||||
return mem->ops->export_dma_buf(mem, log_obj, fd_out);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nvkmd_va_free(struct nvkmd_va *va)
|
||||
{
|
||||
va->ops->free(va);
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_va_bind_mem(struct nvkmd_va *va,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t va_offset_B,
|
||||
struct nvkmd_mem *mem,
|
||||
uint64_t mem_offset_B,
|
||||
uint64_t range_B)
|
||||
{
|
||||
assert(va_offset_B <= va->size_B);
|
||||
assert(va_offset_B + range_B <= va->size_B);
|
||||
assert(mem_offset_B <= mem->size_B);
|
||||
assert(mem_offset_B + range_B <= mem->size_B);
|
||||
|
||||
return va->ops->bind_mem(va, log_obj, va_offset_B,
|
||||
mem, mem_offset_B, range_B);
|
||||
}
|
||||
|
||||
static inline VkResult MUST_CHECK
|
||||
nvkmd_va_unbind(struct nvkmd_va *va,
|
||||
struct vk_object_base *log_obj,
|
||||
uint64_t va_offset_B,
|
||||
uint64_t range_B)
|
||||
{
|
||||
assert(va_offset_B <= va->size_B);
|
||||
assert(va_offset_B + range_B <= va->size_B);
|
||||
|
||||
return va->ops->unbind(va, log_obj, va_offset_B, range_B);
|
||||
}
|
||||
|
||||
#endif /* NVKMD_H */
|
||||
|
||||
Reference in New Issue
Block a user