X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fetnaviv%2Fetnaviv_clear_blit.c;h=d9ff9624fa4c4e0cc1e2665e662efcd6b78ae10a;hb=bccd21ee88f633efafb59d0ef8a42478f2faa90b;hp=ea416bf192f314516a28f0bbcb929f0bdba3acff;hpb=a276c32a08bd41ceb8fd9b604ba9ac8229d59b64;p=mesa.git diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c index ea416bf192f..d9ff9624fa4 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c @@ -100,13 +100,24 @@ etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf, }); } +static inline uint32_t +pack_rgba(enum pipe_format format, const float *rgba) +{ + union util_color uc; + util_pack_color(rgba, format, &uc); + if (util_format_get_blocksize(format) == 2) + return uc.ui[0] << 16 | uc.ui[0]; + else + return uc.ui[0]; +} + static void etna_blit_clear_color(struct pipe_context *pctx, struct pipe_surface *dst, const union pipe_color_union *color) { struct etna_context *ctx = etna_context(pctx); struct etna_surface *surf = etna_surface(dst); - uint32_t new_clear_value = translate_clear_color(surf->base.format, color); + uint32_t new_clear_value = pack_rgba(surf->base.format, color->f); if (surf->surf.ts_size) { /* TS: use precompiled clear command */ ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value; @@ -285,8 +296,6 @@ etna_resource_copy_region(struct pipe_context *pctx, struct pipe_resource *dst, /* The resource must be of the same format. */ assert(src->format == dst->format); - /* Resources with nr_samples > 1 are not allowed. */ - assert(src->nr_samples <= 1 && dst->nr_samples <= 1); /* XXX we can use the RS as a literal copy engine here * the only complexity is tiling; the size of the boxes needs to be aligned @@ -446,7 +455,8 @@ etna_try_rs_blit(struct pipe_context *pctx, if (width > src_lev->padded_width || width > dst_lev->padded_width * msaa_xscale || height > src_lev->padded_height || - height > dst_lev->padded_height * msaa_yscale) + height > dst_lev->padded_height * msaa_yscale || + width & (w_align - 1) || height & (h_align - 1)) goto manual; if (src->base.nr_samples > 1) { @@ -455,16 +465,24 @@ etna_try_rs_blit(struct pipe_context *pctx, ts_mem_config |= VIVS_TS_MEM_CONFIG_MSAA | msaa_format; } - uint32_t to_flush = 0; - - if (src->base.bind & PIPE_BIND_RENDER_TARGET) - to_flush |= VIVS_GL_FLUSH_CACHE_COLOR; - if (src->base.bind & PIPE_BIND_DEPTH_STENCIL) - to_flush |= VIVS_GL_FLUSH_CACHE_DEPTH; - - if (to_flush) { - etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, to_flush); + /* Always flush color and depth cache together before resolving. This works + * around artifacts that appear in some cases when scanning out a texture + * directly after it has been rendered to, such as rendering an animated web + * page in a QtWebEngine based WebView on GC2000. The artifacts look like + * the texture sampler samples zeroes instead of texture data in a small, + * irregular triangle in the lower right of each browser tile quad. Other + * attempts to avoid these artifacts, including a pipeline stall before the + * color flush or a TS cache flush afterwards, or flushing multiple times, + * with stalls before and after each flush, have shown no effect. */ + if (src->base.bind & PIPE_BIND_RENDER_TARGET || + src->base.bind & PIPE_BIND_DEPTH_STENCIL) { + etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, + VIVS_GL_FLUSH_CACHE_COLOR | VIVS_GL_FLUSH_CACHE_DEPTH); etna_stall(ctx->stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE); + + if (src->levels[blit_info->src.level].ts_size && + src->levels[blit_info->src.level].ts_valid) + etna_set_state(ctx->stream, VIVS_TS_FLUSH_CACHE, VIVS_TS_FLUSH_CACHE_FLUSH); } /* Set up color TS to source surface before blit, if needed */ @@ -592,10 +610,11 @@ etna_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc) { struct etna_resource *rsc = etna_resource(prsc); - if (rsc->scanout && - 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->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; + } } else if (etna_resource_needs_flush(rsc)) { etna_copy_resource(pctx, prsc, prsc, 0, 0); rsc->flush_seqno = rsc->seqno; @@ -626,9 +645,9 @@ etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst, for (int level = first_level; level <= last_level; level++) { blit.src.level = blit.dst.level = level; blit.src.box.width = blit.dst.box.width = - MIN2(src_priv->levels[level].width, dst_priv->levels[level].width); + MIN2(src_priv->levels[level].padded_width, dst_priv->levels[level].padded_width); blit.src.box.height = blit.dst.box.height = - MIN2(src_priv->levels[level].height, dst_priv->levels[level].height); + MIN2(src_priv->levels[level].padded_height, dst_priv->levels[level].padded_height); for (int layer = 0; layer < dst->array_size; layer++) { blit.src.box.z = blit.dst.box.z = layer;