diff mbox series

[i-g-t,v5,1/6] lib/igt_kms: Add writeback support

Message ID 20190115174747.3138-2-liviu.dudau@arm.com (mailing list archive)
State New, archived
Headers show
Series igt: Add support for testing writeback connectors | expand

Commit Message

Liviu Dudau Jan. 15, 2019, 5:47 p.m. UTC
From: Brian Starkey <brian.starkey@arm.com>

Add support in igt_kms for writeback connectors, with the ability
to attach framebuffers.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated to the latest igt style]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h |  6 ++++++
 2 files changed, 63 insertions(+)

Comments

Brian Starkey Feb. 4, 2019, 1:31 p.m. UTC | #1
Hi Liviu,

On Tue, Jan 15, 2019 at 05:47:42PM +0000, Liviu Dudau wrote:
> From: Brian Starkey <brian.starkey@arm.com>

[snip]

>  
> +/**
> + * igt_output_set_writeback_fb:
> + * @output: Target output
> + * @fb: Target framebuffer
> + *
> + * This function sets the given @fb to be used as the target framebuffer for the
> + * writeback engine at the next atomic commit. It will also request a writeback
> + * out fence that will contain the fd number of the out fence created by KMS if
> + * the given @fb is valid.
> + */
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> +{
> +	igt_display_t *display = output->display;
> +
> +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> +	/* only request a writeback out fence if the framebuffer is valid */
> +	if (fb)
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> +					  (ptrdiff_t)&output->writeback_out_fence_fd);

I'm still not sure (ptrdiff_t) is the right type here, (uintptr_t)
seems better.

Thanks,
-Brian
Rodrigo Siqueira March 6, 2019, 9:30 p.m. UTC | #2
Hi Liviu,

I’m using your patchset to guide my implementation of writeback in the
VKMS, so, first of all, thanks :)

During my work, I noticed that you’re setting the drmSetClientCap()
before drmModeGetResources() which make the writeback capability
‘invisible’ for drmModeGetResources(). I made the following change, and
I could pass the igt_display_require():

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index f4ff3a96..bb2d8e06 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1912,6 +1912,12 @@ void igt_display_require(igt_display_t *display, int drm_fd)
 
        display->drm_fd = drm_fd;
 
+       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
+               display->is_atomic = 1;
+
+       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
+
        resources = drmModeGetResources(display->drm_fd);
        if (!resources)
                goto out;
@@ -1924,12 +1930,6 @@ void igt_display_require(igt_display_t *display, int drm_fd)
        display->pipes = calloc(sizeof(igt_pipe_t), display->n_pipes);
        igt_assert_f(display->pipes, "Failed to allocate memory for %d pipes\n", display->n_pipes);
 
-       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
-       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
-               display->is_atomic = 1;
-
-       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
-
        plane_resources = drmModeGetPlaneResources(display->drm_fd);
        igt_assert(plane_resources);

I'm not 100% confident about this issue, because of this I will send an
RFC and see if I can get more details about this issue.

Additionally, if you need any help with this patchset I will be glad to
help since I’m using it \o/

Best Regards
Rodrigo Siqueira

On 02/04, Brian Starkey wrote:
> Hi Liviu,
> 
> On Tue, Jan 15, 2019 at 05:47:42PM +0000, Liviu Dudau wrote:
> > From: Brian Starkey <brian.starkey@arm.com>
> 
> [snip]
> 
> >  
> > +/**
> > + * igt_output_set_writeback_fb:
> > + * @output: Target output
> > + * @fb: Target framebuffer
> > + *
> > + * This function sets the given @fb to be used as the target framebuffer for the
> > + * writeback engine at the next atomic commit. It will also request a writeback
> > + * out fence that will contain the fd number of the out fence created by KMS if
> > + * the given @fb is valid.
> > + */
> > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > +{
> > +	igt_display_t *display = output->display;
> > +
> > +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > +
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > +	/* only request a writeback out fence if the framebuffer is valid */
> > +	if (fb)
> > +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> 
> I'm still not sure (ptrdiff_t) is the right type here, (uintptr_t)
> seems better.
> 
> Thanks,
> -Brian
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
Liviu Dudau March 18, 2019, 10:41 a.m. UTC | #3
On Wed, Mar 06, 2019 at 06:30:05PM -0300, Rodrigo Siqueira wrote:
> Hi Liviu,
> 
> I’m using your patchset to guide my implementation of writeback in the
> VKMS, so, first of all, thanks :)
> 
> During my work, I noticed that you’re setting the drmSetClientCap()
> before drmModeGetResources() which make the writeback capability

before? I believe your patchset moves it to be before, which makes
sense, as the writeback applies to connectors, not planes (sorry for the
confusion, I think I wrote the code when we were toying with the idea
that writeback was going to be a plane property).

> ‘invisible’ for drmModeGetResources(). I made the following change, and
> I could pass the igt_display_require():
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index f4ff3a96..bb2d8e06 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -1912,6 +1912,12 @@ void igt_display_require(igt_display_t *display, int drm_fd)
>  
>         display->drm_fd = drm_fd;
>  
> +       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> +       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> +               display->is_atomic = 1;
> +
> +       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> +
>         resources = drmModeGetResources(display->drm_fd);
>         if (!resources)
>                 goto out;
> @@ -1924,12 +1930,6 @@ void igt_display_require(igt_display_t *display, int drm_fd)
>         display->pipes = calloc(sizeof(igt_pipe_t), display->n_pipes);
>         igt_assert_f(display->pipes, "Failed to allocate memory for %d pipes\n", display->n_pipes);
>  
> -       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> -       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> -               display->is_atomic = 1;
> -
> -       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> -
>         plane_resources = drmModeGetPlaneResources(display->drm_fd);
>         igt_assert(plane_resources);
> 
> I'm not 100% confident about this issue, because of this I will send an
> RFC and see if I can get more details about this issue.

It actually looks correct to me, so 

Acked-by: Liviu Dudau <liviu.dudau@arm.com>

> 
> Additionally, if you need any help with this patchset I will be glad to
> help since I’m using it \o/

Well, I need to send an updated version and if you could review that
then I can merge it into igt.

Best regards,
Liviu

> 
> Best Regards
> Rodrigo Siqueira
> 
> On 02/04, Brian Starkey wrote:
> > Hi Liviu,
> > 
> > On Tue, Jan 15, 2019 at 05:47:42PM +0000, Liviu Dudau wrote:
> > > From: Brian Starkey <brian.starkey@arm.com>
> > 
> > [snip]
> > 
> > >  
> > > +/**
> > > + * igt_output_set_writeback_fb:
> > > + * @output: Target output
> > > + * @fb: Target framebuffer
> > > + *
> > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > + * the given @fb is valid.
> > > + */
> > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > +{
> > > +	igt_display_t *display = output->display;
> > > +
> > > +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > +
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > +	/* only request a writeback out fence if the framebuffer is valid */
> > > +	if (fb)
> > > +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> > 
> > I'm still not sure (ptrdiff_t) is the right type here, (uintptr_t)
> > seems better.
> > 
> > Thanks,
> > -Brian
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> 
> -- 
> Rodrigo Siqueira
> https://siqueira.tech
> Graduate Student
> Department of Computer Science
> University of São Paulo
Rodrigo Siqueira March 18, 2019, 10:05 p.m. UTC | #4
On 03/18, Liviu Dudau wrote:
> On Wed, Mar 06, 2019 at 06:30:05PM -0300, Rodrigo Siqueira wrote:
> > Hi Liviu,
> > 
> > I’m using your patchset to guide my implementation of writeback in the
> > VKMS, so, first of all, thanks :)
> > 
> > During my work, I noticed that you’re setting the drmSetClientCap()
> > before drmModeGetResources() which make the writeback capability
> 
> before? I believe your patchset moves it to be before, which makes
> sense, as the writeback applies to connectors, not planes (sorry for the
> confusion, I think I wrote the code when we were toying with the idea
> that writeback was going to be a plane property).
> 
> > ‘invisible’ for drmModeGetResources(). I made the following change, and
> > I could pass the igt_display_require():
> > 
> > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > index f4ff3a96..bb2d8e06 100644
> > --- a/lib/igt_kms.c
> > +++ b/lib/igt_kms.c
> > @@ -1912,6 +1912,12 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> >  
> >         display->drm_fd = drm_fd;
> >  
> > +       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> > +       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> > +               display->is_atomic = 1;
> > +
> > +       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > +
> >         resources = drmModeGetResources(display->drm_fd);
> >         if (!resources)
> >                 goto out;
> > @@ -1924,12 +1930,6 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> >         display->pipes = calloc(sizeof(igt_pipe_t), display->n_pipes);
> >         igt_assert_f(display->pipes, "Failed to allocate memory for %d pipes\n", display->n_pipes);
> >  
> > -       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> > -       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> > -               display->is_atomic = 1;
> > -
> > -       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > -
> >         plane_resources = drmModeGetPlaneResources(display->drm_fd);
> >         igt_assert(plane_resources);
> > 
> > I'm not 100% confident about this issue, because of this I will send an
> > RFC and see if I can get more details about this issue.
> 
> It actually looks correct to me, so 
> 
> Acked-by: Liviu Dudau <liviu.dudau@arm.com>
> 
> > 
> > Additionally, if you need any help with this patchset I will be glad to
> > help since I’m using it \o/
> 
> Well, I need to send an updated version and if you could review that
> then I can merge it into igt.

