diff mbox series

drm/amdgpu: Ensure that the modifier requested is supported by plane.

Message ID 20210310161444.1015500-1-markyacoub@chromium.org (mailing list archive)
State New, archived
Headers show
Series drm/amdgpu: Ensure that the modifier requested is supported by plane. | expand

Commit Message

Mark Yacoub March 10, 2021, 4:14 p.m. UTC
From: Mark Yacoub <markyacoub@google.com>

On initializing the framebuffer, call drm_any_plane_has_format to do a
check if the modifier is supported. drm_any_plane_has_format calls
dm_plane_format_mod_supported which is extended to validate that the
modifier is on the list of the plane's supported modifiers.

The bug was caught using igt-gpu-tools test: kms_addfb_basic.addfb25-bad-modifier

Tested on ChromeOS Zork by turning on the display, running an overlay
test, and running a YT video.

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c       | 13 +++++++++++++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +++++++++
 2 files changed, 22 insertions(+)

Comments

Mark Yacoub March 22, 2021, 3:17 p.m. UTC | #1
"friendly ping"

On Wed, Mar 10, 2021 at 11:14 AM Mark Yacoub <markyacoub@chromium.org>
wrote:

> From: Mark Yacoub <markyacoub@google.com>
>
> On initializing the framebuffer, call drm_any_plane_has_format to do a
> check if the modifier is supported. drm_any_plane_has_format calls
> dm_plane_format_mod_supported which is extended to validate that the
> modifier is on the list of the plane's supported modifiers.
>
> The bug was caught using igt-gpu-tools test:
> kms_addfb_basic.addfb25-bad-modifier
>
> Tested on ChromeOS Zork by turning on the display, running an overlay
> test, and running a YT video.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c       | 13 +++++++++++++
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +++++++++
>  2 files changed, 22 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index afa5f8ad0f563..a947b5aa420d2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -908,6 +908,19 @@ int amdgpu_display_gem_fb_verify_and_init(
>                                          &amdgpu_fb_funcs);
>         if (ret)
>                 goto err;
> +       /* Verify that the modifier is supported. */
> +       if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
> +                                     mode_cmd->modifier[0])) {
> +               struct drm_format_name_buf format_name;
> +               drm_dbg_kms(dev,
> +                           "unsupported pixel format %s / modifier
> 0x%llx\n",
> +                           drm_get_format_name(mode_cmd->pixel_format,
> +                                               &format_name),
> +                           mode_cmd->modifier[0]);
> +
> +               ret = -EINVAL;
> +               goto err;
> +       }
>
>         ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
>         if (ret)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 961abf1cf040c..21314024a83ce 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3939,6 +3939,7 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
>  {
>         struct amdgpu_device *adev = drm_to_adev(plane->dev);
>         const struct drm_format_info *info = drm_format_info(format);
> +       int i;
>
>         enum dm_micro_swizzle microtile =
> modifier_gfx9_swizzle_mode(modifier) & 3;
>
> @@ -3952,6 +3953,14 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
>         if (modifier == DRM_FORMAT_MOD_LINEAR)
>                 return true;
>
> +       /* Check that the modifier is on the list of the plane's supported
> modifiers. */
> +       for (i = 0; i < plane->modifier_count; i++) {
> +               if (modifier == plane->modifiers[i])
> +                       break;
> +       }
> +       if (i == plane->modifier_count)
> +               return false;
> +
>         /*
>          * The arbitrary tiling support for multiplane formats has not
> been hooked
>          * up.
> --
> 2.30.1.766.gb4fecdf3b7-goog
>
>
Alex Deucher March 23, 2021, 3:02 p.m. UTC | #2
On Wed, Mar 10, 2021 at 11:15 AM Mark Yacoub <markyacoub@chromium.org> wrote:
>
> From: Mark Yacoub <markyacoub@google.com>
>
> On initializing the framebuffer, call drm_any_plane_has_format to do a
> check if the modifier is supported. drm_any_plane_has_format calls
> dm_plane_format_mod_supported which is extended to validate that the
> modifier is on the list of the plane's supported modifiers.
>
> The bug was caught using igt-gpu-tools test: kms_addfb_basic.addfb25-bad-modifier
>
> Tested on ChromeOS Zork by turning on the display, running an overlay
> test, and running a YT video.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>

I'm not an expert with modifiers yet.  Will this break chips which
don't currently support modifiers?

Alex


> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c       | 13 +++++++++++++
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +++++++++
>  2 files changed, 22 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index afa5f8ad0f563..a947b5aa420d2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -908,6 +908,19 @@ int amdgpu_display_gem_fb_verify_and_init(
>                                          &amdgpu_fb_funcs);
>         if (ret)
>                 goto err;
> +       /* Verify that the modifier is supported. */
> +       if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
> +                                     mode_cmd->modifier[0])) {
> +               struct drm_format_name_buf format_name;
> +               drm_dbg_kms(dev,
> +                           "unsupported pixel format %s / modifier 0x%llx\n",
> +                           drm_get_format_name(mode_cmd->pixel_format,
> +                                               &format_name),
> +                           mode_cmd->modifier[0]);
> +
> +               ret = -EINVAL;
> +               goto err;
> +       }
>
>         ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
>         if (ret)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 961abf1cf040c..21314024a83ce 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3939,6 +3939,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
>  {
>         struct amdgpu_device *adev = drm_to_adev(plane->dev);
>         const struct drm_format_info *info = drm_format_info(format);
> +       int i;
>
>         enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
>
> @@ -3952,6 +3953,14 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
>         if (modifier == DRM_FORMAT_MOD_LINEAR)
>                 return true;
>
> +       /* Check that the modifier is on the list of the plane's supported modifiers. */
> +       for (i = 0; i < plane->modifier_count; i++) {
> +               if (modifier == plane->modifiers[i])
> +                       break;
> +       }
> +       if (i == plane->modifier_count)
> +               return false;
> +
>         /*
>          * The arbitrary tiling support for multiplane formats has not been hooked
>          * up.
> --
> 2.30.1.766.gb4fecdf3b7-goog
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Bas Nieuwenhuizen March 23, 2021, 3:08 p.m. UTC | #3
On Wed, Mar 10, 2021 at 5:14 PM Mark Yacoub <markyacoub@chromium.org> wrote:

> From: Mark Yacoub <markyacoub@google.com>
>
> On initializing the framebuffer, call drm_any_plane_has_format to do a
> check if the modifier is supported. drm_any_plane_has_format calls
> dm_plane_format_mod_supported which is extended to validate that the
> modifier is on the list of the plane's supported modifiers.
>
> The bug was caught using igt-gpu-tools test:
> kms_addfb_basic.addfb25-bad-modifier
>
> Tested on ChromeOS Zork by turning on the display, running an overlay
> test, and running a YT video.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c       | 13 +++++++++++++
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +++++++++
>  2 files changed, 22 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index afa5f8ad0f563..a947b5aa420d2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -908,6 +908,19 @@ int amdgpu_display_gem_fb_verify_and_init(
>                                          &amdgpu_fb_funcs);
>         if (ret)
>                 goto err;
> +       /* Verify that the modifier is supported. */
> +       if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
> +                                     mode_cmd->modifier[0])) {
> +               struct drm_format_name_buf format_name;
> +               drm_dbg_kms(dev,
> +                           "unsupported pixel format %s / modifier
> 0x%llx\n",
> +                           drm_get_format_name(mode_cmd->pixel_format,
> +                                               &format_name),
> +                           mode_cmd->modifier[0]);
> +
> +               ret = -EINVAL;
> +               goto err;
> +       }
>

