summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/si_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_texture.c')
-rw-r--r--src/gallium/drivers/radeonsi/si_texture.c152
1 files changed, 71 insertions, 81 deletions
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index bdd19d12545..450e819a311 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -1471,45 +1471,62 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
NULL, &surface);
}
-static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
- const struct pipe_resource *templ,
- struct winsys_handle *whandle,
- unsigned usage)
+static struct pipe_resource *si_texture_from_winsys_buffer(struct si_screen *sscreen,
+ const struct pipe_resource *templ,
+ struct pb_buffer *buf,
+ unsigned stride,
+ unsigned offset,
+ unsigned usage,
+ bool dedicated)
{
- struct si_screen *sscreen = (struct si_screen*)screen;
- struct pb_buffer *buf = NULL;
- unsigned stride = 0, offset = 0;
enum radeon_surf_mode array_mode;
struct radeon_surf surface = {};
- int r;
struct radeon_bo_metadata metadata = {};
struct si_texture *tex;
bool is_scanout;
+ int r;
- /* Support only 2D textures without mipmaps */
- if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
- templ->depth0 != 1 || templ->last_level != 0)
- return NULL;
-
- buf = sscreen->ws->buffer_from_handle(sscreen->ws, whandle, &stride, &offset);
- if (!buf)
- return NULL;
-
- sscreen->ws->buffer_get_metadata(buf, &metadata);
- si_surface_import_metadata(sscreen, &surface, &metadata,
- &array_mode, &is_scanout);
+ if (dedicated) {
+ sscreen->ws->buffer_get_metadata(buf, &metadata);
+ si_surface_import_metadata(sscreen, &surface, &metadata,
+ &array_mode, &is_scanout);
+ } 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;
+ is_scanout = false;
+ }
unsigned num_color_samples = si_get_num_color_samples(sscreen, templ, true);
r = si_init_surface(sscreen, &surface, templ, num_color_samples,
array_mode, stride, offset, true, is_scanout,
false, false);
- if (r) {
+ if (r)
return NULL;
- }
- tex = si_texture_create_object(screen, templ, num_color_samples,
- buf, &surface);
+ tex = si_texture_create_object(&sscreen->b, templ, num_color_samples,
+ buf, &surface);
if (!tex)
return NULL;
@@ -1522,6 +1539,28 @@ static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
return &tex->buffer.b.b;
}
+static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle,
+ unsigned usage)
+{
+ struct si_screen *sscreen = (struct si_screen*)screen;
+ struct pb_buffer *buf = NULL;
+ unsigned stride = 0, offset = 0;
+
+ /* Support only 2D textures without mipmaps */
+ if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
+ templ->depth0 != 1 || templ->last_level != 0)
+ return NULL;
+
+ buf = sscreen->ws->buffer_from_handle(sscreen->ws, whandle, &stride, &offset);
+ if (!buf)
+ return NULL;
+
+ return si_texture_from_winsys_buffer(sscreen, templ, buf, stride,
+ offset, usage, true);
+}
+
bool si_init_flushed_depth_texture(struct pipe_context *ctx,
struct pipe_resource *texture,
struct si_texture **staging)
@@ -2392,71 +2431,22 @@ si_texture_from_memobj(struct pipe_screen *screen,
struct pipe_memory_object *_memobj,
uint64_t offset)
{
- int r;
struct si_screen *sscreen = (struct si_screen*)screen;
struct r600_memory_object *memobj = (struct r600_memory_object *)_memobj;
- struct si_texture *tex;
- struct radeon_surf surface = {};
- struct radeon_bo_metadata metadata = {};
- enum radeon_surf_mode array_mode;
- bool is_scanout;
- struct pb_buffer *buf = NULL;
-
- if (memobj->b.dedicated) {
- sscreen->ws->buffer_get_metadata(memobj->buf, &metadata);
- si_surface_import_metadata(sscreen, &surface, &metadata,
- &array_mode, &is_scanout);
- } 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;
- is_scanout = false;
- }
-
- unsigned num_color_samples = si_get_num_color_samples(sscreen, templ, true);
-
- r = si_init_surface(sscreen, &surface, templ, num_color_samples,
- array_mode, memobj->stride, offset, true,
- is_scanout, false, false);
- if (r)
- return NULL;
-
- tex = si_texture_create_object(screen, templ, num_color_samples,
- memobj->buf, &surface);
+ struct pipe_resource *tex =
+ si_texture_from_winsys_buffer(sscreen, templ, memobj->buf,
+ memobj->stride, offset,
+ PIPE_HANDLE_USAGE_READ_WRITE,
+ memobj->b.dedicated);
if (!tex)
return NULL;
- /* si_texture_create_object doesn't increment refcount of
+ /* si_texture_from_winsys_buffer doesn't increment refcount of
* memobj->buf, so increment it here.
*/
+ struct pb_buffer *buf = NULL;
pb_reference(&buf, memobj->buf);
-
- tex->buffer.b.is_shared = true;
- tex->buffer.external_usage = PIPE_HANDLE_USAGE_READ_WRITE;
-
- si_apply_opaque_metadata(sscreen, tex, &metadata);
-
- return &tex->buffer.b.b;
+ return tex;
}
static bool si_check_resource_capability(struct pipe_screen *screen,