diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index 33ce616d21d..1d0673f9362 100644 --- a/src/gallium/drivers/radeonsi/si_buffer.c +++ b/src/gallium/drivers/radeonsi/si_buffer.c @@ -657,31 +657,57 @@ static struct pipe_resource *si_buffer_from_user_memory(struct pipe_screen *scre struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen, const struct pipe_resource *templ, struct pb_buffer *imported_buf, - bool dedicated) + uint64_t offset) { + if (offset + templ->width0 > imported_buf->size) + return NULL; + struct si_screen *sscreen = (struct si_screen *)screen; struct si_resource *res = si_alloc_buffer_struct(screen, templ, false); if (!res) - return 0; + return NULL; - res->buf = imported_buf; - res->gpu_address = sscreen->ws->buffer_get_virtual_address(res->buf); - res->bo_size = imported_buf->size; - res->bo_alignment_log2 = imported_buf->alignment_log2; - res->domains = sscreen->ws->buffer_get_initial_domain(res->buf); + enum radeon_bo_domain domains = sscreen->ws->buffer_get_initial_domain(res->buf); - res->memory_usage_kb = MAX2(1, res->bo_size / 1024); + /* Get or guess the BO flags. */ + unsigned flags = RADEON_FLAG_NO_SUBALLOC; if (sscreen->ws->buffer_get_flags) - res->flags = sscreen->ws->buffer_get_flags(res->buf); + res->flags |= sscreen->ws->buffer_get_flags(res->buf); + else + flags |= RADEON_FLAG_GTT_WC; /* unknown flags, guess them */ - if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE) { - res->b.b.flags |= SI_RESOURCE_FLAG_UNMAPPABLE; - res->flags |= RADEON_FLAG_SPARSE; + /* Deduce the usage. */ + switch (domains) { + case RADEON_DOMAIN_VRAM: + case RADEON_DOMAIN_VRAM_GTT: + res->b.b.usage = PIPE_USAGE_DEFAULT; + break; + + default: + /* Other values are interpreted as GTT. */ + domains = RADEON_DOMAIN_GTT; + + if (flags & RADEON_FLAG_GTT_WC) + res->b.b.usage = PIPE_USAGE_STREAM; + else + res->b.b.usage = PIPE_USAGE_STAGING; } + si_init_resource_fields(sscreen, res, imported_buf->size, + 1 << imported_buf->alignment_log2); + + res->b.is_shared = true; res->b.buffer_id_unique = util_idalloc_mt_alloc(&sscreen->buffer_ids); + res->buf = imported_buf; + res->gpu_address = sscreen->ws->buffer_get_virtual_address(res->buf) + offset; + res->domains = domains; + res->flags = flags; + + util_range_add((struct pipe_resource *)templ, &res->valid_buffer_range, 0, templ->width0); + util_range_add((struct pipe_resource *)templ, &res->b.valid_buffer_range, 0, templ->width0); + return &res->b.b; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 211ec7f740e..af83efcf0e8 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1333,6 +1333,10 @@ struct pipe_resource *pipe_aligned_buffer_create(struct pipe_screen *screen, uns unsigned usage, unsigned size, unsigned alignment); struct si_resource *si_aligned_buffer_create(struct pipe_screen *screen, unsigned flags, unsigned usage, unsigned size, unsigned alignment); +struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pb_buffer *imported_buf, + uint64_t offset); void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst, struct pipe_resource *src, unsigned num_rebinds, uint32_t rebind_mask, uint32_t delete_buffer_id); @@ -2037,11 +2041,6 @@ static inline unsigned si_num_vbos_in_user_sgprs(struct si_screen *sscreen) #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); - #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 39a230c8f5c..0d8f293ee93 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -2230,8 +2230,7 @@ static struct pipe_resource *si_resource_from_memobj(struct pipe_screen *screen, struct pipe_resource *res; if (templ->target == PIPE_BUFFER) - res = si_buffer_from_winsys_buffer(screen, templ, memobj->buf, - memobj->b.dedicated); + res = si_buffer_from_winsys_buffer(screen, templ, memobj->buf, offset); else res = si_texture_from_winsys_buffer(sscreen, templ, memobj->buf, memobj->stride,