mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
panfrost: Add a batch fence
So we can implement fine-grained dependency tracking between batches. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
parent
a8bd265cef
commit
6936b7f319
2 changed files with 94 additions and 1 deletions
|
|
@ -36,6 +36,45 @@
|
|||
#include "pan_util.h"
|
||||
#include "pandecode/decode.h"
|
||||
|
||||
static struct panfrost_batch_fence *
|
||||
panfrost_create_batch_fence(struct panfrost_batch *batch)
|
||||
{
|
||||
struct panfrost_batch_fence *fence;
|
||||
ASSERTED int ret;
|
||||
|
||||
fence = rzalloc(NULL, struct panfrost_batch_fence);
|
||||
assert(fence);
|
||||
pipe_reference_init(&fence->reference, 1);
|
||||
fence->ctx = batch->ctx;
|
||||
fence->batch = batch;
|
||||
ret = drmSyncobjCreate(pan_screen(batch->ctx->base.screen)->fd, 0,
|
||||
&fence->syncobj);
|
||||
assert(!ret);
|
||||
|
||||
return fence;
|
||||
}
|
||||
|
||||
static void
|
||||
panfrost_free_batch_fence(struct panfrost_batch_fence *fence)
|
||||
{
|
||||
drmSyncobjDestroy(pan_screen(fence->ctx->base.screen)->fd,
|
||||
fence->syncobj);
|
||||
ralloc_free(fence);
|
||||
}
|
||||
|
||||
void
|
||||
panfrost_batch_fence_unreference(struct panfrost_batch_fence *fence)
|
||||
{
|
||||
if (pipe_reference(&fence->reference, NULL))
|
||||
panfrost_free_batch_fence(fence);
|
||||
}
|
||||
|
||||
void
|
||||
panfrost_batch_fence_reference(struct panfrost_batch_fence *fence)
|
||||
{
|
||||
pipe_reference(NULL, &fence->reference);
|
||||
}
|
||||
|
||||
static struct panfrost_batch *
|
||||
panfrost_create_batch(struct panfrost_context *ctx,
|
||||
const struct pipe_framebuffer_state *key)
|
||||
|
|
@ -53,6 +92,7 @@ panfrost_create_batch(struct panfrost_context *ctx,
|
|||
|
||||
util_dynarray_init(&batch->headers, batch);
|
||||
util_dynarray_init(&batch->gpu_headers, batch);
|
||||
batch->out_sync = panfrost_create_batch_fence(batch);
|
||||
util_copy_framebuffer_state(&batch->key, key);
|
||||
|
||||
return batch;
|
||||
|
|
@ -74,6 +114,15 @@ panfrost_free_batch(struct panfrost_batch *batch)
|
|||
if (ctx->batch == batch)
|
||||
ctx->batch = NULL;
|
||||
|
||||
/* The out_sync fence lifetime is different from the the batch one
|
||||
* since other batches might want to wait on a fence of already
|
||||
* submitted/signaled batch. All we need to do here is make sure the
|
||||
* fence does not point to an invalid batch, which the core will
|
||||
* interpret as 'batch is already submitted'.
|
||||
*/
|
||||
batch->out_sync->batch = NULL;
|
||||
panfrost_batch_fence_unreference(batch->out_sync);
|
||||
|
||||
util_unreference_framebuffer_state(&batch->key);
|
||||
ralloc_free(batch);
|
||||
}
|
||||
|
|
@ -441,8 +490,13 @@ panfrost_batch_submit(struct panfrost_batch *batch)
|
|||
int ret;
|
||||
|
||||
/* Nothing to do! */
|
||||
if (!batch->last_job.gpu && !batch->clear)
|
||||
if (!batch->last_job.gpu && !batch->clear) {
|
||||
/* Mark the fence as signaled so the fence logic does not try
|
||||
* to wait on it.
|
||||
*/
|
||||
batch->out_sync->signaled = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!batch->clear && batch->last_tiler.gpu)
|
||||
panfrost_batch_draw_wallpaper(batch);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,36 @@
|
|||
#include "pan_allocate.h"
|
||||
#include "pan_resource.h"
|
||||
|
||||
/* panfrost_batch_fence is the out fence of a batch that users or other batches
|
||||
* might want to wait on. The batch fence lifetime is different from the batch
|
||||
* one as want will certainly want to wait upon the fence after the batch has
|
||||
* been submitted (which is when panfrost_batch objects are freed).
|
||||
*/
|
||||
struct panfrost_batch_fence {
|
||||
/* Refcounting object for the fence. */
|
||||
struct pipe_reference reference;
|
||||
|
||||
/* Batch that created this fence object. Will become NULL at batch
|
||||
* submission time. This field is mainly here to know whether the
|
||||
* batch has been flushed or not.
|
||||
*/
|
||||
struct panfrost_batch *batch;
|
||||
|
||||
/* Context this fence is attached to. We need both ctx and batch, as
|
||||
* the batch will go away after it's been submitted, but the fence
|
||||
* will stay a bit longer.
|
||||
*/
|
||||
struct panfrost_context *ctx;
|
||||
|
||||
/* Sync object backing this fence. */
|
||||
uint32_t syncobj;
|
||||
|
||||
/* Cached value of the signaled state to avoid calling WAIT_SYNCOBJs
|
||||
* when we know the fence has already been signaled.
|
||||
*/
|
||||
bool signaled;
|
||||
};
|
||||
|
||||
#define PAN_REQ_MSAA (1 << 0)
|
||||
#define PAN_REQ_DEPTH_WRITE (1 << 1)
|
||||
|
||||
|
|
@ -120,10 +150,19 @@ struct panfrost_batch {
|
|||
|
||||
/* Framebuffer descriptor. */
|
||||
mali_ptr framebuffer;
|
||||
|
||||
/* Output sync object. Only valid when submitted is true. */
|
||||
struct panfrost_batch_fence *out_sync;
|
||||
};
|
||||
|
||||
/* Functions for managing the above */
|
||||
|
||||
void
|
||||
panfrost_batch_fence_unreference(struct panfrost_batch_fence *fence);
|
||||
|
||||
void
|
||||
panfrost_batch_fence_reference(struct panfrost_batch_fence *batch);
|
||||
|
||||
struct panfrost_batch *
|
||||
panfrost_get_batch_for_fbo(struct panfrost_context *ctx);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue