dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents
@ 2023-06-27 18:22 Carlos Eduardo Gallo Filho
  2023-07-12 23:30 ` André Almeida
  0 siblings, 1 reply; 4+ messages in thread
From: Carlos Eduardo Gallo Filho @ 2023-06-27 18:22 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: matthew.d.roper, tvrtko.ursulin, stanislav.lisovskiy,
	andrealmeid, juhapekka.heikkila, tales.aparecida,
	Carlos Eduardo Gallo Filho, mripard, mairacanal, tzimmermann,
	rodrigo.vivi, niranjana.vishwanathapura, arthurgrillo

The functions drm_framebuffer_plane{width,height} and
fb_plane_{width,height} do exactly the same job of its
equivalents drm_format_info_plane_{width,height} from drm_fourcc.

The only reason to have these functions on drm_framebuffer
would be if they would added a abstraction layer to call it just
passing a drm_framebuffer pointer and the desired plane index,
which is not the case, where these functions actually implements
just part of it. In the actual implementation, every call to both
drm_framebuffer_plane_{width,height} and fb_plane_{width,height} should
pass some drm_framebuffer attribute, which is the same as calling the
drm_format_info_plane_{width,height} functions.

The drm_format_info_pane_{width,height} functions are much more
consistent in both its implementation and its location on code. The
kind of calculation that they do is intrinsically derivated from the
drm_format_info struct and has not to do with drm_framebuffer, except
by the potential motivation described above, which is still not a good
justificative to have drm_framebuffer functions to calculate it.

So, replace each drm_framebuffer_plane_{width,height} and
fb_plane_{width,height} call to drm_format_info_plane_{width,height}
and remove them.

Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org>
---
 drivers/gpu/drm/drm_framebuffer.c       | 64 ++-----------------------
 drivers/gpu/drm/i915/display/intel_fb.c |  2 +-
 include/drm/drm_framebuffer.h           |  5 --
 3 files changed, 5 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index aff3746dedfb..efed4cd7965e 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -151,24 +151,6 @@ int drm_mode_addfb_ioctl(struct drm_device *dev,
 	return drm_mode_addfb(dev, data, file_priv);
 }
 
-static int fb_plane_width(int width,
-			  const struct drm_format_info *format, int plane)
-{
-	if (plane == 0)
-		return width;
-
-	return DIV_ROUND_UP(width, format->hsub);
-}
-
-static int fb_plane_height(int height,
-			   const struct drm_format_info *format, int plane)
-{
-	if (plane == 0)
-		return height;
-
-	return DIV_ROUND_UP(height, format->vsub);
-}
-
 static int framebuffer_check(struct drm_device *dev,
 			     const struct drm_mode_fb_cmd2 *r)
 {
@@ -196,8 +178,8 @@ static int framebuffer_check(struct drm_device *dev,
 	info = drm_get_format_info(dev, r);
 
 	for (i = 0; i < info->num_planes; i++) {
-		unsigned int width = fb_plane_width(r->width, info, i);
-		unsigned int height = fb_plane_height(r->height, info, i);
+		unsigned int width = drm_format_info_plane_width(info, r->width, i);
+		unsigned int height = drm_format_info_plane_height(info, r->height, i);
 		unsigned int block_size = info->char_per_block[i];
 		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
 
@@ -1136,44 +1118,6 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
 }
 EXPORT_SYMBOL(drm_framebuffer_remove);
 
-/**
- * drm_framebuffer_plane_width - width of the plane given the first plane
- * @width: width of the first plane
- * @fb: the framebuffer
- * @plane: plane index
- *
- * Returns:
- * The width of @plane, given that the width of the first plane is @width.
- */
-int drm_framebuffer_plane_width(int width,
-				const struct drm_framebuffer *fb, int plane)
-{
-	if (plane >= fb->format->num_planes)
-		return 0;
-
-	return fb_plane_width(width, fb->format, plane);
-}
-EXPORT_SYMBOL(drm_framebuffer_plane_width);
-
-/**
- * drm_framebuffer_plane_height - height of the plane given the first plane
- * @height: height of the first plane
- * @fb: the framebuffer
- * @plane: plane index
- *
- * Returns:
- * The height of @plane, given that the height of the first plane is @height.
- */
-int drm_framebuffer_plane_height(int height,
-				 const struct drm_framebuffer *fb, int plane)
-{
-	if (plane >= fb->format->num_planes)
-		return 0;
-
-	return fb_plane_height(height, fb->format, plane);
-}
-EXPORT_SYMBOL(drm_framebuffer_plane_height);
-
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
 				const struct drm_framebuffer *fb)
 {
@@ -1189,8 +1133,8 @@ void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
 
 	for (i = 0; i < fb->format->num_planes; i++) {
 		drm_printf_indent(p, indent + 1, "size[%u]=%dx%d\n", i,
-				  drm_framebuffer_plane_width(fb->width, fb, i),
-				  drm_framebuffer_plane_height(fb->height, fb, i));
+				  drm_format_info_plane_width(fb->format, fb->width, i),
+				  drm_format_info_plane_height(fb->format, fb->height, i));
 		drm_printf_indent(p, indent + 1, "pitch[%u]=%u\n", i, fb->pitches[i]);
 		drm_printf_indent(p, indent + 1, "offset[%u]=%u\n", i, fb->offsets[i]);
 		drm_printf_indent(p, indent + 1, "obj[%u]:%s\n", i,
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 446bbf7986b6..5de2453ff7a3 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -1113,7 +1113,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
 		return -EINVAL;
 	}
 
-	height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
+	height = drm_format_info_plane_height(fb->format, fb->height, color_plane);
 	height = ALIGN(height, intel_tile_height(fb, color_plane));
 
 	/* Catch potential overflows early */
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index 0dcc07b68654..80ece7b6dd9b 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -292,11 +292,6 @@ static inline void drm_framebuffer_assign(struct drm_framebuffer **p,
 	     &fb->head != (&(dev)->mode_config.fb_list);			\
 	     fb = list_next_entry(fb, head))
 
-int drm_framebuffer_plane_width(int width,
-				const struct drm_framebuffer *fb, int plane);
-int drm_framebuffer_plane_height(int height,
-				 const struct drm_framebuffer *fb, int plane);
-
 /**
  * struct drm_afbc_framebuffer - a special afbc frame buffer object
  *
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents
  2023-06-27 18:22 [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents Carlos Eduardo Gallo Filho
@ 2023-07-12 23:30 ` André Almeida
  2023-07-17 19:04   ` Carlos
  0 siblings, 1 reply; 4+ messages in thread
From: André Almeida @ 2023-07-12 23:30 UTC (permalink / raw)
  To: Carlos Eduardo Gallo Filho
  Cc: tvrtko.ursulin, stanislav.lisovskiy, juhapekka.heikkila,
	tales.aparecida, intel-gfx, mripard, mairacanal, matthew.d.roper,
	dri-devel, tzimmermann, rodrigo.vivi, niranjana.vishwanathapura,
	arthurgrillo

Hi Carlos,

Em 27/06/2023 15:22, Carlos Eduardo Gallo Filho escreveu:
[...]
> 
> So, replace each drm_framebuffer_plane_{width,height} and
> fb_plane_{width,height} call to drm_format_info_plane_{width,height}
> and remove them.
> 

I see that with this replace, there's a small code change from

	return DIV_ROUND_UP(width, format->hsub);

to
	return width / info->hsub;

is there any case that the replaced function will give different results?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents
  2023-07-12 23:30 ` André Almeida
@ 2023-07-17 19:04   ` Carlos
  2023-07-19  7:21     ` Maxime Ripard
  0 siblings, 1 reply; 4+ messages in thread
From: Carlos @ 2023-07-17 19:04 UTC (permalink / raw)
  To: André Almeida
  Cc: tvrtko.ursulin, stanislav.lisovskiy, juhapekka.heikkila,
	tales.aparecida, intel-gfx, mripard, mairacanal, matthew.d.roper,
	dri-devel, tzimmermann, rodrigo.vivi, niranjana.vishwanathapura,
	arthurgrillo

Hi André, thanks for review!

On 7/12/23 20:30, André Almeida wrote:
> Hi Carlos,
>
> Em 27/06/2023 15:22, Carlos Eduardo Gallo Filho escreveu:
> [...]
>>
>> So, replace each drm_framebuffer_plane_{width,height} and
>> fb_plane_{width,height} call to drm_format_info_plane_{width,height}
>> and remove them.
>>
>
> I see that with this replace, there's a small code change from
>
>     return DIV_ROUND_UP(width, format->hsub);
>
> to
>     return width / info->hsub;
>
> is there any case that the replaced function will give different results?

Well, short answer: Yes, and I'm already thinking on how do address it.

Taking a look at some drivers, I could notice that almost every driver do
some similar calculating to obtain the size of a plane given the size of
the first (I guess that they would be using these functions though). So, I
stated that nearly all drivers implements this as a regular division, with
exception of exynos, sun4i and i915 (counting with the replaced function),
which all has at some point a DIV_ROUND_UP involving hsub or vsub.

Curiously, even the i915 having a DIV_ROUND_UP in some places, it also
has regular division involving hsub/vsub in others, which leads me to
guess if the chosen rounding method really matters. I also discovered
the existence of the intel_plane_check_src_coordinates() function,
that do some checks, which one of them consist of ensuring that for a
plane, both source coordinates and sizes are multiples of the vsub and
hsub, implying that no division rounding should occurs at all when it's
used. However, I couldn't state if this function is always called for
every source on every plane, so I can't assume anything from this.

