iris: implement SVM interfaces

Acked-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35174>
This commit is contained in:
Karol Herbst
2024-12-16 00:30:54 +01:00
committed by Marge Bot
parent a34a8fc0cd
commit 13e47cde01
6 changed files with 125 additions and 21 deletions
+1 -1
View File
@@ -756,7 +756,7 @@ Rusticl OpenCL 1.2 -- all DONE:
Rusticl OpenCL 2.0 -- all DONE:
Shared virtual memory DONE (nvc0, llvmpipe)
Shared virtual memory DONE (iris, nvc0, llvmpipe)
Device queues not started
- cl_khr_create_command_queue DONE
- Additional queries for clGetDeviceInfo DONE
+1 -1
View File
@@ -28,7 +28,7 @@ VK_EXT_texel_buffer_alignment on panvk
cl_khr_kernel_clock on freedreno, iris, llvmpipe, nvc0, panfrost, radeonsi and zink with llvm-19 or newer
GL_KHR_texture_compression_astc_hdr on panfrost and asahi
cl_ext_buffer_device_address on iris, llvmpipe and zink
Completed OpenCL 2.0 coarse grain buffer SVM support
Completed OpenCL 2.0 coarse grain buffer SVM support for iris
VK_EXT_shader_subgroup_ballot on panvk
VK_EXT_shader_subgroup_vote on panvk
Vulkan video support on GFX12 (RDNA4) for RADV
+55 -16
View File
@@ -288,7 +288,7 @@ static struct bo_cache_bucket *
bucket_for_size(struct iris_bufmgr *bufmgr, uint64_t size,
enum iris_heap heap, enum bo_alloc_flags flags)
{
if (flags & BO_ALLOC_PROTECTED)
if (flags & (BO_ALLOC_PROTECTED | BO_ALLOC_NO_VMA))
return NULL;
const struct intel_device_info *devinfo = &bufmgr->devinfo;
@@ -394,6 +394,37 @@ vma_alloc(struct iris_bufmgr *bufmgr,
return intel_canonical_address(addr);
}
bool
iris_bufmgr_alloc_heap(struct iris_bufmgr *bufmgr, uint64_t start, uint64_t size)
{
simple_mtx_lock(&bufmgr->lock);
bool res = util_vma_heap_alloc_addr(&bufmgr->vma_allocator[IRIS_MEMZONE_OTHER], start, size);
simple_mtx_unlock(&bufmgr->lock);
return res;
}
void
iris_bufmgr_free_heap(struct iris_bufmgr *bufmgr, uint64_t start, uint64_t size)
{
simple_mtx_lock(&bufmgr->lock);
util_vma_heap_free(&bufmgr->vma_allocator[IRIS_MEMZONE_OTHER], start, size);
simple_mtx_unlock(&bufmgr->lock);
}
bool
iris_bufmgr_assign_vma(struct iris_bufmgr *bufmgr, struct iris_bo *bo, uint64_t address)
{
assert(bo->address == 0 || address == 0);
bo->address = intel_canonical_address(address);
/* we disallow addresses to be assigned which need to be made canonical */
assert(bo->address == address);
if (address)
return bufmgr->kmd_backend->gem_vm_bind(bo, 0);
else
return bufmgr->kmd_backend->gem_vm_unbind(bo);
}
static void
vma_free(struct iris_bufmgr *bufmgr,
uint64_t address,
@@ -1280,7 +1311,7 @@ iris_bo_alloc(struct iris_bufmgr *bufmgr,
return NULL;
}
if (bo->address == 0ull) {
if (bo->address == 0ull && !(flags & BO_ALLOC_NO_VMA)) {
simple_mtx_lock(&bufmgr->lock);
bo->address = vma_alloc(bufmgr, memzone, bo->size, alignment);
simple_mtx_unlock(&bufmgr->lock);
@@ -1339,7 +1370,7 @@ iris_bo_close(int fd, uint32_t gem_handle)
struct iris_bo *
iris_bo_create_userptr(struct iris_bufmgr *bufmgr, const char *name,
void *ptr, size_t size,
void *ptr, size_t size, unsigned flags,
enum iris_memory_zone memzone)
{
struct iris_bo *bo;
@@ -1362,13 +1393,6 @@ iris_bo_create_userptr(struct iris_bufmgr *bufmgr, const char *name,
if (INTEL_DEBUG(DEBUG_CAPTURE_ALL))
bo->real.capture = true;
simple_mtx_lock(&bufmgr->lock);
bo->address = vma_alloc(bufmgr, memzone, size, 1);
simple_mtx_unlock(&bufmgr->lock);
if (bo->address == 0ull)
goto err_close;
p_atomic_set(&bo->refcount, 1);
bo->index = -1;
bo->idle = true;
@@ -1376,8 +1400,17 @@ iris_bo_create_userptr(struct iris_bufmgr *bufmgr, const char *name,
bo->real.mmap_mode = heap_to_mmap_mode(bufmgr, bo->real.heap);
bo->real.prime_fd = -1;
if (!bufmgr->kmd_backend->gem_vm_bind(bo, 0))
goto err_vma_free;
if (!(flags & BO_ALLOC_NO_VMA)) {
simple_mtx_lock(&bufmgr->lock);
bo->address = vma_alloc(bufmgr, memzone, size, 1);
simple_mtx_unlock(&bufmgr->lock);
if (bo->address == 0ull)
goto err_close;
if (!bufmgr->kmd_backend->gem_vm_bind(bo, 0))
goto err_vma_free;
}
return bo;
@@ -1428,6 +1461,8 @@ iris_bo_gem_create_from_name(struct iris_bufmgr *bufmgr,
{
struct iris_bo *bo;
assert(!(flags & BO_ALLOC_NO_VMA));
/* At the moment most applications only have a few named bo.
* For instance, in a DRI client only the render buffers passed
* between X and the client are named. And since X returns the
@@ -1538,10 +1573,12 @@ bo_close(struct iris_bo *bo)
}
/* Unbind and return the VMA for reuse */
if (bufmgr->kmd_backend->gem_vm_unbind(bo))
vma_free(bo->bufmgr, bo->address, bo->size);
else
DBG("Unable to unbind vm of buf %u\n", bo->gem_handle);
if (bo->address) {
if (bufmgr->kmd_backend->gem_vm_unbind(bo))
vma_free(bo->bufmgr, bo->address, bo->size);
else
DBG("Unable to unbind vm of buf %u\n", bo->gem_handle);
}
if (bo->real.prime_fd != -1)
close(bo->real.prime_fd);
@@ -1951,6 +1988,8 @@ iris_bo_import_dmabuf(struct iris_bufmgr *bufmgr, int prime_fd,
uint32_t handle;
struct iris_bo *bo;
assert(!(flags & BO_ALLOC_NO_VMA));
simple_mtx_lock(&bufmgr->lock);
int ret = drmPrimeFDToHandle(bufmgr->fd, prime_fd, &handle);
if (ret) {
+7 -1
View File
@@ -411,6 +411,8 @@ enum bo_alloc_flags {
BO_ALLOC_CPU_VISIBLE = (1<<9),
/* BO content is compressed. */
BO_ALLOC_COMPRESSED = (1<<10),
/* Do not allocate or bind a vma */
BO_ALLOC_NO_VMA = (1<<11),
};
/**
@@ -429,7 +431,7 @@ struct iris_bo *iris_bo_alloc(struct iris_bufmgr *bufmgr,
struct iris_bo *
iris_bo_create_userptr(struct iris_bufmgr *bufmgr, const char *name,
void *ptr, size_t size,
void *ptr, size_t size, unsigned flags,
enum iris_memory_zone memzone);
/** Takes a reference on a buffer object */
@@ -696,6 +698,10 @@ bool iris_bufmgr_compute_engine_supported(struct iris_bufmgr *bufmgr);
uint64_t iris_bufmgr_get_dummy_aux_address(struct iris_bufmgr *bufmgr);
struct iris_bo *iris_bufmgr_get_mem_fence_bo(struct iris_bufmgr *bufmgr);
bool iris_bufmgr_alloc_heap(struct iris_bufmgr *bufmgr, uint64_t start, uint64_t size);
void iris_bufmgr_free_heap(struct iris_bufmgr *bufmgr, uint64_t start, uint64_t size);
bool iris_bufmgr_assign_vma(struct iris_bufmgr *bufmgr, struct iris_bo *bo, uint64_t address);
enum iris_madvice {
IRIS_MADVICE_WILL_NEED = 0,
IRIS_MADVICE_DONT_NEED = 1,
+54 -2
View File
@@ -48,6 +48,7 @@
#include "util/ralloc.h"
#include "i915/iris_bufmgr.h"
#include "iris_batch.h"
#include "iris_bufmgr.h"
#include "iris_context.h"
#include "iris_resource.h"
#include "iris_screen.h"
@@ -489,6 +490,9 @@ iris_resource_alloc_flags(const struct iris_screen *screen,
if (templ->bind & PIPE_BIND_SCANOUT)
flags |= BO_ALLOC_SCANOUT;
if (templ->flags & PIPE_RESOURCE_FLAG_FRONTEND_VM)
flags |= BO_ALLOC_NO_SUBALLOC | BO_ALLOC_NO_VMA;
if (templ->flags & (PIPE_RESOURCE_FLAG_MAP_COHERENT |
PIPE_RESOURCE_FLAG_MAP_PERSISTENT))
flags |= BO_ALLOC_SMEM | BO_ALLOC_CACHED_COHERENT;
@@ -533,6 +537,9 @@ iris_resource_destroy(struct pipe_screen *screen,
if (p_res->target == PIPE_BUFFER)
util_range_destroy(&res->valid_buffer_range);
if (p_res->flags & PIPE_RESOURCE_FLAG_FRONTEND_VM)
assert(res->bo->address == 0);
iris_resource_disable_aux(res);
threaded_resource_deinit(p_res);
@@ -1241,6 +1248,7 @@ iris_resource_from_user_memory(struct pipe_screen *pscreen,
struct iris_screen *screen = (struct iris_screen *)pscreen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
struct iris_resource *res = iris_alloc_resource(pscreen, templ);
unsigned flags = 0;
if (!res)
return NULL;
@@ -1272,10 +1280,13 @@ iris_resource_from_user_memory(struct pipe_screen *pscreen,
size_t mem_size = offset + res_size;
mem_size = ALIGN_NPOT(mem_size, page_size);
if (templ->flags & PIPE_RESOURCE_FLAG_FRONTEND_VM)
flags |= BO_ALLOC_NO_VMA;
res->internal_format = templ->format;
res->base.is_user_ptr = true;
res->bo = iris_bo_create_userptr(bufmgr, "user", mem_start, mem_size,
IRIS_MEMZONE_OTHER);
flags, IRIS_MEMZONE_OTHER);
res->offset = offset;
if (!res->bo) {
iris_resource_destroy(pscreen, &res->base.b);
@@ -1977,7 +1988,8 @@ iris_invalidate_buffer(struct iris_context *ice, struct iris_resource *res)
struct iris_screen *screen = (void *) ice->ctx.screen;
if (res->base.b.target != PIPE_BUFFER ||
res->base.b.flags & PIPE_RESOURCE_FLAG_FIXED_ADDRESS)
res->base.b.flags & PIPE_RESOURCE_FLAG_FIXED_ADDRESS ||
res->base.b.flags & PIPE_RESOURCE_FLAG_FRONTEND_VM)
return false;
/* If it's already invalidated, don't bother doing anything.
@@ -2737,6 +2749,43 @@ static const struct u_transfer_vtbl transfer_vtbl = {
.get_stencil = iris_resource_get_separate_stencil,
};
static struct pipe_vm_allocation *
iris_alloc_vm(struct pipe_screen *pscreen, uint64_t start, uint64_t size)
{
struct iris_screen *screen = (struct iris_screen *)pscreen;
if (!iris_bufmgr_alloc_heap(screen->bufmgr, start, size))
return NULL;
struct pipe_vm_allocation *res = CALLOC_STRUCT(pipe_vm_allocation);
if (!res) {
iris_bufmgr_free_heap(screen->bufmgr, start, size);
return NULL;
}
res->start = start;
res->size = size;
return res;
}
static void
iris_free_vm(struct pipe_screen *pscreen, struct pipe_vm_allocation *alloc)
{
struct iris_screen *screen = (struct iris_screen *)pscreen;
iris_bufmgr_free_heap(screen->bufmgr, alloc->start, alloc->size);
FREE(alloc);
}
static bool
iris_resource_assign_vma(struct pipe_screen *pscreen,
struct pipe_resource *presource, uint64_t address)
{
struct iris_screen *screen = (struct iris_screen *)pscreen;
struct iris_resource *res = (struct iris_resource *)presource;
assert(presource->flags & PIPE_RESOURCE_FLAG_FRONTEND_VM);
return iris_bufmgr_assign_vma(screen->bufmgr, res->bo, address);
}
static uint64_t
iris_resource_get_address(struct pipe_screen *pscreen,
struct pipe_resource *presrouce)
@@ -2763,6 +2812,9 @@ iris_init_screen_resource_functions(struct pipe_screen *pscreen)
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
pscreen->memobj_create_from_handle = iris_memobj_create_from_handle;
pscreen->memobj_destroy = iris_memobj_destroy;
pscreen->alloc_vm = iris_alloc_vm;
pscreen->free_vm = iris_free_vm;
pscreen->resource_assign_vma = iris_resource_assign_vma;
pscreen->resource_get_address = iris_resource_get_address;
pscreen->transfer_helper =
u_transfer_helper_create(&transfer_vtbl,
+7
View File
@@ -491,6 +491,13 @@ iris_init_screen_caps(struct iris_screen *screen)
caps->max_texture_anisotropy = 16.0f;
caps->max_texture_lod_bias = 15.0f;
caps->min_vma = IRIS_MEMZONE_OTHER_START;
/* Exclude addresses which would need to be converted to their canonical form.
* The easy way to go about this is to take the highest address and simply
* shift it right by one, so the highest valid address bit gets unset.
*/
caps->max_vma = intel_48b_address(UINT64_MAX) >> 1;
}
static uint64_t