llvmpipe: add support for memory allocation APIs

This adds llvmpipe driver support for the vulkan split memory/resource API
and the the don't overallocate flag.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6082>
This commit is contained in:
Dave Airlie
2020-06-19 16:27:32 +10:00
parent ecb617a6a7
commit 94e4a17f29
2 changed files with 119 additions and 24 deletions

View File

@@ -171,6 +171,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
lpr->sample_stride = total_size;
total_size *= num_samples;
lpr->size_required = total_size;
if (allocate) {
lpr->tex_data = align_malloc(total_size, mip_align);
if (!lpr->tex_data) {
@@ -242,9 +243,9 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
static struct pipe_resource *
llvmpipe_resource_create_front(struct pipe_screen *_screen,
const struct pipe_resource *templat,
const void *map_front_private)
llvmpipe_resource_create_all(struct pipe_screen *_screen,
const struct pipe_resource *templat,
const void *map_front_private, bool alloc_backing)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
@@ -267,7 +268,7 @@ llvmpipe_resource_create_front(struct pipe_screen *_screen,
}
else {
/* texture map */
if (!llvmpipe_texture_layout(screen, lpr, true))
if (!llvmpipe_texture_layout(screen, lpr, alloc_backing))
goto fail;
}
}
@@ -283,17 +284,24 @@ llvmpipe_resource_create_front(struct pipe_screen *_screen,
* read/write always LP_RASTER_BLOCK_SIZE pixels, but the element
* offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE.
*/
lpr->data = align_malloc(bytes + (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float), 64);
/*
* buffers don't really have stride but it's probably safer
* (for code doing same calculations for buffers and textures)
* to put something sane in there.
*/
lpr->row_stride[0] = bytes;
if (!lpr->data)
goto fail;
memset(lpr->data, 0, bytes);
lpr->size_required = bytes;
if (!(templat->flags & PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE))
lpr->size_required += (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float);
if (alloc_backing) {
lpr->data = align_malloc(lpr->size_required, 64);
if (!lpr->data)
goto fail;
memset(lpr->data, 0, bytes);
}
}
lpr->id = id_counter++;
@@ -309,6 +317,13 @@ llvmpipe_resource_create_front(struct pipe_screen *_screen,
return NULL;
}
static struct pipe_resource *
llvmpipe_resource_create_front(struct pipe_screen *_screen,
const struct pipe_resource *templat,
const void *map_front_private)
{
return llvmpipe_resource_create_all(_screen, templat, map_front_private, true);
}
static struct pipe_resource *
llvmpipe_resource_create(struct pipe_screen *_screen,
@@ -317,6 +332,21 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
return llvmpipe_resource_create_front(_screen, templat, NULL);
}
static struct pipe_resource *
llvmpipe_resource_create_unbacked(struct pipe_screen *_screen,
const struct pipe_resource *templat,
uint64_t *size_required)
{
struct pipe_resource *pt;
struct llvmpipe_resource *lpr;
pt = llvmpipe_resource_create_all(_screen, templat, NULL, false);
if (!pt)
return pt;
lpr = llvmpipe_resource(pt);
lpr->backable = true;
*size_required = lpr->size_required;
return pt;
}
static void
llvmpipe_resource_destroy(struct pipe_screen *pscreen,
@@ -325,23 +355,24 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
if (lpr->dt) {
/* display target */
struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpr->dt);
}
else if (llvmpipe_resource_is_texture(pt)) {
/* free linear image data */
if (lpr->tex_data) {
align_free(lpr->tex_data);
lpr->tex_data = NULL;
if (!lpr->backable) {
if (lpr->dt) {
/* display target */
struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpr->dt);
}
else if (llvmpipe_resource_is_texture(pt)) {
/* free linear image data */
if (lpr->tex_data) {
align_free(lpr->tex_data);
lpr->tex_data = NULL;
}
}
else if (!lpr->userBuffer) {
if (lpr->data)
align_free(lpr->data);
}
}
else if (!lpr->userBuffer) {
assert(lpr->data);
align_free(lpr->data);
}
#ifdef DEBUG
if (lpr->next)
remove_from_list(lpr);
@@ -793,6 +824,45 @@ llvmpipe_memory_barrier(struct pipe_context *pipe,
llvmpipe_finish(pipe, "barrier");
}
static struct pipe_memory_allocation *llvmpipe_allocate_memory(struct pipe_screen *screen, uint64_t size)
{
return os_malloc_aligned(size, 256);
}
static void llvmpipe_free_memory(struct pipe_screen *screen,
struct pipe_memory_allocation *pmem)
{
os_free_aligned(pmem);
}
static void llvmpipe_resource_bind_backing(struct pipe_screen *screen,
struct pipe_resource *pt,
struct pipe_memory_allocation *pmem,
uint64_t offset)
{
struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
if (!lpr->backable)
return;
if (llvmpipe_resource_is_texture(&lpr->base))
lpr->tex_data = (char *)pmem + offset;
else
lpr->data = (char *)pmem + offset;
lpr->backing_offset = offset;
}
static void *llvmpipe_map_memory(struct pipe_screen *screen,
struct pipe_memory_allocation *pmem)
{
return pmem;
}
static void llvmpipe_unmap_memory(struct pipe_screen *screen,
struct pipe_memory_allocation *pmem)
{
}
#ifdef DEBUG
void
llvmpipe_print_resources(void)
@@ -814,6 +884,17 @@ llvmpipe_print_resources(void)
}
#endif
static void
llvmpipe_get_resource_info(struct pipe_screen *screen,
struct pipe_resource *resource,
unsigned *stride,
unsigned *offset)
{
struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
*stride = lpr->row_stride[0];
*offset = 0;
}
void
llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
@@ -836,6 +917,16 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
screen->resource_from_handle = llvmpipe_resource_from_handle;
screen->resource_get_handle = llvmpipe_resource_get_handle;
screen->can_create_resource = llvmpipe_can_create_resource;
screen->resource_create_unbacked = llvmpipe_resource_create_unbacked;
screen->resource_get_info = llvmpipe_get_resource_info;
screen->allocate_memory = llvmpipe_allocate_memory;
screen->free_memory = llvmpipe_free_memory;
screen->map_memory = llvmpipe_map_memory;
screen->unmap_memory = llvmpipe_unmap_memory;
screen->resource_bind_backing = llvmpipe_resource_bind_backing;
}