From patchwork Sun Mar 2 22:18:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenyu Wang X-Patchwork-Id: 3751021 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 706A29F35F for ; Mon, 3 Mar 2014 05:17:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EA75820395 for ; Mon, 3 Mar 2014 05:17:26 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 92D072038C for ; Mon, 3 Mar 2014 05:17:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B3460FA2B0; Sun, 2 Mar 2014 21:17:23 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 32639FA2B0 for ; Sun, 2 Mar 2014 21:17:20 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 02 Mar 2014 21:12:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,575,1389772800"; d="scan'208";a="492642386" Received: from debian-hsw.sh.intel.com ([10.239.36.133]) by orsmga002.jf.intel.com with ESMTP; 02 Mar 2014 21:17:00 -0800 From: Zhenyu Wang To: intel-gfx@lists.freedesktop.org Date: Mon, 3 Mar 2014 06:18:52 +0800 Message-Id: <1393798732-5028-1-git-send-email-zhenyuw@linux.intel.com> X-Mailer: git-send-email 1.9.0 Subject: [Intel-gfx] [PATCH] sna: Add multiple planes support for Xv video on sprite X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00, DATE_IN_PAST_06_12, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On VLV there're two sprite planes for each pipe that both can be used simultaneously for Xv video. This one trys to expose those capability through multiple Xv ports on sprite video adaptor. I've tried to use this to validate new two sprite planes for single pipe on VLV which works fine. Signed-off-by: Zhenyu Wang --- src/sna/sna.h | 5 ++- src/sna/sna_display.c | 106 ++++++++++++++++++++++++++++++++++----------- src/sna/sna_video_sprite.c | 87 ++++++++++++++++++++----------------- 3 files changed, 131 insertions(+), 67 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 4651632..ce51fef 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -285,6 +285,7 @@ struct sna { unsigned num_real_crtc; unsigned num_real_output; unsigned num_fake; + unsigned num_sprite; } mode; struct sna_dri { @@ -442,9 +443,9 @@ static inline void sna_dri_close(struct sna *sna, ScreenPtr pScreen) { } #endif void sna_dri_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap); -extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation); +extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, XvPortPtr port, uint32_t rotation); extern int sna_crtc_to_pipe(xf86CrtcPtr crtc); -extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc); +extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, XvPortPtr port); extern uint32_t sna_crtc_id(xf86CrtcPtr crtc); CARD32 sna_format_for_depth(int depth); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index de08cb9..2e05733 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -100,13 +100,19 @@ struct rotation { uint32_t current; }; +struct sna_crtc_sprite { + uint32_t id; + struct rotation sprite_rotation; +}; + struct sna_crtc { struct drm_mode_modeinfo kmode; int dpms_mode; PixmapPtr scanout_pixmap; struct kgem_bo *bo, *shadow_bo; uint32_t cursor; - uint32_t sprite; + int num_sprite; + struct sna_crtc_sprite *sprite; bool shadow; bool fallback_shadow; bool transform; @@ -115,7 +121,6 @@ struct sna_crtc { uint32_t rotation; struct rotation primary_rotation; - struct rotation sprite_rotation; }; struct sna_property { @@ -200,9 +205,24 @@ int sna_crtc_to_pipe(xf86CrtcPtr crtc) return to_sna_crtc(crtc)->pipe; } -uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc) +static int sna_sprite_num(XvPortPtr port) { - return to_sna_crtc(crtc)->sprite; + XvAdaptorPtr adaptor = port->pAdaptor; + int i; + + for (i = 0; i < adaptor->nPorts; i++) { + if (port == &adaptor->pPorts[i]) + return i; + } + return 0; +} + +uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, XvPortPtr port) +{ + struct sna_crtc *sna_crtc = to_sna_crtc(crtc); + int num = sna_sprite_num(port); + + return sna_crtc->sprite[num].id; } #ifndef NDEBUG @@ -674,15 +694,18 @@ rotation_reset(struct rotation *r) r->current = 0; } -bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) +bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, XvPortPtr port, uint32_t rotation) { + struct sna_crtc *sna_crtc = to_sna_crtc(crtc); + int num = sna_sprite_num(port); + DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n", __FUNCTION__, - to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->sprite, + sna_crtc->id, sna_crtc->pipe, sna_crtc->sprite[num].id, rotation)); return rotation_set(to_sna(crtc->scrn), - &to_sna_crtc(crtc)->sprite_rotation, + &sna_crtc->sprite[num].sprite_rotation, rotation); } @@ -1717,6 +1740,7 @@ sna_crtc_destroy(xf86CrtcPtr crtc) sna_crtc_hide_cursor(crtc); gem_close(to_sna(crtc->scrn)->kgem.fd, sna_crtc->cursor); + free(sna_crtc->sprite); free(sna_crtc); crtc->driver_private = NULL; } @@ -1750,32 +1774,39 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = { #endif }; -static int -sna_crtc_find_sprite(struct sna *sna, int pipe) +static void +sna_crtc_find_sprite(struct sna *sna, struct sna_crtc *sna_crtc, int pipe) { #ifdef DRM_IOCTL_MODE_GETPLANERESOURCES struct drm_mode_get_plane_res r; - uint32_t *planes, id = 0; + uint32_t *planes, *id; int i; VG_CLEAR(r); r.count_planes = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &r)) - return 0; + return; if (!r.count_planes) - return 0; + return; planes = malloc(sizeof(uint32_t)*r.count_planes); - if (planes == NULL) - return 0; + id = malloc(sizeof(uint32_t)*r.count_planes); + if (planes == NULL || id == NULL) + return; r.plane_id_ptr = (uintptr_t)planes; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &r)) r.count_planes = 0; + if (!r.count_planes) + return; + + sna->mode.num_sprite = r.count_planes; + VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes)); + sna_crtc->num_sprite = 0; for (i = 0; i < r.count_planes; i++) { struct drm_mode_get_plane p; @@ -1784,35 +1815,54 @@ sna_crtc_find_sprite(struct sna *sna, int pipe) p.count_format_types = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANE, &p) == 0) { if (p.possible_crtcs & (1 << pipe)) { - id = p.plane_id; - break; + id[sna_crtc->num_sprite++] = p.plane_id; + continue; } } } + + sna_crtc->sprite = malloc(sizeof(struct sna_crtc_sprite)*sna_crtc->num_sprite); + if (sna_crtc->sprite == NULL) { + free(planes); + free(id); + return; + } + + for (i = 0; i < sna_crtc->num_sprite; i++) + sna_crtc->sprite[i].id = id[i]; + free(planes); + free(id); - assert(id); - return id; + return; #else - return 0; + return; #endif } static void sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc) { + int i; sna_crtc->rotation = RR_Rotate_0; sna_crtc->primary_rotation.supported = RR_Rotate_0; sna_crtc->primary_rotation.current = RR_Rotate_0; - sna_crtc->sprite_rotation = sna_crtc->primary_rotation; rotation_init(sna, &sna_crtc->primary_rotation, sna_crtc->id, LOCAL_MODE_OBJECT_CRTC); - rotation_init(sna, &sna_crtc->sprite_rotation, sna_crtc->sprite, LOCAL_MODE_OBJECT_PLANE); - DBG(("%s: CRTC:%d [pipe=%d], primary: supported-rotations=%x, current-rotation=%x, sprite: supported-rotations=%x, current-rotation=%x\n", + DBG(("%s: CRTC:%d [pipe=%d], primary: supported-rotations=%x, current-rotation=%x\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe, - sna_crtc->primary_rotation.supported, sna_crtc->primary_rotation.current, - sna_crtc->sprite_rotation.supported, sna_crtc->sprite_rotation.current)); + sna_crtc->primary_rotation.supported, sna_crtc->primary_rotation.current)); + + for (i = 0; i < sna_crtc->num_sprite; i++) { + sna_crtc->sprite[i].sprite_rotation = sna_crtc->primary_rotation; + rotation_init(sna, &sna_crtc->sprite[i].sprite_rotation, sna_crtc->sprite[i].id, + LOCAL_MODE_OBJECT_PLANE); + DBG(("%s: CRTC:%d [pipe=%d], sprite[%d]: supported-rotations=%x, current-rotation=%x\n", + __FUNCTION__, sna_crtc->id, sna_crtc->pipe, i, + sna_crtc->sprite[i].sprite_rotation.supported, + sna_crtc->sprite[i].sprite_rotation.current)); + } } static bool @@ -1842,16 +1892,18 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num) return false; } sna_crtc->pipe = get_pipe.pipe; - sna_crtc->sprite = sna_crtc_find_sprite(sna, sna_crtc->pipe); + sna_crtc_find_sprite(sna, sna_crtc, sna_crtc->pipe); if (xf86IsEntityShared(scrn->entityList[0]) && scrn->confScreen->device->screen != sna_crtc->pipe) { + free(sna_crtc->sprite); free(sna_crtc); return true; } crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs); if (crtc == NULL) { + free(sna_crtc->sprite); free(sna_crtc); return false; } @@ -1860,6 +1912,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num) sna->mode.cursor_width*sna->mode.cursor_height*4); if (!sna_crtc->cursor) { xf86CrtcDestroy(crtc); + free(sna_crtc->sprite); free(sna_crtc); return false; } @@ -4093,7 +4146,8 @@ void sna_mode_reset(struct sna *sna) /* Force the rotation property to be reset on next use */ rotation_reset(&sna_crtc->primary_rotation); - rotation_reset(&sna_crtc->sprite_rotation); + for (int j = 0; j < sna_crtc->num_sprite; j++) + rotation_reset(&sna_crtc->sprite[i].sprite_rotation); } for (i = 0; i < config->num_output; i++) { diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c index f4dcb82..2d6794a 100644 --- a/src/sna/sna_video_sprite.c +++ b/src/sna/sna_video_sprite.c @@ -195,6 +195,7 @@ update_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox) static bool sna_video_sprite_show(struct sna *sna, + XvPortPtr port, struct sna_video *video, struct sna_video_frame *frame, xf86CrtcPtr crtc, @@ -205,7 +206,7 @@ sna_video_sprite_show(struct sna *sna, /* XXX handle video spanning multiple CRTC */ VG_CLEAR(s); - s.plane_id = sna_crtc_to_sprite(crtc); + s.plane_id = sna_crtc_to_sprite(crtc, port); update_dst_box_to_crtc_coords(sna, crtc, dstBox); if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) { @@ -383,13 +384,13 @@ static int sna_video_sprite_put_image(ClientPtr client, &clip)) goto invisible; - if (!crtc || sna_crtc_to_sprite(crtc) == 0) + if (!crtc || sna_crtc_to_sprite(crtc, port) == 0) goto invisible; /* if sprite can't handle rotation natively, store it for the copy func */ video->rotation = RR_Rotate_0; - if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) { - sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0); + if (!sna_crtc_set_sprite_rotation(crtc, port, crtc->rotation)) { + sna_crtc_set_sprite_rotation(crtc, port, RR_Rotate_0); video->rotation = crtc->rotation; } @@ -429,7 +430,7 @@ static int sna_video_sprite_put_image(ClientPtr client, } ret = Success; - if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst_box)) { + if (!sna_video_sprite_show(sna, port, video, &frame, crtc, &dst_box)) { DBG(("%s: failed to show video frame\n", __FUNCTION__)); ret = BadAlloc; } else { @@ -525,7 +526,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) XvAdaptorPtr adaptor; struct drm_mode_get_plane_res r; struct sna_video *video; - XvPortPtr port; + int sprite_per_crtc, i; if (sna->flags & SNA_IS_HOSTED) return; @@ -542,11 +543,13 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) if (!adaptor) return; - video = calloc(1, sizeof(*video)); - port = calloc(1, sizeof(*port)); - if (video == NULL || port == NULL) { + sprite_per_crtc = sna->mode.num_sprite / sna->mode.kmode->count_crtcs; + + video = calloc(sprite_per_crtc, sizeof(struct sna_video)); + adaptor->pPorts = calloc(sprite_per_crtc, sizeof(XvPortRec)); + if (video == NULL || adaptor->pPorts == NULL) { free(video); - free(port); + free(adaptor->pPorts); sna->xv.num_adaptors--; return; } @@ -586,35 +589,41 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) adaptor->ddPutImage = sna_video_sprite_put_image; adaptor->ddQueryImageAttributes = sna_video_sprite_query; - adaptor->nPorts = 1; - adaptor->pPorts = port; - - adaptor->base_id = port->id = FakeClientID(0); - AddResource(port->id, XvGetRTPort(), port); - port->pAdaptor = adaptor; - port->pNotify = NULL; - port->pDraw = NULL; - port->client = NULL; - port->grab.client = NULL; - port->time = currentTime; - port->devPriv.ptr = video; - - video->sna = sna; - video->alignment = 64; - video->color_key = sna_video_sprite_color_key(sna); - video->color_key_changed = true; - video->brightness = -19; /* (255/219) * -16 */ - video->contrast = 75; /* 255/219 * 64 */ - video->saturation = 146; /* 128/112 * 128 */ - video->desired_crtc = NULL; - video->gamma5 = 0xc0c0c0; - video->gamma4 = 0x808080; - video->gamma3 = 0x404040; - video->gamma2 = 0x202020; - video->gamma1 = 0x101010; - video->gamma0 = 0x080808; - video->rotation = RR_Rotate_0; - RegionNull(&video->clip); + for (i = 0; i < sprite_per_crtc; i++) { + struct sna_video *v = &video[i]; + XvPortPtr port = &adaptor->pPorts[i]; + + port->id = FakeClientID(0); + AddResource(port->id, XvGetRTPort(), port); + + port->pAdaptor = adaptor; + port->pNotify = NULL; + port->pDraw = NULL; + port->client = NULL; + port->grab.client = NULL; + port->time = currentTime; + port->devPriv.ptr = v; + + v->sna = sna; + v->alignment = 64; + v->color_key = sna_video_sprite_color_key(sna); + v->color_key_changed = true; + v->brightness = -19; /* (255/219) * -16 */ + v->contrast = 75; /* 255/219 * 64 */ + v->saturation = 146; /* 128/112 * 128 */ + v->desired_crtc = NULL; + v->gamma5 = 0xc0c0c0; + v->gamma4 = 0x808080; + v->gamma3 = 0x404040; + v->gamma2 = 0x202020; + v->gamma1 = 0x101010; + v->gamma0 = 0x080808; + v->rotation = RR_Rotate_0; + RegionNull(&v->clip); + } + + adaptor->base_id = adaptor->pPorts[0].id; + adaptor->nPorts = sprite_per_crtc; xvColorKey = MAKE_ATOM("XV_COLORKEY"); xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");