[PATCH xf86-video-amdgpu 07/13] DRI2: Use helper functions for DRM event queue management

Michel Dänzer michel at daenzer.net
Tue Jun 2 02:21:25 PDT 2015


From: Michel Dänzer <michel.daenzer at amd.com>

This is mostly in preparation for Present support, but it also simplifies
the DRI2 specific code a little.

(Cherry picked from radeon commit 6c3a721cde9317233072b573f9502348dcd21b16)

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/amdgpu_dri2.c     | 271 ++++++++++++++++++--------------------------------
 src/amdgpu_dri2.h     |  37 -------
 src/drmmode_display.c |  90 +++++++++++------
 src/drmmode_display.h |  13 ++-
 4 files changed, 165 insertions(+), 246 deletions(-)

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index c139dec..95db216 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -49,6 +49,8 @@
 
 #include "amdgpu_list.h"
 
+#include <xf86Priv.h>
+
 #if DRI2INFOREC_VERSION >= 9
 #define USE_DRI2_PRIME
 #endif
@@ -370,65 +372,20 @@ typedef struct _DRI2FrameEvent {
 	XID drawable_id;
 	ClientPtr client;
 	enum DRI2FrameEventType type;
-	int frame;
+	unsigned frame;
 	xf86CrtcPtr crtc;
+	OsTimerPtr timer;
+	struct amdgpu_drm_queue_entry *drm_queue;
 
 	/* for swaps & flips only */
 	DRI2SwapEventPtr event_complete;
 	void *event_data;
 	DRI2BufferPtr front;
 	DRI2BufferPtr back;
-
-	Bool valid;
-
-	struct xorg_list link;
 } DRI2FrameEventRec, *DRI2FrameEventPtr;
 
-typedef struct _DRI2ClientEvents {
-	struct xorg_list reference_list;
-} DRI2ClientEventsRec, *DRI2ClientEventsPtr;
-
-#if HAS_DEVPRIVATEKEYREC
-
 static int DRI2InfoCnt;
 
-static DevPrivateKeyRec DRI2ClientEventsPrivateKeyRec;
-#define DRI2ClientEventsPrivateKey (&DRI2ClientEventsPrivateKeyRec)
-
-#else
-
-static int DRI2ClientEventsPrivateKeyIndex;
-DevPrivateKey DRI2ClientEventsPrivateKey = &DRI2ClientEventsPrivateKeyIndex;
-
-#endif /* HAS_DEVPRIVATEKEYREC */
-
-#define GetDRI2ClientEvents(pClient)	((DRI2ClientEventsPtr) \
-    dixLookupPrivate(&(pClient)->devPrivates, DRI2ClientEventsPrivateKey))
-
-static int ListAddDRI2ClientEvents(ClientPtr client, struct xorg_list *entry)
-{
-	DRI2ClientEventsPtr pClientPriv;
-	pClientPriv = GetDRI2ClientEvents(client);
-
-	if (!pClientPriv) {
-		return BadAlloc;
-	}
-
-	xorg_list_add(entry, &pClientPriv->reference_list);
-	return 0;
-}
-
-static void ListDelDRI2ClientEvents(ClientPtr client, struct xorg_list *entry)
-{
-	DRI2ClientEventsPtr pClientPriv;
-	pClientPriv = GetDRI2ClientEvents(client);
-
-	if (!pClientPriv) {
-		return;
-	}
-	xorg_list_del(entry);
-}
-
 static void amdgpu_dri2_ref_buffer(BufferPtr buffer)
 {
 	struct dri2_buffer_priv *private = buffer->driverPrivate;
@@ -448,30 +405,13 @@ static void
 amdgpu_dri2_client_state_changed(CallbackListPtr * ClientStateCallback,
 				 pointer data, pointer calldata)
 {
-	DRI2ClientEventsPtr pClientEventsPriv;
-	DRI2FrameEventPtr ref;
 	NewClientInfoRec *clientinfo = calldata;
 	ClientPtr pClient = clientinfo->client;
-	pClientEventsPriv = GetDRI2ClientEvents(pClient);
 
 	switch (pClient->clientState) {
-	case ClientStateInitial:
-		xorg_list_init(&pClientEventsPriv->reference_list);
-		break;
-	case ClientStateRunning:
-		break;
-
 	case ClientStateRetained:
 	case ClientStateGone:
-		if (pClientEventsPriv) {
-			xorg_list_for_each_entry(ref,
-						 &pClientEventsPriv->
-						 reference_list, link) {
-				ref->valid = FALSE;
-				amdgpu_dri2_unref_buffer(ref->front);
-				amdgpu_dri2_unref_buffer(ref->back);
-			}
-		}
+		amdgpu_drm_abort_client(pClient);
 		break;
 	default:
 		break;
@@ -497,37 +437,42 @@ xf86CrtcPtr amdgpu_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
 		return NULL;
 }
 
-void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
-				    unsigned int tv_usec, void *event_data)
+static void
+amdgpu_dri2_flip_event_abort(ScrnInfoPtr scrn, void *event_data)
+{
+	free(event_data);
+}
+
+static void
+amdgpu_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
+			       void *event_data)
 {
 	DRI2FrameEventPtr flip = event_data;
+	unsigned tv_sec, tv_usec;
 	DrawablePtr drawable;
 	ScreenPtr screen;
-	ScrnInfoPtr scrn;
 	int status;
 	PixmapPtr pixmap;
 
 	status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient,
 				   M_ANY, DixWriteAccess);
