diff --git a/src/gallium/drivers/panfrost/pan_blitter.c b/src/gallium/drivers/panfrost/pan_blitter.c index f41061ff769..53d8c3f7dec 100644 --- a/src/gallium/drivers/panfrost/pan_blitter.c +++ b/src/gallium/drivers/panfrost/pan_blitter.c @@ -34,6 +34,32 @@ panfrost_blitter_draw_rectangle(struct blitter_context *blitter, struct panfrost_context *pctx = pan_context(ctx); struct panfrost_screen *scr = pan_screen(ctx->screen); + /* u_blitter allows src == dst for disjoint texel sets without any texture + * barrier enforcement. Mali tile-based architecture can't guarantee that a + * read from the dst texture will fetch up-to-date values since it depends + * on the tile processing order. Request a fresh batch to ensure any writes + * to the resource are flushed. Doing so in this callback ensures that the + * framebuffer state is set for the current blit. + * + * XXX This should ideally be done at the draw call handling level when it + * requests a batch for the current framebuffer (see prepare_draw) by first + * submitting any batches writing to the draw call's sampler views. This + * check (along with resource accesses handling) is currently done when + * emitting texture descriptors but it explicitly discards the special case + * where the batch writing to the draw call's sampler views is the current + * batch because it can't be submitted at this time of the draw call + * handling (see panfrost_batch_update_access). + */ + if (pctx->has_blit_loop) { + panfrost_get_fresh_batch_for_fbo(pctx, "Pre-blit flush"); + + /* XXX On all arch, Piglit's copy-pixels test sometimes fails to copy a + * block of pixels. Most easily reproducible at image size + * 50x38. Fallback to draw_vbo for now. + */ + goto fallback; + } + if (scr->dev.arch <= 8 || depth != 0.0f || num_instances > 1) goto fallback; @@ -77,6 +103,10 @@ panfrost_blitter_draw_rectangle(struct blitter_context *blitter, /* Fallback to draw_vbo. */ util_blitter_draw_rectangle(blitter, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth, num_instances, type, attrib); + + /* XXX Depth/Stencil blits on v9 need that too. Not sure why. */ + if (pctx->has_blit_loop && scr->dev.arch == 9) + panfrost_flush_all_batches(pctx, "Post-blit flush"); } struct blitter_context * @@ -157,7 +187,9 @@ panfrost_blitter_blit_legalized(struct pipe_context *pipe, } panfrost_blitter_save(ctx, states); + ctx->has_blit_loop = info->src.resource == info->dst.resource; util_blitter_blit(ctx->blitter, info, NULL); + ctx->has_blit_loop = false; } void @@ -183,9 +215,7 @@ panfrost_blitter_blit(struct pipe_context *pipe, util_format_linear(info->src.format), false, false); pan_legalize_format(ctx, pan_resource(info->dst.resource), util_format_linear(info->dst.format), true, false); - panfrost_flush_all_batches(ctx, "Blit"); panfrost_blitter_blit_legalized(pipe, info); - panfrost_flush_all_batches(ctx, "Blit"); } /* Setup HW tile buffer clears if the batch for the current FBO doesn't have diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 6470921f16b..91e3d89bf9c 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -192,6 +192,7 @@ struct panfrost_context { } texture_buffer[MESA_SHADER_STAGES]; struct blitter_context *blitter; + bool has_blit_loop; struct pan_mod_convert_shaders mod_convert_shaders;