From bfd96b092db5e4e0fc2446752deafd1156cf37b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 18 Dec 2012 20:54:33 +0000 Subject: sna/video: Fix presentation of cropped sprites Signed-off-by: Chris Wilson --- src/sna/sna_video.c | 50 ++++++++++++++++---------------------- src/sna/sna_video.h | 2 ++ src/sna/sna_video_overlay.c | 12 ++++++++++ src/sna/sna_video_sprite.c | 57 ++++++++++++++++++++++++++++---------------- src/sna/sna_video_textured.c | 1 + 5 files changed, 73 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c index 7d335c0e..0a0f1527 100644 --- a/src/sna/sna_video.c +++ b/src/sna/sna_video.c @@ -100,9 +100,17 @@ sna_video_buffer(struct sna *sna, if (video->buf && __kgem_bo_size(video->buf) < frame->size) sna_video_free_buffers(sna, video); - if (video->buf == NULL) - video->buf = kgem_create_linear(&sna->kgem, frame->size, - CREATE_GTT_MAP); + if (video->buf == NULL) { + if (video->tiled) { + video->buf = kgem_create_2d(&sna->kgem, + frame->width, frame->height, 32, + I915_TILING_X, + CREATE_EXACT | CREATE_SCANOUT); + } else { + video->buf = kgem_create_linear(&sna->kgem, frame->size, + CREATE_GTT_MAP); + } + } return video->buf; } @@ -178,7 +186,7 @@ sna_video_clip_helper(ScrnInfoPtr scrn, frame->image.y2 = ALIGN(frame->src.y2, 2); } else { frame->image.y1 = frame->src.y1; - frame->image.y1 = frame->src.y2; + frame->image.y2 = frame->src.y2; } return ret; @@ -197,29 +205,10 @@ sna_video_frame_init(struct sna *sna, frame->width = width; frame->height = height; - /* Only needs to be DWORD-aligned for textured on i915, but overlay has - * stricter requirements. - */ - if (video->textured) { - align = 4; - } else { - if (sna->kgem.gen >= 040) - /* Actually the alignment is 64 bytes, too. But the - * stride must be at least 512 bytes. Take the easy fix - * and align on 512 bytes unconditionally. */ - align = 512; - else if (sna->kgem.gen < 021) - /* Harsh, errata on these chipsets limit the stride - * to be a multiple of 256 bytes. - */ - align = 256; - else - align = 64; - } - + align = video->alignment; #if SNA_XVMC /* for i915 xvmc, hw requires 1kb aligned surfaces */ - if (id == FOURCC_XVMC && sna->kgem.gen < 040) + if (id == FOURCC_XVMC && sna->kgem.gen < 040 && align < 1024) align = 1024; #endif @@ -453,13 +442,16 @@ sna_video_copy_data(struct sna *sna, { uint8_t *dst; - DBG(("%s: handle=%d, size=%dx%d, rotation=%d\n", + DBG(("%s: handle=%d, size=%dx%d, rotation=%d, is-texture=%d\n", __FUNCTION__, frame->bo ? frame->bo->handle : 0, - frame->width, frame->height, video->rotation)); - DBG(("%s: top=%d, left=%d\n", __FUNCTION__, frame->top, frame->left)); + frame->width, frame->height, video->rotation, video->textured)); + DBG(("%s: image=(%d, %d), (%d, %d), source=(%d, %d), (%d, %d)\n", + __FUNCTION__, + frame->image.x1, frame->image.y1, frame->image.x2, frame->image.y2, + frame->src.x1, frame->src.y1, frame->src.x2, frame->src.y2)); /* In the common case, we can simply the upload in a single pwrite */ - if (video->rotation == RR_Rotate_0) { + if (video->rotation == RR_Rotate_0 && !video->tiled) { if (is_planar_fourcc(frame->id)) { int w = frame->image.x2 - frame->image.x1; int h = frame->image.y2 - frame->image.y1; diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h index 774ddb8d..c0c023cf 100644 --- a/src/sna/sna_video.h +++ b/src/sna/sna_video.h @@ -57,6 +57,8 @@ struct sna_video { struct kgem_bo *old_buf[2]; struct kgem_bo *buf; + int alignment; + bool tiled; bool textured; Rotation rotation; int plane; diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c index a1a905a6..3655b876 100644 --- a/src/sna/sna_video_overlay.c +++ b/src/sna/sna_video_overlay.c @@ -702,6 +702,18 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna, adaptor->PutImage = sna_video_overlay_put_image; adaptor->QueryImageAttributes = sna_video_overlay_query_video_attributes; + if (sna->kgem.gen >= 040) + /* Actually the alignment is 64 bytes, too. But the + * stride must be at least 512 bytes. Take the easy fix + * and align on 512 bytes unconditionally. */ + video->alignment = 512; + else if (sna->kgem.gen < 021) + /* Harsh, errata on these chipsets limit the stride + * to be a multiple of 256 bytes. + */ + video->alignment = 256; + else + video->alignment = 64; video->textured = false; video->color_key = sna_video_overlay_color_key(sna); video->brightness = -19; /* (255/219) * -16 */ diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c index 79b4af20..7737460b 100644 --- a/src/sna/sna_video_sprite.c +++ b/src/sna/sna_video_sprite.c @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef DRM_IOCTL_MODE_GETPLANERESOURCES #include @@ -62,13 +63,14 @@ static XF86AttributeRec attribs[] = { static void sna_video_sprite_off(struct sna *sna, struct sna_video *video) { + struct drm_mode_set_plane s; + if (video->plane == 0) return; - if (drmModeSetPlane(sna->kgem.fd, - video->plane, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0)) + memset(&s, 0, sizeof(s)); + s.plane_id = video->plane; + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s)) xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "failed to disable plane\n"); @@ -183,7 +185,10 @@ sna_video_sprite_show(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox) { - uint32_t plane = sna_crtc_to_plane(crtc); + struct drm_mode_set_plane s; + + VG_CLEAR(s); + s.plane_id = sna_crtc_to_plane(crtc); update_dst_box_to_crtc_coords(sna, crtc, dstBox); if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) { @@ -193,13 +198,13 @@ sna_video_sprite_show(struct sna *sna, } #if defined(DRM_I915_SET_SPRITE_DESTKEY) - if (video->color_key_changed || video->plane != plane) { + if (video->color_key_changed || video->plane != s.plane_id) { struct drm_intel_set_sprite_destkey set; DBG(("%s: updating color key: %x\n", __FUNCTION__, video->color_key)); - set.plane_id = plane; + set.plane_id = s.plane_id; set.value = video->color_key; if (drmIoctl(sna->kgem.fd, @@ -230,8 +235,9 @@ sna_video_sprite_show(struct sna *sna, pitches[0] = frame->pitch[0]; offsets[0] = 0; - DBG(("%s: creating new fb for handle=%d\n", - __FUNCTION__, frame->bo->handle)); + DBG(("%s: creating new fb for handle=%d, width=%d, height=%d, stride=%d\n", + __FUNCTION__, frame->bo->handle, + frame->width, frame->height, frame->pitch[0])); if (drmModeAddFB2(sna->kgem.fd, frame->width, frame->height, pixel_format, @@ -245,22 +251,33 @@ sna_video_sprite_show(struct sna *sna, frame->bo->scanout = true; } - DBG(("%s: updating plane=%d, handle=%d [fb %d], dst=(%d,%d)x(%d,%d)\n", - __FUNCTION__, plane, frame->bo->handle, frame->bo->delta, - dstBox->x1, dstBox->y1, - dstBox->x2 - dstBox->x1, dstBox->y2 - dstBox->y1)); assert(frame->bo->scanout); assert(frame->bo->delta); - if (drmModeSetPlane(sna->kgem.fd, - plane, sna_crtc_id(crtc), frame->bo->delta, 0, - dstBox->x1, dstBox->y1, - dstBox->x2 - dstBox->x1, dstBox->y2 - dstBox->y1, - 0, 0, frame->width << 16, frame->height << 16)) + s.crtc_id = sna_crtc_id(crtc); + s.fb_id = frame->bo->delta; + s.flags = 0; + s.crtc_x = dstBox->x1; + s.crtc_y = dstBox->y1; + s.crtc_w = dstBox->x2 - dstBox->x1; + s.crtc_h = dstBox->y2 - dstBox->y1; + s.src_x = 0; + s.src_y = 0; + s.src_w = (frame->image.x2 - frame->image.x1) << 16; + s.src_h = (frame->image.y2 - frame->image.y1) << 16; + + DBG(("%s: updating crtc=%d, plane=%d, handle=%d [fb %d], dst=(%d,%d)x(%d,%d), src=(%d,%d)x(%d,%d)\n", + __FUNCTION__, s.crtc_id, s.plane_id, frame->bo->handle, s.fb_id, + s.crtc_x, s.crtc_y, s.crtc_w, s.crtc_h, + s.src_x >> 16, s.src_y >> 16, s.src_w >> 16, s.src_h >> 16)); + + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s)) { + DBG(("SET_PLANE failed: ret=%d\n", errno)); return false; + } frame->bo->domain = DOMAIN_NONE; - video->plane = plane; + video->plane = s.plane_id; return true; } @@ -422,7 +439,7 @@ XF86VideoAdaptorPtr sna_video_sprite_setup(struct sna *sna, adaptor->PutImage = sna_video_sprite_put_image; adaptor->QueryImageAttributes = sna_video_sprite_query_attrs; - video->textured = false; + video->alignment = 64; video->color_key = sna_video_sprite_color_key(sna); video->color_key_changed = true; video->brightness = -19; /* (255/219) * -16 */ diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c index cc35c57c..c5947ed5 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -453,6 +453,7 @@ XF86VideoAdaptorPtr sna_video_textured_setup(struct sna *sna, struct sna_video *v = &video[i]; v->textured = true; + video->alignment = 4; v->rotation = RR_Rotate_0; v->SyncToVblank = 1; -- cgit v1.2.3