diff options
Diffstat (limited to 'qxl_cursor_fix.patch')
-rw-r--r-- | qxl_cursor_fix.patch | 565 |
1 files changed, 0 insertions, 565 deletions
diff --git a/qxl_cursor_fix.patch b/qxl_cursor_fix.patch deleted file mode 100644 index 8d59cb48b..000000000 --- a/qxl_cursor_fix.patch +++ /dev/null @@ -1,565 +0,0 @@ -From fda212272d75dd46a53bdeba9466c6f7db7ee3fa Mon Sep 17 00:00:00 2001 -From: Ray Strode <rstrode@redhat.com> -Date: Fri, 17 Nov 2017 15:08:05 -0500 -Subject: [PATCH 1/2] drm/qxl: unref cursor bo when finished with it - -qxl_cursor_atomic_update allocs a bo for the cursor that -it never frees up at the end of the function. - -This commit fixes that. - -Signed-off-by: Ray Strode <rstrode@redhat.com> ---- - drivers/gpu/drm/qxl/qxl_display.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c -index da6648e75374..dab9f860626f 100644 ---- a/drivers/gpu/drm/qxl/qxl_display.c -+++ b/drivers/gpu/drm/qxl/qxl_display.c -@@ -551,61 +551,61 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane, - struct qxl_device *qdev = plane->dev->dev_private; - - if (old_state->fb) { - struct qxl_framebuffer *qfb = - to_qxl_framebuffer(old_state->fb); - struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj); - - if (bo->is_primary) { - qxl_io_destroy_primary(qdev); - bo->is_primary = false; - } - } - } - - int qxl_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) - { - return 0; - } - - static void qxl_cursor_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) - { - struct drm_device *dev = plane->dev; - struct qxl_device *qdev = dev->dev_private; - struct drm_framebuffer *fb = plane->state->fb; - struct qxl_release *release; - struct qxl_cursor_cmd *cmd; - struct qxl_cursor *cursor; - struct drm_gem_object *obj; -- struct qxl_bo *cursor_bo, *user_bo = NULL; -+ struct qxl_bo *cursor_bo = NULL, *user_bo = NULL; - int ret; - void *user_ptr; - int size = 64*64*4; - - ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), - QXL_RELEASE_CURSOR_CMD, - &release, NULL); - if (ret) - return; - - if (fb != old_state->fb) { - obj = to_qxl_framebuffer(fb)->obj; - user_bo = gem_to_qxl_bo(obj); - - /* pinning is done in the prepare/cleanup framevbuffer */ - ret = qxl_bo_kmap(user_bo, &user_ptr); - if (ret) - goto out_free_release; - - ret = qxl_alloc_bo_reserved(qdev, release, - sizeof(struct qxl_cursor) + size, - &cursor_bo); - if (ret) - goto out_kunmap; - - ret = qxl_release_reserve_list(release, true); - if (ret) - goto out_free_bo; - - ret = qxl_bo_kmap(cursor_bo, (void **)&cursor); -@@ -621,60 +621,62 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, - cursor->data_size = size; - cursor->chunk.next_chunk = 0; - cursor->chunk.prev_chunk = 0; - cursor->chunk.data_size = size; - memcpy(cursor->chunk.data, user_ptr, size); - qxl_bo_kunmap(cursor_bo); - qxl_bo_kunmap(user_bo); - - cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); - cmd->u.set.visible = 1; - cmd->u.set.shape = qxl_bo_physical_address(qdev, - cursor_bo, 0); - cmd->type = QXL_CURSOR_SET; - } else { - - ret = qxl_release_reserve_list(release, true); - if (ret) - goto out_free_release; - - cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); - cmd->type = QXL_CURSOR_MOVE; - } - - cmd->u.position.x = plane->state->crtc_x + fb->hot_x; - cmd->u.position.y = plane->state->crtc_y + fb->hot_y; - - qxl_release_unmap(qdev, release, &cmd->release_info); - qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); - qxl_release_fence_buffer_objects(release); - -+ qxl_bo_unref (&cursor_bo); -+ - return; - - out_backoff: - qxl_release_backoff_reserve_list(release); - out_free_bo: - qxl_bo_unref(&cursor_bo); - out_kunmap: - qxl_bo_kunmap(user_bo); - out_free_release: - qxl_release_free(qdev, release); - return; - - } - - void qxl_cursor_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) - { - struct qxl_device *qdev = plane->dev->dev_private; - struct qxl_release *release; - struct qxl_cursor_cmd *cmd; - int ret; - - ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), - QXL_RELEASE_CURSOR_CMD, - &release, NULL); - if (ret) - return; - - ret = qxl_release_reserve_list(release, true); - if (ret) { --- -2.14.3 - - -From c779c917be6cd38a0c39ebb10f75f223efc5ffef Mon Sep 17 00:00:00 2001 -From: Ray Strode <rstrode@redhat.com> -Date: Fri, 17 Nov 2017 14:49:46 -0500 -Subject: [PATCH 2/2] drm/qxl: reapply cursor after resetting primary - -QXL associates mouse state with its primary plane. - -Destroying a primary plane and putting a new one -in place has the side effect of destroying the cursor -as well. - -This commit changes the driver to reapply the cursor -any time a new primary is created. It achieves this -by keeping a reference to the cursor bo on the qxl_crtc -struct. - -This fix is very similar to commit 4532b241a4b which -got implicitly reverted as part of implementing the -atomic modeset feature. - -Signed-off-by: Ray Strode <rstrode@redhat.com> - -https://bugzilla.redhat.com/show_bug.cgi?id=1512097 ---- - drivers/gpu/drm/qxl/qxl_display.c | 59 +++++++++++++++++++++++++++++++++++++++ - drivers/gpu/drm/qxl/qxl_drv.h | 2 ++ - 2 files changed, 61 insertions(+) - -diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c -index dab9f860626f..ef5c3a83130f 100644 ---- a/drivers/gpu/drm/qxl/qxl_display.c -+++ b/drivers/gpu/drm/qxl/qxl_display.c -@@ -262,60 +262,61 @@ static int qxl_add_common_modes(struct drm_connector *connector, - mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, - 60, false, false, false); - if (common_modes[i].w == pwidth && common_modes[i].h == pheight) - mode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, mode); - } - return i - 1; - } - - static void qxl_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) - { - struct drm_device *dev = crtc->dev; - struct drm_pending_vblank_event *event; - unsigned long flags; - - if (crtc->state && crtc->state->event) { - event = crtc->state->event; - crtc->state->event = NULL; - - spin_lock_irqsave(&dev->event_lock, flags); - drm_crtc_send_vblank_event(crtc, event); - spin_unlock_irqrestore(&dev->event_lock, flags); - } - } - - static void qxl_crtc_destroy(struct drm_crtc *crtc) - { - struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc); - -+ qxl_bo_unref(&qxl_crtc->cursor_bo); - drm_crtc_cleanup(crtc); - kfree(qxl_crtc); - } - - static const struct drm_crtc_funcs qxl_crtc_funcs = { - .set_config = drm_atomic_helper_set_config, - .destroy = qxl_crtc_destroy, - .page_flip = drm_atomic_helper_page_flip, - .reset = drm_atomic_helper_crtc_reset, - .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, - }; - - void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) - { - struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); - struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj); - - WARN_ON(bo->shadow); - drm_gem_object_unreference_unlocked(qxl_fb->obj); - drm_framebuffer_cleanup(fb); - kfree(qxl_fb); - } - - static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned flags, unsigned color, - struct drm_clip_rect *clips, - unsigned num_clips) - { -@@ -471,193 +472,251 @@ static void qxl_crtc_disable(struct drm_crtc *crtc) - static const struct drm_crtc_helper_funcs qxl_crtc_helper_funcs = { - .dpms = qxl_crtc_dpms, - .disable = qxl_crtc_disable, - .mode_fixup = qxl_crtc_mode_fixup, - .mode_set_nofb = qxl_mode_set_nofb, - .commit = qxl_crtc_commit, - .atomic_flush = qxl_crtc_atomic_flush, - }; - - int qxl_primary_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) - { - struct qxl_device *qdev = plane->dev->dev_private; - struct qxl_framebuffer *qfb; - struct qxl_bo *bo; - - if (!state->crtc || !state->fb) - return 0; - - qfb = to_qxl_framebuffer(state->fb); - bo = gem_to_qxl_bo(qfb->obj); - - if (bo->surf.stride * bo->surf.height > qdev->vram_size) { - DRM_ERROR("Mode doesn't fit in vram size (vgamem)"); - return -EINVAL; - } - - return 0; - } - -+static int qxl_primary_apply_cursor(struct drm_plane *plane) -+{ -+ struct drm_device *dev = plane->dev; -+ struct qxl_device *qdev = dev->dev_private; -+ struct drm_framebuffer *fb = plane->state->fb; -+ struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); -+ struct qxl_cursor_cmd *cmd; -+ struct qxl_release *release; -+ int ret = 0; -+ -+ if (!qcrtc->cursor_bo) -+ return 0; -+ -+ ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), -+ QXL_RELEASE_CURSOR_CMD, -+ &release, NULL); -+ if (ret) -+ return ret; -+ -+ ret = qxl_release_list_add(release, qcrtc->cursor_bo); -+ if (ret) -+ goto out_free_release; -+ -+ ret = qxl_release_reserve_list(release, false); -+ if (ret) -+ goto out_free_release; -+ -+ cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); -+ cmd->type = QXL_CURSOR_SET; -+ cmd->u.set.position.x = plane->state->crtc_x + fb->hot_x; -+ cmd->u.set.position.y = plane->state->crtc_y + fb->hot_y; -+ -+ cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0); -+ -+ cmd->u.set.visible = 1; -+ qxl_release_unmap(qdev, release, &cmd->release_info); -+ -+ qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); -+ qxl_release_fence_buffer_objects(release); -+ -+ return ret; -+ -+out_free_release: -+ qxl_release_free(qdev, release); -+ return ret; -+} -+ - static void qxl_primary_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) - { - struct qxl_device *qdev = plane->dev->dev_private; - struct qxl_framebuffer *qfb = - to_qxl_framebuffer(plane->state->fb); - struct qxl_framebuffer *qfb_old; - struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj); - struct qxl_bo *bo_old; - struct drm_clip_rect norect = { - .x1 = 0, - .y1 = 0, - .x2 = qfb->base.width, - .y2 = qfb->base.height - }; -+ int ret; - bool same_shadow = false; - - if (old_state->fb) { - qfb_old = to_qxl_framebuffer(old_state->fb); - bo_old = gem_to_qxl_bo(qfb_old->obj); - } else { - bo_old = NULL; - } - - if (bo == bo_old) - return; - - if (bo_old && bo_old->shadow && bo->shadow && - bo_old->shadow == bo->shadow) { - same_shadow = true; - } - - if (bo_old && bo_old->is_primary) { - if (!same_shadow) - qxl_io_destroy_primary(qdev); - bo_old->is_primary = false; -+ -+ ret = qxl_primary_apply_cursor(plane); -+ if (ret) { -+ DRM_ERROR("could not set cursor after creating primary"); -+ } - } - - if (!bo->is_primary) { - if (!same_shadow) - qxl_io_create_primary(qdev, 0, bo); - bo->is_primary = true; - } - - qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1); - } - - static void qxl_primary_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) - { - struct qxl_device *qdev = plane->dev->dev_private; - - if (old_state->fb) { - struct qxl_framebuffer *qfb = - to_qxl_framebuffer(old_state->fb); - struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj); - - if (bo->is_primary) { - qxl_io_destroy_primary(qdev); - bo->is_primary = false; - } - } - } - - int qxl_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) - { - return 0; - } - - static void qxl_cursor_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) - { - struct drm_device *dev = plane->dev; - struct qxl_device *qdev = dev->dev_private; - struct drm_framebuffer *fb = plane->state->fb; -+ struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); - struct qxl_release *release; - struct qxl_cursor_cmd *cmd; - struct qxl_cursor *cursor; - struct drm_gem_object *obj; - struct qxl_bo *cursor_bo = NULL, *user_bo = NULL; - int ret; - void *user_ptr; - int size = 64*64*4; - - ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), - QXL_RELEASE_CURSOR_CMD, - &release, NULL); - if (ret) - return; - - if (fb != old_state->fb) { - obj = to_qxl_framebuffer(fb)->obj; - user_bo = gem_to_qxl_bo(obj); - - /* pinning is done in the prepare/cleanup framevbuffer */ - ret = qxl_bo_kmap(user_bo, &user_ptr); - if (ret) - goto out_free_release; - - ret = qxl_alloc_bo_reserved(qdev, release, - sizeof(struct qxl_cursor) + size, - &cursor_bo); - if (ret) - goto out_kunmap; - - ret = qxl_release_reserve_list(release, true); - if (ret) - goto out_free_bo; - - ret = qxl_bo_kmap(cursor_bo, (void **)&cursor); - if (ret) - goto out_backoff; - - cursor->header.unique = 0; - cursor->header.type = SPICE_CURSOR_TYPE_ALPHA; - cursor->header.width = 64; - cursor->header.height = 64; - cursor->header.hot_spot_x = fb->hot_x; - cursor->header.hot_spot_y = fb->hot_y; - cursor->data_size = size; - cursor->chunk.next_chunk = 0; - cursor->chunk.prev_chunk = 0; - cursor->chunk.data_size = size; - memcpy(cursor->chunk.data, user_ptr, size); - qxl_bo_kunmap(cursor_bo); - qxl_bo_kunmap(user_bo); - - cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); - cmd->u.set.visible = 1; - cmd->u.set.shape = qxl_bo_physical_address(qdev, - cursor_bo, 0); - cmd->type = QXL_CURSOR_SET; -+ -+ qxl_bo_unref (&qcrtc->cursor_bo); -+ qcrtc->cursor_bo = cursor_bo; -+ cursor_bo = NULL; - } else { - - ret = qxl_release_reserve_list(release, true); - if (ret) - goto out_free_release; - - cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); - cmd->type = QXL_CURSOR_MOVE; - } - - cmd->u.position.x = plane->state->crtc_x + fb->hot_x; - cmd->u.position.y = plane->state->crtc_y + fb->hot_y; - - qxl_release_unmap(qdev, release, &cmd->release_info); - qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); - qxl_release_fence_buffer_objects(release); - - qxl_bo_unref (&cursor_bo); - - return; - - out_backoff: - qxl_release_backoff_reserve_list(release); - out_free_bo: - qxl_bo_unref(&cursor_bo); - out_kunmap: - qxl_bo_kunmap(user_bo); - out_free_release: - qxl_release_free(qdev, release); - return; -diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h -index b5e9dc6eebac..d3e2373ef821 100644 ---- a/drivers/gpu/drm/qxl/qxl_drv.h -+++ b/drivers/gpu/drm/qxl/qxl_drv.h -@@ -107,60 +107,62 @@ struct qxl_bo { - struct ttm_bo_kmap_obj kmap; - unsigned pin_count; - void *kptr; - int type; - - /* Constant after initialization */ - struct drm_gem_object gem_base; - bool is_primary; /* is this now a primary surface */ - bool is_dumb; - struct qxl_bo *shadow; - bool hw_surf_alloc; - struct qxl_surface surf; - uint32_t surface_id; - struct qxl_release *surf_create; - }; - #define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base) - #define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo) - - struct qxl_gem { - struct mutex mutex; - struct list_head objects; - }; - - struct qxl_bo_list { - struct ttm_validate_buffer tv; - }; - - struct qxl_crtc { - struct drm_crtc base; - int index; -+ -+ struct qxl_bo *cursor_bo; - }; - - struct qxl_output { - int index; - struct drm_connector base; - struct drm_encoder enc; - }; - - struct qxl_framebuffer { - struct drm_framebuffer base; - struct drm_gem_object *obj; - }; - - #define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base) - #define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base) - #define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc) - #define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base) - - struct qxl_mman { - struct ttm_bo_global_ref bo_global_ref; - struct drm_global_reference mem_global_ref; - bool mem_global_referenced; - struct ttm_bo_device bdev; - }; - - struct qxl_mode_info { - bool mode_config_initialized; - - /* pointer to fbdev info structure */ - struct qxl_fbdev *qfbdev; --- -2.14.3 - |