});
}
+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;
- if (!DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE) &&
- VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
+ if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
/* Set number of color tiles to be filled */
etna_set_state(ctx->stream, VIVS_TS_COLOR_AUTO_DISABLE_COUNT,
surf->surf.padded_width * surf->surf.padded_height / 16);
if (surf->surf.ts_size) { /* TS: use precompiled clear command */
/* Set new clear depth value */
ctx->framebuffer.TS_DEPTH_CLEAR_VALUE = new_clear_value;
- if (!DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE) &&
- VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
+ if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
/* Set number of depth tiles to be filled */
etna_set_state(ctx->stream, VIVS_TS_DEPTH_AUTO_DISABLE_COUNT,
surf->surf.padded_width * surf->surf.padded_height / 16);
/* 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
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) {
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 */
manual:
if (src->layout == ETNA_LAYOUT_TILED && dst->layout == ETNA_LAYOUT_TILED) {
- etna_resource_wait(pctx, dst);
- etna_resource_wait(pctx, src);
+ if ((src->status & ETNA_PENDING_WRITE) ||
+ (dst->status & ETNA_PENDING_WRITE))
+ pctx->flush(pctx, NULL, 0);
return etna_manual_blit(dst, dst_lev, dst_offset, src, src_lev, src_offset, blit_info);
}
{
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;
}
}
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;