llvmpipe: Use an anonymous file for memory allocations

Preparation for sparse.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29408>
This commit is contained in:
Konstantin Seurer
2024-06-11 16:42:09 +02:00
committed by Marge Bot
parent fcc0fd2fc1
commit a062544d3d
4 changed files with 81 additions and 4 deletions

View File

@@ -43,6 +43,7 @@
#include "util/os_misc.h"
#include "util/os_time.h"
#include "util/u_helpers.h"
#include "util/anon_file.h"
#include "lp_texture.h"
#include "lp_fence.h"
#include "lp_jit.h"
@@ -929,6 +930,10 @@ llvmpipe_destroy_screen(struct pipe_screen *_screen)
close(screen->udmabuf_fd);
#endif
util_vma_heap_finish(&screen->mem_heap);
close(screen->fd_mem_alloc);
mtx_destroy(&screen->mem_mutex);
mtx_destroy(&screen->rast_mutex);
mtx_destroy(&screen->cs_mutex);
FREE(screen);
@@ -1170,6 +1175,16 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
screen->udmabuf_fd = open("/dev/udmabuf", O_RDWR);
#endif
screen->fd_mem_alloc = os_create_anonymous_file(0, "allocation fd");
(void) mtx_init(&screen->mem_mutex, mtx_plain);
uint64_t alignment;
if (!os_get_page_size(&alignment))
alignment = 256;
util_vma_heap_init(&screen->mem_heap, alignment, UINT64_MAX - alignment);
screen->mem_heap.alloc_high = false;
snprintf(screen->renderer_string, sizeof(screen->renderer_string),
"llvmpipe (LLVM " MESA_LLVM_VERSION_STRING ", %u bits)",
lp_build_init_native_width() );

View File

@@ -38,6 +38,7 @@
#include "pipe/p_defines.h"
#include "util/u_thread.h"
#include "util/list.h"
#include "util/vma.h"
#include "gallivm/lp_bld.h"
#include "gallivm/lp_bld_misc.h"
@@ -77,6 +78,11 @@ struct llvmpipe_screen
#ifdef HAVE_LIBDRM
int udmabuf_fd;
#endif
int fd_mem_alloc;
mtx_t mem_mutex;
uint64_t mem_file_size;
struct util_vma_heap mem_heap;
};

View File

@@ -35,6 +35,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/detect_os.h"
#include "util/simple_mtx.h"
#include "util/u_inlines.h"
#include "util/u_cpu_detect.h"
@@ -43,6 +44,10 @@
#include "util/u_memory.h"
#include "util/u_transfer.h"
#if DETECT_OS_POSIX
#include "util/os_mman.h"
#endif
#include "lp_context.h"
#include "lp_flush.h"
#include "lp_screen.h"
@@ -1101,22 +1106,60 @@ llvmpipe_memory_barrier(struct pipe_context *pipe,
static struct pipe_memory_allocation *
llvmpipe_allocate_memory(struct pipe_screen *screen, uint64_t size)
llvmpipe_allocate_memory(struct pipe_screen *_screen, uint64_t size)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
struct llvmpipe_memory_allocation *mem = CALLOC_STRUCT(llvmpipe_memory_allocation);
uint64_t alignment;
if (!os_get_page_size(&alignment))
alignment = 256;
mem->cpu_addr = os_malloc_aligned(size, alignment);
mem->fd = screen->fd_mem_alloc;
mem->size = align64(size, alignment);
#if DETECT_OS_LINUX
mem->cpu_addr = MAP_FAILED;
mtx_lock(&screen->mem_mutex);
mem->offset = util_vma_heap_alloc(&screen->mem_heap, mem->size, alignment);
if (mem->offset + mem->size > screen->mem_file_size) {
/* expand the anonymous file */
screen->mem_file_size = mem->offset + mem->size;
ftruncate(screen->fd_mem_alloc, screen->mem_file_size);
}
mtx_unlock(&screen->mem_mutex);
#else
mem->cpu_addr = malloc(mem->size);
#endif
return (struct pipe_memory_allocation *)mem;
}
static void
llvmpipe_free_memory(struct pipe_screen *screen,
llvmpipe_free_memory(struct pipe_screen *pscreen,
struct pipe_memory_allocation *pmem)
{
os_free_aligned(pmem);
struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
struct llvmpipe_memory_allocation *mem = (struct llvmpipe_memory_allocation *)pmem;
if (mem->fd) {
mtx_lock(&screen->mem_mutex);
util_vma_heap_free(&screen->mem_heap, mem->offset, mem->size);
mtx_unlock(&screen->mem_mutex);
}
#if DETECT_OS_LINUX
if (mem->cpu_addr != MAP_FAILED)
munmap(mem->cpu_addr, mem->size);
#else
free(mem->cpu_addr);
#endif
FREE(mem);
}
@@ -1300,6 +1343,17 @@ llvmpipe_map_memory(struct pipe_screen *screen,
struct pipe_memory_allocation *pmem)
{
struct llvmpipe_memory_allocation *mem = (struct llvmpipe_memory_allocation *)pmem;
#if DETECT_OS_LINUX
if (mem->cpu_addr != MAP_FAILED)
return mem->cpu_addr;
/* create a "CPU" mapping */
mem->cpu_addr = mmap(NULL, mem->size, PROT_READ|PROT_WRITE, MAP_SHARED,
mem->fd, mem->offset);
assert(mem->cpu_addr != MAP_FAILED);
#endif
return mem->cpu_addr;
}

View File

@@ -126,6 +126,8 @@ struct llvmpipe_transfer
struct llvmpipe_memory_allocation
{
int fd;
uint64_t offset;
void *cpu_addr;
uint64_t size;
enum llvmpipe_memory_fd_type type;