mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 11:10:10 +01:00
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 <jonathan@marek.ca> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
parent
e7e02435a8
commit
b962776530
7 changed files with 64 additions and 58 deletions
|
|
@ -138,10 +138,10 @@ etna_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
|
||||||
{
|
{
|
||||||
struct etna_resource *rsc = etna_resource(prsc);
|
struct etna_resource *rsc = etna_resource(prsc);
|
||||||
|
|
||||||
if (rsc->external) {
|
if (rsc->render) {
|
||||||
if (etna_resource_older(etna_resource(rsc->external), rsc)) {
|
if (etna_resource_older(rsc, etna_resource(rsc->render))) {
|
||||||
etna_copy_resource(pctx, rsc->external, prsc, 0, 0);
|
etna_copy_resource(pctx, prsc, rsc->render, 0, 0);
|
||||||
etna_resource(rsc->external)->seqno = rsc->seqno;
|
rsc->seqno = etna_resource(rsc->render)->seqno;
|
||||||
}
|
}
|
||||||
} else if (etna_resource_needs_flush(rsc)) {
|
} else if (etna_resource_needs_flush(rsc)) {
|
||||||
etna_copy_resource(pctx, prsc, prsc, 0, 0);
|
etna_copy_resource(pctx, prsc, prsc, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -472,12 +472,7 @@ etna_resource_create_modifiers(struct pipe_screen *pscreen,
|
||||||
static void
|
static void
|
||||||
etna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc)
|
etna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc)
|
||||||
{
|
{
|
||||||
struct etna_resource *res = etna_resource(prsc);
|
etna_resource(prsc)->seqno++;
|
||||||
|
|
||||||
if (res->external)
|
|
||||||
etna_resource(res->external)->seqno++;
|
|
||||||
else
|
|
||||||
res->seqno++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
renderonly_scanout_destroy(rsc->scanout, etna_screen(pscreen)->ro);
|
||||||
|
|
||||||
pipe_resource_reference(&rsc->texture, NULL);
|
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++)
|
for (unsigned i = 0; i < ETNA_NUM_LOD; i++)
|
||||||
FREE(rsc->levels[i].patch_offsets);
|
FREE(rsc->levels[i].patch_offsets);
|
||||||
|
|
@ -587,29 +582,6 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
|
||||||
if (!rsc->pending_ctx)
|
if (!rsc->pending_ctx)
|
||||||
goto fail;
|
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;
|
return prsc;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
@ -630,13 +602,6 @@ etna_resource_get_handle(struct pipe_screen *pscreen,
|
||||||
/* Scanout is always attached to the base resource */
|
/* Scanout is always attached to the base resource */
|
||||||
struct renderonly_scanout *scanout = rsc->scanout;
|
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->stride = rsc->levels[0].stride;
|
||||||
handle->offset = rsc->levels[0].offset;
|
handle->offset = rsc->levels[0].offset;
|
||||||
handle->modifier = layout_to_modifier(rsc->layout);
|
handle->modifier = layout_to_modifier(rsc->layout);
|
||||||
|
|
|
||||||
|
|
@ -84,13 +84,10 @@ struct etna_resource {
|
||||||
|
|
||||||
struct etna_resource_level levels[ETNA_NUM_LOD];
|
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;
|
struct pipe_resource *texture;
|
||||||
/*
|
/* for when PE doesn't support the base layout */
|
||||||
* If imported resources have an render/sampler incompatible tiling, we keep
|
struct pipe_resource *render;
|
||||||
* them as an external resource, which is blitted as needed.
|
|
||||||
*/
|
|
||||||
struct pipe_resource *external;
|
|
||||||
|
|
||||||
enum etna_resource_status status;
|
enum etna_resource_status status;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,14 +108,19 @@ etna_set_constant_buffer(struct pipe_context *pctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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))) {
|
if (base->texture && etna_resource_newer(etna_resource(base->texture), base))
|
||||||
/* The render buffer is older than the texture buffer. Copy it over. */
|
from = etna_resource(base->texture);
|
||||||
etna_copy_resource(pctx, pres, res->texture, 0, pres->last_level);
|
|
||||||
res->seqno = etna_resource(res->texture)->seqno;
|
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;
|
bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
|
||||||
|
|
||||||
assert(res->layout & ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
|
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 =
|
cs->PE_COLOR_FORMAT =
|
||||||
VIVS_PE_COLOR_FORMAT_FORMAT(translate_rs_format(cbuf->base.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_surface *zsbuf = etna_surface(sv->zsbuf);
|
||||||
struct etna_resource *res = etna_resource(zsbuf->base.texture);
|
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 */
|
assert(res->layout &ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,47 @@
|
||||||
|
|
||||||
#include "hw/common.xml.h"
|
#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 *
|
static struct pipe_surface *
|
||||||
etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
|
etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||||
const struct pipe_surface *templat)
|
const struct pipe_surface *templat)
|
||||||
{
|
{
|
||||||
struct etna_context *ctx = etna_context(pctx);
|
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);
|
struct etna_surface *surf = CALLOC_STRUCT(etna_surface);
|
||||||
|
|
||||||
if (!surf)
|
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_reference_init(&surf->base.reference, 1);
|
||||||
pipe_resource_reference(&surf->base.texture, &rsc->base);
|
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,
|
/* 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).
|
* 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)
|
etna_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf)
|
||||||
{
|
{
|
||||||
pipe_resource_reference(&psurf->texture, NULL);
|
pipe_resource_reference(&psurf->texture, NULL);
|
||||||
|
pipe_resource_reference(&etna_surface(psurf)->prsc, NULL);
|
||||||
FREE(psurf);
|
FREE(psurf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ struct etna_surface {
|
||||||
struct etna_resource_level *level;
|
struct etna_resource_level *level;
|
||||||
struct etna_reloc reloc[ETNA_MAX_PIXELPIPES];
|
struct etna_reloc reloc[ETNA_MAX_PIXELPIPES];
|
||||||
struct etna_reloc ts_reloc;
|
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 *
|
static inline struct etna_surface *
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,8 @@ etna_update_sampler_source(struct pipe_sampler_view *view, int num)
|
||||||
struct etna_context *ctx = etna_context(view->context);
|
struct etna_context *ctx = etna_context(view->context);
|
||||||
bool enable_sampler_ts = false;
|
bool enable_sampler_ts = false;
|
||||||
|
|
||||||
if (base->external && etna_resource_newer(etna_resource(base->external), base))
|
if (base->render && etna_resource_newer(etna_resource(base->render), base))
|
||||||
from = etna_resource(base->external);
|
from = etna_resource(base->render);
|
||||||
|
|
||||||
if (base->texture)
|
if (base->texture)
|
||||||
to = etna_resource(base->texture);
|
to = etna_resource(base->texture);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue