summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/etnaviv
diff options
context:
space:
mode:
authorJonathan Marek <[email protected]>2019-08-10 17:00:32 -0400
committerJonathan Marek <[email protected]>2019-10-11 07:26:52 -0400
commitb9627765303356328c409cd59bef43d15f4eafcf (patch)
treeb981fe2476fafd92fc45c672d9012a06423d1313 /src/gallium/drivers/etnaviv
parente7e02435a88ec3262c556f56d2e279753b81f2dd (diff)
etnaviv: rework compatible render base
For PE-incompatible layouts, use a mechanism similar to what texture does to create a compatible base resource. Signed-off-by: Jonathan Marek <[email protected]> Reviewed-by: Christian Gmeiner <[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.c39
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_resource.h9
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_state.c21
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_surface.c39
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_surface.h2
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_texture.c4
7 files changed, 64 insertions, 58 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
index 4a3f62ac133..51d16aa19f7 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
@@ -138,10 +138,10 @@ etna_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
{
struct etna_resource *rsc = etna_resource(prsc);
- 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;
+ if (rsc->render) {
+ if (etna_resource_older(rsc, etna_resource(rsc->render))) {
+ etna_copy_resource(pctx, prsc, rsc->render, 0, 0);
+ rsc->seqno = etna_resource(rsc->render)->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 6cd5eca2930..2e55421360b 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c
@@ -472,12 +472,7 @@ etna_resource_create_modifiers(struct pipe_screen *pscreen,
static void
etna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc)
{
- struct etna_resource *res = etna_resource(prsc);
-
- if (res->external)
- etna_resource(res->external)->seqno++;
- else
- res->seqno++;
+ etna_resource(prsc)->seqno++;
}
static void
@@ -501,7 +496,7 @@ etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc)
renderonly_scanout_destroy(rsc->scanout, etna_screen(pscreen)->ro);
pipe_resource_reference(&rsc->texture, NULL);
- pipe_resource_reference(&rsc->external, NULL);
+ pipe_resource_reference(&rsc->render, NULL);
for (unsigned i = 0; i < ETNA_NUM_LOD; i++)
FREE(rsc->levels[i].patch_offsets);
@@ -587,29 +582,6 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
if (!rsc->pending_ctx)
goto fail;
- if (rsc->layout == ETNA_LAYOUT_LINEAR) {
- /*
- * Both sampler and pixel pipes can't handle linear, create a compatible
- * base resource, where we can attach the imported buffer as an external
- * resource.
- */
- struct pipe_resource tiled_templat = *tmpl;
-
- /*
- * Remove BIND_SCANOUT to avoid recursion, as etna_resource_create uses
- * this function to import the scanout buffer and get a tiled resource.
- */
- tiled_templat.bind &= ~PIPE_BIND_SCANOUT;
-
- ptiled = etna_resource_create(pscreen, &tiled_templat);
- if (!ptiled)
- goto fail;
-
- etna_resource(ptiled)->external = prsc;
-
- return ptiled;
- }
-
return prsc;
fail:
@@ -630,13 +602,6 @@ etna_resource_get_handle(struct pipe_screen *pscreen,
/* 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);
-
handle->stride = rsc->levels[0].stride;
handle->offset = rsc->levels[0].offset;
handle->modifier = layout_to_modifier(rsc->layout);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h
index 5beb8454afc..1c253006471 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h
@@ -84,13 +84,10 @@ struct etna_resource {
struct etna_resource_level levels[ETNA_NUM_LOD];
- /* When we are rendering to a texture, we need a differently tiled resource */
+ /* for when TE doesn't support the base layout */
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;
+ /* for when PE doesn't support the base layout */
+ struct pipe_resource *render;
enum etna_resource_status status;
diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c
index c629aab6494..79922f26647 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_state.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_state.c
@@ -108,14 +108,19 @@ etna_set_constant_buffer(struct pipe_context *pctx,
}
static void
-etna_update_render_resource(struct pipe_context *pctx, struct pipe_resource *pres)
+etna_update_render_resource(struct pipe_context *pctx, struct etna_resource *base)
{
- struct etna_resource *res = etna_resource(pres);
+ struct etna_resource *to = base, *from = base;
- if (res->texture && etna_resource_older(res, etna_resource(res->texture))) {
- /* The render buffer is older than the texture buffer. Copy it over. */
- etna_copy_resource(pctx, pres, res->texture, 0, pres->last_level);
- res->seqno = etna_resource(res->texture)->seqno;
+ if (base->texture && etna_resource_newer(etna_resource(base->texture), base))
+ from = etna_resource(base->texture);
+
+ if (base->render)
+ to = etna_resource(base->render);
+
+ if ((to != from) && etna_resource_older(to, from)) {
+ etna_copy_resource(pctx, &to->base, &from->base, 0, base->base.last_level);
+ to->seqno = from->seqno;
}
}
@@ -138,7 +143,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
assert(res->layout & ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
- etna_update_render_resource(pctx, cbuf->base.texture);
+ etna_update_render_resource(pctx, etna_resource(cbuf->prsc));
cs->PE_COLOR_FORMAT =
VIVS_PE_COLOR_FORMAT_FORMAT(translate_rs_format(cbuf->base.format)) |
@@ -215,7 +220,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
struct etna_surface *zsbuf = etna_surface(sv->zsbuf);
struct etna_resource *res = etna_resource(zsbuf->base.texture);
- etna_update_render_resource(pctx, zsbuf->base.texture);
+ etna_update_render_resource(pctx, etna_resource(zsbuf->prsc));
assert(res->layout &ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c b/src/gallium/drivers/etnaviv/etnaviv_surface.c
index 44295738008..d93519db6df 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_surface.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c
@@ -37,12 +37,47 @@
#include "hw/common.xml.h"
+#include "drm-uapi/drm_fourcc.h"
+
+static struct etna_resource *
+etna_render_handle_incompatible(struct pipe_context *pctx, struct pipe_resource *prsc)
+{
+ struct etna_context *ctx = etna_context(pctx);
+ struct etna_resource *res = etna_resource(prsc);
+ bool need_multitiled = ctx->specs.pixel_pipes > 1 && !ctx->specs.single_buffer;
+ bool want_supertiled = ctx->specs.can_supertile;
+
+ /* Resource is compatible if it is tiled and has multi tiling when required
+ * TODO: LINEAR_PE feature means render to linear is possible ?
+ */
+ if (res->layout != ETNA_LAYOUT_LINEAR &&
+ (!need_multitiled || (res->layout & ETNA_LAYOUT_BIT_MULTI)))
+ return res;
+
+ if (!res->render) {
+ struct pipe_resource templat = *prsc;
+ unsigned layout = ETNA_LAYOUT_TILED;
+ if (need_multitiled)
+ layout |= ETNA_LAYOUT_BIT_MULTI;
+ if (want_supertiled)
+ layout |= ETNA_LAYOUT_BIT_SUPER;
+
+ templat.bind &= (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_BLENDABLE);
+ res->render =
+ etna_resource_alloc(pctx->screen, layout,
+ DRM_FORMAT_MOD_LINEAR, &templat);
+ assert(res->render);
+ }
+ return etna_resource(res->render);
+}
+
static struct pipe_surface *
etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
const struct pipe_surface *templat)
{
struct etna_context *ctx = etna_context(pctx);
- struct etna_resource *rsc = etna_resource(prsc);
+ struct etna_resource *rsc = etna_render_handle_incompatible(pctx, prsc);
struct etna_surface *surf = CALLOC_STRUCT(etna_surface);
if (!surf)
@@ -57,6 +92,7 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
pipe_reference_init(&surf->base.reference, 1);
pipe_resource_reference(&surf->base.texture, &rsc->base);
+ pipe_resource_reference(&surf->prsc, prsc);
/* Allocate a TS for the resource if there isn't one yet,
* and it is allowed by the hw (width is a multiple of 16).
@@ -148,6 +184,7 @@ static void
etna_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf)
{
pipe_resource_reference(&psurf->texture, NULL);
+ pipe_resource_reference(&etna_surface(psurf)->prsc, NULL);
FREE(psurf);
}
diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.h b/src/gallium/drivers/etnaviv/etnaviv_surface.h
index e8cfd209af4..fef85f521e5 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_surface.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_surface.h
@@ -41,6 +41,8 @@ struct etna_surface {
struct etna_resource_level *level;
struct etna_reloc reloc[ETNA_MAX_PIXELPIPES];
struct etna_reloc ts_reloc;
+ /* keep pointer to original resource (for when a render compatible resource is used) */
+ struct pipe_resource *prsc;
};
static inline struct etna_surface *
diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c
index a38fd1c4a57..748d3ff3e6f 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_texture.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c
@@ -147,8 +147,8 @@ etna_update_sampler_source(struct pipe_sampler_view *view, int num)
struct etna_context *ctx = etna_context(view->context);
bool enable_sampler_ts = false;
- if (base->external && etna_resource_newer(etna_resource(base->external), base))
- from = etna_resource(base->external);
+ if (base->render && etna_resource_newer(etna_resource(base->render), base))
+ from = etna_resource(base->render);
if (base->texture)
to = etna_resource(base->texture);