diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index 1237074e0c6..31f1318542d 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 7db1650cd0b..6cadec8a4d7 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 93e52e75c8d..25b6c380e3d 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;