summaryrefslogtreecommitdiff
path: root/tegra/fence.c
diff options
context:
space:
mode:
Diffstat (limited to 'tegra/fence.c')
-rw-r--r--tegra/fence.c95
1 files changed, 69 insertions, 26 deletions
diff --git a/tegra/fence.c b/tegra/fence.c
index a2dd394e..7e3dc432 100644
--- a/tegra/fence.c
+++ b/tegra/fence.c
@@ -1,7 +1,5 @@
/*
- * Copyright © 2012, 2013 Thierry Reding
- * Copyright © 2013 Erik Faye-Lund
- * Copyright © 2014 NVIDIA Corporation
+ * Copyright © 2018 NVIDIA Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -27,44 +25,89 @@
#endif
#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h> /* XXX remove */
#include <string.h>
+#include <unistd.h>
#include <sys/ioctl.h>
+#include <sys/poll.h>
#include "private.h"
-int drm_tegra_fence_wait_timeout(struct drm_tegra_fence *fence,
- unsigned long timeout)
+static int drm_tegra_syncobj_destroy(struct drm_tegra *drm, uint32_t handle)
{
- struct drm_tegra_syncpt_wait args;
+ struct drm_syncobj_destroy args;
int err;
memset(&args, 0, sizeof(args));
- args.id = fence->syncpt;
- args.thresh = fence->value;
- args.timeout = timeout;
+ args.handle = handle;
- while (true) {
- err = ioctl(fence->drm->fd, DRM_IOCTL_TEGRA_SYNCPT_WAIT, &args);
- if (err < 0) {
- if (errno == EINTR)
- continue;
-
- return -errno;
- }
-
- break;
- }
+ err = ioctl(drm->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &args);
+ if (err < 0)
+ return -errno;
return 0;
}
-int drm_tegra_fence_wait(struct drm_tegra_fence *fence)
+int drm_tegra_fence_wait(struct drm_tegra *drm, struct drm_tegra_fence *fence)
{
- return drm_tegra_fence_wait_timeout(fence, -1);
-}
+ int err;
-void drm_tegra_fence_free(struct drm_tegra_fence *fence)
-{
- free(fence);
+ if ((fence->flags & DRM_TEGRA_FENCE_EMIT) == 0)
+ return 0;
+
+ printf("fence: %p\n", fence);
+ printf(" handle: %u\n", fence->handle);
+ printf(" flags: %x\n", fence->flags);
+ printf(" offset: %x\n", fence->offset);
+ printf(" index: %u\n", fence->index);
+ printf(" value: %u\n", fence->value);
+
+ if (fence->flags & DRM_TEGRA_FENCE_FD) {
+ while (true) {
+ struct pollfd fds = {
+ .fd = fence->handle,
+ .events = POLLIN,
+ };
+
+ err = poll(&fds, 1, -1);
+ if (err > 0) {
+ if (fds.revents & (POLLERR | POLLNVAL))
+ err = -EINVAL;
+ else
+ err = 0;
+
+ break;
+ }
+
+ if (err == 0) {
+ err = -ETIMEDOUT;
+ break;
+ }
+
+ if (errno != EINTR && errno != EAGAIN) {
+ err = -errno;
+ break;
+ }
+ }
+
+ close(fence->handle);
+ } else {
+ struct drm_syncobj_wait args;
+
+ memset(&args, 0, sizeof(args));
+ args.handles = (uintptr_t)&fence->handle;
+ args.count_handles = 1;
+ args.timeout_nsec = -1;
+ args.flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
+
+ err = ioctl(drm->fd, DRM_IOCTL_SYNCOBJ_WAIT, &args);
+ if (err < 0)
+ err = -errno;
+
+ drm_tegra_syncobj_destroy(drm, fence->handle);
+ }
+
+ return err;
}