diff mbox series

[12/15] drm: add user fence support to drm_gem_plane_helper_prepare_fb

Message ID 20220502163722.3957-13-christian.koenig@amd.com (mailing list archive)
State New, archived
Headers show
Series [01/15] dma-buf: rename DMA_FENCE_FLAG_USER_BITS to _DEVICE | expand

Commit Message

Christian König May 2, 2022, 4:37 p.m. UTC
Just handle them the same way as fences with the DMA_RESV_USAGE_WRITE
flag when the DRIVER_USER_FENCE flag is set.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/drm_gem_atomic_helper.c | 68 ++++++++++++++++---------
 1 file changed, 45 insertions(+), 23 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c
index a5026f617739..75d04333ff2e 100644
--- a/drivers/gpu/drm/drm_gem_atomic_helper.c
+++ b/drivers/gpu/drm/drm_gem_atomic_helper.c
@@ -5,6 +5,7 @@ 
 
 #include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_atomic_uapi.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
@@ -121,6 +122,40 @@ 
  * Plane Helpers
  */
 
+static int chain_fb_fences(struct drm_framebuffer *fb,
+			   enum dma_resv_usage usage,
+			   struct dma_fence **fence)
+{
+	size_t i;
+	int ret;
+
+	for (i = 0; i < fb->format->num_planes; ++i) {
+		struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, i);
+		struct dma_fence *new;
+
+		if (WARN_ON_ONCE(!obj))
+			continue;
+
+		ret = dma_resv_get_singleton(obj->resv, usage, &new);
+		if (ret)
+			return ret;
+
+		if (new && *fence) {
+			struct dma_fence_chain *chain = dma_fence_chain_alloc();
+
+			if (!chain)
+				return -ENOMEM;
+
+			dma_fence_chain_init(chain, *fence, new, 1);
+			*fence = &chain->base;
+
+		} else if (new) {
+			*fence = new;
+		}
+	}
+	return 0;
+}
+
 /**
  * drm_gem_plane_helper_prepare_fb() - Prepare a GEM backed framebuffer
  * @plane: Plane
@@ -143,8 +178,6 @@  int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 {
 	struct dma_fence *fence = dma_fence_get(state->fence);
-	enum dma_resv_usage usage;
-	size_t i;
 	int ret;
 
 	if (!state->fb)
@@ -163,32 +196,21 @@  int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane,
 	 * obeys both implicit and explicit fences for plane updates, then it
 	 * will break all the benefits of explicit fencing.
 	 */
-	usage = fence ? DMA_RESV_USAGE_KERNEL : DMA_RESV_USAGE_WRITE;
-
-	for (i = 0; i < state->fb->format->num_planes; ++i) {
-		struct drm_gem_object *obj = drm_gem_fb_get_obj(state->fb, i);
-		struct dma_fence *new;
-
-		if (WARN_ON_ONCE(!obj))
-			continue;
-
-		ret = dma_resv_get_singleton(obj->resv, usage, &new);
+	if (fence) {
+		ret = chain_fb_fences(state->fb, DMA_RESV_USAGE_KERNEL, &fence);
 		if (ret)
 			goto error;
 
-		if (new && fence) {
-			struct dma_fence_chain *chain = dma_fence_chain_alloc();
+	} else {
+		ret = chain_fb_fences(state->fb, DMA_RESV_USAGE_WRITE, &fence);
+		if (ret)
+			goto error;
 
-			if (!chain) {
-				ret = -ENOMEM;
+		if (drm_core_check_feature(plane->dev, DRIVER_USER_FENCE)) {
+			ret = chain_fb_fences(state->fb, DMA_RESV_USAGE_USER,
+					      &fence);
+			if (ret)
 				goto error;
-			}
-
-			dma_fence_chain_init(chain, fence, new, 1);
-			fence = &chain->base;
-
-		} else if (new) {
-			fence = new;
 		}
 	}