summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/etnaviv
diff options
context:
space:
mode:
authorLucas Stach <[email protected]>2017-06-09 18:23:16 +0200
committerLucas Stach <[email protected]>2017-07-19 16:26:49 +0200
commitc4818808991134cc7d7741c8f29dc50f6d2102a0 (patch)
tree79added36f8a71a9687360cb024988e5822e4fe8 /src/gallium/drivers/etnaviv
parenta9fad437f7ad1c1a8c0a694c2d8b4b6ad4d32098 (diff)
renderonly/etnaviv: stop importing resource from renderonly
The current way of importing the resource from renderonly after allocation is opaque and is taking away control from the driver, which it needs in order to implement more advanced scenarios than the simple linear scanout with matching stride alignments. Signed-off-by: Lucas Stach <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]> Acked-by: Daniel Stone <[email protected]>
Diffstat (limited to 'src/gallium/drivers/etnaviv')
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_clear_blit.c8
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_resource.c34
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_resource.h5
3 files changed, 35 insertions, 12 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
index d9ff9624fa4..b832dd8f263 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
@@ -610,10 +610,10 @@ etna_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
{
struct etna_resource *rsc = etna_resource(prsc);
- if (rsc->scanout) {
- if (etna_resource_older(etna_resource(rsc->scanout->prime), rsc)) {
- etna_copy_resource(pctx, rsc->scanout->prime, prsc, 0, 0);
- etna_resource(rsc->scanout->prime)->seqno = rsc->seqno;
+ if (rsc->external) {
+ if (etna_resource_older(etna_resource(rsc->external), rsc)) {
+ etna_copy_resource(pctx, rsc->external, prsc, 0, 0);
+ etna_resource(rsc->external)->seqno = rsc->seqno;
}
} else if (etna_resource_needs_flush(rsc)) {
etna_copy_resource(pctx, prsc, prsc, 0, 0);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c
index a709482c1b6..8d96baf2a04 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c
@@ -214,8 +214,20 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout,
rsc->bo = bo;
rsc->ts_bo = 0; /* TS is only created when first bound to surface */
- if (templat->bind & PIPE_BIND_SCANOUT)
- rsc->scanout = renderonly_scanout_for_resource(&rsc->base, screen->ro);
+ if (templat->bind & PIPE_BIND_SCANOUT) {
+ struct winsys_handle handle;
+ rsc->scanout = renderonly_scanout_for_resource(&rsc->base, screen->ro,
+ &handle);
+ if (!rsc->scanout)
+ goto free_rsc;
+
+ rsc->external = pscreen->resource_from_handle(pscreen, &rsc->base,
+ &handle,
+ PIPE_HANDLE_USAGE_WRITE);
+ close(handle.handle);
+ if (!rsc->external)
+ goto free_rsc;
+ }
if (DBG_ENABLED(ETNA_DBG_ZERO)) {
void *map = etna_bo_map(bo);
@@ -310,6 +322,7 @@ etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc)
list_delinit(&rsc->list);
pipe_resource_reference(&rsc->texture, NULL);
+ pipe_resource_reference(&rsc->external, NULL);
FREE(rsc);
}
@@ -379,16 +392,12 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
/* Render targets are linear in Xorg but must be tiled
* here. It would be nice if dri_drawable_get_format()
* set scanout for these buffers too. */
- struct etna_resource *tiled;
ptiled = etna_resource_create(pscreen, tmpl);
if (!ptiled)
goto fail;
- tiled = etna_resource(ptiled);
- tiled->scanout = renderonly_scanout_for_prime(prsc, screen->ro);
- if (!tiled->scanout)
- goto fail;
+ etna_resource(ptiled)->external = prsc;
return ptiled;
}
@@ -410,9 +419,18 @@ etna_resource_get_handle(struct pipe_screen *pscreen,
struct winsys_handle *handle, unsigned usage)
{
struct etna_resource *rsc = etna_resource(prsc);
+ /* Scanout is always attached to the base resource */
+ struct renderonly_scanout *scanout = rsc->scanout;
+
+ /*
+ * External resources are preferred, so a import->export chain of
+ * render/sampler incompatible buffers yield the same handle.
+ */
+ if (rsc->external)
+ rsc = etna_resource(rsc->external);
if (handle->type == DRM_API_HANDLE_TYPE_KMS &&
- renderonly_get_handle(rsc->scanout, handle))
+ renderonly_get_handle(scanout, handle))
return TRUE;
return etna_screen_bo_get_handle(pscreen, rsc->bo, rsc->levels[0].stride,
diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h
index 3507e5ccecb..5f563c06adc 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h
@@ -75,6 +75,11 @@ struct etna_resource {
/* When we are rendering to a texture, we need a differently tiled resource */
struct pipe_resource *texture;
+ /*
+ * If imported resources have an render/sampler incompatible tiling, we keep
+ * them as an external resource, which is blitted as needed.
+ */
+ struct pipe_resource *external;
enum etna_resource_status status;