summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2020-06-19 16:27:32 +1000
committerDave Airlie <airlied@redhat.com>2020-08-17 14:30:49 +1000
commit94e4a17f29b5f487213b37e8376eadd87308856a (patch)
treea4c611ea312f3dbdc4c3f832463d8647cc0ad177 /src/gallium/drivers/llvmpipe
parentecb617a6a757a375a66b3c2ad25990011624c41a (diff)
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>
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c139
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h4
2 files changed, 119 insertions, 24 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index efcfbed80d5..e93b8a666ac 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -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;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 5965ef8443f..ba2cdffc878 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -91,6 +91,10 @@ struct llvmpipe_resource
unsigned id; /**< temporary, for debugging */
unsigned sample_stride;
+
+ uint64_t size_required;
+ uint64_t backing_offset;
+ bool backable;
#ifdef DEBUG
/** for linked list */
struct llvmpipe_resource *prev, *next;