Sure! I will be glad to take some time to review your code :)

I can also try to test it on my current implementation of VKMS.
One question, I have a NanoPc-T1 device [1] which has a Mali GPU, can I
test the writeback feature in this device? All kind of Mali GPU has
support for the writeback feature?

1. http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T1

Thanks!
Best Regards
 
> Best regards,
> Liviu
> 
> > 
> > Best Regards
> > Rodrigo Siqueira
> > 
> > On 02/04, Brian Starkey wrote:
> > > Hi Liviu,
> > > 
> > > On Tue, Jan 15, 2019 at 05:47:42PM +0000, Liviu Dudau wrote:
> > > > From: Brian Starkey <brian.starkey@arm.com>
> > > 
> > > [snip]
> > > 
> > > >  
> > > > +/**
> > > > + * igt_output_set_writeback_fb:
> > > > + * @output: Target output
> > > > + * @fb: Target framebuffer
> > > > + *
> > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > + * the given @fb is valid.
> > > > + */
> > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > +{
> > > > +	igt_display_t *display = output->display;
> > > > +
> > > > +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > +
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > +	/* only request a writeback out fence if the framebuffer is valid */
> > > > +	if (fb)
> > > > +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> > > 
> > > I'm still not sure (ptrdiff_t) is the right type here, (uintptr_t)
> > > seems better.
> > > 
> > > Thanks,
> > > -Brian
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > 
> > -- 
> > Rodrigo Siqueira
> > https://siqueira.tech
> > Graduate Student
> > Department of Computer Science
> > University of São Paulo
> 
> 
> 
> -- 
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯
Liviu Dudau March 20, 2019, 2:46 p.m. UTC | #5
On Mon, Mar 18, 2019 at 07:05:29PM -0300, Rodrigo Siqueira wrote:
> On 03/18, Liviu Dudau wrote:
> > On Wed, Mar 06, 2019 at 06:30:05PM -0300, Rodrigo Siqueira wrote:
> > > Hi Liviu,
> > > 
> > > I’m using your patchset to guide my implementation of writeback in the
> > > VKMS, so, first of all, thanks :)
> > > 
> > > During my work, I noticed that you’re setting the drmSetClientCap()
> > > before drmModeGetResources() which make the writeback capability
> > 
> > before? I believe your patchset moves it to be before, which makes
> > sense, as the writeback applies to connectors, not planes (sorry for the
> > confusion, I think I wrote the code when we were toying with the idea
> > that writeback was going to be a plane property).
> > 
> > > ‘invisible’ for drmModeGetResources(). I made the following change, and
> > > I could pass the igt_display_require():
> > > 
> > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > index f4ff3a96..bb2d8e06 100644
> > > --- a/lib/igt_kms.c
> > > +++ b/lib/igt_kms.c
> > > @@ -1912,6 +1912,12 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > >  
> > >         display->drm_fd = drm_fd;
> > >  
> > > +       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> > > +       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> > > +               display->is_atomic = 1;
> > > +
> > > +       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > +
> > >         resources = drmModeGetResources(display->drm_fd);
> > >         if (!resources)
> > >                 goto out;
> > > @@ -1924,12 +1930,6 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > >         display->pipes = calloc(sizeof(igt_pipe_t), display->n_pipes);
> > >         igt_assert_f(display->pipes, "Failed to allocate memory for %d pipes\n", display->n_pipes);
> > >  
> > > -       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> > > -       if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> > > -               display->is_atomic = 1;
> > > -
> > > -       drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > -
> > >         plane_resources = drmModeGetPlaneResources(display->drm_fd);
> > >         igt_assert(plane_resources);
> > > 
> > > I'm not 100% confident about this issue, because of this I will send an
> > > RFC and see if I can get more details about this issue.
> > 
> > It actually looks correct to me, so 
> > 
> > Acked-by: Liviu Dudau <liviu.dudau@arm.com>
> > 
> > > 
> > > Additionally, if you need any help with this patchset I will be glad to
> > > help since I’m using it \o/
> > 
> > Well, I need to send an updated version and if you could review that
> > then I can merge it into igt.
> 
> Sure! I will be glad to take some time to review your code :)
> 
> I can also try to test it on my current implementation of VKMS.
> One question, I have a NanoPc-T1 device [1] which has a Mali GPU, can I
> test the writeback feature in this device? All kind of Mali GPU has
> support for the writeback feature?
> 
> 1. http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T1

