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:
@@ -171,6 +171,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
|
|||||||
lpr->sample_stride = total_size;
|
lpr->sample_stride = total_size;
|
||||||
total_size *= num_samples;
|
total_size *= num_samples;
|
||||||
|
|
||||||
|
lpr->size_required = total_size;
|
||||||
if (allocate) {
|
if (allocate) {
|
||||||
lpr->tex_data = align_malloc(total_size, mip_align);
|
lpr->tex_data = align_malloc(total_size, mip_align);
|
||||||
if (!lpr->tex_data) {
|
if (!lpr->tex_data) {
|
||||||
@@ -242,9 +243,9 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
|
|||||||
|
|
||||||
|
|
||||||
static struct pipe_resource *
|
static struct pipe_resource *
|
||||||
llvmpipe_resource_create_front(struct pipe_screen *_screen,
|
llvmpipe_resource_create_all(struct pipe_screen *_screen,
|
||||||
const struct pipe_resource *templat,
|
const struct pipe_resource *templat,
|
||||||
const void *map_front_private)
|
const void *map_front_private, bool alloc_backing)
|
||||||
{
|
{
|
||||||
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
||||||
struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
|
struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
|
||||||
@@ -267,7 +268,7 @@ llvmpipe_resource_create_front(struct pipe_screen *_screen,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* texture map */
|
/* texture map */
|
||||||
if (!llvmpipe_texture_layout(screen, lpr, true))
|
if (!llvmpipe_texture_layout(screen, lpr, alloc_backing))
|
||||||
goto fail;
|
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
|
* read/write always LP_RASTER_BLOCK_SIZE pixels, but the element
|
||||||
* offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE.
|
* 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
|
* buffers don't really have stride but it's probably safer
|
||||||
* (for code doing same calculations for buffers and textures)
|
* (for code doing same calculations for buffers and textures)
|
||||||
* to put something sane in there.
|
* to put something sane in there.
|
||||||
*/
|
*/
|
||||||
lpr->row_stride[0] = bytes;
|
lpr->row_stride[0] = bytes;
|
||||||
if (!lpr->data)
|
|
||||||
goto fail;
|
lpr->size_required = bytes;
|
||||||
memset(lpr->data, 0, 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++;
|
lpr->id = id_counter++;
|
||||||
@@ -309,6 +317,13 @@ llvmpipe_resource_create_front(struct pipe_screen *_screen,
|
|||||||
return NULL;
|
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 *
|
static struct pipe_resource *
|
||||||
llvmpipe_resource_create(struct pipe_screen *_screen,
|
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);
|
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
|
static void
|
||||||
llvmpipe_resource_destroy(struct pipe_screen *pscreen,
|
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_screen *screen = llvmpipe_screen(pscreen);
|
||||||
struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
|
struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
|
||||||
|
|
||||||
if (lpr->dt) {
|
if (!lpr->backable) {
|
||||||
/* display target */
|
if (lpr->dt) {
|
||||||
struct sw_winsys *winsys = screen->winsys;
|
/* display target */
|
||||||
winsys->displaytarget_destroy(winsys, lpr->dt);
|
struct sw_winsys *winsys = screen->winsys;
|
||||||
}
|
winsys->displaytarget_destroy(winsys, lpr->dt);
|
||||||
else if (llvmpipe_resource_is_texture(pt)) {
|
}
|
||||||
/* free linear image data */
|
else if (llvmpipe_resource_is_texture(pt)) {
|
||||||
if (lpr->tex_data) {
|
/* free linear image data */
|
||||||
align_free(lpr->tex_data);
|
if (lpr->tex_data) {
|
||||||
lpr->tex_data = NULL;
|
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
|
#ifdef DEBUG
|
||||||
if (lpr->next)
|
if (lpr->next)
|
||||||
remove_from_list(lpr);
|
remove_from_list(lpr);
|
||||||
@@ -793,6 +824,45 @@ llvmpipe_memory_barrier(struct pipe_context *pipe,
|
|||||||
llvmpipe_finish(pipe, "barrier");
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
llvmpipe_print_resources(void)
|
llvmpipe_print_resources(void)
|
||||||
@@ -814,6 +884,17 @@ llvmpipe_print_resources(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
|
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_from_handle = llvmpipe_resource_from_handle;
|
||||||
screen->resource_get_handle = llvmpipe_resource_get_handle;
|
screen->resource_get_handle = llvmpipe_resource_get_handle;
|
||||||
screen->can_create_resource = llvmpipe_can_create_resource;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -91,6 +91,10 @@ struct llvmpipe_resource
|
|||||||
unsigned id; /**< temporary, for debugging */
|
unsigned id; /**< temporary, for debugging */
|
||||||
|
|
||||||
unsigned sample_stride;
|
unsigned sample_stride;
|
||||||
|
|
||||||
|
uint64_t size_required;
|
||||||
|
uint64_t backing_offset;
|
||||||
|
bool backable;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/** for linked list */
|
/** for linked list */
|
||||||
struct llvmpipe_resource *prev, *next;
|
struct llvmpipe_resource *prev, *next;
|
||||||
|
Reference in New Issue
Block a user