-	if (status != Success) {
-		free(flip);
-		return;
-	}
-	if (!flip->crtc) {
-		free(flip);
-		return;
-	}
-	frame += amdgpu_get_interpolated_vblanks(flip->crtc);
+	if (status != Success)
+		goto abort;
 
-	screen = drawable->pScreen;
-	scrn = xf86ScreenToScrn(screen);
+	if (!flip->crtc)
+		goto abort;
+	frame += amdgpu_get_interpolated_vblanks(flip->crtc);
 
+	screen = scrn->pScreen;
 	pixmap = screen->GetScreenPixmap(screen);
 	xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "%s:%d fevent[%p] width %d pitch %d (/4 %d)\n",
 		       __func__, __LINE__, flip, pixmap->drawable.width,
 		       pixmap->devKind, pixmap->devKind / 4);
 
+	tv_sec = usec / 1000000;
+	tv_usec = usec % 1000000;
+
 	/* We assume our flips arrive in order, so we don't check the frame */
 	switch (flip->type) {
 	case DRI2_SWAP:
@@ -537,7 +482,7 @@ void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
 		 */
 		if ((frame < flip->frame) && (flip->frame - frame < 5)) {
 			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-				   "%s: Pageflip completion event has impossible msc %d < target_msc %d\n",
+				   "%s: Pageflip completion event has impossible msc %u < target_msc %u\n",
 				   __func__, frame, flip->frame);
 			/* All-Zero values signal failure of (msc, ust) timestamping to client. */
 			frame = tv_sec = tv_usec = 0;
@@ -554,7 +499,8 @@ void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
 		break;
 	}
 
-	free(flip);
+abort:
+	amdgpu_dri2_flip_event_abort(scrn, event_data);
 }
 
 static Bool
@@ -589,7 +535,10 @@ amdgpu_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
 	back_priv = back->driverPrivate;
 	bo = amdgpu_get_pixmap_bo(back_priv->pixmap);
 
-	return amdgpu_do_pageflip(scrn, bo, flip_info, ref_crtc_hw_id);
+	return amdgpu_do_pageflip(scrn, client, bo, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+				  flip_info, ref_crtc_hw_id,
+				  amdgpu_dri2_flip_event_handler,
+				  amdgpu_dri2_flip_event_abort);
 }
 
 static Bool update_front(DrawablePtr draw, DRI2BufferPtr front)
@@ -719,31 +668,36 @@ amdgpu_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front,
 	DamageRegionProcessPending(&front_priv->pixmap->drawable);
 }
 
-void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
-				     unsigned int tv_usec, void *event_data)
+static void amdgpu_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
+{
+	DRI2FrameEventPtr event = event_data;
+
+	TimerCancel(event->timer);
+	TimerFree(event->timer);
+	amdgpu_dri2_unref_buffer(event->front);
+	amdgpu_dri2_unref_buffer(event->back);
+	free(event);
+}
+
+static void amdgpu_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq,
+					    uint64_t usec, void *event_data)
 {
 	DRI2FrameEventPtr event = event_data;
 	DrawablePtr drawable;
-	ScreenPtr screen;
-	ScrnInfoPtr scrn;
 	int status;
 	int swap_type;
 	BoxRec box;
 	RegionRec region;
 
-	if (!event->valid)
+	if (!event->crtc)
 		goto cleanup;
 
 	status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
 				   M_ANY, DixWriteAccess);
 	if (status != Success)
 		goto cleanup;
-	if (!event->crtc)
-		goto cleanup;
-	frame += amdgpu_get_interpolated_vblanks(event->crtc);
 
-	screen = drawable->pScreen;
-	scrn = xf86ScreenToScrn(screen);
+	seq += amdgpu_get_interpolated_vblanks(event->crtc);
 
 	switch (event->type) {
 	case DRI2_FLIP:
@@ -778,14 +732,14 @@ void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
 			swap_type = DRI2_BLIT_COMPLETE;
 		}
 
-		DRI2SwapComplete(event->client, drawable, frame, tv_sec,
-				 tv_usec, swap_type, event->event_complete,
+		DRI2SwapComplete(event->client, drawable, seq, usec / 1000000,
+				 usec % 1000000, swap_type, event->event_complete,
 				 event->event_data);
 
 		break;
 	case DRI2_WAITMSC:
-		DRI2WaitMSCComplete(event->client, drawable, frame, tv_sec,
-				    tv_usec);
+		DRI2WaitMSCComplete(event->client, drawable, seq, usec / 1000000,
+				    usec % 1000000);
 		break;
 	default:
 		/* Unknown type */
@@ -795,12 +749,7 @@ void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
 	}
 
 cleanup:
-	if (event->valid) {
-		amdgpu_dri2_unref_buffer(event->front);
-		amdgpu_dri2_unref_buffer(event->back);
-		ListDelDRI2ClientEvents(event->client, &event->link);
-	}
-	free(event);
+	amdgpu_dri2_frame_event_abort(scrn, event_data);
 }
 
 drmVBlankSeqType amdgpu_populate_vbl_request_type(xf86CrtcPtr crtc)
@@ -972,17 +921,13 @@ static
 CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
 {
 	DRI2FrameEventPtr event_info = (DRI2FrameEventPtr) data;
-	DrawablePtr drawable;
-	ScreenPtr screen;
+	xf86CrtcPtr crtc = event_info->crtc;
 	ScrnInfoPtr scrn;
 	AMDGPUInfoPtr info;
-	int status;
 	CARD64 drm_now;
 	int ret;
-	unsigned int tv_sec, tv_usec;
 	CARD64 delta_t, delta_seq, frame;
 	drmmode_crtc_private_ptr drmmode_crtc;
-	TimerFree(timer);
 
 	/*
 	 * This is emulated event, so its time is current time, which we
@@ -993,29 +938,26 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
 	 */
 	if (!event_info->crtc) {
 		ErrorF("%s no crtc\n", __func__);
-		amdgpu_dri2_frame_event_handler(0, 0, 0, data);
+		if (event_info->drm_queue)
+			amdgpu_drm_abort_entry(event_info->drm_queue);
+		else
+			amdgpu_dri2_frame_event_abort(NULL, data);
 		return 0;
 	}
-	status =
-	    dixLookupDrawable(&drawable, event_info->drawable_id, serverClient,
-			      M_ANY, DixWriteAccess);
-	if (status != Success) {
-		ErrorF("%s cannot lookup drawable\n", __func__);
-		amdgpu_dri2_frame_event_handler(0, 0, 0, data);
-		return 0;
-	}
-	screen = drawable->pScreen;
-	scrn = xf86ScreenToScrn(screen);
+
+	scrn = crtc->scrn;
 	info = AMDGPUPTR(scrn);
 	ret = drmmode_get_current_ust(info->dri2.drm_fd, &drm_now);
 	if (ret) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "%s cannot get current time\n", __func__);
