summaryrefslogtreecommitdiff
path: root/src/tegra_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tegra_stream.c')
-rw-r--r--src/tegra_stream.c91
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;