Why is this needed?


>         ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
>         if (ret)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 961abf1cf040c..21314024a83ce 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3939,6 +3939,7 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
>  {
>         struct amdgpu_device *adev = drm_to_adev(plane->dev);
>         const struct drm_format_info *info = drm_format_info(format);
> +       int i;
>
>         enum dm_micro_swizzle microtile =
> modifier_gfx9_swizzle_mode(modifier) & 3;
>
> @@ -3952,6 +3953,14 @@ static bool dm_plane_format_mod_supported(struct
> drm_plane *plane,
>         if (modifier == DRM_FORMAT_MOD_LINEAR)
>                 return true;
>
> +       /* Check that the modifier is on the list of the plane's supported
> modifiers. */
> +       for (i = 0; i < plane->modifier_count; i++) {
> +               if (modifier == plane->modifiers[i])
> +                       break;
> +       }
> +       if (i == plane->modifier_count)
> +               return false;
> +
>

This part seems fine by me.

>         /*
>          * The arbitrary tiling support for multiplane formats has not
> been hooked
>          * up.
> --
> 2.30.1.766.gb4fecdf3b7-goog
>
>
Mark Yacoub March 23, 2021, 3:32 p.m. UTC | #4
On Tue, Mar 23, 2021 at 11:02 AM Alex Deucher <alexdeucher@gmail.com> wrote:
>
> On Wed, Mar 10, 2021 at 11:15 AM Mark Yacoub <markyacoub@chromium.org> wrote:
> >
> > From: Mark Yacoub <markyacoub@google.com>
> >
> > On initializing the framebuffer, call drm_any_plane_has_format to do a
> > check if the modifier is supported. drm_any_plane_has_format calls
> > dm_plane_format_mod_supported which is extended to validate that the
> > modifier is on the list of the plane's supported modifiers.
> >
> > The bug was caught using igt-gpu-tools test: kms_addfb_basic.addfb25-bad-modifier
> >
> > Tested on ChromeOS Zork by turning on the display, running an overlay
> > test, and running a YT video.
> >
> > Cc: Alex Deucher <alexander.deucher@amd.com>
> > Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> > Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
>
> I'm not an expert with modifiers yet.  Will this break chips which
> don't currently support modifiers?
No it shouldn't. When you don't support modifiers yet, your will
default to Linear Modifier (DRM_FORMAT_MOD_LINEAR),
which is later checked in amdgpu_dm.c::dm_plane_format_mod_supported()
    /*
    * We always have to allow this modifier, because core DRM still
    * checks LINEAR support if userspace does not provide modifiers.
    */
    if (modifier == DRM_FORMAT_MOD_LINEAR)
        return true;

>
> Alex
>
>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c       | 13 +++++++++++++
> >  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +++++++++
> >  2 files changed, 22 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index afa5f8ad0f563..a947b5aa420d2 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -908,6 +908,19 @@ int amdgpu_display_gem_fb_verify_and_init(
> >                                          &amdgpu_fb_funcs);
> >         if (ret)
> >                 goto err;
> > +       /* Verify that the modifier is supported. */
> > +       if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
> > +                                     mode_cmd->modifier[0])) {
> > +               struct drm_format_name_buf format_name;
> > +               drm_dbg_kms(dev,
> > +                           "unsupported pixel format %s / modifier 0x%llx\n",
> > +                           drm_get_format_name(mode_cmd->pixel_format,
> > +                                               &format_name),
> > +                           mode_cmd->modifier[0]);
> > +
> > +               ret = -EINVAL;
> > +               goto err;
> > +       }
> >
> >         ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
> >         if (ret)
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index 961abf1cf040c..21314024a83ce 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -3939,6 +3939,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
> >  {
> >         struct amdgpu_device *adev = drm_to_adev(plane->dev);
> >         const struct drm_format_info *info = drm_format_info(format);
> > +       int i;
> >
> >         enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
> >
> > @@ -3952,6 +3953,14 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
> >         if (modifier == DRM_FORMAT_MOD_LINEAR)
> >                 return true;
> >
> > +       /* Check that the modifier is on the list of the plane's supported modifiers. */
> > +       for (i = 0; i < plane->modifier_count; i++) {
> > +               if (modifier == plane->modifiers[i])
> > +                       break;
> > +       }
> > +       if (i == plane->modifier_count)
> > +               return false;
> > +
> >         /*
> >          * The arbitrary tiling support for multiplane formats has not been hooked
> >          * up.
> > --
> > 2.30.1.766.gb4fecdf3b7-goog
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
Mark Yacoub March 23, 2021, 3:34 p.m. UTC | #5
On Tue, Mar 23, 2021 at 11:08 AM Bas Nieuwenhuizen
<bas@basnieuwenhuizen.nl> wrote:
>
>
>
> On Wed, Mar 10, 2021 at 5:14 PM Mark Yacoub <markyacoub@chromium.org> wrote:
>>
>> From: Mark Yacoub <markyacoub@google.com>
>>
>> On initializing the framebuffer, call drm_any_plane_has_format to do a
>> check if the modifier is supported. drm_any_plane_has_format calls
>> dm_plane_format_mod_supported which is extended to validate that the
>> modifier is on the list of the plane's supported modifiers.
>>
>> The bug was caught using igt-gpu-tools test: kms_addfb_basic.addfb25-bad-modifier
>>
>> Tested on ChromeOS Zork by turning on the display, running an overlay
>> test, and running a YT video.
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>> Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c       | 13 +++++++++++++
>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  9 +++++++++
>>  2 files changed, 22 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>> index afa5f8ad0f563..a947b5aa420d2 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>> @@ -908,6 +908,19 @@ int amdgpu_display_gem_fb_verify_and_init(
>>                                          &amdgpu_fb_funcs);
>>         if (ret)
>>                 goto err;
>> +       /* Verify that the modifier is supported. */
>> +       if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
>> +                                     mode_cmd->modifier[0])) {
>> +               struct drm_format_name_buf format_name;
>> +               drm_dbg_kms(dev,
>> +                           "unsupported pixel format %s / modifier 0x%llx\n",
>> +                           drm_get_format_name(mode_cmd->pixel_format,
>> +                                               &format_name),
>> +                           mode_cmd->modifier[0]);
>> +
>> +               ret = -EINVAL;
>> +               goto err;
>> +       }
>
>
> Why is this needed?
This is the function that initiates the check for modifiers.
Inside it we call `plane->funcs->format_mod_supported` which is implemented as
dm_plane_format_mod_supported in amdgpu_dm.c, modified below as well.

>
>>
>>         ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
>>         if (ret)
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 961abf1cf040c..21314024a83ce 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -3939,6 +3939,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
>>  {
>>         struct amdgpu_device *adev = drm_to_adev(plane->dev);
>>         const struct drm_format_info *info = drm_format_info(format);
>> +       int i;
>>
>>         enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
>>
>> @@ -3952,6 +3953,14 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
>>         if (modifier == DRM_FORMAT_MOD_LINEAR)
>>                 return true;
>>
>> +       /* Check that the modifier is on the list of the plane's supported modifiers. */
>> +       for (i = 0; i < plane->modifier_count; i++) {
>> +               if (modifier == plane->modifiers[i])
>> +                       break;
>> +       }
>> +       if (i == plane->modifier_count)
>> +               return false;
>> +
>
>
> This part seems fine by me.
>>
>>         /*
>>          * The arbitrary tiling support for multiplane formats has not been hooked
>>          * up.
>> --
>> 2.30.1.766.gb4fecdf3b7-goog
>>
Michel Dänzer March 24, 2021, 10:13 a.m. UTC | #6
On 2021-03-23 4:32 p.m., Mark Yacoub wrote:
> On Tue, Mar 23, 2021 at 11:02 AM Alex Deucher <alexdeucher@gmail.com> wrote:
>>
>> On Wed, Mar 10, 2021 at 11:15 AM Mark Yacoub <markyacoub@chromium.org> wrote:
>>>
>>> From: Mark Yacoub <markyacoub@google.com>
>>>
>>> On initializing the framebuffer, call drm_any_plane_has_format to do a
>>> check if the modifier is supported. drm_any_plane_has_format calls
>>> dm_plane_format_mod_supported which is extended to validate that the
>>> modifier is on the list of the plane's supported modifiers.
>>>
>>> The bug was caught using igt-gpu-tools test: kms_addfb_basic.addfb25-bad-modifier
>>>
>>> Tested on ChromeOS Zork by turning on the display, running an overlay
>>> test, and running a YT video.
>>>
>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>>> Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
>>
>> I'm not an expert with modifiers yet.  Will this break chips which
>> don't currently support modifiers?
> No it shouldn't. When you don't support modifiers yet, your will
> default to Linear Modifier (DRM_FORMAT_MOD_LINEAR),
> [...]
No modifier support does not imply linear. It's generally signalled via DRM_FORMAT_MOD_INVALID, which roughly means "tiling is determined by driver specific mechanisms".
Bas Nieuwenhuizen March 24, 2021, 10:53 a.m. UTC | #7
On Wed, Mar 24, 2021 at 11:13 AM Michel Dänzer <michel@daenzer.net> wrote:

> On 2021-03-23 4:32 p.m., Mark Yacoub wrote:
> > On Tue, Mar 23, 2021 at 11:02 AM Alex Deucher <alexdeucher@gmail.com>
> wrote:
> >>
> >> On Wed, Mar 10, 2021 at 11:15 AM Mark Yacoub <markyacoub@chromium.org>
> wrote:
> >>>
> >>> From: Mark Yacoub <markyacoub@google.com>
> >>>
> >>> On initializing the framebuffer, call drm_any_plane_has_format to do a
> >>> check if the modifier is supported. drm_any_plane_has_format calls
> >>> dm_plane_format_mod_supported which is extended to validate that the
> >>> modifier is on the list of the plane's supported modifiers.
> >>>
> >>> The bug was caught using igt-gpu-tools test:
> kms_addfb_basic.addfb25-bad-modifier
> >>>
> >>> Tested on ChromeOS Zork by turning on the display, running an overlay
> >>> test, and running a YT video.
> >>>
> >>> Cc: Alex Deucher <alexander.deucher@amd.com>
> >>> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> >>> Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
> >>
> >> I'm not an expert with modifiers yet.  Will this break chips which
> >> don't currently support modifiers?
> > No it shouldn't. When you don't support modifiers yet, your will
> > default to Linear Modifier (DRM_FORMAT_MOD_LINEAR),
> > [...]
> No modifier support does not imply linear. It's generally signalled via
> DRM_FORMAT_MOD_INVALID, which roughly means "tiling is determined by driver
> specific mechanisms".
>

Doesn't quite work that way in the kernel sadly. If you don't set
DRM_MODE_FB_MODIFIERS then the modifier fields have to be 0 (which happens
to alias DRM_FORMAT_MOD_LINEAR and then now deprecated
DRM_FORMAT_MOD_NONE). This is verified in shared drm code.

(and all userspace code I've seen simply doesn't set DRM_MODE_FB_MODIFIERS
if the incoming modifier is DRM_FORMAT_MOD_INVALID)

>
>
> --
> Earthling Michel Dänzer               |               https://redhat.com
> Libre software enthusiast             |             Mesa and X developer
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>
Daniel Stone March 24, 2021, 12:10 p.m. UTC | #8
On Wed, 24 Mar 2021 at 10:53, Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
wrote:

> On Wed, Mar 24, 2021 at 11:13 AM Michel Dänzer <michel@daenzer.net> wrote:
>
>> No modifier support does not imply linear. It's generally signalled via
>> DRM_FORMAT_MOD_INVALID, which roughly means "tiling is determined by driver
>> specific mechanisms".
>>
>
> Doesn't quite work that way in the kernel sadly. If you don't set
> DRM_MODE_FB_MODIFIERS then the modifier fields have to be 0 (which happens
> to alias DRM_FORMAT_MOD_LINEAR and then now deprecated
> DRM_FORMAT_MOD_NONE). This is verified in shared drm code.
>
> (and all userspace code I've seen simply doesn't set DRM_MODE_FB_MODIFIERS
> if the incoming modifier is DRM_FORMAT_MOD_INVALID)
>

Yes, but even though the field is zero, the lack of the flag means it must
be treated as INVALID. If the kernel is not doing this, the kernel is
objectively wrong. (And I know it doesn't do this in most cases, because
otherwise I wouldn't be able to use this GNOME session on an Intel laptop,
where modifiers are blacklisted.)

Cheers,
Daniel
Mark Yacoub March 24, 2021, 2:58 p.m. UTC | #9
On Wed, Mar 24, 2021 at 8:10 AM Daniel Stone <daniel@fooishbar.org> wrote:
>
> On Wed, 24 Mar 2021 at 10:53, Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> wrote:
>>
>> On Wed, Mar 24, 2021 at 11:13 AM Michel Dänzer <michel@daenzer.net> wrote:
>>>
>>> No modifier support does not imply linear. It's generally signalled via DRM_FORMAT_MOD_INVALID, which roughly means "tiling is determined by driver specific mechanisms".
So you mean it would make more sense to be more explicit in handling
DRM_FORMAT_MOD_INVALID as an incoming modifier (which will, just like
DRM_FORMAT_MOD_LINEAR, will return true in
dm_plane_format_mod_supported)?
>>
>>
>> Doesn't quite work that way in the kernel sadly. If you don't set DRM_MODE_FB_MODIFIERS then the modifier fields have to be 0 (which happens to alias DRM_FORMAT_MOD_LINEAR and then now deprecated DRM_FORMAT_MOD_NONE). This is verified in shared drm code.
>>
>> (and all userspace code I've seen simply doesn't set DRM_MODE_FB_MODIFIERS if the incoming modifier is DRM_FORMAT_MOD_INVALID)
>
>
> Yes, but even though the field is zero, the lack of the flag means it must be treated as INVALID. If the kernel is not doing this, the kernel is objectively wrong. (And I know it doesn't do this in most cases, because otherwise I wouldn't be able to use this GNOME session on an Intel laptop, where modifiers are blacklisted.)
>
> Cheers,
> Daniel
Daniel Stone March 24, 2021, 3:25 p.m. UTC | #10
Hi Mark,

On Wed, 24 Mar 2021 at 14:58, Mark Yacoub <markyacoub@chromium.org> wrote:

> So you mean it would make more sense to be more explicit in handling
> DRM_FORMAT_MOD_INVALID as an incoming modifier (which will, just like
> DRM_FORMAT_MOD_LINEAR, will return true in
> dm_plane_format_mod_supported)?
>

That's correct. Not passing any modifiers is the same as explicitly passing
INVALID, both of which mean 'the driver will figure it out somehow'; that
driver-specific determination is not the same as explicit LINEAR.

(I cannot regret enough that INVALID is not 0.)

Cheers,
Daniel
Mark Yacoub March 24, 2021, 3:32 p.m. UTC | #11
On Wed, Mar 24, 2021 at 11:25 AM Daniel Stone <daniel@fooishbar.org> wrote:
>
> Hi Mark,
>
> On Wed, 24 Mar 2021 at 14:58, Mark Yacoub <markyacoub@chromium.org> wrote:
>>
>> So you mean it would make more sense to be more explicit in handling
>> DRM_FORMAT_MOD_INVALID as an incoming modifier (which will, just like
>> DRM_FORMAT_MOD_LINEAR, will return true in
>> dm_plane_format_mod_supported)?
>
>
> That's correct. Not passing any modifiers is the same as explicitly passing INVALID, both of which mean 'the driver will figure it out somehow'; that driver-specific determination is not the same as explicit LINEAR.
>
> (I cannot regret enough that INVALID is not 0.)
I feel you. When I tested it on a board that doesn't support
modifiers, the modifier value was Zero. when I checked it, it was
basically LINEAR.
I'll amend my changes to explicitly handle INVALID.
>
> Cheers,
> Daniel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index afa5f8ad0f563..a947b5aa420d2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -908,6 +908,19 @@  int amdgpu_display_gem_fb_verify_and_init(
 					 &amdgpu_fb_funcs);
 	if (ret)
 		goto err;
+	/* Verify that the modifier is supported. */
+	if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
+				      mode_cmd->modifier[0])) {
+		struct drm_format_name_buf format_name;
+		drm_dbg_kms(dev,
+			    "unsupported pixel format %s / modifier 0x%llx\n",
+			    drm_get_format_name(mode_cmd->pixel_format,
+						&format_name),
+			    mode_cmd->modifier[0]);
+
+		ret = -EINVAL;
+		goto err;
+	}
 
 	ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
 	if (ret)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 961abf1cf040c..21314024a83ce 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3939,6 +3939,7 @@  static bool dm_plane_format_mod_supported(struct drm_plane *plane,
 {
 	struct amdgpu_device *adev = drm_to_adev(plane->dev);
 	const struct drm_format_info *info = drm_format_info(format);
+	int i;
 
 	enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
 
@@ -3952,6 +3953,14 @@  static bool dm_plane_format_mod_supported(struct drm_plane *plane,
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
 
+	/* Check that the modifier is on the list of the plane's supported modifiers. */
+	for (i = 0; i < plane->modifier_count; i++) {
+		if (modifier == plane->modifiers[i])
+			break;
+	}
+	if (i == plane->modifier_count)
+		return false;
+
 	/*
 	 * The arbitrary tiling support for multiplane formats has not been hooked
 	 * up.