diff mbox series

[5/6] drm/i915: wait for write fences before pflip

Message ID 20180809113713.48024-6-christian.koenig@amd.com (mailing list archive)
State New, archived
Headers show
Series [1/6] dma-buf: remove shared fence staging in reservation object | expand

Commit Message

Christian König Aug. 9, 2018, 11:37 a.m. UTC
Wait for all write operations before page flipping.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/i915/intel_display.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2c16c3a3cdea..154dc86062a3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -48,6 +48,7 @@ 
 #include <drm/drm_rect.h>
 #include <linux/dma_remapping.h>
 #include <linux/reservation.h>
+#include <linux/dma-fence-array.h>
 
 /* Primary plane formats for gen <= 3 */
 static const uint32_t i8xx_primary_formats[] = {
@@ -13022,7 +13023,8 @@  intel_prepare_plane_fb(struct drm_plane *plane,
 	intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
 
 	if (!new_state->fence) { /* implicit fencing */
-		struct dma_fence *fence;
+		struct dma_fence *fence, **fences;
+		unsigned count;
 
 		ret = i915_sw_fence_await_reservation(&intel_state->commit_ready,
 						      obj->resv, NULL,
@@ -13031,7 +13033,29 @@  intel_prepare_plane_fb(struct drm_plane *plane,
 		if (ret < 0)
 			return ret;
 
-		fence = reservation_object_get_excl_rcu(obj->resv);
+		ret = reservation_object_get_fences_rcu(obj->resv, true, NULL,
+							&count, &fences);
+		if (ret)
+			return ret;
+
+		if (count == 0) {
+			fence = NULL;
+		} else if (count == 1) {
+			fence = fences[0];
+			kfree(fences);
+		} else {
+			uint64_t context = dma_fence_context_alloc(1);
+			struct dma_fence_array *array;
+
+			array = dma_fence_array_create(count, fences, context,
+						       1, false);
+			if (!array) {
+				kfree(fences);
+				return -ENOMEM;
+			}
+			fence = &array->base;
+		}
+
 		if (fence) {
 			add_rps_boost_after_vblank(new_state->crtc, fence);
 			dma_fence_put(fence);