Re: [PATCH 13/13] drm/sun4i: Align VI buffer addresses for subsampled formats

Chen-Yu Tsai <[email protected]>
Newsgroups gmane.linux.kernel,gmane.comp.video.dri.devel,gmane.linux.ports.arm.kernel
Message-ID <CAGb2v67ugarRQAB=yDiyGti4E_r=dF0G08-TiGgphQSefHs8zQ@mail.gmail.com>
On Tue, Aug 4, 2026 at 1:25 AM Chen-Yu Tsai <[email protected]> wrote:
>
> On Tue, Aug 4, 2026 at 12:11 AM Jernej Skrabec <[email protected]> wrote:
> >
> > This is a partial revert of commit 79ac1c945ab8 ("drm/sun4i: layers:
> > Use drm_fb_dma_get_gem_addr() to get display memory").
> >
> > Chroma must start at the beginning of a subsampling block, for example
> > chroma start address for NV12 must be aligned to 2 pixels.
> > drm_fb_dma_get_gem_addr() offsets luma by the exact source coordinates
> > and chroma by the coordinates divided by the subsampling factor, so for
> > odd offsets both planes no longer describe the same pixel, which the
> > Display Engine scaler can't handle.
> >
> > Align source coordinates down for all planes instead. Remaining shift
> > of one pixel is already compensated with scaler phase shift in
> > sun8i_vi_layer_update_coord().
>
> Well I think this applies to the format in general, and probably should
> be fixed in drm_fb_dma_get_gem_addr() instead?
>
> > Fixes: 79ac1c945ab8 ("drm/sun4i: layers: Use drm_fb_dma_get_gem_addr() to get display memory")
> > Signed-off-by: Jernej Skrabec <[email protected]>
> > ---
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 20 ++++++++++++++++++--
> >  1 file changed, 18 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> > index 09f668c8af24..ad036cb9d88e 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> > @@ -197,15 +197,31 @@ static void sun8i_vi_layer_update_buffer(struct sun8i_layer *layer,
> >         struct drm_plane_state *state = plane->state;
> >         struct drm_framebuffer *fb = state->fb;
> >         const struct drm_format_info *format = fb->format;
> > +       struct drm_gem_dma_object *gem;
> > +       u32 dx, dy, src_x, src_y;
> >         dma_addr_t dma_addr;
> >         u32 ch_base;
> >         int i;
> >
> >         ch_base = sun8i_channel_base(layer);
> >
> > +       /* Adjust x and y to be divisible by subsampling factor */
> > +       src_x = (state->src.x1 >> 16) & ~(format->hsub - 1);
> > +       src_y = (state->src.y1 >> 16) & ~(format->vsub - 1);
>
> AFAICT the only difference compared to drm_fb_dma_get_gem_addr()
> is the masking here, i.e. round_down().
>
> > +
> >         for (i = 0; i < format->num_planes; i++) {
> > -               /* Get the start of the displayed memory */
> > -               dma_addr = drm_fb_dma_get_gem_addr(fb, state, i);
> > +               gem = drm_fb_dma_get_gem_obj(fb, i);
> > +               dma_addr = gem->dma_addr + fb->offsets[i];
> > +
> > +               dx = src_x;
> > +               dy = src_y;
> > +               if (i > 0) {
> > +                       dx /= format->hsub;
> > +                       dy /= format->vsub;
> > +               }
> > +
> > +               dma_addr += dx * format->cpp[i];
> > +               dma_addr += dy * fb->pitches[i];
>
>
> Where as the helper has (or used to have before the blocksize stuff):
>
>     paddr += (format->cpp[plane] * (state->src_x >> 16)) / fb->format->hsub;
>     paddr += (fb->pitches[plane] * (state->src_y >> 16)) / fb->format->vsub;
>
> Am I missing something?

After some headbanging on my end I see that the offset for the Y plane
needs to be rounded down.

But instead of reverting the whole thing and open-coding the helper
again, could you adjust the address returned by the helper for odd
offsets?

And just a heads up, this also needs a clipped version of
drm_fb_dma_get_gem_addr() as sun8i_ui_layer_update_coord() uses the
clipped dimensions. I am currently working on this part.


ChenYu

> >
> >                 /* Set the line width */
> >                 DRM_DEBUG_DRIVER("Layer %d. line width: %d bytes\n",
> > --
> > 2.43.0
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.