From patchwork Wed Sep 5 23:38:53 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: 10589629 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 219FD174C for ; Wed, 5 Sep 2018 23:39:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 101DE2AA6B for ; Wed, 5 Sep 2018 23:39:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 044D32AA71; Wed, 5 Sep 2018 23:39:39 +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 729802AA6B for ; Wed, 5 Sep 2018 23:39:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E866D6E56B; Wed, 5 Sep 2018 23:39:33 +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 5370B6E56E for ; Wed, 5 Sep 2018 23:39:33 +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:26 -0700 Received: from ubuntu.localdomain (promb-2n-dhcp79.eng.vmware.com [10.20.88.79]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id A3AFAB06E3; Wed, 5 Sep 2018 19:39:32 -0400 (EDT) From: Deepak Rawat To: , , , Subject: [PATCH 06/14] drm/vmwgfx: implement STDU plane update for surface backed fb Date: Wed, 5 Sep 2018 16:38:53 -0700 Message-ID: <20180905233901.2321-7-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 Using the new interface implement STDU plane update for surface backed fb. Signed-off-by: Deepak Rawat --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 11 ++ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 209 ++++++++++++++++++++++++++- 2 files changed, 219 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 6bda8d3fb52f..0ecc5231b617 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -160,6 +160,17 @@ struct vmw_du_update_plane { struct vmw_fence_obj **out_fence; }; +/** + * struct vmw_du_update_plane_surface - closure structure for surface + * + * @base: base closure structure. + * @ctx: validation context. + */ +struct vmw_du_update_plane_surface { + struct vmw_du_update_plane base; + struct vmw_validation_ctx *ctx; +}; + /** * struct vmw_kms_dirty - closure structure for the vmw_kms_helper_dirty * function. diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 93f6b96ca7bb..b5115b4a1787 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -30,7 +30,7 @@ #include #include #include - +#include #define vmw_crtc_to_stdu(x) \ container_of(x, struct vmw_screen_target_display_unit, base.crtc) @@ -92,6 +92,10 @@ struct vmw_stdu_surface_copy { SVGA3dCmdSurfaceCopy body; }; +struct vmw_stdu_update_gb_image { + SVGA3dCmdHeader header; + SVGA3dCmdUpdateGBImage body; +}; /** * struct vmw_screen_target_display_unit @@ -1240,7 +1244,210 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, return ret; } +static int vmw_stdu_surface_prepare(struct vmw_du_update_plane *update) +{ + struct vmw_du_update_plane_surface *srf_update; + struct vmw_framebuffer_surface *vfbs; + + srf_update = container_of(update, typeof(*srf_update), base); + vfbs = container_of(update->vfb, typeof(*vfbs), base); + + return vmw_kms_helper_resource_prepare(&vfbs->surface->res, true, + srf_update->ctx); +} + +static uint32_t +vmw_stdu_surface_fifo_size_same_display(struct vmw_du_update_plane *update, + uint32_t num_hits) +{ + struct vmw_framebuffer_surface *vfbs; + uint32_t size = 0; + + vfbs = container_of(update->vfb, typeof(*vfbs), base); + + if (vfbs->is_bo_proxy) + size += sizeof(struct vmw_stdu_update_gb_image) * num_hits; + + size += sizeof(struct vmw_stdu_update); + + return size; +} + +static uint32_t vmw_stdu_surface_fifo_size(struct vmw_du_update_plane *update, + uint32_t num_hits) +{ + struct vmw_framebuffer_surface *vfbs; + uint32_t size = 0; + + vfbs = container_of(update->vfb, typeof(*vfbs), base); + + if (vfbs->is_bo_proxy) + size += sizeof(struct vmw_stdu_update_gb_image) * num_hits; + + size += sizeof(struct vmw_stdu_surface_copy) + sizeof(SVGA3dCopyBox) * + num_hits + sizeof(struct vmw_stdu_update); + + return size; +} + +static uint32_t +vmw_stdu_surface_update_proxy(struct vmw_du_update_plane *update, void *cmd) +{ + struct vmw_framebuffer_surface *vfbs; + 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 vmw_stdu_update_gb_image *cmd_update = cmd; + struct drm_rect clip; + uint32_t copy_size = 0; + + vfbs = container_of(update->vfb, typeof(*vfbs), base); + + /* + * proxy surface is special where a buffer object type fb is wrapped + * in a surface and need an update gb image command to sync with device. + */ + drm_atomic_helper_damage_iter_init(&iter, old_state, state); + while (drm_atomic_helper_damage_iter_next(&iter, &clip)) { + SVGA3dBox *box = &cmd_update->body.box; + + cmd_update->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE; + cmd_update->header.size = sizeof(cmd_update->body); + cmd_update->body.image.sid = vfbs->surface->res.id; + cmd_update->body.image.face = 0; + cmd_update->body.image.mipmap = 0; + + box->x = clip.x1; + box->y = clip.y1; + box->z = 0; + box->w = drm_rect_width(&clip); + box->h = drm_rect_height(&clip); + box->d = 1; + + copy_size += sizeof(*cmd_update); + cmd_update++; + } + + return copy_size; +} + +static uint32_t +vmw_stdu_surface_populate_copy(struct vmw_du_update_plane *update, void *cmd, + uint32_t num_hits) +{ + struct vmw_screen_target_display_unit *stdu; + struct vmw_framebuffer_surface *vfbs; + struct vmw_stdu_surface_copy *cmd_copy = cmd; + + stdu = container_of(update->du, typeof(*stdu), base); + vfbs = container_of(update->vfb, typeof(*vfbs), base); + cmd_copy->header.id = SVGA_3D_CMD_SURFACE_COPY; + cmd_copy->header.size = sizeof(cmd_copy->body) + sizeof(SVGA3dCopyBox) * + num_hits; + cmd_copy->body.src.sid = vfbs->surface->res.id; + cmd_copy->body.dest.sid = stdu->display_srf->res.id; + + return sizeof(*cmd_copy); +} + +static uint32_t +vmw_stdu_surface_populate_clip(struct vmw_du_update_plane *update, void *cmd, + struct drm_rect *clip, uint32_t fb_x, + uint32_t fb_y) +{ + struct SVGA3dCopyBox *box = cmd; + + box->srcx = fb_x; + box->srcy = fb_y; + box->srcz = 0; + box->x = clip->x1; + box->y = clip->y1; + box->z = 0; + box->w = drm_rect_width(clip); + box->h = drm_rect_height(clip); + box->d = 1; + + return sizeof(*box); +} + +static uint32_t +vmw_stud_surface_populate_update(struct vmw_du_update_plane *update, void *cmd, + struct drm_rect *bb) +{ + vmw_stdu_populate_update(cmd, update->du->unit, bb->x1, bb->x2, bb->y1, + bb->y2); + + return sizeof(struct vmw_stdu_update); +} + +static void vmw_stdu_surface_finish(struct vmw_du_update_plane *update) +{ + struct vmw_du_update_plane_surface *srf_update = + container_of(update, typeof(*srf_update), base); + + vmw_kms_helper_resource_finish(srf_update->ctx, update->out_fence); +} + +/** + * vmw_stdu_plane_update_surface - update display unit for surface backed fb + * @dev_priv: device private + * @plane: plane state + * @old_state: old plane state + * @vfb: framebuffer which is blitted to display unit + * @out_fence: (optional) If non-NULL, will return a ref-counted pointer to a + * struct vmw_fence_obj. The returned fence pointer may be NULL in which case + * the device has already synchronized. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ +static int vmw_stdu_plane_update_surface(struct vmw_private *dev_priv, + struct drm_plane *plane, + struct drm_plane_state *old_state, + struct vmw_framebuffer *vfb, + struct vmw_fence_obj **out_fence) +{ + struct vmw_du_update_plane_surface srf_update; + struct vmw_screen_target_display_unit *stdu; + struct vmw_framebuffer_surface *vfbs; + struct vmw_validation_ctx ctx; + + stdu = vmw_crtc_to_stdu(plane->state->crtc); + vfbs = container_of(vfb, typeof(*vfbs), base); + + memset(&srf_update, 0, sizeof(struct vmw_du_update_plane_surface)); + srf_update.base.plane = plane; + srf_update.base.old_state = old_state; + srf_update.base.dev_priv = dev_priv; + srf_update.base.du = vmw_crtc_to_du(plane->state->crtc); + srf_update.base.vfb = vfb; + srf_update.base.out_fence = out_fence; + + srf_update.ctx = &ctx; + + srf_update.base.prepare = vmw_stdu_surface_prepare; + + if (vfbs->is_bo_proxy) + srf_update.base.post_prepare = vmw_stdu_surface_update_proxy; + + if (vfbs->surface->res.id != stdu->display_srf->res.id) { + srf_update.base.calc_fifo_size = vmw_stdu_surface_fifo_size; + srf_update.base.pre_clip = vmw_stdu_surface_populate_copy; + srf_update.base.clip = vmw_stdu_surface_populate_clip; + } else { + srf_update.base.calc_fifo_size = + vmw_stdu_surface_fifo_size_same_display; + } + + srf_update.base.post_clip = vmw_stud_surface_populate_update; + srf_update.base.finish = vmw_stdu_surface_finish; + /* Nothing special to do for revert */ + srf_update.base.revert = vmw_stdu_surface_finish; + + return vmw_du_helper_plane_update(&srf_update.base); +} /** * vmw_stdu_primary_plane_atomic_update - formally switches STDU to new plane