From patchwork Wed Sep 5 23:38:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Singh Rawat X-Patchwork-Id: 10589631 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D432A13BB for ; Wed, 5 Sep 2018 23:39:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C2D832AA6B for ; Wed, 5 Sep 2018 23:39:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B6C382AA71; Wed, 5 Sep 2018 23:39:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2CB9B2AA6B for ; Wed, 5 Sep 2018 23:39:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D35076E570; Wed, 5 Sep 2018 23:39:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EX13-EDG-OU-002.vmware.com (ex13-edg-ou-002.vmware.com [208.91.0.190]) by gabe.freedesktop.org (Postfix) with ESMTPS id 841ED6E56B for ; Wed, 5 Sep 2018 23:39:32 +0000 (UTC) Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-002.vmware.com (10.113.208.156) with Microsoft SMTP Server id 15.0.1156.6; Wed, 5 Sep 2018 16:39:25 -0700 Received: from ubuntu.localdomain (promb-2n-dhcp79.eng.vmware.com [10.20.88.79]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id C8E75B06E7; Wed, 5 Sep 2018 19:39:31 -0400 (EDT) From: Deepak Rawat To: , , , Subject: [PATCH 05/14] drm/vmwgfx: add a new interface for plane update on a display unit Date: Wed, 5 Sep 2018 16:38:52 -0700 Message-ID: <20180905233901.2321-6-drawat@vmware.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180905233901.2321-1-drawat@vmware.com> References: <20180905233901.2321-1-drawat@vmware.com> MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-002.vmware.com: drawat@vmware.com does not designate permitted sender hosts) X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Deepak Rawat , lukasz.spintzyk@displaylink.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add a new struct vmw_du_update_plane similar to vmw_kms_dirty which represent the flow of operations needed to update a display unit from surface or bo(blit a new framebuffer). Signed-off-by: Deepak Rawat --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 108 +++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 143 ++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 1edbae73d6d6..c1de8f609bf4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Might need a hrtimer here? */ #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) @@ -3077,3 +3078,110 @@ void vmw_kms_lost_device(struct drm_device *dev) { drm_atomic_helper_shutdown(dev); } + +/** + * vmw_du_helper_plane_update - helper to do plane update on display unit + * + * @update: The closure structure. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ +int vmw_du_helper_plane_update(struct vmw_du_update_plane *update) +{ + struct drm_plane_state *state = update->plane->state; + struct drm_plane_state *old_state = update->old_state; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + struct drm_rect bb; + uint32_t reserved_size = 0; + uint32_t submit_size = 0; + uint32_t curr_size = 0; + uint32_t num_hits = 0; + void *cmd_start; + char *cmd_next; + int ret; + + /* + * Iterate in advance to check if really need plane update and find the + * number of clips that actually are in plane src for fifo allocation. + * Iterator init returns negative error code if no need to do plane + * update. + */ + ret = drm_atomic_helper_damage_iter_init(&iter, old_state, state); + if (ret) + return 0; + + while (drm_atomic_helper_damage_iter_next(&iter, &clip)) + num_hits++; + + /* + * If all clips are outside plane src no need to do plane update on + * display unit + */ + if (num_hits == 0) + return 0; + + ret = update->prepare(update); + if (ret) { + DRM_ERROR("Failed to validate FB for command submission\n"); + return ret; + } + + reserved_size = update->calc_fifo_size(update, num_hits); + cmd_start = vmw_fifo_reserve(update->dev_priv, reserved_size); + if (!cmd_start) { + DRM_ERROR("Failed to allocate FIFO space for plane update\n"); + update->revert(update); + return -ENOMEM; + } + cmd_next = cmd_start; + + if (update->post_prepare) { + curr_size = update->post_prepare(update, cmd_next); + cmd_next += curr_size; + submit_size += curr_size; + } + + if (update->pre_clip) { + curr_size = update->pre_clip(update, cmd_next, num_hits); + cmd_next += curr_size; + submit_size += curr_size; + } + + bb.x1 = INT_MAX; + bb.y1 = INT_MAX; + bb.x2 = INT_MIN; + bb.y2 = INT_MIN; + + drm_atomic_helper_damage_iter_init(&iter, old_state, state); + while (drm_atomic_helper_damage_iter_next(&iter, &clip)) { + uint32_t fb_x = clip.x1; + uint32_t fb_y = clip.y1; + + vmw_du_translate_to_crtc(state, &clip); + if (update->clip) { + curr_size = update->clip(update, cmd_next, &clip, fb_x, + fb_y); + cmd_next += curr_size; + submit_size += curr_size; + } + bb.x1 = min_t(int, bb.x1, clip.x1); + bb.y1 = min_t(int, bb.y1, clip.y1); + bb.x2 = max_t(int, bb.x2, clip.x2); + bb.y2 = max_t(int, bb.y2, clip.y2); + } + + curr_size = update->post_clip(update, cmd_next, &bb); + submit_size += curr_size; + + if (reserved_size < submit_size) + submit_size = 0; + + vmw_fifo_commit(update->dev_priv, submit_size); + + update->finish(update); + + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 31311298ec0b..6bda8d3fb52f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -33,7 +33,132 @@ #include #include "vmwgfx_drv.h" +/** + * struct vmw_du_update_plane - closure structure for vmw_du_helper_plane_update + * + * This structure loosely represent the set of operations needed to perform a + * plane update on a display unit. Implementer will define that functionality + * according to the function callbacks for this structure. In brief it involves + * surface/buffer object validation, populate FIFO commands and command + * submission to the device. + * + * @plane: plane which is being updated. + * @old_state: old state of plane. + * @dev_priv: device private. + * @du: display unit on which to update the plane. + * @vfb: framebuffer which is blitted to display unit. + * @out_fence: (optional) out fence for resource finish. + */ +struct vmw_du_update_plane { + /** + * @prepare: + * + * This callback should be called to prepare the surface resource or the + * buffer object to validate it before command submission. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ + int (*prepare)(struct vmw_du_update_plane *update); + + /** + * @calc_fifo_size: + * + * Determine fifo size for the commands needed for update. The number of + * damage clips on display unit @num_hits will be passed to allocate + * sufficient fifo space. + * + * RETURNS: + * + * Fifo size needed + */ + uint32_t (*calc_fifo_size)(struct vmw_du_update_plane *update, + uint32_t num_hits); + /** + * @post_prepare: + * + * Some surface resource or buffer object need some extra cmd submission + * like update GB image for proxy surface and define a GMRFB for screen + * object. That should should be done here as this callback will be + * called after FIFO allocation with the address of command buufer. + * + * This callback is optional. + * + * RETURNS: + * + * Size of commands populated to command buffer. + */ + uint32_t (*post_prepare)(struct vmw_du_update_plane *update, void *cmd); + + /** + * @pre_clip: + * + * This is where pre clip related command should be populated like + * surface copy/DMA, etc. + * + * This callback is optional. + * + * RETURNS: + * + * Size of commands populated to command buffer. + */ + uint32_t (*pre_clip)(struct vmw_du_update_plane *update, void *cmd, + uint32_t num_hits); + + /** + * @clip: + * + * This is where to populate clips for surface copy/dma or blit commands + * if needed. This will be called times have damage in display unit, + * which is one if doing full update. @clip is the damage in destination + * coordinates which is crtc/DU and @src_x, @src_y is damage clip src in + * framebuffer coordinate. + * + * This callback is optional. + * + * RETURNS: + * + * Size of commands populated to command buffer. + */ + uint32_t (*clip)(struct vmw_du_update_plane *update, void *cmd, + struct drm_rect *clip, uint32_t src_x, uint32_t src_y); + + /** + * @post_clip: + * + * This is where to populate display unit update commands or blit + * commands. + * + * RETURNS: + * + * Size of commands populated to command buffer. + */ + uint32_t (*post_clip)(struct vmw_du_update_plane *update, void *cmd, + struct drm_rect *bb); + + /** + * @finish: + * + * Finish surface resource or buffer object. + */ + void (*finish)(struct vmw_du_update_plane *update); + + /** + * @revert: + * + * Revert surface resource or buffer object in case of failure. + */ + void (*revert)(struct vmw_du_update_plane *update); + + struct drm_plane *plane; + struct drm_plane_state *old_state; + struct vmw_private *dev_priv; + struct vmw_display_unit *du; + struct vmw_framebuffer *vfb; + struct vmw_fence_obj **out_fence; +}; /** * struct vmw_kms_dirty - closure structure for the vmw_kms_helper_dirty @@ -470,4 +595,22 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, int vmw_kms_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx); + +int vmw_du_helper_plane_update(struct vmw_du_update_plane *update); + +/** + * vmw_du_translate_to_crtc - translate a rect from framebuffer to crtc + * + * @state: plane state. + * @r: rect to translate. + */ +static inline void vmw_du_translate_to_crtc(struct drm_plane_state *state, + struct drm_rect *r) +{ + int translate_crtc_x = -((state->src_x >> 16) - state->crtc_x); + int translate_crtc_y = -((state->src_y >> 16) - state->crtc_y); + + drm_rect_translate(r, translate_crtc_x, translate_crtc_y); +} + #endif