llvmpipe: support sparse resource with LLVMPIPE_MEMORY_FD_TYPE_OPAQUE

Store a dup fd for OPAQUE type as required by sparse binding. Use
os_map_memory_fd_placed to handle binding for opaque fd backed memory,
while the unbind will still correctly share the same code path with
other cases. This adds sparse resource support with OPAQUE type in
addition to DMA_BUF, and venus no longer has to hide sparse resource on
lavapipe.

Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38074>
This commit is contained in:
Yiwei Zhang 2025-10-27 01:40:49 -07:00 committed by Marge Bot
parent 0d72b86fe9
commit 125b93595e

View file

@ -1520,7 +1520,12 @@ llvmpipe_allocate_memory_fd(struct pipe_screen *pscreen,
if (!alloc->cpu_addr)
goto fail;
alloc->fd = -1;
alloc->fd = os_dupfd_cloexec(fd);
if (alloc->fd < 0) {
os_free_fd(alloc->cpu_addr);
goto fail;
}
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
}
@ -1544,25 +1549,21 @@ llvmpipe_import_memory_fd(struct pipe_screen *screen,
if (!alloc)
return false;
alloc->mem_fd = -1;
alloc->fd = -1;
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
if (dmabuf) {
int dup_fd = os_dupfd_cloexec(fd);
if (dup_fd < 0)
goto fail;
if (!llvmpipe_dmabuf_import(dup_fd, alloc)) {
close(dup_fd);
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
if (dmabuf) {
if (!llvmpipe_dmabuf_import(dup_fd, alloc))
goto fail;
}
} else
#endif
{
if (!os_import_memory_fd(fd, &alloc->cpu_addr, &alloc->size, driver_id))
if (!os_import_memory_fd(dup_fd, &alloc->cpu_addr, &alloc->size, driver_id))
goto fail;
alloc->fd = -1;
alloc->fd = dup_fd;
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
}
@ -1571,6 +1572,8 @@ llvmpipe_import_memory_fd(struct pipe_screen *screen,
return true;
fail:
if (dup_fd >= 0)
close(dup_fd);
FREE(alloc);
return false;
}
@ -1583,6 +1586,7 @@ llvmpipe_free_memory_fd(struct pipe_screen *screen,
struct llvmpipe_memory_allocation *alloc = (struct llvmpipe_memory_allocation*)pmem;
if (alloc->type == LLVMPIPE_MEMORY_FD_TYPE_OPAQUE) {
os_free_fd(alloc->cpu_addr);
close(alloc->fd);
}
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
else {
@ -1632,6 +1636,8 @@ llvmpipe_resource_bind_sparse(struct llvmpipe_resource *lpr,
struct llvmpipe_memory_allocation *mem = (struct llvmpipe_memory_allocation *)pmem;
bool ok;
assert(!mem || mem->fd >= 0);
if (offset >= lpr->size_required)
return false;
@ -1639,8 +1645,15 @@ llvmpipe_resource_bind_sparse(struct llvmpipe_resource *lpr,
: (char *)lpr->data + offset;
if (mem) {
fd_offset += mem->offset;
if (mem->type == LLVMPIPE_MEMORY_FD_TYPE_OPAQUE) {
ok = os_map_memory_fd_placed(mem->fd, addr, size, fd_offset,
driver_id);
} else {
ok = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
mem->fd, mem->offset + fd_offset) != MAP_FAILED;
mem->fd, fd_offset) != MAP_FAILED;
}
} else {
ok = mmap(addr, size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0) != MAP_FAILED;