mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 12:40:09 +01:00
llvmpipe: refactor dmabuf and opaque fd handling
This change: 1. add new helpers to handle dmabuf alloc/import/free 2. use FREE to match with alloc macro 3. simplify opaque fd code path Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38074>
This commit is contained in:
parent
4d0fbd1c67
commit
e8f66ef197
1 changed files with 125 additions and 113 deletions
|
|
@ -1383,64 +1383,104 @@ llvmpipe_free_memory(struct pipe_screen *pscreen,
|
|||
|
||||
|
||||
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
|
||||
static void*
|
||||
llvmpipe_resource_alloc_udmabuf(struct llvmpipe_screen *screen,
|
||||
struct llvmpipe_memory_allocation *alloc,
|
||||
size_t size)
|
||||
static void
|
||||
llvmpipe_dmabuf_free(struct llvmpipe_memory_allocation *alloc)
|
||||
{
|
||||
assert(alloc->cpu_addr != NULL && alloc->fd >= 0);
|
||||
munmap(alloc->cpu_addr, alloc->size);
|
||||
close(alloc->fd);
|
||||
if (alloc->mem_fd >= 0)
|
||||
close(alloc->mem_fd);
|
||||
}
|
||||
|
||||
static bool
|
||||
llvmpipe_dmabuf_import(int fd, struct llvmpipe_memory_allocation *alloc)
|
||||
{
|
||||
const off_t size = lseek(fd, 0, SEEK_END);
|
||||
if (size < 0)
|
||||
return false;
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
void *cpu_addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (cpu_addr == MAP_FAILED)
|
||||
return false;
|
||||
|
||||
*alloc = (struct llvmpipe_memory_allocation){
|
||||
.fd = fd,
|
||||
.offset = 0,
|
||||
.cpu_addr = cpu_addr,
|
||||
.size = size,
|
||||
.type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF,
|
||||
.mem_fd = -1,
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
llvmpipe_dmabuf_alloc(struct llvmpipe_screen *screen,
|
||||
size_t size,
|
||||
struct llvmpipe_memory_allocation *alloc)
|
||||
{
|
||||
int mem_fd = -1;
|
||||
int dmabuf_fd = -1;
|
||||
if (screen->udmabuf_fd != -1) {
|
||||
uint64_t alignment;
|
||||
if (!os_get_page_size(&alignment))
|
||||
alignment = 256;
|
||||
|
||||
size = align(size, alignment);
|
||||
if (screen->udmabuf_fd < 0)
|
||||
return false;
|
||||
|
||||
mem_fd = memfd_create("lp_dma_buf", MFD_ALLOW_SEALING);
|
||||
if (mem_fd == -1)
|
||||
goto fail;
|
||||
uint64_t alignment;
|
||||
if (!os_get_page_size(&alignment))
|
||||
alignment = 256;
|
||||
|
||||
int res = ftruncate(mem_fd, size);
|
||||
if (res == -1)
|
||||
goto fail;
|
||||
size = align(size, alignment);
|
||||
|
||||
/* udmabuf create requires that the memfd have
|
||||
* have the F_SEAL_SHRINK seal added and must not
|
||||
* have the F_SEAL_WRITE seal added */
|
||||
if (fcntl(mem_fd, F_ADD_SEALS, F_SEAL_SHRINK) < 0)
|
||||
goto fail;
|
||||
mem_fd = memfd_create("lp_dma_buf", MFD_ALLOW_SEALING);
|
||||
if (mem_fd < 0)
|
||||
goto fail;
|
||||
|
||||
struct udmabuf_create create = {
|
||||
.memfd = mem_fd,
|
||||
.flags = UDMABUF_FLAGS_CLOEXEC,
|
||||
.offset = 0,
|
||||
.size = size
|
||||
};
|
||||
if (ftruncate(mem_fd, size) < 0)
|
||||
goto fail;
|
||||
|
||||
dmabuf_fd = ioctl(screen->udmabuf_fd, UDMABUF_CREATE, &create);
|
||||
if (dmabuf_fd < 0)
|
||||
goto fail;
|
||||
/* udmabuf create requires that the memfd have have the F_SEAL_SHRINK seal
|
||||
* added and must not have the F_SEAL_WRITE seal added
|
||||
*/
|
||||
if (fcntl(mem_fd, F_ADD_SEALS, F_SEAL_SHRINK) < 0)
|
||||
goto fail;
|
||||
|
||||
struct pipe_memory_allocation *data =
|
||||
mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, 0);
|
||||
if (data == MAP_FAILED)
|
||||
goto fail;
|
||||
struct udmabuf_create create = {
|
||||
.memfd = mem_fd,
|
||||
.flags = UDMABUF_FLAGS_CLOEXEC,
|
||||
.offset = 0,
|
||||
.size = size
|
||||
};
|
||||
|
||||
alloc->mem_fd = mem_fd;
|
||||
alloc->fd = dmabuf_fd;
|
||||
alloc->size = size;
|
||||
return data;
|
||||
}
|
||||
dmabuf_fd = ioctl(screen->udmabuf_fd, UDMABUF_CREATE, &create);
|
||||
if (dmabuf_fd < 0)
|
||||
goto fail;
|
||||
|
||||
void *cpu_addr =
|
||||
mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, 0);
|
||||
if (cpu_addr == MAP_FAILED)
|
||||
goto fail;
|
||||
|
||||
*alloc = (struct llvmpipe_memory_allocation){
|
||||
.fd = dmabuf_fd,
|
||||
.offset = 0,
|
||||
.cpu_addr = cpu_addr,
|
||||
.size = size,
|
||||
.type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF,
|
||||
.mem_fd = mem_fd,
|
||||
};
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (dmabuf_fd >= 0)
|
||||
close(dmabuf_fd);
|
||||
if (mem_fd != -1)
|
||||
if (mem_fd >= 0)
|
||||
close(mem_fd);
|
||||
/* If we don't have access to the udmabuf device
|
||||
* or something else fails we return NULL */
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1448,56 +1488,53 @@ fail:
|
|||
static struct pipe_memory_allocation *
|
||||
llvmpipe_allocate_memory_fd(struct pipe_screen *pscreen,
|
||||
uint64_t size,
|
||||
int *fd,
|
||||
int *out_fd,
|
||||
bool dmabuf)
|
||||
{
|
||||
struct llvmpipe_memory_allocation *alloc = CALLOC_STRUCT(llvmpipe_memory_allocation);
|
||||
if (!alloc)
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
alloc->mem_fd = -1;
|
||||
alloc->fd = -1;
|
||||
int fd = -1;
|
||||
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
|
||||
if (dmabuf) {
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF;
|
||||
alloc->cpu_addr = llvmpipe_resource_alloc_udmabuf(screen, alloc, size);
|
||||
if (!llvmpipe_dmabuf_alloc(screen, size, alloc))
|
||||
goto fail;
|
||||
|
||||
if (alloc->cpu_addr) {
|
||||
*fd = os_dupfd_cloexec(alloc->fd);
|
||||
if (*fd < 0) {
|
||||
close(alloc->mem_fd);
|
||||
close(alloc->fd);
|
||||
FREE(alloc);
|
||||
goto fail;
|
||||
}
|
||||
fd = os_dupfd_cloexec(alloc->fd);
|
||||
if (fd < 0) {
|
||||
llvmpipe_dmabuf_free(alloc);
|
||||
goto fail;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
|
||||
uint64_t alignment;
|
||||
if (!os_get_page_size(&alignment))
|
||||
alignment = 256;
|
||||
alloc->cpu_addr = os_malloc_aligned_fd(size, alignment, fd,
|
||||
uint64_t alignment = 256;
|
||||
os_get_page_size(&alignment);
|
||||
alloc->cpu_addr = os_malloc_aligned_fd(size, alignment, &fd,
|
||||
"llvmpipe memory fd", driver_id);
|
||||
if (!alloc->cpu_addr)
|
||||
goto fail;
|
||||
|
||||
alloc->fd = -1;
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
|
||||
}
|
||||
|
||||
if(alloc && !alloc->cpu_addr) {
|
||||
free(alloc);
|
||||
alloc = NULL;
|
||||
}
|
||||
*out_fd = fd;
|
||||
return (struct pipe_memory_allocation*)alloc;
|
||||
|
||||
fail:
|
||||
return (struct pipe_memory_allocation*)alloc;
|
||||
FREE(alloc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
llvmpipe_import_memory_fd(struct pipe_screen *screen,
|
||||
int fd,
|
||||
struct pipe_memory_allocation **ptr,
|
||||
uint64_t *size,
|
||||
struct pipe_memory_allocation **out_ptr,
|
||||
uint64_t *out_size,
|
||||
bool dmabuf)
|
||||
{
|
||||
struct llvmpipe_memory_allocation *alloc = CALLOC_STRUCT(llvmpipe_memory_allocation);
|
||||
|
|
@ -1508,52 +1545,31 @@ llvmpipe_import_memory_fd(struct pipe_screen *screen,
|
|||
alloc->fd = -1;
|
||||
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
|
||||
if (dmabuf) {
|
||||
off_t mmap_size = lseek(fd, 0, SEEK_END);
|
||||
if (mmap_size < 0) {
|
||||
free(alloc);
|
||||
*ptr = NULL;
|
||||
return false;
|
||||
int dup_fd = os_dupfd_cloexec(fd);
|
||||
if (dup_fd < 0)
|
||||
goto fail;
|
||||
|
||||
if (!llvmpipe_dmabuf_import(dup_fd, alloc)) {
|
||||
close(dup_fd);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
void *cpu_addr = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (cpu_addr == MAP_FAILED) {
|
||||
free(alloc);
|
||||
*ptr = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF;
|
||||
alloc->cpu_addr = cpu_addr;
|
||||
alloc->size = mmap_size;
|
||||
alloc->fd = os_dupfd_cloexec(fd);
|
||||
if (alloc->fd < 0) {
|
||||
munmap(alloc->cpu_addr, alloc->size);
|
||||
free(alloc);
|
||||
*ptr = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
*ptr = (struct pipe_memory_allocation*)alloc;
|
||||
*size = mmap_size;
|
||||
|
||||
return true;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
bool ret = os_import_memory_fd(fd, (void**)&alloc->cpu_addr, size, driver_id);
|
||||
|
||||
if (!ret) {
|
||||
free(alloc);
|
||||
*ptr = NULL;
|
||||
return false;
|
||||
} else {
|
||||
*ptr = (struct pipe_memory_allocation*)alloc;
|
||||
}
|
||||
if (!os_import_memory_fd(fd, &alloc->cpu_addr, &alloc->size, driver_id))
|
||||
goto fail;
|
||||
|
||||
alloc->fd = -1;
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_ptr = (struct pipe_memory_allocation*)alloc;
|
||||
*out_size = alloc->size;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
FREE(alloc);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1567,15 +1583,11 @@ llvmpipe_free_memory_fd(struct pipe_screen *screen,
|
|||
}
|
||||
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
|
||||
else {
|
||||
munmap(alloc->cpu_addr, alloc->size);
|
||||
if (alloc->fd >= 0)
|
||||
close(alloc->fd);
|
||||
if (alloc->mem_fd >= 0)
|
||||
close(alloc->mem_fd);
|
||||
llvmpipe_dmabuf_free(alloc);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(alloc);
|
||||
FREE(alloc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue