drm/i915: Support NV12 in rotated GGTT mapping
Just adding the rotated UV plane at the end of the rotated Y plane. v2: Rebase. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
804beb4b5b
commit
89e3e14276
|
@ -3282,10 +3282,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. */
|
||||
|
@ -3294,12 +3297,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;
|
||||
|
||||
|
@ -3311,15 +3320,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);
|
||||
|
||||
|
@ -3331,10 +3355,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -138,10 +138,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 {
|
||||
|
|
|
@ -2263,6 +2263,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,
|
||||
|
@ -2272,6 +2273,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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue