From: Dave Airlie <airl...@redhat.com> Signed-off-by: Andres Rodriguez <andre...@gmail.com> --- src/gallium/drivers/radeon/r600_pipe_common.h | 7 ++ src/gallium/drivers/radeon/r600_texture.c | 112 ++++++++++++++++++++++++++ 2 files changed, 119 insertions(+)
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index b22a3a7..4c1a706 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -377,6 +377,13 @@ union r600_mmio_counters { unsigned array[0]; }; +struct r600_memory_object { + struct pipe_memory_object b; + struct pb_buffer *buf; + uint32_t stride; + uint32_t offset; +}; + struct r600_common_screen { struct pipe_screen b; struct radeon_winsys *ws; diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 2deb56a..0baa0ee 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -2822,10 +2822,122 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx, } } +static struct pipe_memory_object * +r600_memobj_from_handle(struct pipe_screen *screen, + struct winsys_handle *whandle, + bool dedicated) +{ + struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; + struct r600_memory_object *memobj = CALLOC_STRUCT(r600_memory_object); + struct pb_buffer *buf = NULL; + uint32_t stride, offset; + + if (!memobj) + return NULL; + + buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, + &stride, &offset); + if (!buf) + return NULL; + + memobj->b.dedicated = dedicated; + memobj->buf = buf; + memobj->stride = stride; + memobj->offset = offset; + + return (struct pipe_memory_object *)memobj; +} + +static void +r600_memobj_destroy(struct pipe_screen *screen, + struct pipe_memory_object *memobj) +{ + free(memobj); +} + +static struct pipe_resource * +r600_texture_from_memobj(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pipe_memory_object *_memobj, + uint64_t offset) +{ + int r; + struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; + struct r600_memory_object *memobj = (struct r600_memory_object *)_memobj; + struct r600_texture *rtex; + struct radeon_surf surface; + struct radeon_bo_metadata metadata = {}; + unsigned array_mode; + + if (memobj->b.dedicated) { + rscreen->ws->buffer_get_metadata(memobj->buf, &metadata); + + surface.u.legacy.pipe_config = metadata.u.legacy.pipe_config; + surface.u.legacy.bankw = metadata.u.legacy.bankw; + surface.u.legacy.bankh = metadata.u.legacy.bankh; + surface.u.legacy.tile_split = metadata.u.legacy.tile_split; + surface.u.legacy.mtilea = metadata.u.legacy.mtilea; + surface.u.legacy.num_banks = metadata.u.legacy.num_banks; + + if (metadata.u.legacy.macrotile == RADEON_LAYOUT_TILED) + array_mode = RADEON_SURF_MODE_2D; + else if (metadata.u.legacy.microtile == RADEON_LAYOUT_TILED) + array_mode = RADEON_SURF_MODE_1D; + else + array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED; + } else { + /** + * The bo metadata is unset for un-dedicated images. So we fall + * back to linear. See answer to question 5 of the + * VK_KHX_external_memory spec for some details. + * + * It is possible that this case isn't going to work if the + * surface pitch isn't correctly aligned by default. + * + * In order to support it correctly we require multi-image + * metadata to be syncrhonized between radv and radeonsi. The + * semantics of associating multiple image metadata to a memory + * object on the vulkan export side are not concretely defined + * either. + * + * All the use cases we are aware of at the moment for memory + * objects use dedicated allocations. So lets keep the initial + * implementation simple. + * + * A possible alternative is to attempt to reconstruct the + * tiling information when the TexParameter TEXTURE_TILING_EXT + * is set. + */ + array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED; + + } + + r = r600_init_surface(rscreen, &surface, templ, + array_mode, memobj->stride, + offset, true, metadata.u.legacy.scanout, + false, false); + if (r) + return NULL; + + rtex = r600_texture_create_object(screen, templ, memobj->buf, &surface); + if (!rtex) + return NULL; + + rtex->resource.b.is_shared = true; + + if (rscreen->apply_opaque_metadata) + rscreen->apply_opaque_metadata(rscreen, rtex, &metadata); + + return &rtex->resource.b.b; +} + void r600_init_screen_texture_functions(struct r600_common_screen *rscreen) { rscreen->b.resource_from_handle = r600_texture_from_handle; rscreen->b.resource_get_handle = r600_texture_get_handle; + rscreen->b.resource_from_memobj = r600_texture_from_memobj; + rscreen->b.memobj_create_from_handle = r600_memobj_from_handle; + rscreen->b.memobj_destroy = r600_memobj_destroy; } void r600_init_context_texture_functions(struct r600_common_context *rctx) -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev