uint32_t *bo_handles;
int ret;
- submit.in_syncs = (u64) (uintptr_t) &ctx->out_sync;
- submit.in_sync_count = 1;
- submit.out_sync = ctx->out_sync;
+ if (ctx->last_out_sync) {
+ submit.in_sync_count = 1;
+ submit.in_syncs = (uintptr_t)&ctx->last_out_sync->syncobj;
+ }
+ submit.out_sync = batch->out_sync->syncobj;
submit.jc = first_job_desc;
submit.requirements = reqs;
submit.bo_handles = (u64) (uintptr_t) bo_handles;
ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_SUBMIT, &submit);
free(bo_handles);
+
+ /* Release the last batch fence if any, and retain the new one */
+ if (ctx->last_out_sync)
+ panfrost_batch_fence_unreference(ctx->last_out_sync);
+
+ panfrost_batch_fence_reference(batch->out_sync);
+ ctx->last_out_sync = batch->out_sync;
+
if (ret) {
fprintf(stderr, "Error submitting: %m\n");
return errno;
/* Trace the job if we're doing that */
if (pan_debug & PAN_DBG_TRACE) {
/* Wait so we can get errors reported back */
- drmSyncobjWait(screen->fd, &ctx->out_sync, 1, INT64_MAX, 0, NULL);
+ drmSyncobjWait(screen->fd, &batch->out_sync->syncobj, 1,
+ INT64_MAX, 0, NULL);
pandecode_jc(submit.jc, FALSE);
}
* to wait on it.
*/
batch->out_sync->signaled = true;
+
+ /* Release the last batch fence if any, and set ->last_out_sync
+ * to NULL
+ */
+ if (ctx->last_out_sync) {
+ panfrost_batch_fence_unreference(ctx->last_out_sync);
+ ctx->last_out_sync = NULL;
+ }
+
goto out;
}
* rendering is quite broken right now (to be fixed by the panfrost_job
* refactor, just take the perf hit for correctness)
*/
- drmSyncobjWait(pan_screen(ctx->base.screen)->fd, &ctx->out_sync, 1,
- INT64_MAX, 0, NULL);
+ if (!batch->out_sync->signaled)
+ drmSyncobjWait(pan_screen(ctx->base.screen)->fd,
+ &batch->out_sync->syncobj, 1, INT64_MAX, 0,
+ NULL);
+
panfrost_free_batch(batch);
}
struct panfrost_screen *screen = pan_screen(pscreen);
struct panfrost_fence *f = (struct panfrost_fence *)fence;
int ret;
-
unsigned syncobj;
+
+ /* The fence was already signaled */
+ if (f->fd == -1)
+ return true;
+
ret = drmSyncobjCreate(screen->fd, 0, &syncobj);
if (ret) {
fprintf(stderr, "Failed to create syncobj to wait on: %m\n");
if (!f)
return NULL;
+ f->fd = -1;
+
+ /* There was no job flushed yet or the batch fence was already
+ * signaled, let's return a dummy fence object that returns true
+ * directly when ->fence_finish() is called.
+ */
+ if (!ctx->last_out_sync || ctx->last_out_sync->signaled)
+ goto out;
+
/* Snapshot the last Panfrost's rendering's out fence. We'd rather have
* another syncobj instead of a sync file, but this is all we get.
* (HandleToFD/FDToHandle just gives you another syncobj ID for the
* same syncobj).
*/
- drmSyncobjExportSyncFile(screen->fd, ctx->out_sync, &f->fd);
+ drmSyncobjExportSyncFile(screen->fd, ctx->last_out_sync->syncobj, &f->fd);
if (f->fd == -1) {
fprintf(stderr, "export failed: %m\n");
free(f);
return NULL;
}
+out:
pipe_reference_init(&f->reference, 1);
return f;