From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Just adding the rotated UV plane at the end of the rotated Y plane. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_gtt.c | 47 ++++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d7f2e5d..bf3ee44 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2693,12 +2693,18 @@ intel_calc_tiled_geometry(struct drm_device *dev, unsigned int plane) { unsigned int tile_height, tile_pitch; + unsigned int height; + + if (rot_info->pixel_format == DRM_FORMAT_NV12 && plane == 1) + height = rot_info->height / 2; + else + height = rot_info->height; tile_height = intel_tile_height(dev, rot_info->pixel_format, rot_info->fb_modifier, plane); tile_pitch = PAGE_SIZE / tile_height; *width_pages = DIV_ROUND_UP(rot_info->pitch, tile_pitch); - *height_pages = DIV_ROUND_UP(rot_info->height, tile_height); + *height_pages = DIV_ROUND_UP(height, tile_height); return (*width_pages) * (*height_pages); } @@ -2709,12 +2715,15 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, { struct drm_device *dev = obj->base.dev; struct intel_rotation_info *rot_info = &ggtt_view->rotation_info; - unsigned long pages, rot_pages; + unsigned long pages, rot_pages, rot_pages_uv = 0; struct sg_page_iter sg_iter; unsigned long i; dma_addr_t *page_addr_list; struct sg_table *st; unsigned int width_pages, height_pages; + unsigned int width_pages_uv, height_pages_uv; + unsigned int uv_start_page; + struct scatterlist *sg; int ret = -ENOMEM; pages = obj->base.size / PAGE_SIZE; @@ -2723,6 +2732,13 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, rot_pages = intel_calc_tiled_geometry(dev, rot_info, &width_pages, &height_pages, 0); + /* Account for UV plane with NV12. */ + if (rot_info->pixel_format == DRM_FORMAT_NV12) { + rot_pages_uv = intel_calc_tiled_geometry(dev, rot_info, + &width_pages_uv, + &height_pages_uv, 1); + } + /* Allocate a temporary list of source pages for random access. */ page_addr_list = drm_malloc_ab(pages, sizeof(dma_addr_t)); if (!page_addr_list) @@ -2733,7 +2749,7 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, if (!st) goto err_st_alloc; - ret = sg_alloc_table(st, rot_pages, GFP_KERNEL); + ret = sg_alloc_table(st, rot_pages + rot_pages_uv, GFP_KERNEL); if (ret) goto err_sg_alloc; @@ -2745,13 +2761,28 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, } /* Rotate the pages. */ - rotate_pages(page_addr_list, 0, width_pages, height_pages, st, NULL); + sg = rotate_pages(page_addr_list, 0, + width_pages, height_pages, + st, NULL); + + /* Append the UV plane if NV12. */ + if (rot_info->pixel_format == DRM_FORMAT_NV12) { + uv_start_page = rot_pages; + + /* Check for tile-row un-alignment. */ + if (offset_in_page(rot_info->uv_offset)) + uv_start_page--; + + rotate_pages(page_addr_list, uv_start_page, + width_pages_uv, height_pages_uv, + st, sg); + } DRM_DEBUG_KMS( - "Created rotated page mapping for object size %lu (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %lu pages).\n", + "Created rotated page mapping for object size %lu (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %lu pages (%lu plane 0)).\n", obj->base.size, rot_info->pitch, rot_info->height, rot_info->pixel_format, width_pages, height_pages, - rot_pages); + rot_pages + rot_pages_uv, rot_pages); drm_free_large(page_addr_list); @@ -2763,10 +2794,10 @@ err_st_alloc: drm_free_large(page_addr_list); DRM_DEBUG_KMS( - "Failed to create rotated mapping for object size %lu! (%d) (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %lu pages)\n", + "Failed to create rotated mapping for object size %lu! (%d) (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %lu pages (%lu plane 0))\n", obj->base.size, ret, rot_info->pitch, rot_info->height, rot_info->pixel_format, width_pages, height_pages, - rot_pages); + rot_pages + rot_pages_uv, rot_pages); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 4e6cac5..5118da1 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -123,6 +123,7 @@ enum i915_ggtt_view_type { struct intel_rotation_info { unsigned int height; unsigned int pitch; + unsigned int uv_offset; uint32_t pixel_format; uint64_t fb_modifier; }; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a87faca..b4bf998 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2346,6 +2346,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, info->pixel_format = fb->pixel_format; info->pitch = fb->pitches[0]; info->fb_modifier = fb->modifier[0]; + info->uv_offset = fb->offsets[1]; return 0; } -- 2.4.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx