summaryrefslogtreecommitdiff
path: root/src/amdgpu_drm_queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amdgpu_drm_queue.c')
-rw-r--r--src/amdgpu_drm_queue.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/src/amdgpu_drm_queue.c b/src/amdgpu_drm_queue.c
index f866082..b13d280 100644
--- a/src/amdgpu_drm_queue.c
+++ b/src/amdgpu_drm_queue.c
@@ -118,6 +118,30 @@ amdgpu_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec,
}
/*
+ * Handle deferred DRM vblank events
+ *
+ * This function must be called after amdgpu_drm_wait_pending_flip, once
+ * it's safe to attempt queueing a flip again
+ */
+void
+amdgpu_drm_queue_handle_deferred(xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct amdgpu_drm_queue_entry *e, *tmp;
+
+ if (drmmode_crtc->wait_flip_nesting_level == 0 ||
+ --drmmode_crtc->wait_flip_nesting_level > 0)
+ return;
+
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_vblank_signalled, list) {
+ drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private;
+
+ if (drmmode_crtc->wait_flip_nesting_level == 0)
+ amdgpu_drm_queue_handle_one(e);
+ }
+}
+
+/*
* Enqueue a potential drm response; when the associated response
* appears, we've got data to pass to the handler from here
*/
@@ -191,6 +215,13 @@ amdgpu_drm_abort_entry(uintptr_t seq)
if (seq == AMDGPU_DRM_QUEUE_ERROR)
return;
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_vblank_signalled, list) {
+ if (e->seq == seq) {
+ amdgpu_drm_abort_one(e);
+ return;
+ }
+ }
+
xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
if (e->seq == seq) {
amdgpu_drm_abort_one(e);
@@ -229,8 +260,12 @@ amdgpu_drm_handle_event(int fd, drmEventContext *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);
+ xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_vblank_signalled, list) {
+ drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private;
+
+ if (drmmode_crtc->wait_flip_nesting_level == 0)
+ amdgpu_drm_queue_handle_one(e);
+ }
return r;
}
@@ -244,6 +279,8 @@ void amdgpu_drm_wait_pending_flip(xf86CrtcPtr crtc)
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn);
struct amdgpu_drm_queue_entry *e, *tmp;
+ drmmode_crtc->wait_flip_nesting_level++;
+
xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_flip_signalled, list)
amdgpu_drm_queue_handle_one(e);