diff options
Diffstat (limited to 'src/tegra_stream.c')
-rw-r--r-- | src/tegra_stream.c | 91 |
1 files changed, 60 insertions, 31 deletions
diff --git a/src/tegra_stream.c b/src/tegra_stream.c index 92e5e6f..7f9b58f 100644 --- a/src/tegra_stream.c +++ b/src/tegra_stream.c @@ -25,6 +25,11 @@ * Arto Merilainen <amerilainen@nvidia.com> */ +#include <errno.h> +#include <unistd.h> + +#include <sys/ioctl.h> + #include "xorg-server.h" #include "xf86.h" @@ -44,9 +49,10 @@ * tegra_stream_push(). */ -int tegra_stream_create(struct tegra_stream *stream) +int tegra_stream_create(struct tegra_stream *stream, struct drm_tegra *drm) { stream->status = TEGRADRM_STREAM_FREE; + stream->drm = drm; return 0; } @@ -62,8 +68,8 @@ void tegra_stream_destroy(struct tegra_stream *stream) if (!stream) return; - tegra_stream_wait_fence(stream->last_fence); - tegra_stream_put_fence(stream->last_fence); + tegra_stream_wait_fence(stream, stream->last_fence); + tegra_stream_put_fence(stream, stream->last_fence); drm_tegra_job_free(stream->job); } @@ -91,14 +97,13 @@ int tegra_stream_cleanup(struct tegra_stream *stream) int tegra_stream_flush(struct tegra_stream *stream) { - struct drm_tegra_fence *fence; int result = 0; if (!stream) return -1; - tegra_stream_wait_fence(stream->last_fence); - tegra_stream_put_fence(stream->last_fence); + tegra_stream_wait_fence(stream, stream->last_fence); + tegra_stream_put_fence(stream, stream->last_fence); stream->last_fence = NULL; /* Reflushing is fine */ @@ -111,21 +116,19 @@ int tegra_stream_flush(struct tegra_stream *stream) goto cleanup; } - result = drm_tegra_job_submit(stream->job, &fence); + result = drm_tegra_job_submit(stream->job, 1000); if (result != 0) { ErrorMsg("drm_tegra_job_submit() failed %d\n", result); result = -1; goto cleanup; } - result = drm_tegra_fence_wait_timeout(fence, 1000); + result = drm_tegra_job_wait(stream->job); if (result != 0) { - ErrorMsg("drm_tegra_fence_wait_timeout() failed %d\n", result); + ErrorMsg("drm_tegra_job_wait() failed %d\n", result); result = -1; } - drm_tegra_fence_free(fence); - cleanup: tegra_stream_cleanup(stream); @@ -134,7 +137,6 @@ cleanup: struct tegra_fence * tegra_stream_submit(struct tegra_stream *stream, bool gr2d) { - struct drm_tegra_fence *fence; struct tegra_fence *f; int result; @@ -153,13 +155,39 @@ struct tegra_fence * tegra_stream_submit(struct tegra_stream *stream, bool gr2d) goto cleanup; } - result = drm_tegra_job_submit(stream->job, &fence); + result = drm_tegra_job_submit(stream->job, 1000); if (result != 0) { ErrorMsg("drm_tegra_job_submit() failed %d\n", result); result = -1; } else { - f = tegra_stream_create_fence(fence, gr2d); - tegra_stream_put_fence(stream->last_fence); + unsigned int num_fences, count; + struct drm_fence *fences; + + num_fences = drm_tegra_job_get_fences(stream->job, NULL, 0); + if (num_fences == 0) { + result = -1; + goto cleanup; + } + + fences = calloc(num_fences, sizeof(*fences)); + if (!fences) { + result = -1; + goto cleanup; + } + + count = drm_tegra_job_get_fences(stream->job, fences, num_fences); + if (count != num_fences) { + result = -1; + goto cleanup; + } + + f = tegra_stream_create_fence(fences, num_fences, gr2d); + if (!f) { + result = -1; + goto cleanup; + } + + tegra_stream_put_fence(stream, stream->last_fence); stream->last_fence = f; } @@ -191,42 +219,43 @@ struct tegra_fence * tegra_stream_get_last_fence(struct tegra_stream *stream) return NULL; } -struct tegra_fence * tegra_stream_create_fence(struct drm_tegra_fence *fence, +struct tegra_fence * tegra_stream_create_fence(struct drm_fence *fences, + unsigned int num_fences, bool gr2d) { struct tegra_fence *f = calloc(1, sizeof(*f)); if (f) { - f->fence = fence; + f->num_fences = num_fences; + f->fences = fences; f->gr2d = gr2d; } return f; } -bool tegra_stream_wait_fence(struct tegra_fence *f) +bool tegra_stream_wait_fence(struct tegra_stream *stream, struct tegra_fence *f) { int result; - if (f && f->fence) { - result = drm_tegra_fence_wait_timeout(f->fence, 1000); + if (f && f->num_fences > 0) { + result = drm_tegra_wait_fences(stream->drm, f->fences, f->num_fences); if (result != 0) { - ErrorMsg("drm_tegra_fence_wait_timeout() failed %d\n", result); + ErrorMsg("drm_tegra_wait_fences() failed: %d\n", result); + return false; } - drm_tegra_fence_free(f->fence); - f->fence = NULL; - return true; } return false; } -void tegra_stream_put_fence(struct tegra_fence *f) +void tegra_stream_put_fence(struct tegra_stream *stream, struct tegra_fence *f) { if (f && --f->refcnt < 0) { - drm_tegra_fence_free(f->fence); + drm_tegra_put_fences(stream->drm, f->fences, f->num_fences); + free(f->fences); free(f); } } @@ -369,8 +398,8 @@ int tegra_stream_end(struct tegra_stream *stream) if (stream->op_done_synced) goto ready; - ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, - DRM_TEGRA_SYNCPT_COND_OP_DONE); + ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, 0, 1, + DRM_TEGRA_SYNC_COND_OP_DONE); if (ret != 0) { stream->status = TEGRADRM_STREAM_CONSTRUCTION_FAILED; ErrorMsg("drm_tegra_pushbuf_sync() failed %d\n", ret); @@ -480,7 +509,7 @@ int tegra_stream_prep(struct tegra_stream *stream, uint32_t words) } int tegra_stream_sync(struct tegra_stream *stream, - enum drm_tegra_syncpt_cond cond) + enum drm_tegra_sync_cond cond) { int ret; @@ -489,14 +518,14 @@ int tegra_stream_sync(struct tegra_stream *stream, return -1; } - ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, cond); + ret = drm_tegra_pushbuf_sync(stream->buffer.pushbuf, 0, 1, cond); if (ret != 0) { stream->status = TEGRADRM_STREAM_CONSTRUCTION_FAILED; ErrorMsg("drm_tegra_pushbuf_sync() failed %d\n", ret); return -1; } - if (cond == DRM_TEGRA_SYNCPT_COND_OP_DONE) + if (cond == DRM_TEGRA_SYNC_COND_OP_DONE) stream->op_done_synced = true; return 0; |