summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/winsys/drm/nouveau/nouveau_bo.c34
-rw-r--r--src/gallium/winsys/drm/nouveau/nouveau_drmif.h3
2 files changed, 37 insertions, 0 deletions
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/nouveau_bo.c
index b5942994d9..76b98bed67 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_bo.c
+++ b/src/gallium/winsys/drm/nouveau/nouveau_bo.c
@@ -273,6 +273,40 @@ nouveau_bo_del(struct nouveau_bo **bo)
}
int
+nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags)
+{
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+ struct nouveau_fence *fence;
+
+ if (!nvbo)
+ return -EINVAL;
+
+ /* If the buffer is pending it must be busy, unless
+ * both are RD, in which case we can allow access */
+ if (nvbo->pending) {
+ if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD &&
+ (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD)
+ return 0;
+ else
+ return 1;
+ }
+
+ if (flags & NOUVEAU_BO_WR)
+ fence = nvbo->fence;
+ else
+ fence = nvbo->wr_fence;
+
+ /* If the buffer is not pending and doesn't have a fence
+ * that conflicts with our flags then it can't be busy
+ */
+ if (!fence)
+ return 0;
+ else
+ /* If the fence is signalled the buffer is not busy, else is busy */
+ return !nouveau_fence(fence)->signalled;
+}
+
+int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
{
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
diff --git a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h
index dcd6a5eb0a..5f72800676 100644
--- a/src/gallium/winsys/drm/nouveau/nouveau_drmif.h
+++ b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h
@@ -287,6 +287,9 @@ extern void
nouveau_bo_del(struct nouveau_bo **);
extern int
+nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags);
+
+extern int
nouveau_bo_map(struct nouveau_bo *, uint32_t flags);
extern void