-		amdgpu_dri2_frame_event_handler(0, 0, 0, data);
+		if (event_info->drm_queue)
+			amdgpu_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0,
+						 event_info->drm_queue);
+		else
+			amdgpu_dri2_frame_event_handler(scrn, 0, 0, data);
 		return 0;
 	}
-	tv_sec = (unsigned int)(drm_now / 1000000);
-	tv_usec = (unsigned int)(drm_now - (CARD64) tv_sec * 1000000);
 	/*
 	 * calculate the frame number from current time
 	 * that would come from CRTC if it were running
@@ -1025,21 +967,22 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
 	delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
 	delta_seq /= 1000000;
 	frame = (CARD64) drmmode_crtc->dpms_last_seq + delta_seq;
-	frame &= 0xffffffff;
-	amdgpu_dri2_frame_event_handler((unsigned int)frame, tv_sec, tv_usec,
-					data);
+	if (event_info->drm_queue)
+		amdgpu_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000,
+					 drm_now % 1000000, event_info->drm_queue);
+	else
+		amdgpu_dri2_frame_event_handler(scrn, frame, drm_now, data);
 	return 0;
 }
 
 static
-void amdgpu_dri2_schedule_event(CARD32 delay, pointer arg)
+void amdgpu_dri2_schedule_event(CARD32 delay, DRI2FrameEventPtr event_info)
 {
-	OsTimerPtr timer;
-
-	timer = TimerSet(NULL, 0, delay, amdgpu_dri2_deferred_event, arg);
+	event_info->timer = TimerSet(NULL, 0, delay, amdgpu_dri2_deferred_event,
+				     event_info);
 	if (delay == 0) {
 		CARD32 now = GetTimeInMillis();
-		amdgpu_dri2_deferred_event(timer, now, arg);
+		amdgpu_dri2_deferred_event(event_info->timer, now, event_info);
 	}
 }
 
@@ -1057,6 +1000,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
 	DRI2FrameEventPtr wait_info = NULL;
+	struct amdgpu_drm_queue_entry *wait = NULL;
 	xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
 	drmVBlank vbl;
 	int ret;
@@ -1079,17 +1023,8 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 	wait_info->drawable_id = draw->id;
 	wait_info->client = client;
 	wait_info->type = DRI2_WAITMSC;
-	wait_info->valid = TRUE;
 	wait_info->crtc = crtc;
 
-	if (ListAddDRI2ClientEvents(client, &wait_info->link)) {
-		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			   "add events to client private failed.\n");
-		free(wait_info);
-		wait_info = NULL;
-		goto out_complete;
-	}
-
 	/*
 	 * CRTC is in DPMS off state, calculate wait time from current time,
 	 * target_msc and last vblank time/sequence when CRTC was turned off
@@ -1118,6 +1053,16 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 	    vbl.reply.sequence + amdgpu_get_interpolated_vblanks(crtc);
 	current_msc &= 0xffffffff;
 
+	wait = amdgpu_drm_queue_alloc(scrn, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+				      wait_info, amdgpu_dri2_frame_event_handler,
+				      amdgpu_dri2_frame_event_abort);
+	if (!wait) {
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "Allocating DRM queue event entry failed.\n");
+		goto out_complete;
+	}
+	wait_info->drm_queue = wait;
+
 	/*
 	 * If divisor is zero, or current_msc is smaller than target_msc,
 	 * we just need to make sure target_msc passes  before waking up the
@@ -1136,7 +1081,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 		vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
 		vbl.request.sequence = target_msc;
 		vbl.request.sequence -= amdgpu_get_interpolated_vblanks(crtc);
-		vbl.request.signal = (unsigned long)wait_info;
+		vbl.request.signal = (unsigned long)wait;
 		ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
 		if (ret) {
 			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1169,7 +1114,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 		vbl.request.sequence += divisor;
 	vbl.request.sequence -= amdgpu_get_interpolated_vblanks(crtc);
 
-	vbl.request.signal = (unsigned long)wait_info;
+	vbl.request.signal = (unsigned long)wait;
 	ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
 	if (ret) {
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1182,11 +1127,8 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 	return TRUE;
 
 out_complete:
-	if (wait_info) {
-		ListDelDRI2ClientEvents(wait_info->client, &wait_info->link);
-		free(wait_info);
-	}
-	DRI2WaitMSCComplete(client, draw, target_msc, 0, 0);
+	if (wait_info)
+		amdgpu_dri2_deferred_event(NULL, 0, wait_info);
 	return TRUE;
 }
 
@@ -1223,6 +1165,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	drmVBlank vbl;
 	int ret, flip = 0;
 	DRI2FrameEventPtr swap_info = NULL;
+	struct amdgpu_drm_queue_entry *swap;
 	CARD64 current_msc;
 	BoxRec box;
 	RegionRec region;
@@ -1255,15 +1198,17 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	swap_info->event_data = data;
 	swap_info->front = front;
 	swap_info->back = back;
-	swap_info->valid = TRUE;
 	swap_info->crtc = crtc;
-	if (ListAddDRI2ClientEvents(client, &swap_info->link)) {
+
+	swap = amdgpu_drm_queue_alloc(scrn, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+				      swap_info, amdgpu_dri2_frame_event_handler,
+				      amdgpu_dri2_frame_event_abort);
+	if (!swap) {
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			   "add events to client private failed.\n");
-		free(swap_info);
-		swap_info = NULL;
+			   "Allocating DRM queue entry failed.\n");
 		goto blit_fallback;
 	}
+	swap_info->drm_queue = swap;
 
 	/*
 	 * CRTC is in DPMS off state, fallback to blit, but calculate
@@ -1331,7 +1276,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 
 		vbl.request.sequence = *target_msc;
 		vbl.request.sequence -= amdgpu_get_interpolated_vblanks(crtc);
-		vbl.request.signal = (unsigned long)swap_info;
+		vbl.request.signal = (unsigned long)swap;
 		ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
 		if (ret) {
 			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1378,7 +1323,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	/* Account for 1 frame extra pageflip delay if flip > 0 */
 	vbl.request.sequence -= flip;
 
-	vbl.request.signal = (unsigned long)swap_info;
+	vbl.request.signal = (unsigned long)swap;
 	ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
 	if (ret) {
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1472,26 +1417,6 @@ Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
 		driverNames[0] = driverNames[1] = dri2_info.driverName;
 
 		if (DRI2InfoCnt == 0) {
-#if HAS_DIXREGISTERPRIVATEKEY
-			if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey,
-						   PRIVATE_CLIENT,
-						   sizeof(DRI2ClientEventsRec)))
-			{
-				xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-					   "DRI2 registering "
-					   "private key to client failed\n");
-				return FALSE;
-			}
-#else
-			if (!dixRequestPrivate(DRI2ClientEventsPrivateKey,
-					       sizeof(DRI2ClientEventsRec))) {
-				xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-					   "DRI2 requesting "
-					   "private key to client failed\n");
-				return FALSE;
-			}
-#endif
-
 			AddCallback(&ClientStateCallback,
 				    amdgpu_dri2_client_state_changed, 0);
 		}
diff --git a/src/amdgpu_dri2.h b/src/amdgpu_dri2.h
index 3ca9dd2..d9bec91 100644
--- a/src/amdgpu_dri2.h
+++ b/src/amdgpu_dri2.h
@@ -43,12 +43,6 @@ struct amdgpu_dri2 {
 Bool amdgpu_dri2_screen_init(ScreenPtr pScreen);
 void amdgpu_dri2_close_screen(ScreenPtr pScreen);
 
-int drmmode_get_crtc_id(xf86CrtcPtr crtc);
-void amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
-				     unsigned int tv_usec, void *event_data);
-void amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
-				    unsigned int tv_usec, void *event_data);
-
 #else
 
 static inline Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
