From: Tvrtko Ursulin <tvrtko.ursu...@intel.com>

Just adding the rotated UV plane at the end of the rotated Y plane.

v2: Rebase.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursu...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c  | 37 ++++++++++++++++++++++++++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.h  |  3 +++
 drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++++
 3 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b4c6ed5d02dd..6495996c285e 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2760,10 +2760,13 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view 
*ggtt_view,
 {
        struct intel_rotation_info *rot_info = &ggtt_view->rotation_info;
        unsigned int size_pages = rot_info->size >> PAGE_SHIFT;
+       unsigned int size_pages_uv;
        struct sg_page_iter sg_iter;
        unsigned long i;
        dma_addr_t *page_addr_list;
        struct sg_table *st;
+       unsigned int uv_start_page;
+       struct scatterlist *sg;
        int ret = -ENOMEM;
 
        /* Allocate a temporary list of source pages for random access. */
@@ -2772,12 +2775,18 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view 
*ggtt_view,
        if (!page_addr_list)
                return ERR_PTR(ret);
 
+       /* Account for UV plane with NV12. */
+       if (rot_info->pixel_format == DRM_FORMAT_NV12)
+               size_pages_uv = rot_info->size_uv >> PAGE_SHIFT;
+       else
+               size_pages_uv = 0;
+
        /* Allocate target SG list. */
        st = kmalloc(sizeof(*st), GFP_KERNEL);
        if (!st)
                goto err_st_alloc;
 
-       ret = sg_alloc_table(st, size_pages, GFP_KERNEL);
+       ret = sg_alloc_table(st, size_pages + size_pages_uv, GFP_KERNEL);
        if (ret)
                goto err_sg_alloc;
 
@@ -2789,15 +2798,30 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view 
*ggtt_view,
        }
 
        /* Rotate the pages. */
-       rotate_pages(page_addr_list, 0,
+       sg = rotate_pages(page_addr_list, 0,
                     rot_info->width_pages, rot_info->height_pages,
                     st, NULL);
 
+       /* Append the UV plane if NV12. */
+       if (rot_info->pixel_format == DRM_FORMAT_NV12) {
+               uv_start_page = size_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,
+                            rot_info->width_pages_uv,
+                            rot_info->height_pages_uv,
+                            st, sg);
+       }
+
        DRM_DEBUG_KMS(
-                     "Created rotated page mapping for object size %zu 
(pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %u pages).\n",
+                     "Created rotated page mapping for object size %zu 
(pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %u pages (%u plane 
0)).\n",
                      obj->base.size, rot_info->pitch, rot_info->height,
                      rot_info->pixel_format, rot_info->width_pages,
-                     rot_info->height_pages, size_pages);
+                     rot_info->height_pages, size_pages + size_pages_uv,
+                     size_pages);
 
        drm_free_large(page_addr_list);
 
@@ -2809,10 +2833,11 @@ err_st_alloc:
        drm_free_large(page_addr_list);
 
        DRM_DEBUG_KMS(
-                     "Failed to create rotated mapping for object size %zu! 
(%d) (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %u pages)\n",
+                     "Failed to create rotated mapping for object size %zu! 
(%d) (pitch=%u, height=%u, pixel_format=0x%x, %ux%u tiles, %u pages (%u plane 
0))\n",
                      obj->base.size, ret, rot_info->pitch, rot_info->height,
                      rot_info->pixel_format, rot_info->width_pages,
-                     rot_info->height_pages, size_pages);
+                     rot_info->height_pages, size_pages + size_pages_uv,
+                     size_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 e1cfa292f9ad..3daa60332e28 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -124,10 +124,13 @@ 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;
        unsigned int width_pages, height_pages;
        uint64_t size;
+       unsigned int width_pages_uv, height_pages_uv;
+       uint64_t size_uv;
 };
 
 struct i915_ggtt_view {
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 03e550874aec..342d96553a7b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2297,6 +2297,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, 
struct drm_framebuffer *fb,
        info->height = fb->height;
        info->pixel_format = fb->pixel_format;
        info->pitch = fb->pitches[0];
+       info->uv_offset = fb->offsets[1];
        info->fb_modifier = fb->modifier[0];
 
        tile_height = intel_tile_height(fb->dev, fb->pixel_format,
@@ -2306,6 +2307,17 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, 
struct drm_framebuffer *fb,
        info->height_pages = DIV_ROUND_UP(fb->height, tile_height);
        info->size = info->width_pages * info->height_pages * PAGE_SIZE;
 
+       if (info->pixel_format == DRM_FORMAT_NV12) {
+               tile_height = intel_tile_height(fb->dev, fb->pixel_format,
+                                               fb->modifier[0], 1);
+               tile_pitch = PAGE_SIZE / tile_height;
+               info->width_pages_uv = DIV_ROUND_UP(fb->pitches[0], tile_pitch);
+               info->height_pages_uv = DIV_ROUND_UP(fb->height / 2,
+                                                    tile_height);
+               info->size_uv = info->width_pages_uv * info->height_pages_uv *
+                               PAGE_SIZE;
+       }
+
        return 0;
 }
 
-- 
2.4.6

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to