mirror of https://gitlab.freedesktop.org/mesa/mesa
llvmpipe: Implement dmabuf handling
For export this is handled through the use of the udmabuf driver to allocate a dmabuf we can control from userspace. For import this is handled through mmap-ing a dmabuf handle. Please note that you can only mmap a dmabuf handle if its linear and the dmabuf handle was created with matching read and write permissions. Co-authored-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27805>
This commit is contained in:
parent
7e5c5d313b
commit
d74ea2c117
|
@ -59,6 +59,9 @@
|
|||
|
||||
#include "nir.h"
|
||||
|
||||
#ifdef PIPE_MEMORY_FD
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
int LP_DEBUG = 0;
|
||||
|
||||
|
@ -902,6 +905,10 @@ llvmpipe_destroy_screen(struct pipe_screen *_screen)
|
|||
|
||||
glsl_type_singleton_decref();
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
close(screen->udmabuf_fd);
|
||||
#endif
|
||||
|
||||
mtx_destroy(&screen->rast_mutex);
|
||||
mtx_destroy(&screen->cs_mutex);
|
||||
FREE(screen);
|
||||
|
@ -1139,6 +1146,9 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
|
|||
screen->num_threads);
|
||||
screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS);
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
screen->udmabuf_fd = open("/dev/udmabuf", O_RDWR);
|
||||
#endif
|
||||
|
||||
snprintf(screen->renderer_string, sizeof(screen->renderer_string),
|
||||
"llvmpipe (LLVM " MESA_LLVM_VERSION_STRING ", %u bits)",
|
||||
|
|
|
@ -73,6 +73,10 @@ struct llvmpipe_screen
|
|||
char renderer_string[100];
|
||||
|
||||
struct disk_cache *disk_shader_cache;
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
int udmabuf_fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,13 @@
|
|||
#include "drm-uapi/drm_fourcc.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/udmabuf.h>
|
||||
#include <util/os_file.h>
|
||||
#endif
|
||||
|
||||
#if MESA_DEBUG
|
||||
static struct llvmpipe_resource resource_list;
|
||||
|
@ -66,6 +73,12 @@ static simple_mtx_t resource_list_mutex = SIMPLE_MTX_INITIALIZER;
|
|||
static unsigned id_counter = 0;
|
||||
|
||||
|
||||
#ifdef PIPE_MEMORY_FD
|
||||
|
||||
static const char *driver_id = "llvmpipe" MESA_GIT_SHA1;
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Conventional allocation path for non-display textures:
|
||||
* Compute strides and allocate data (unless asked not to).
|
||||
|
@ -250,6 +263,10 @@ llvmpipe_resource_create_all(struct pipe_screen *_screen,
|
|||
pipe_reference_init(&lpr->base.reference, 1);
|
||||
lpr->base.screen = &screen->base;
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
lpr->dmabuf_alloc = NULL;
|
||||
#endif
|
||||
|
||||
/* assert(lpr->base.bind); */
|
||||
|
||||
if (llvmpipe_resource_is_texture(&lpr->base)) {
|
||||
|
@ -334,6 +351,21 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
|
|||
return llvmpipe_resource_create_front(_screen, templat, NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
static struct pipe_resource *
|
||||
llvmpipe_resource_create_with_modifiers(struct pipe_screen *_screen,
|
||||
const struct pipe_resource *templat,
|
||||
const uint64_t *modifiers, int count)
|
||||
{
|
||||
bool has_linear = false;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
if (modifiers[i] == DRM_FORMAT_MOD_LINEAR)
|
||||
has_linear = true;
|
||||
if (!has_linear)
|
||||
return NULL;
|
||||
return llvmpipe_resource_create_front(_screen, templat, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pipe_resource *
|
||||
llvmpipe_resource_create_unbacked(struct pipe_screen *_screen,
|
||||
|
@ -474,6 +506,12 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
|
|||
align_free(lpr->data);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
if (lpr->dmabuf_alloc)
|
||||
pscreen->free_memory_fd(pscreen, (struct pipe_memory_allocation*)lpr->dmabuf_alloc);
|
||||
#endif
|
||||
|
||||
#if MESA_DEBUG
|
||||
simple_mtx_lock(&resource_list_mutex);
|
||||
if (!list_is_empty(&lpr->list))
|
||||
|
@ -505,6 +543,8 @@ llvmpipe_resource_map(struct pipe_resource *resource,
|
|||
tex_usage == LP_TEX_USAGE_WRITE_ALL);
|
||||
|
||||
if (lpr->dt) {
|
||||
if (lpr->dmabuf)
|
||||
return lpr->tex_data;
|
||||
/* display target */
|
||||
struct llvmpipe_screen *screen = lpr->screen;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
|
@ -547,6 +587,8 @@ llvmpipe_resource_unmap(struct pipe_resource *resource,
|
|||
struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
|
||||
|
||||
if (lpr->dt) {
|
||||
if (lpr->dmabuf)
|
||||
return;
|
||||
/* display target */
|
||||
struct llvmpipe_screen *lp_screen = lpr->screen;
|
||||
struct sw_winsys *winsys = lp_screen->winsys;
|
||||
|
@ -580,7 +622,10 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen,
|
|||
struct sw_winsys *winsys = screen->winsys;
|
||||
struct llvmpipe_resource *lpr;
|
||||
|
||||
/* XXX Seems like from_handled depth textures doesn't work that well */
|
||||
/* no multisampled */
|
||||
assert(template->nr_samples < 2);
|
||||
/* no miplevels */
|
||||
assert(template->last_level == 0);
|
||||
|
||||
lpr = CALLOC_STRUCT(llvmpipe_resource);
|
||||
if (!lpr) {
|
||||
|
@ -589,6 +634,7 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen,
|
|||
|
||||
lpr->base = *template;
|
||||
lpr->screen = screen;
|
||||
lpr->dt_format = whandle->format;
|
||||
pipe_reference_init(&lpr->base.reference, 1);
|
||||
lpr->base.screen = _screen;
|
||||
|
||||
|
@ -601,15 +647,44 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen,
|
|||
assert(lpr->base.height0 == height);
|
||||
#endif
|
||||
|
||||
lpr->dt = winsys->displaytarget_from_handle(winsys,
|
||||
template,
|
||||
whandle,
|
||||
&lpr->row_stride[0]);
|
||||
if (!lpr->dt) {
|
||||
void *data;
|
||||
#ifdef HAVE_LIBDRM
|
||||
struct llvmpipe_memory_fd_alloc *alloc;
|
||||
uint64_t size;
|
||||
if(_screen->import_memory_fd(_screen, whandle->handle, (struct pipe_memory_allocation**)&alloc, &size, true)) {
|
||||
data = alloc->data;
|
||||
lpr->dt = winsys->displaytarget_create_mapped(winsys, template->bind,
|
||||
template->format, template->width0, template->height0,
|
||||
whandle->stride, data);
|
||||
if (!lpr->dt)
|
||||
goto no_dt;
|
||||
lpr->dmabuf_alloc = alloc;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
lpr->dt = winsys->displaytarget_from_handle(winsys,
|
||||
template,
|
||||
whandle,
|
||||
&lpr->row_stride[0]);
|
||||
if (!lpr->dt)
|
||||
goto no_dt;
|
||||
data = winsys->displaytarget_map(winsys, lpr->dt, PIPE_MAP_READ_WRITE);
|
||||
}
|
||||
if (!data) {
|
||||
winsys->displaytarget_destroy(winsys, lpr->dt);
|
||||
goto no_dt;
|
||||
}
|
||||
|
||||
lpr->row_stride[0] = whandle->stride;
|
||||
unsigned nblocksy = util_format_get_nblocksy(template->format, align(template->height0, LP_RASTER_BLOCK_SIZE));
|
||||
lpr->img_stride[0] = whandle->stride * nblocksy;
|
||||
lpr->sample_stride = lpr->img_stride[0];
|
||||
lpr->size_required = lpr->sample_stride;
|
||||
|
||||
assert(llvmpipe_resource_is_texture(&lpr->base));
|
||||
lpr->tex_data = data;
|
||||
lpr->id = id_counter++;
|
||||
lpr->dmabuf = true;
|
||||
|
||||
#if MESA_DEBUG
|
||||
simple_mtx_lock(&resource_list_mutex);
|
||||
|
@ -627,15 +702,52 @@ no_lpr:
|
|||
|
||||
|
||||
static bool
|
||||
llvmpipe_resource_get_handle(struct pipe_screen *screen,
|
||||
llvmpipe_resource_get_handle(struct pipe_screen *_screen,
|
||||
struct pipe_context *ctx,
|
||||
struct pipe_resource *pt,
|
||||
struct winsys_handle *whandle,
|
||||
unsigned usage)
|
||||
{
|
||||
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
|
||||
|
||||
whandle->stride = lpr->row_stride[0];
|
||||
#ifdef HAVE_LIBDRM
|
||||
whandle->modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
if (!lpr->dt && whandle->type == WINSYS_HANDLE_TYPE_FD) {
|
||||
if (!lpr->dmabuf_alloc) {
|
||||
lpr->dmabuf_alloc = (struct llvmpipe_memory_fd_alloc*)_screen->allocate_memory_fd(_screen, lpr->size_required, (int*)&whandle->handle, true);
|
||||
if (!lpr->dmabuf_alloc)
|
||||
return false;
|
||||
|
||||
/* replace existing backing with fd backing */
|
||||
bool is_tex = llvmpipe_resource_is_texture(pt);
|
||||
if (is_tex) {
|
||||
if (lpr->tex_data)
|
||||
memcpy(lpr->dmabuf_alloc->data, lpr->tex_data, lpr->size_required);
|
||||
} else {
|
||||
if (lpr->data)
|
||||
memcpy(lpr->dmabuf_alloc->data, lpr->data, lpr->size_required);
|
||||
}
|
||||
if (!lpr->imported_memory)
|
||||
align_free(is_tex ? lpr->tex_data : lpr->data);
|
||||
if (is_tex)
|
||||
lpr->tex_data = lpr->dmabuf_alloc;
|
||||
else
|
||||
lpr->data = lpr->dmabuf_alloc->data;
|
||||
/* reuse lavapipe codepath to handle destruction */
|
||||
lpr->backable = true;
|
||||
}
|
||||
whandle->handle = lpr->dmabuf_alloc->dmabuf_fd;
|
||||
return true;
|
||||
} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
|
||||
/* dri winsys code will use this to query the drm modifiers
|
||||
* We can just return an null handle and return DRM_FORMAT_MOD_LINEAR */
|
||||
whandle->handle = 0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
assert(lpr->dt);
|
||||
if (!lpr->dt)
|
||||
return false;
|
||||
|
@ -983,22 +1095,105 @@ llvmpipe_free_memory(struct pipe_screen *screen,
|
|||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
static void*
|
||||
llvmpipe_resource_alloc_udmabuf(struct llvmpipe_screen *screen,
|
||||
struct llvmpipe_memory_fd_alloc *alloc,
|
||||
size_t size)
|
||||
{
|
||||
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);
|
||||
|
||||
int mem_fd = memfd_create("lp_dma_buf", MFD_ALLOW_SEALING);
|
||||
if (mem_fd == -1)
|
||||
goto fail;
|
||||
|
||||
int res = ftruncate(mem_fd, size);
|
||||
if (res == -1)
|
||||
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 udmabuf_create create = {
|
||||
.memfd = mem_fd,
|
||||
.flags = UDMABUF_FLAGS_CLOEXEC,
|
||||
.offset = 0,
|
||||
.size = size
|
||||
};
|
||||
|
||||
int dmabuf_fd = ioctl(screen->udmabuf_fd, UDMABUF_CREATE, &create);
|
||||
if (dmabuf_fd < 0)
|
||||
goto fail;
|
||||
|
||||
struct pipe_memory_allocation *data =
|
||||
mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, 0);
|
||||
|
||||
if (!data)
|
||||
goto fail;
|
||||
|
||||
alloc->mem_fd = mem_fd;
|
||||
alloc->dmabuf_fd = dmabuf_fd;
|
||||
alloc->size = size;
|
||||
return data;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (mem_fd != -1)
|
||||
close(mem_fd);
|
||||
if (dmabuf_fd != -1)
|
||||
close(dmabuf_fd);
|
||||
/* If we don't have access to the udmabuf device
|
||||
* or something else fails we return NULL */
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PIPE_MEMORY_FD
|
||||
|
||||
static const char *driver_id = "llvmpipe" MESA_GIT_SHA1;
|
||||
|
||||
|
||||
static struct pipe_memory_allocation *
|
||||
llvmpipe_allocate_memory_fd(struct pipe_screen *screen,
|
||||
llvmpipe_allocate_memory_fd(struct pipe_screen *pscreen,
|
||||
uint64_t size,
|
||||
int *fd,
|
||||
bool dmabuf)
|
||||
{
|
||||
uint64_t alignment;
|
||||
if (!os_get_page_size(&alignment))
|
||||
alignment = 256;
|
||||
return os_malloc_aligned_fd(size, alignment, fd,
|
||||
"llvmpipe memory fd", driver_id);
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
|
||||
struct llvmpipe_memory_fd_alloc *alloc = CALLOC_STRUCT(llvmpipe_memory_fd_alloc);
|
||||
if (!alloc)
|
||||
goto fail;
|
||||
|
||||
alloc->mem_fd = -1;
|
||||
alloc->dmabuf_fd = -1;
|
||||
if (dmabuf) {
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF;
|
||||
alloc->data = llvmpipe_resource_alloc_udmabuf(screen, alloc, size);
|
||||
|
||||
if (alloc->data)
|
||||
*fd = os_dupfd_cloexec(alloc->dmabuf_fd);
|
||||
} else {
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
|
||||
uint64_t alignment;
|
||||
if (!os_get_page_size(&alignment))
|
||||
alignment = 256;
|
||||
alloc->data = os_malloc_aligned_fd(size, alignment, fd,
|
||||
"llvmpipe memory fd", driver_id);
|
||||
}
|
||||
|
||||
if(alloc && !alloc->data) {
|
||||
free(alloc);
|
||||
alloc = NULL;
|
||||
}
|
||||
|
||||
fail:
|
||||
return (struct pipe_memory_allocation*)alloc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1009,7 +1204,40 @@ llvmpipe_import_memory_fd(struct pipe_screen *screen,
|
|||
uint64_t *size,
|
||||
bool dmabuf)
|
||||
{
|
||||
return os_import_memory_fd(fd, (void**)ptr, size, driver_id);
|
||||
struct llvmpipe_memory_fd_alloc *alloc = CALLOC_STRUCT(llvmpipe_memory_fd_alloc);
|
||||
alloc->mem_fd = -1;
|
||||
alloc->dmabuf_fd = -1;
|
||||
if (dmabuf) {
|
||||
off_t mmap_size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
void *data = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (data == MAP_FAILED) {
|
||||
free(alloc);
|
||||
*ptr = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF;
|
||||
alloc->data = data;
|
||||
alloc->size = mmap_size;
|
||||
alloc->dmabuf_fd = os_dupfd_cloexec(fd);
|
||||
*ptr = (struct pipe_memory_allocation*)alloc;
|
||||
*size = mmap_size;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
bool ret = os_import_memory_fd(fd, (void**)&alloc->data, size, driver_id);
|
||||
|
||||
if (!ret) {
|
||||
free(alloc);
|
||||
*ptr = NULL;
|
||||
} else {
|
||||
*ptr = (struct pipe_memory_allocation*)alloc;
|
||||
}
|
||||
|
||||
alloc->type = LLVMPIPE_MEMORY_FD_TYPE_OPAQUE;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1017,7 +1245,18 @@ static void
|
|||
llvmpipe_free_memory_fd(struct pipe_screen *screen,
|
||||
struct pipe_memory_allocation *pmem)
|
||||
{
|
||||
os_free_fd(pmem);
|
||||
struct llvmpipe_memory_fd_alloc *alloc = (struct llvmpipe_memory_fd_alloc*)pmem;
|
||||
if (alloc->type == LLVMPIPE_MEMORY_FD_TYPE_OPAQUE) {
|
||||
os_free_fd(alloc->data);
|
||||
} else {
|
||||
munmap(alloc->data, alloc->size);
|
||||
if (alloc->dmabuf_fd >= 0)
|
||||
close(alloc->dmabuf_fd);
|
||||
if (alloc->mem_fd >= 0)
|
||||
close(alloc->mem_fd);
|
||||
}
|
||||
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1115,7 +1354,7 @@ llvmpipe_resource_get_param(struct pipe_screen *screen,
|
|||
|
||||
switch (param) {
|
||||
case PIPE_RESOURCE_PARAM_NPLANES:
|
||||
*value = 1;
|
||||
*value = lpr->dt ? util_format_get_num_planes(lpr->dt_format) : 1;
|
||||
return true;
|
||||
case PIPE_RESOURCE_PARAM_STRIDE:
|
||||
*value = lpr->row_stride[level];
|
||||
|
@ -1128,7 +1367,7 @@ llvmpipe_resource_get_param(struct pipe_screen *screen,
|
|||
return true;
|
||||
#ifndef _WIN32
|
||||
case PIPE_RESOURCE_PARAM_MODIFIER:
|
||||
*value = DRM_FORMAT_MOD_INVALID;
|
||||
*value = lpr->dt ? DRM_FORMAT_MOD_LINEAR : DRM_FORMAT_MOD_INVALID;
|
||||
return true;
|
||||
#endif
|
||||
case PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED:
|
||||
|
@ -1159,6 +1398,28 @@ llvmpipe_resource_get_param(struct pipe_screen *screen,
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
static void
|
||||
llvmpipe_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count)
|
||||
{
|
||||
if (max) {
|
||||
*count = 1;
|
||||
*modifiers = DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
llvmpipe_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format, bool *external_only)
|
||||
{
|
||||
return modifier == DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
llvmpipe_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format)
|
||||
{
|
||||
return modifier == DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
|
||||
|
@ -1197,6 +1458,12 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
|
|||
screen->allocate_memory_fd = llvmpipe_allocate_memory_fd;
|
||||
screen->import_memory_fd = llvmpipe_import_memory_fd;
|
||||
screen->free_memory_fd = llvmpipe_free_memory_fd;
|
||||
#endif
|
||||
#ifdef HAVE_LIBDRM
|
||||
screen->query_dmabuf_modifiers = llvmpipe_query_dmabuf_modifiers;
|
||||
screen->is_dmabuf_modifier_supported = llvmpipe_is_dmabuf_modifier_supported;
|
||||
screen->get_dmabuf_modifier_planes = llvmpipe_get_dmabuf_modifier_planes;
|
||||
screen->resource_create_with_modifiers = llvmpipe_resource_create_with_modifiers;
|
||||
#endif
|
||||
screen->map_memory = llvmpipe_map_memory;
|
||||
screen->unmap_memory = llvmpipe_unmap_memory;
|
||||
|
|
|
@ -44,6 +44,12 @@ enum lp_texture_usage
|
|||
LP_TEX_USAGE_WRITE_ALL
|
||||
};
|
||||
|
||||
enum llvmpipe_memory_fd_type
|
||||
{
|
||||
LLVMPIPE_MEMORY_FD_TYPE_OPAQUE,
|
||||
LLVMPIPE_MEMORY_FD_TYPE_DMA_BUF,
|
||||
};
|
||||
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
|
@ -52,6 +58,13 @@ struct llvmpipe_screen;
|
|||
|
||||
struct sw_displaytarget;
|
||||
|
||||
struct llvmpipe_memory_fd_alloc {
|
||||
void *data;
|
||||
enum llvmpipe_memory_fd_type type;
|
||||
int mem_fd;
|
||||
int dmabuf_fd;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* llvmpipe subclass of pipe_resource. A texture, drawing surface,
|
||||
|
@ -81,6 +94,7 @@ struct llvmpipe_resource
|
|||
* usage.
|
||||
*/
|
||||
struct sw_displaytarget *dt;
|
||||
enum pipe_format dt_format;
|
||||
|
||||
/**
|
||||
* Malloc'ed data for regular textures, or a mapping to dt above.
|
||||
|
@ -101,8 +115,12 @@ struct llvmpipe_resource
|
|||
|
||||
uint64_t size_required;
|
||||
uint64_t backing_offset;
|
||||
#ifdef HAVE_LIBDRM
|
||||
struct llvmpipe_memory_fd_alloc *dmabuf_alloc;
|
||||
#endif
|
||||
bool backable;
|
||||
bool imported_memory;
|
||||
bool dmabuf;
|
||||
#if MESA_DEBUG
|
||||
struct list_head list;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue