vc4/drm: vc4_plane: Remove subpixel positioning check
authorDom Cobley <popcornmix@gmail.com>
Mon, 15 Mar 2021 13:28:06 +0000 (13:28 +0000)
committerDom Cobley <popcornmix@gmail.com>
Mon, 21 Mar 2022 16:04:18 +0000 (16:04 +0000)
There is little harm in ignoring fractional coordinates
(they just get truncated).

Without this:
modetest -M vc4 -F tiles,gradient -s 32:1920x1080-60 -P89@74:1920x1080*.1.1@XR24

is rejected. We have the same issue in Kodi when trying to
use zoom options on video.

Note: even if all coordinates are fully integer. e.g.
src:[0,0,1920,1080] dest:[-10,-10,1940,1100]

it will still get rejected as drm_atomic_helper_check_plane_state
uses drm_rect_clip_scaled which transforms this to fractional src coords

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
drivers/gpu/drm/vc4/vc4_plane.c

index 920a9ee..f0f80ef 100644 (file)
@@ -339,7 +339,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
        struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
        struct drm_framebuffer *fb = state->fb;
        struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
-       u32 subpixel_src_mask = (1 << 16) - 1;
        int num_planes = fb->format->num_planes;
        struct drm_crtc_state *crtc_state;
        u32 h_subsample = fb->format->hsub;
@@ -361,18 +360,14 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
        for (i = 0; i < num_planes; i++)
                vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
 
-       /* We don't support subpixel source positioning for scaling. */
-       if ((state->src.x1 & subpixel_src_mask) ||
-           (state->src.x2 & subpixel_src_mask) ||
-           (state->src.y1 & subpixel_src_mask) ||
-           (state->src.y2 & subpixel_src_mask)) {
-               return -EINVAL;
-       }
-
-       vc4_state->src_x = state->src.x1 >> 16;
-       vc4_state->src_y = state->src.y1 >> 16;
-       vc4_state->src_w[0] = (state->src.x2 - state->src.x1) >> 16;
-       vc4_state->src_h[0] = (state->src.y2 - state->src.y1) >> 16;
+       /* We don't support subpixel source positioning for scaling,
+        * but fractional coordinates can be generated by clipping
+        * so just round for now
+        */
+       vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1<<16);
+       vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1<<16);
+       vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1<<16) - vc4_state->src_x;
+       vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1<<16) - vc4_state->src_y;
 
        vc4_state->crtc_x = state->dst.x1;
        vc4_state->crtc_y = state->dst.y1;