Furthermore, I found the 33f673aa55e96 ("drm: Remove fb hsub/vsub
alignment requirement") commit, that explains the motivation for having
DIV_ROUND_UP on drm_framebuffer_plane_{width,height} functions. It says
that the DIV_ROUND_UP is needed on places where the
source isn't necessarily aligned with respect to the subsampling factors,
that should be the sane default for a core function.

Saying that, I thought some ways to address this problem:

1. Replace the regular division on drm_format_info_plane_{width,height}
    functions to DIV_ROUND_UP so that we assert that this function is
    always correct (as it seems that the places where regular division
    is used assumes alignment, implying no division rounding at all).

2. Create DIV_ROUND_UP variants of drm_format_info_plane_{width,height}
    functions and use each of them in the right place. Maybe
    let the default be the one with DIV_ROUND_UP and the
    variant with regular division, naming it as something like
    "drm_format_info_aligned_plane_{width,height}".

I personally would prefer the second alternative, as it provides more
flexibility and avoids using DIV_ROUND_UP unnecessarily. If nobody states
anything wrong with this approach, I'll be sending the second version
of this patch with it.

Thanks,
Carlos

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents
  2023-07-17 19:04   ` Carlos
@ 2023-07-19  7:21     ` Maxime Ripard
  0 siblings, 0 replies; 4+ messages in thread
From: Maxime Ripard @ 2023-07-19  7:21 UTC (permalink / raw)
  To: Carlos
  Cc: matthew.d.roper, tvrtko.ursulin, stanislav.lisovskiy,
	André Almeida, juhapekka.heikkila, tales.aparecida,
	intel-gfx, dri-devel, mairacanal, tzimmermann, rodrigo.vivi,
	niranjana.vishwanathapura, arthurgrillo

[-- Attachment #1: Type: text/plain, Size: 3522 bytes --]

Hi,

On Mon, Jul 17, 2023 at 04:04:43PM -0300, Carlos wrote:
> On 7/12/23 20:30, André Almeida wrote:
> > Hi Carlos,
> > 
> > Em 27/06/2023 15:22, Carlos Eduardo Gallo Filho escreveu:
> > [...]
> > > 
> > > So, replace each drm_framebuffer_plane_{width,height} and
> > > fb_plane_{width,height} call to drm_format_info_plane_{width,height}
> > > and remove them.
> > > 
> > 
> > I see that with this replace, there's a small code change from
> > 
> >     return DIV_ROUND_UP(width, format->hsub);
> > 
> > to
> >     return width / info->hsub;
> > 
> > is there any case that the replaced function will give different results?
> 
> Well, short answer: Yes, and I'm already thinking on how do address it.
> 
> Taking a look at some drivers, I could notice that almost every driver do
> some similar calculating to obtain the size of a plane given the size of
> the first (I guess that they would be using these functions though). So, I
> stated that nearly all drivers implements this as a regular division, with
> exception of exynos, sun4i and i915 (counting with the replaced function),
> which all has at some point a DIV_ROUND_UP involving hsub or vsub.
> 
> Curiously, even the i915 having a DIV_ROUND_UP in some places, it also
> has regular division involving hsub/vsub in others, which leads me to
> guess if the chosen rounding method really matters. I also discovered
> the existence of the intel_plane_check_src_coordinates() function,
> that do some checks, which one of them consist of ensuring that for a
> plane, both source coordinates and sizes are multiples of the vsub and
> hsub, implying that no division rounding should occurs at all when it's
> used. However, I couldn't state if this function is always called for
> every source on every plane, so I can't assume anything from this.
> 
> Furthermore, I found the 33f673aa55e96 ("drm: Remove fb hsub/vsub
> alignment requirement") commit, that explains the motivation for having
> DIV_ROUND_UP on drm_framebuffer_plane_{width,height} functions. It says
> that the DIV_ROUND_UP is needed on places where the
> source isn't necessarily aligned with respect to the subsampling factors,
> that should be the sane default for a core function.

Honestly, I don't think there's a problem, but rather something that was
done in each and every driver differently and without a second thought.

I think we should indeed converge to a single helper, and if that helper
is broken fix it. It will be broken for everyone anyway.

So I can definitely see a patch that adds DIV_ROUND_UP() to
drm_plane_info_plane_width and height, and then the first patch of
yours.

> Saying that, I thought some ways to address this problem:
> 
> 1. Replace the regular division on drm_format_info_plane_{width,height}
>    functions to DIV_ROUND_UP so that we assert that this function is
>    always correct (as it seems that the places where regular division
>    is used assumes alignment, implying no division rounding at all).

+1

> 2. Create DIV_ROUND_UP variants of drm_format_info_plane_{width,height}
>    functions and use each of them in the right place. Maybe
>    let the default be the one with DIV_ROUND_UP and the
>    variant with regular division, naming it as something like
>    "drm_format_info_aligned_plane_{width,height}".

No, that won't work. Provided with a choice, a driver is most likely to
cargo-cult it anyway. And it's not like we know what we should do here.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-07-19  7:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-27 18:22 [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents Carlos Eduardo Gallo Filho
2023-07-12 23:30 ` André Almeida
2023-07-17 19:04   ` Carlos
2023-07-19  7:21     ` Maxime Ripard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).