diff options
-rw-r--r-- | src/amdgpu_drm_queue.c | 94 | ||||
-rw-r--r-- | src/amdgpu_drm_queue.h | 1 | ||||
-rw-r--r-- | src/amdgpu_present.c | 2 | ||||
-rw-r--r-- | src/drmmode_display.c | 4 |
4 files changed, 83 insertions, 18 deletions
diff --git a/src/amdgpu_drm_queue.c b/src/amdgpu_drm_queue.c index 9c01661..f866082 100644 --- a/src/amdgpu_drm_queue.c +++ b/src/amdgpu_drm_queue.c @@ -40,6 +40,7 @@ struct amdgpu_drm_queue_entry { struct xorg_list list; + uint64_t usec; uint64_t id; uintptr_t seq; void *data; @@ -47,39 +48,76 @@ struct amdgpu_drm_queue_entry { xf86CrtcPtr crtc; amdgpu_drm_handler_proc handler; amdgpu_drm_abort_proc abort; + unsigned int frame; }; static int amdgpu_drm_queue_refcnt; static struct xorg_list amdgpu_drm_queue; +static struct xorg_list amdgpu_drm_flip_signalled; +static struct xorg_list amdgpu_drm_vblank_signalled; static uintptr_t amdgpu_drm_queue_seq; /* - * Handle a DRM event + * Process a DRM event */ static void -amdgpu_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *user_ptr) +amdgpu_drm_queue_handle_one(struct amdgpu_drm_queue_entry *e) +{ + xorg_list_del(&e->list); + if (e->handler) { + e->handler(e->crtc, e->frame, e->usec, e->data); + } else + e->abort(e->crtc, e->data); + free(e); +} + +static void +amdgpu_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, + unsigned int sec, unsigned int usec, void *user_ptr) { uintptr_t seq = (uintptr_t)user_ptr; struct amdgpu_drm_queue_entry *e, *tmp; xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) { if (e->seq == seq) { - xorg_list_del(&e->list); - if (e->handler) - e->handler(e->crtc, frame, - (uint64_t)sec * 1000000 + usec, - e->data); - else + if (!e->handler) { e->abort(e->crtc, e->data); - free(e); + break; + } + + xorg_list_del(&e->list); + e->usec = (uint64_t)sec * 1000000 + usec; + e->frame = frame; + xorg_list_append(&e->list, signalled); break; } } } /* + * Signal a DRM page flip event + */ +static void +amdgpu_drm_page_flip_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) +{ + amdgpu_drm_queue_handler(&amdgpu_drm_flip_signalled, frame, sec, usec, + user_ptr); +} + +/* + * Signal a DRM vblank event + */ +static void +amdgpu_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) +{ + amdgpu_drm_queue_handler(&amdgpu_drm_vblank_signalled, frame, sec, usec, + user_ptr); +} + +/* * Enqueue a potential drm response; when the associated response * appears, we've got data to pass to the handler from here */ @@ -178,16 +216,40 @@ amdgpu_drm_abort_id(uint64_t id) } /* + * drmHandleEvent wrapper + */ +int +amdgpu_drm_handle_event(int fd, drmEventContext *event_context) +{ + struct amdgpu_drm_queue_entry *e, *tmp; + int r; + + r = drmHandleEvent(fd, event_context); + + xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_flip_signalled, list) + amdgpu_drm_queue_handle_one(e); + + xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_vblank_signalled, list) + amdgpu_drm_queue_handle_one(e); + + return r; +} + +/* * Wait for pending page flip on given CRTC to complete */ void amdgpu_drm_wait_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn); - drmmode_ptr drmmode = drmmode_crtc->drmmode; + struct amdgpu_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_flip_signalled, list) + amdgpu_drm_queue_handle_one(e); - while (drmmode_crtc->flip_pending && - drmHandleEvent(pAMDGPUEnt->fd, &drmmode->event_context) > 0); + while (drmmode_crtc->flip_pending + && amdgpu_drm_handle_event(pAMDGPUEnt->fd, + &drmmode_crtc->drmmode->event_context) > 0); } /* @@ -200,13 +262,15 @@ amdgpu_drm_queue_init(ScrnInfoPtr scrn) drmmode_ptr drmmode = &info->drmmode; drmmode->event_context.version = 2; - drmmode->event_context.vblank_handler = amdgpu_drm_queue_handler; - drmmode->event_context.page_flip_handler = amdgpu_drm_queue_handler; + drmmode->event_context.vblank_handler = amdgpu_drm_vblank_handler; + drmmode->event_context.page_flip_handler = amdgpu_drm_page_flip_handler; if (amdgpu_drm_queue_refcnt++) return; xorg_list_init(&amdgpu_drm_queue); + xorg_list_init(&amdgpu_drm_flip_signalled); + xorg_list_init(&amdgpu_drm_vblank_signalled); } /* diff --git a/src/amdgpu_drm_queue.h b/src/amdgpu_drm_queue.h index cb6d5ff..48ba9ab 100644 --- a/src/amdgpu_drm_queue.h +++ b/src/amdgpu_drm_queue.h @@ -49,6 +49,7 @@ uintptr_t amdgpu_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, void amdgpu_drm_abort_client(ClientPtr client); void amdgpu_drm_abort_entry(uintptr_t seq); void amdgpu_drm_abort_id(uint64_t id); +int amdgpu_drm_handle_event(int fd, drmEventContext *event_context); void amdgpu_drm_wait_pending_flip(xf86CrtcPtr crtc); void amdgpu_drm_queue_init(ScrnInfoPtr scrn); void amdgpu_drm_queue_close(ScrnInfoPtr scrn); diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c index 4e74bfa..a6676af 100644 --- a/src/amdgpu_present.c +++ b/src/amdgpu_present.c @@ -110,7 +110,7 @@ amdgpu_present_flush_drm_events(ScreenPtr screen) if (r <= 0) return 0; - return drmHandleEvent(pAMDGPUEnt->fd, &drmmode->event_context) >= 0; + return amdgpu_drm_handle_event(pAMDGPUEnt->fd, &drmmode->event_context) >= 0; } /* diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 7f521b6..167b300 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3096,7 +3096,7 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even static void drmmode_notify_fd(int fd, int notify, void *data) { drmmode_ptr drmmode = data; - drmHandleEvent(fd, &drmmode->event_context); + amdgpu_drm_handle_event(fd, &drmmode->event_context); } #else static void drm_wakeup_handler(pointer data, int err, pointer p) @@ -3106,7 +3106,7 @@ static void drm_wakeup_handler(pointer data, int err, pointer p) fd_set *read_mask = p; if (err >= 0 && FD_ISSET(pAMDGPUEnt->fd, read_mask)) { - drmHandleEvent(pAMDGPUEnt->fd, &drmmode->event_context); + amdgpu_drm_handle_event(pAMDGPUEnt->fd, &drmmode->event_context); } } #endif |