panfrost: Make sure a clear does not re-use a pre-existing batch
glClear()s are expected to be the first thing GL apps do before drawing new things. If there's already an existing batch targetting the same FBO that has draws attached to it, we should make sure the new clear gets a new batch assigned to guaranteed that the FB content is actually cleared with the requested color/depth/stencil values. We create a panfrost_get_fresh_batch_for_fbo() helper for that and call it from panfrost_clear(). Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
@@ -162,7 +162,14 @@ panfrost_clear(
|
||||
double depth, unsigned stencil)
|
||||
{
|
||||
struct panfrost_context *ctx = pan_context(pipe);
|
||||
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
|
||||
|
||||
/* TODO: panfrost_get_fresh_batch_for_fbo() instantiates a new batch if
|
||||
* the existing batch targeting this FBO has draws. We could probably
|
||||
* avoid that by replacing plain clears by quad-draws with a specific
|
||||
* color/depth/stencil value, thus avoiding the generation of extra
|
||||
* fragment/set_value jobs.
|
||||
*/
|
||||
struct panfrost_batch *batch = panfrost_get_fresh_batch_for_fbo(ctx);
|
||||
|
||||
panfrost_batch_add_fbo_bos(batch);
|
||||
panfrost_batch_clear(batch, buffers, color, depth, stencil);
|
||||
|
||||
@@ -293,6 +293,27 @@ panfrost_get_batch_for_fbo(struct panfrost_context *ctx)
|
||||
return batch;
|
||||
}
|
||||
|
||||
struct panfrost_batch *
|
||||
panfrost_get_fresh_batch_for_fbo(struct panfrost_context *ctx)
|
||||
{
|
||||
struct panfrost_batch *batch;
|
||||
|
||||
batch = panfrost_get_batch(ctx, &ctx->pipe_framebuffer);
|
||||
|
||||
/* The batch has no draw/clear queued, let's return it directly.
|
||||
* Note that it's perfectly fine to re-use a batch with an
|
||||
* existing clear, we'll just update it with the new clear request.
|
||||
*/
|
||||
if (!batch->last_job.gpu)
|
||||
return batch;
|
||||
|
||||
/* Otherwise, we need to freeze the existing one and instantiate a new
|
||||
* one.
|
||||
*/
|
||||
panfrost_freeze_batch(batch);
|
||||
return panfrost_get_batch(ctx, &ctx->pipe_framebuffer);
|
||||
}
|
||||
|
||||
static bool
|
||||
panfrost_batch_fence_is_signaled(struct panfrost_batch_fence *fence)
|
||||
{
|
||||
|
||||
@@ -169,6 +169,9 @@ panfrost_batch_fence_reference(struct panfrost_batch_fence *batch);
|
||||
struct panfrost_batch *
|
||||
panfrost_get_batch_for_fbo(struct panfrost_context *ctx);
|
||||
|
||||
struct panfrost_batch *
|
||||
panfrost_get_fresh_batch_for_fbo(struct panfrost_context *ctx);
|
||||
|
||||
void
|
||||
panfrost_batch_init(struct panfrost_context *ctx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user