@@ -60,37 +54,6 @@ static inline void amdgpu_dri2_close_screen(ScreenPtr pScreen)
 {
 }
 
-static inline void
-amdgpu_dri2_dummy_event_handler(unsigned int frame, unsigned int tv_sec,
-				unsigned int tv_usec, void *event_data,
-				const char *name)
-{
-	static Bool warned;
-
-	if (!warned) {
-		ErrorF("%s called but DRI2 disabled at build time\n", name);
-		warned = TRUE;
-	}
-
-	free(event_data);
-}
-
-static inline void
-amdgpu_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
-				unsigned int tv_usec, void *event_data)
-{
-	amdgpu_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
-					__func__);
-}
-
-static inline void
-amdgpu_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
-			       unsigned int tv_usec, void *event_data)
-{
-	amdgpu_dri2_dummy_event_handler(frame, tv_sec, tv_usec, event_data,
-					__func__);
-}
-
 #endif
 
 #endif /* AMDGPU_DRI2_H */
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index bb93833..aa7c8c4 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1391,46 +1391,52 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 };
 
 static void
-drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec,
-		       unsigned int tv_usec, void *event_data)
+drmmode_flip_free(drmmode_flipevtcarrier_ptr flipcarrier)
 {
-	amdgpu_dri2_frame_event_handler(frame, tv_sec, tv_usec, event_data);
+	drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
+
+	free(flipcarrier);
+
+	if (--flipdata->flip_count > 0)
+		return;
+
+	/* Release framebuffer */
+	drmModeRmFB(flipdata->drmmode->fd, flipdata->old_fb_id);
+
+	free(flipdata);
+}
+
+static void
+drmmode_flip_abort(ScrnInfoPtr scrn, void *event_data)
+{
+	drmmode_flipevtcarrier_ptr flipcarrier = event_data;
+	drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
+
+	if (flipdata->flip_count == 1)
+		flipcarrier->abort(scrn, flipdata->event_data);
+
+	drmmode_flip_free(flipcarrier);
 }
 
 static void
-drmmode_flip_handler(int fd, unsigned int frame, unsigned int tv_sec,
-		     unsigned int tv_usec, void *event_data)
+drmmode_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *event_data)
 {
 	drmmode_flipevtcarrier_ptr flipcarrier = event_data;
 	drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
-	drmmode_ptr drmmode = flipdata->drmmode;
 
 	/* Is this the event whose info shall be delivered to higher level? */
 	if (flipcarrier->dispatch_me) {
 		/* Yes: Cache msc, ust for later delivery. */
 		flipdata->fe_frame = frame;
-		flipdata->fe_tv_sec = tv_sec;
-		flipdata->fe_tv_usec = tv_usec;
+		flipdata->fe_usec = usec;
 	}
-	free(flipcarrier);
-
-	/* Last crtc completed flip? */
-	flipdata->flip_count--;
-	if (flipdata->flip_count > 0)
-		return;
-
-	/* Release framebuffer */
-	drmModeRmFB(drmmode->fd, flipdata->old_fb_id);
-
-	if (flipdata->event_data == NULL)
-		return;
 
 	/* Deliver cached msc, ust from reference crtc to flip event handler */
-	amdgpu_dri2_flip_event_handler(flipdata->fe_frame, flipdata->fe_tv_sec,
-				       flipdata->fe_tv_usec,
-				       flipdata->event_data);
+	if (flipdata->event_data && flipdata->flip_count == 1)
+		flipcarrier->handler(scrn, flipdata->fe_frame, flipdata->fe_usec,
+				     flipdata->event_data);
 
-	free(flipdata);
+	drmmode_flip_free(flipcarrier);
 }
 
 static void drm_wakeup_handler(pointer data, int err, pointer p)
@@ -1475,8 +1481,8 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	xf86InitialConfiguration(pScrn, TRUE);
 
 	drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
-	drmmode->event_context.vblank_handler = drmmode_vblank_handler;
-	drmmode->event_context.page_flip_handler = drmmode_flip_handler;
+	drmmode->event_context.vblank_handler = amdgpu_drm_queue_handler;
+	drmmode->event_context.page_flip_handler = amdgpu_drm_queue_handler;
 
 	return TRUE;
 }
@@ -1743,8 +1749,10 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
 #endif
 }
 
-Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
-			void *data, int ref_crtc_hw_id)
+Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
+			struct amdgpu_buffer *new_front, uint64_t id, void *data,
+			int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
+			amdgpu_drm_abort_proc abort)
 {
 	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1754,7 +1762,8 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
 	int i, old_fb_id;
 	int height, emitted = 0;
 	drmmode_flipdata_ptr flipdata;
-	drmmode_flipevtcarrier_ptr flipcarrier;
+	drmmode_flipevtcarrier_ptr flipcarrier = NULL;
+	struct amdgpu_drm_queue_entry *drm_queue = 0;
 	union gbm_bo_handle bo_handle;
 	uint32_t handle;
 
@@ -1823,10 +1832,22 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
 		flipcarrier->dispatch_me =
 		    (drmmode_crtc->hw_id == ref_crtc_hw_id);
 		flipcarrier->flipdata = flipdata;
+		flipcarrier->handler = handler;
+		flipcarrier->abort = abort;
+
+		drm_queue = amdgpu_drm_queue_alloc(scrn, client, id,
+						   flipcarrier,
+						   drmmode_flip_handler,
+						   drmmode_flip_abort);
+		if (!drm_queue) {
+			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+				   "Allocating DRM queue event entry failed.\n");
+			goto error_undo;
+		}
 
-		if (drmModePageFlip
-		    (drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-		     drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT, flipcarrier)) {
+		if (drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+				    drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT,
+				    drm_queue)) {
 			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
 				   "flip queue failed: %s\n", strerror(errno));
 			free(flipcarrier);
@@ -1841,6 +1862,11 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
 	return TRUE;
 
 error_undo:
+	if (drm_queue)
+		amdgpu_drm_abort_entry(drm_queue);
+	else
+		drmmode_flip_abort(scrn, flipcarrier);
+
 	drmModeRmFB(drmmode->fd, drmmode->fb_id);
 	drmmode->fb_id = old_fb_id;
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index c2ec683..9cf6932 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -32,6 +32,7 @@
 #include "libudev.h"
 #endif
 
+#include "amdgpu_drm_queue.h"
 #include "amdgpu_probe.h"
 #include "amdgpu.h"
 
@@ -59,13 +60,14 @@ typedef struct {
 	int flip_count;
 	void *event_data;
 	unsigned int fe_frame;
-	unsigned int fe_tv_sec;
-	unsigned int fe_tv_usec;
+	uint64_t fe_usec;
 } drmmode_flipdata_rec, *drmmode_flipdata_ptr;
 
 typedef struct {
 	drmmode_flipdata_ptr flipdata;
 	Bool dispatch_me;
+	amdgpu_drm_handler_proc handler;
+	amdgpu_drm_abort_proc abort;
 } drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
 
 typedef struct {
@@ -117,9 +119,12 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 
+extern int drmmode_get_crtc_id(xf86CrtcPtr crtc);
 extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe);
-Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, struct amdgpu_buffer *new_front,
-			void *data, int ref_crtc_hw_id);
+Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
+			struct amdgpu_buffer *new_front, uint64_t id, void *data,
+			int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
+			amdgpu_drm_abort_proc abort);
 int drmmode_get_current_ust(int drm_fd, CARD64 * ust);
 
 #endif
-- 
2.1.4



More information about the xorg-driver-ati mailing list