On Thu, Nov 07, 2019 at 05:49:14PM +0000, Brian Starkey wrote:
> Hi Daniel,
> 
> On Thu, Nov 07, 2019 at 06:32:01PM +0100, Daniel Vetter wrote:
> > On Thu, Nov 7, 2019 at 6:20 PM Brian Starkey <brian.star...@arm.com> wrote:
> > >
> > > Hi Daniel,
> > >
> > > On Tue, Nov 05, 2019 at 11:26:36PM +0000, Daniel Stone wrote:
> > > > Hi Andrzej,
> > > > Thanks for taking this on! It's looking better than v1 for sure. A few
> > > > things below:
> > > >
> > > > On Mon, 2019-11-04 at 23:12 +0100, Andrzej Pietrasiewicz wrote:
> > > > > +bool drm_afbc_check_offset(struct drm_device *dev,
> > > > > +                      const struct drm_mode_fb_cmd2 *mode_cmd)
> > > > > +{
> > > > > +   if (mode_cmd->offsets[0] != 0) {
> > > > > +           DRM_DEBUG_KMS("AFBC buffers' plane offset should be
> > > > > 0\n");
> > > > > +           return false;
> > > > > +   }
> > > > > +
> > > > > +   return true;
> > > > > +}
> > > > > +EXPORT_SYMBOL_GPL(drm_afbc_check_offset);
> > > >
> > > > Is this actually universally true? If the offset is sufficiently
> > > > aligned for (e.g.) DMA transfers to succeed, is there any reason why it
> > > > must be zero?
> > > >
> > > > > +bool drm_afbc_check_size_align(struct drm_device *dev,
> > > > > +                          const struct drm_mode_fb_cmd2 *mode_cmd)
> > > > > +{
> > > > > +   switch (mode_cmd->modifier[0] &
> > > > > AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> > > > > +   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> > > > > +           if ((mode_cmd->width % 16) || (mode_cmd->height % 16))
> > > > > {
> > > >
> > > > This is a dealbreaker for many resolutions: for example, 1366x768 isn't
> > > > cleanly divisible by 16 in width. So this means that we would have to
> > > > either use a larger buffer and crop, or scale, or something.
> > > >
> > > > No userspace is prepared to align fb width/height to tile dimensions
> > > > like this, so this check will basically fail everywhere.
> > > >
> > > > However, overallocation relative to the declared width/height isn't a
> > > > problem at all. In order to deal with horizontal alignment, you simply
> > > > need to ensure that the stride is a multiple of the tile width; for
> > > > vertical arrangement, that the buffer is large enough to contain
> > > > sufficient 'lines' to the next tile boundary.
> > > >
> > > > i.e. rather than checking width/height, you should check:
> > > >   * fb_stride >= (ALIGN(fb_width, tile_width), bpp)
> > > >   * buf_size >= fb_stride * ALIGN(fb_height, tile_height)
> > >
> > > Well, sort of.
> > >
> > > I agree with you that for horizontal padding, we can indeed use pitch.
> > >
> > > However, the AFBC decoder(s) need to know exactly what the total
> > > _allocated_ size in pixels of the buffer is - as this influences the
> > > header size, and we need to know the header size to know where it ends
> > > and the body begins.
> > >
> > > I see a couple of possible ways forwards:
> > >
> > >  - Keep it as-is. The restrictive checks ensure that there's no
> > >    ambiguity and we use the fb width/height to determine the real
> > >    allocated width/height. Userspace needs to be AFBC-aware and set up
> > >    plane cropping to handle the alignment differences.
> > >
> > >  - Use pitch to determine the "real" width, and internally in the
> > >    kernel align height up to the next alignment boundary. This works
> > >    OK, so long as there's no additional padding at the bottom of the
> > >    buffer. This would work, but I can't figure a way to check/enforce
> > >    that there's no additional padding at the bottom.
> > >
> > >  - Something else...
> > >
> > > The checks as-implemented were deliberately conservative, and don't
> > > preclude doing some relaxation in the future.
> > >
> > > On Android, gralloc is used to store the "real" allocated width/height
> > > and this is used to set up the DRM API appropriately.
> > 
> > Fake stride + real visible h/w in the drmfb. Because that's how it
> > works with all the tiled formats already, and expecting userspace to
> > fudge this all correctly seems very backwards to me. In a way we had
> > that entire fake stride discussion already for the block size format
> > stuff already, but now in a different flavour.
> 
> Fake stride - like I said, no problem; sounds good. That solves one
> dimension.
> 
> So do you have a proposal for how we determine what the allocated
> height is in that case? I don't really see a way.

Could you compute the height by looking at the buffer size? Or does that
not help since the header stuff is generally rather small?

Otherwise I guess just round up height and hope it works. If we run into a
use-case where that doesn't work anymore somehow, then we get to rev all
the afbc modifiers and make them 2 planes. With that there's no such issue
anymore (which is why the intel compressed stuff has 2 planes).
-Daniel


> Thanks,
> -Brian
> 
> > 
> > Also I think that's more reasons why this should be no-opt-outable
> > code that's done for all drivers when we check framebuffers in addfb.
> > Plus then some helpers to get at computed values for any framebuffer
> > we know to be valid.
> > -Daniel
> > 
> > > > This may force us to do some silly cropping games inside the Rockchip
> > > > KMS driver, but I feel it beats the alternative of breaking userspace.
> > >
> > > Well, nothing's going to get broken - it's just perhaps not ready to
> > > turn on AFBC yet.
> > >
> > > >
> > > > > +                   DRM_DEBUG_KMS(
> > > > > +                           "AFBC buffer must be aligned to 16
> > > > > pixels\n"
> > > > > +                   );
> > > > > +                   return false;
> > > > > +           }
> > > > > +           break;
> > > > > +   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> > > > > +           /* fall through */
> > > >
> > > > It's also incongruous that 32x8 is unsupported here, but has a section
> > > > in get_superblk_wh; please harmonise them so this section either does
> > > > the checks as above, or that get_superblk_wh doesn't support 32x8
> > > > either.
> > > >
> > > > > +bool drm_afbc_check_fb_size_ret(u32 pitch, int bpp,
> > > > > +                           u32 w, u32 h, u32 superblk_w, u32
> > > > > superblk_h,
> > > > > +                           size_t size, u32 offset, u32 hdr_align,
> > > > > +                           u32 *payload_off, u32 *total_size)
> > > > > +{
> > > > > +   int n_superblks = 0;
> > > > > +   u32 superblk_sz = 0;
> > > > > +   u32 afbc_size = 0;
> > > >
> > > > Please don't initialise the above three variables, given that you go on
> > > > to immediately change their values. In this case, initialising to zero
> > > > can only hide legitimate uninitialised-variable-use warnings.
> > > >
> > > > > +   n_superblks = (w / superblk_w) * (h / superblk_h);
> > > > > +   superblk_sz = (bpp * superblk_w * superblk_h) / BITS_PER_BYTE;
> > > > > +   afbc_size = ALIGN(n_superblks * AFBC_HEADER_SIZE, hdr_align);
> > > > > +   *payload_off = afbc_size;
> > > > > +
> > > > > +   afbc_size += n_superblks * ALIGN(superblk_sz,
> > > > > AFBC_SUPERBLK_ALIGNMENT);
> > > > > +   *total_size = afbc_size + offset;
> > > >
> > > > Generally these are referred to as 'tiles' rather than 'superblocks',
> > > > given that I would only expect one superblock per buffer, but if that's
> > > > the terminology AFBC uses then it might be better to stick with it.
> > > >
> > > > > +   if ((w * bpp) != (pitch * BITS_PER_BYTE)) {
> > > > > +           DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE)
> > > > > (=%u) should be same as width (=%u) * bpp (=%u)\n",
> > > > > +                         pitch * BITS_PER_BYTE, w, bpp
> > > > > +           );
> > > > > +           return false;
> > > > > +   }
> > > >
> > > > Having a too-small pitch is obviously a problem and we should reject
> > > > it. But is having a too-large pitch really a problem; does it need to
> > > > be an exact match, or can we support the case where the pitch is too
> > > > large but also tile-aligned? If we can, it would be very good to
> > > > support that.
> > >
> > > The reason for forcing it to be exact is as I said above - we _must_
> > > know what the "real" width and height is. Implementing this check to
> > > force (pitch == width * bpp) ensures that, and also leaves the option
> > > for us to relax to allow a larger pitch (as above) if that was the
> > > preferred approach for alignment.
> > >
> > > In general the current checks are deliberately designed to leave the
> > > door open for future improvements without breaking anything.
> > >
> > > Cheers,
> > > -Brian
> > >
> > > >
> > > > Cheers,
> > > > Daniel
> > > >
> > > IMPORTANT NOTICE: The contents of this email and any attachments are 
> > > confidential and may also be privileged. If you are not the intended 
> > > recipient, please notify the sender immediately and do not disclose the 
> > > contents to any other person, use it for any purpose, or store or copy 
> > > the information in any medium. Thank you.
> 
> Not sure how that snuck in.
> 
> > 
> > 
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to