(sorry, email fell through the cracks)

The writeback is a Mali Display Processor feature, not GPU. As such you
need a device that has Mali DP in it. Commercially there will be a
platform later this year, but until it is announced I cannot say more
about it.

Best regards,
Liviu

> 
> Thanks!
> Best Regards
>  
> > Best regards,
> > Liviu
> > 
> > > 
> > > Best Regards
> > > Rodrigo Siqueira
> > > 
> > > On 02/04, Brian Starkey wrote:
> > > > Hi Liviu,
> > > > 
> > > > On Tue, Jan 15, 2019 at 05:47:42PM +0000, Liviu Dudau wrote:
> > > > > From: Brian Starkey <brian.starkey@arm.com>
> > > > 
> > > > [snip]
> > > > 
> > > > >  
> > > > > +/**
> > > > > + * igt_output_set_writeback_fb:
> > > > > + * @output: Target output
> > > > > + * @fb: Target framebuffer
> > > > > + *
> > > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > > + * the given @fb is valid.
> > > > > + */
> > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > > +{
> > > > > +	igt_display_t *display = output->display;
> > > > > +
> > > > > +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > > +
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > > +	/* only request a writeback out fence if the framebuffer is valid */
> > > > > +	if (fb)
> > > > > +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > 
> > > > I'm still not sure (ptrdiff_t) is the right type here, (uintptr_t)
> > > > seems better.
> > > > 
> > > > Thanks,
> > > > -Brian
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > > 
> > > -- 
> > > Rodrigo Siqueira
> > > https://siqueira.tech
> > > Graduate Student
> > > Department of Computer Science
> > > University of São Paulo
> > 
> > 
> > 
> > -- 
> > ====================
> > | I would like to |
> > | fix the world,  |
> > | but they're not |
> > | giving me the   |
> >  \ source code!  /
> >   ---------------
> >     ¯\_(ツ)_/¯
> 
> -- 
> Rodrigo Siqueira
> https://siqueira.tech
> Graduate Student
> Department of Computer Science
> University of São Paulo
diff mbox series

Patch

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 684a599ca..0bc2996cd 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -197,6 +197,9 @@  const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	[IGT_CONNECTOR_DPMS] = "DPMS",
 	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
 	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
+	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
+	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
+	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
 };
 
 /*
@@ -453,6 +456,7 @@  static const struct type_name connector_type_names[] = {
 	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
 	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
 	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
+	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
 	{}
 };
 
@@ -1802,6 +1806,12 @@  static void igt_output_reset(igt_output_t *output)
 	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
 		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
 					  BROADCAST_RGB_FULL);
+	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
+		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
+	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
+		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /**
@@ -1814,6 +1824,8 @@  static void igt_output_reset(igt_output_t *output)
  * For outputs:
  * - %IGT_CONNECTOR_CRTC_ID
  * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
+ * - %IGT_CONNECTOR_WRITEBACK_FB_ID
+ * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
  * - igt_output_override_mode() to default.
  *
  * For pipes:
@@ -1899,6 +1911,8 @@  void igt_display_require(igt_display_t *display, int drm_fd)
 	if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
 		display->is_atomic = 1;
 
+	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
+
 	plane_resources = drmModeGetPlaneResources(display->drm_fd);
 	igt_assert(plane_resources);
 
@@ -2147,6 +2161,11 @@  static void igt_output_fini(igt_output_t *output)
 	kmstest_free_connector_config(&output->config);
 	free(output->name);
 	output->name = NULL;
+
+	if (output->writeback_out_fence_fd != -1) {
+		close(output->writeback_out_fence_fd);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /**
@@ -3144,6 +3163,11 @@  static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
 					  output->props[i],
 					  output->values[i]));
 	}
+
+	if (output->writeback_out_fence_fd != -1) {
+		close(output->writeback_out_fence_fd);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /*
@@ -3264,6 +3288,16 @@  display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 		else
 			/* no modeset in universal commit, no change to crtc. */
 			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
+
+		if (s == COMMIT_ATOMIC) {
+			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
+				igt_assert(output->writeback_out_fence_fd >= 0);
+
+			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
+			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
+		}
 	}
 
 	if (display->first_commit) {
@@ -3884,6 +3918,29 @@  void igt_pipe_request_out_fence(igt_pipe_t *pipe)
 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
 }
 
+/**
+ * igt_output_set_writeback_fb:
+ * @output: Target output
+ * @fb: Target framebuffer
+ *
+ * This function sets the given @fb to be used as the target framebuffer for the
+ * writeback engine at the next atomic commit. It will also request a writeback
+ * out fence that will contain the fd number of the out fence created by KMS if
+ * the given @fb is valid.
+ */
+void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
+{
+	igt_display_t *display = output->display;
+
+	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
+
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
+	/* only request a writeback out fence if the framebuffer is valid */
+	if (fb)
+		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
+					  (ptrdiff_t)&output->writeback_out_fence_fd);
+}
+
 /**
  * igt_wait_for_vblank_count:
  * @drm_fd: A drm file descriptor
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 4a7c3c979..13d3a9ceb 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -121,6 +121,9 @@  enum igt_atomic_connector_properties {
        IGT_CONNECTOR_DPMS,
        IGT_CONNECTOR_BROADCAST_RGB,
        IGT_CONNECTOR_CONTENT_PROTECTION,
+       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
+       IGT_CONNECTOR_WRITEBACK_FB_ID,
+       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
        IGT_NUM_CONNECTOR_PROPS
 };
 
@@ -359,6 +362,8 @@  typedef struct {
 	bool use_override_mode;
 	drmModeModeInfo override_mode;
 
+	int32_t writeback_out_fence_fd;
+
 	/* bitmask of changed properties */
 	uint64_t changed;
 
@@ -403,6 +408,7 @@  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
 igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
 igt_output_t *igt_output_from_connector(igt_display_t *display,
     drmModeConnector *connector);
+void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
 
 igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
 igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe);