From 03af98abe26e738f2d4175a5e97dc9d62e386493 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Tue, 22 Sep 2020 14:23:22 +0300 Subject: [PATCH] radeonsi: support for external buffers (ext_external_objects) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit So far, the callback to create a resource from a memory object had code for importing textures only. Modified it to allow importing buffers too. Fixes the following piglit tests: - ext_external_objects/vk-buf-exchange - ext_external_objects/vk-pix-buf-update-errors - ext_external_objects/vk-vert-buf-update-errors - ext_external_objects/vk-vert-buf-reuse v2: Used si_alloc_buffer_struct instead of CALLOC v3: Fixed indentation issue, removed free in case of unsuccessful allocation, joined two if conditions together Signed-off-by: Eleni Maria Stea Reviewed-by: Marek Olšák Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_buffer.c | 33 +++++++++++++++++++++++++++++++ src/gallium/drivers/radeonsi/si_pipe.h | 5 +++++ src/gallium/drivers/radeonsi/si_texture.c | 23 ++++++++++++++------- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index 1237074..31f1318 100644 --- a/src/gallium/drivers/radeonsi/si_buffer.c +++ b/src/gallium/drivers/radeonsi/si_buffer.c @@ -731,6 +731,39 @@ static struct pipe_resource *si_buffer_from_user_memory(struct pipe_screen *scre return &buf->b.b; } +struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pb_buffer *imported_buf, + bool dedicated) +{ + struct si_screen *sscreen = (struct si_screen *)screen; + struct si_resource *res = si_alloc_buffer_struct(screen, templ); + + if (!res) + return 0; + + res->buf = imported_buf; + res->gpu_address = sscreen->ws->buffer_get_virtual_address(res->buf); + res->bo_size = imported_buf->size; + res->bo_alignment = imported_buf->alignment; + res->domains = sscreen->ws->buffer_get_initial_domain(res->buf); + + if (res->domains & RADEON_DOMAIN_VRAM) + res->vram_usage = res->bo_size; + else if (res->domains & RADEON_DOMAIN_GTT) + res->gart_usage = res->bo_size; + + if (sscreen->ws->buffer_get_flags) + res->flags = sscreen->ws->buffer_get_flags(res->buf); + + if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE) { + res->b.b.flags |= SI_RESOURCE_FLAG_UNMAPPABLE; + res->flags |= RADEON_FLAG_SPARSE; + } + + return &res->b.b; +} + static struct pipe_resource *si_resource_create(struct pipe_screen *screen, const struct pipe_resource *templ) { diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 7db1650..6cadec8 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1926,4 +1926,9 @@ static inline unsigned si_get_shader_wave_size(struct si_shader *shader) #define PRINT_ERR(fmt, args...) \ fprintf(stderr, "EE %s:%d %s - " fmt, __FILE__, __LINE__, __func__, ##args) +struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pb_buffer *imported_buf, + bool dedicated); + #endif diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 93e52e7..25b6c38 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -2271,17 +2271,26 @@ static void si_memobj_destroy(struct pipe_screen *screen, struct pipe_memory_obj free(memobj); } -static struct pipe_resource *si_texture_from_memobj(struct pipe_screen *screen, +static struct pipe_resource *si_resource_from_memobj(struct pipe_screen *screen, const struct pipe_resource *templ, struct pipe_memory_object *_memobj, uint64_t offset) { struct si_screen *sscreen = (struct si_screen *)screen; struct si_memory_object *memobj = (struct si_memory_object *)_memobj; - struct pipe_resource *tex = si_texture_from_winsys_buffer( - sscreen, templ, memobj->buf, memobj->stride, offset, - PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE | PIPE_HANDLE_USAGE_SHADER_WRITE, memobj->b.dedicated); - if (!tex) + struct pipe_resource *res; + + if (templ->target == PIPE_BUFFER) + res = si_buffer_from_winsys_buffer(screen, templ, memobj->buf, + memobj->b.dedicated); + else + res = si_texture_from_winsys_buffer(sscreen, templ, memobj->buf, + memobj->stride, + offset, + PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE | PIPE_HANDLE_USAGE_SHADER_WRITE, + memobj->b.dedicated); + + if (!res) return NULL; /* si_texture_from_winsys_buffer doesn't increment refcount of @@ -2289,7 +2298,7 @@ static struct pipe_resource *si_texture_from_memobj(struct pipe_screen *screen, */ struct pb_buffer *buf = NULL; pb_reference(&buf, memobj->buf); - return tex; + return res; } static bool si_check_resource_capability(struct pipe_screen *screen, struct pipe_resource *resource, @@ -2317,7 +2326,7 @@ void si_init_screen_texture_functions(struct si_screen *sscreen) sscreen->b.resource_get_handle = si_texture_get_handle; sscreen->b.resource_get_param = si_resource_get_param; sscreen->b.resource_get_info = si_texture_get_info; - sscreen->b.resource_from_memobj = si_texture_from_memobj; + sscreen->b.resource_from_memobj = si_resource_from_memobj; sscreen->b.memobj_create_from_handle = si_memobj_from_handle; sscreen->b.memobj_destroy = si_memobj_destroy; sscreen->b.check_resource_capability = si_check_resource_capability; -- 2.7.4