[Mesa-dev] [PATCH 4/5] egl/wayland: Allow client->server format conversion for PRIME offload. (v2)

2018-06-12 Thread Mario Kleiner
Support PRIME render offload between a Wayland server gpu and a Wayland
client gpu with different channel ordering for their color formats,
e.g., between Intel drivers which currently only support ARGB2101010
and XRGB2101010 import/display and nouveau which only supports ABGR2101010
rendering and display on nv-50 and later.

In the wl_visuals table, we also store for each format an alternate
sibling format which stores colors at the same precision, but with
different channel ordering, e.g., ARGB2101010 <-> ABGR2101010.

If a given client-gpu renderable format is not supported by the server
for import, but the alternate format is supported by the server, expose
the client-gpu renderable format as a valid EGLConfig to the client. At
eglSwapBuffers time, during the blitImage() detiling blit from the client
backbuffer to the linear buffer, the client format is converted to the
server supported format. As we have to do a copy for PRIME anyway,
this channel swizzling conversion comes essentially for free.

Note that even if a server gpu in principle does support sampling
from the clients native format, this conversion will be a performance
advantage if it allows to convert to the servers preferred format
for direct scanout, as the Wayland compositor may then be able to
directly page-flip a fullscreen client wl_buffer onto the primary
plane, or onto a hardware overlay plane, avoiding an extra data copy
for desktop composition.

Tested so far under Weston with: nouveau single-gpu, Intel single-gpu,
AMD single-gpu, "Optimus" Intel server iGPU for display + NVidia
client dGPU for rendering.

v2: Implement minor review comments by Eric Engestrom: Add some
comment and assert, and some style fixes for clarity.
No functional change.

Signed-off-by: Mario Kleiner 
Cc: Eric Engestrom 
---
 src/egl/drivers/dri2/platform_wayland.c | 80 +
 1 file changed, 71 insertions(+), 9 deletions(-)

diff --git a/src/egl/drivers/dri2/platform_wayland.c 
b/src/egl/drivers/dri2/platform_wayland.c
index f64fde8..6a083e4 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -67,49 +67,57 @@ static const struct dri2_wl_visual {
uint32_t wl_drm_format;
uint32_t wl_shm_format;
int dri_image_format;
+   /* alt_dri_image_format is a substitute wl_buffer format to use for a
+* wl-server unsupported dri_image_format, ie. some other dri_image_format 
in
+* the table, of the same precision but with different channel ordering, or
+* __DRI_IMAGE_FORMAT_NONE if an alternate format is not needed or 
supported.
+* The code checks if alt_dri_image_format can be used as a fallback for a
+* dri_image_format for a given wl-server implementation.
+*/
+   int alt_dri_image_format;
int bpp;
unsigned int rgba_masks[4];
 } dri2_wl_visuals[] = {
{
  "XRGB2101010",
  WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
- __DRI_IMAGE_FORMAT_XRGB2101010, 32,
+ __DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 32,
  { 0x3ff0, 0x000ffc00, 0x03ff, 0x }
},
{
  "ARGB2101010",
  WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
- __DRI_IMAGE_FORMAT_ARGB2101010, 32,
+ __DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 32,
  { 0x3ff0, 0x000ffc00, 0x03ff, 0xc000 }
},
{
  "XBGR2101010",
  WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
- __DRI_IMAGE_FORMAT_XBGR2101010, 32,
+ __DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 32,
  { 0x03ff, 0x000ffc00, 0x3ff0, 0x }
},
{
  "ABGR2101010",
  WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
- __DRI_IMAGE_FORMAT_ABGR2101010, 32,
+ __DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 32,
  { 0x03ff, 0x000ffc00, 0x3ff0, 0xc000 }
},
{
  "XRGB",
  WL_DRM_FORMAT_XRGB, WL_SHM_FORMAT_XRGB,
- __DRI_IMAGE_FORMAT_XRGB, 32,
+ __DRI_IMAGE_FORMAT_XRGB, __DRI_IMAGE_FORMAT_NONE, 32,
  { 0x00ff, 0xff00, 0x00ff, 0x }
},
{
  "ARGB",
  WL_DRM_FORMAT_ARGB, WL_SHM_FORMAT_ARGB,
- __DRI_IMAGE_FORMAT_ARGB, 32,
+ __DRI_IMAGE_FORMAT_ARGB, __DRI_IMAGE_FORMAT_NONE, 32,
  { 0x00ff, 0xff00, 0x00ff, 0xff00 }
},
{
  "RGB565",
  WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
- __DRI_IMAGE_FORMAT_RGB565, 16,
+ __DRI_IMAGE_FORMAT_RGB565, __DRI_IMAGE_FORMAT_NONE, 16,
  { 0xf800, 0x07e0, 0x001f, 0x }
},
 };
@@ -449,15 +457,29 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
int use_flags;
int visual_idx;
unsigned int dri_image_format;
+   unsigned int linear_dri_image_format;
uint64_t *modifiers;
int num_modifiers;
 
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);

Re: [Mesa-dev] [PATCH 4/5] egl/wayland: Allow client->server format conversion for PRIME offload.

2018-05-23 Thread Eric Engestrom
On Wednesday, 2018-05-23 06:51:12 +0200, Mario Kleiner wrote:
> On Mon, May 21, 2018 at 4:42 PM, Eric Engestrom
>  wrote:
> > On Saturday, 2018-05-19 05:32:41 +0200, Mario Kleiner wrote:
> >> Support PRIME render offload between a Wayland server gpu and a Wayland
> >> client gpu with different channel ordering for their color formats,
> >> e.g., between Intel drivers which currently only support ARGB2101010
> >> and XRGB2101010 import/display and nouveau which only supports ABGR2101010
> >> rendering and display on nv-50 and later.
> >>
> >> In the wl_visuals table, we also store for each format an alternate
> >> sibling format which stores colors at the same precision, but with
> >> different channel ordering, e.g., ARGB2101010 <-> ABGR2101010.
> >>
> >> If a given client-gpu renderable format is not supported by the server
> >> for import, but the alternate format is supported by the server, expose
> >> the client-gpu renderable format as a valid EGLConfig to the client. At
> >> eglSwapBuffers time, during the blitImage() detiling blit from the client
> >> backbuffer to the linear buffer, the client format is converted to the
> >> server supported format. As we have to do a copy for PRIME anyway,
> >> this channel swizzling conversion comes essentially for free.
> >>
> >> Note that even if a server gpu in principle does support sampling
> >> from the clients native format, this conversion will be a performance
> >> advantage if it allows to convert to the servers preferred format
> >> for direct scanout, as the Wayland compositor may then be able to
> >> directly page-flip a fullscreen client wl_buffer onto the primary
> >> plane, or onto a hardware overlay plane, avoiding an extra data copy
> >> for desktop composition.
> >>
> >> Tested so far under Weston with: nouveau single-gpu, Intel single-gpu,
> >> AMD single-gpu, "Optimus" Intel server iGPU for display + NVidia
> >> client dGPU for rendering.
> >>
> >> Signed-off-by: Mario Kleiner 
> >> Cc: Daniel Stone 
> >> ---
> >>  src/egl/drivers/dri2/platform_wayland.c | 67 
> >> -
> >>  1 file changed, 58 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/src/egl/drivers/dri2/platform_wayland.c 
> >> b/src/egl/drivers/dri2/platform_wayland.c
> >> index 89a7f90118..fb364a6233 100644
> >> --- a/src/egl/drivers/dri2/platform_wayland.c
> >> +++ b/src/egl/drivers/dri2/platform_wayland.c
> >> @@ -68,49 +68,50 @@ static const struct dri2_wl_visual {
> >> uint32_t wl_drm_format;
> >> uint32_t wl_shm_format;
> >> int dri_image_format;
> >> +   int alt_dri_image_format;
> >
> 
> Thanks for the review.
> 
> > A comment here wouldn't hurt, to explain what this "alt" is to someone
> > who sees the code after it landed :)
> >
> 
> Will do, although i usually feel a bit guilty that my patches usually
> suffer from over-commenting and essay length commit messages :)
> 
> >> int bpp;
> >> unsigned int rgba_masks[4];
> >>  } dri2_wl_visuals[] = {
> >> {
> >>   "XRGB2101010",
> >>   WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
> >> - __DRI_IMAGE_FORMAT_XRGB2101010, 32,
> >> + __DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 32,
> >>   { 0x3ff0, 0x000ffc00, 0x03ff, 0x }
> >> },
> >> {
> >>   "ARGB2101010",
> >>   WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
> >> - __DRI_IMAGE_FORMAT_ARGB2101010, 32,
> >> + __DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 32,
> >>   { 0x3ff0, 0x000ffc00, 0x03ff, 0xc000 }
> >> },
> >> {
> >>   "XBGR2101010",
> >>   WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
> >> - __DRI_IMAGE_FORMAT_XBGR2101010, 32,
> >> + __DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 32,
> >>   { 0x03ff, 0x000ffc00, 0x3ff0, 0x }
> >> },
> >> {
> >>   "ABGR2101010",
> >>   WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
> >> - __DRI_IMAGE_FORMAT_ABGR2101010, 32,
> >> + __DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 32,
> >>   { 0x03ff, 0x000ffc00, 0x3ff0, 0xc000 }
> >> },
> >> {
> >>   "XRGB",
> >>   WL_DRM_FORMAT_XRGB, WL_SHM_FORMAT_XRGB,
> >> - __DRI_IMAGE_FORMAT_XRGB, 32,
> >> + __DRI_IMAGE_FORMAT_XRGB, __DRI_IMAGE_FORMAT_NONE, 32,
> >>   { 0x00ff, 0xff00, 0x00ff, 0x }
> >> },
> >> {
> >>   "ARGB",
> >>   WL_DRM_FORMAT_ARGB, WL_SHM_FORMAT_ARGB,
> >> - __DRI_IMAGE_FORMAT_ARGB, 32,
> >> + __DRI_IMAGE_FORMAT_ARGB, __DRI_IMAGE_FORMAT_NONE, 32,
> >>   { 0x00ff, 0xff00, 0x00ff, 0xff00 }
> >> },
> >> {
> >>   "RGB565",
> >>   WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
> >> - __DRI_IMAGE_FORMAT_RGB565, 16,
> >> + __DRI_IMAGE_FORMAT_RGB565, 

Re: [Mesa-dev] [PATCH 4/5] egl/wayland: Allow client->server format conversion for PRIME offload.

2018-05-23 Thread Mike Lothian
Hi Mario

Can you explain how I can test this? I'll test it out on an Intel+AMD system

Cheers

Mike

On Wed, 23 May 2018 at 05:51 Mario Kleiner 
wrote:

> On Mon, May 21, 2018 at 4:42 PM, Eric Engestrom
>  wrote:
> > On Saturday, 2018-05-19 05:32:41 +0200, Mario Kleiner wrote:
> >> Support PRIME render offload between a Wayland server gpu and a Wayland
> >> client gpu with different channel ordering for their color formats,
> >> e.g., between Intel drivers which currently only support ARGB2101010
> >> and XRGB2101010 import/display and nouveau which only supports
> ABGR2101010
> >> rendering and display on nv-50 and later.
> >>
> >> In the wl_visuals table, we also store for each format an alternate
> >> sibling format which stores colors at the same precision, but with
> >> different channel ordering, e.g., ARGB2101010 <-> ABGR2101010.
> >>
> >> If a given client-gpu renderable format is not supported by the server
> >> for import, but the alternate format is supported by the server, expose
> >> the client-gpu renderable format as a valid EGLConfig to the client. At
> >> eglSwapBuffers time, during the blitImage() detiling blit from the
> client
> >> backbuffer to the linear buffer, the client format is converted to the
> >> server supported format. As we have to do a copy for PRIME anyway,
> >> this channel swizzling conversion comes essentially for free.
> >>
> >> Note that even if a server gpu in principle does support sampling
> >> from the clients native format, this conversion will be a performance
> >> advantage if it allows to convert to the servers preferred format
> >> for direct scanout, as the Wayland compositor may then be able to
> >> directly page-flip a fullscreen client wl_buffer onto the primary
> >> plane, or onto a hardware overlay plane, avoiding an extra data copy
> >> for desktop composition.
> >>
> >> Tested so far under Weston with: nouveau single-gpu, Intel single-gpu,
> >> AMD single-gpu, "Optimus" Intel server iGPU for display + NVidia
> >> client dGPU for rendering.
> >>
> >> Signed-off-by: Mario Kleiner 
> >> Cc: Daniel Stone 
> >> ---
> >>  src/egl/drivers/dri2/platform_wayland.c | 67
> -
> >>  1 file changed, 58 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/src/egl/drivers/dri2/platform_wayland.c
> b/src/egl/drivers/dri2/platform_wayland.c
> >> index 89a7f90118..fb364a6233 100644
> >> --- a/src/egl/drivers/dri2/platform_wayland.c
> >> +++ b/src/egl/drivers/dri2/platform_wayland.c
> >> @@ -68,49 +68,50 @@ static const struct dri2_wl_visual {
> >> uint32_t wl_drm_format;
> >> uint32_t wl_shm_format;
> >> int dri_image_format;
> >> +   int alt_dri_image_format;
> >
>
> Thanks for the review.
>
> > A comment here wouldn't hurt, to explain what this "alt" is to someone
> > who sees the code after it landed :)
> >
>
> Will do, although i usually feel a bit guilty that my patches usually
> suffer from over-commenting and essay length commit messages :)
>
> >> int bpp;
> >> unsigned int rgba_masks[4];
> >>  } dri2_wl_visuals[] = {
> >> {
> >>   "XRGB2101010",
> >>   WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
> >> - __DRI_IMAGE_FORMAT_XRGB2101010, 32,
> >> + __DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010,
> 32,
> >>   { 0x3ff0, 0x000ffc00, 0x03ff, 0x }
> >> },
> >> {
> >>   "ARGB2101010",
> >>   WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
> >> - __DRI_IMAGE_FORMAT_ARGB2101010, 32,
> >> + __DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010,
> 32,
> >>   { 0x3ff0, 0x000ffc00, 0x03ff, 0xc000 }
> >> },
> >> {
> >>   "XBGR2101010",
> >>   WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
> >> - __DRI_IMAGE_FORMAT_XBGR2101010, 32,
> >> + __DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010,
> 32,
> >>   { 0x03ff, 0x000ffc00, 0x3ff0, 0x }
> >> },
> >> {
> >>   "ABGR2101010",
> >>   WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
> >> - __DRI_IMAGE_FORMAT_ABGR2101010, 32,
> >> + __DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010,
> 32,
> >>   { 0x03ff, 0x000ffc00, 0x3ff0, 0xc000 }
> >> },
> >> {
> >>   "XRGB",
> >>   WL_DRM_FORMAT_XRGB, WL_SHM_FORMAT_XRGB,
> >> - __DRI_IMAGE_FORMAT_XRGB, 32,
> >> + __DRI_IMAGE_FORMAT_XRGB, __DRI_IMAGE_FORMAT_NONE, 32,
> >>   { 0x00ff, 0xff00, 0x00ff, 0x }
> >> },
> >> {
> >>   "ARGB",
> >>   WL_DRM_FORMAT_ARGB, WL_SHM_FORMAT_ARGB,
> >> - __DRI_IMAGE_FORMAT_ARGB, 32,
> >> + __DRI_IMAGE_FORMAT_ARGB, __DRI_IMAGE_FORMAT_NONE, 32,
> >>   { 0x00ff, 0xff00, 0x00ff, 0xff00 }
> >> },
> >> {
> >>   "RGB565",
> >>   

Re: [Mesa-dev] [PATCH 4/5] egl/wayland: Allow client->server format conversion for PRIME offload.

2018-05-22 Thread Mario Kleiner
On Mon, May 21, 2018 at 4:42 PM, Eric Engestrom
 wrote:
> On Saturday, 2018-05-19 05:32:41 +0200, Mario Kleiner wrote:
>> Support PRIME render offload between a Wayland server gpu and a Wayland
>> client gpu with different channel ordering for their color formats,
>> e.g., between Intel drivers which currently only support ARGB2101010
>> and XRGB2101010 import/display and nouveau which only supports ABGR2101010
>> rendering and display on nv-50 and later.
>>
>> In the wl_visuals table, we also store for each format an alternate
>> sibling format which stores colors at the same precision, but with
>> different channel ordering, e.g., ARGB2101010 <-> ABGR2101010.
>>
>> If a given client-gpu renderable format is not supported by the server
>> for import, but the alternate format is supported by the server, expose
>> the client-gpu renderable format as a valid EGLConfig to the client. At
>> eglSwapBuffers time, during the blitImage() detiling blit from the client
>> backbuffer to the linear buffer, the client format is converted to the
>> server supported format. As we have to do a copy for PRIME anyway,
>> this channel swizzling conversion comes essentially for free.
>>
>> Note that even if a server gpu in principle does support sampling
>> from the clients native format, this conversion will be a performance
>> advantage if it allows to convert to the servers preferred format
>> for direct scanout, as the Wayland compositor may then be able to
>> directly page-flip a fullscreen client wl_buffer onto the primary
>> plane, or onto a hardware overlay plane, avoiding an extra data copy
>> for desktop composition.
>>
>> Tested so far under Weston with: nouveau single-gpu, Intel single-gpu,
>> AMD single-gpu, "Optimus" Intel server iGPU for display + NVidia
>> client dGPU for rendering.
>>
>> Signed-off-by: Mario Kleiner 
>> Cc: Daniel Stone 
>> ---
>>  src/egl/drivers/dri2/platform_wayland.c | 67 
>> -
>>  1 file changed, 58 insertions(+), 9 deletions(-)
>>
>> diff --git a/src/egl/drivers/dri2/platform_wayland.c 
>> b/src/egl/drivers/dri2/platform_wayland.c
>> index 89a7f90118..fb364a6233 100644
>> --- a/src/egl/drivers/dri2/platform_wayland.c
>> +++ b/src/egl/drivers/dri2/platform_wayland.c
>> @@ -68,49 +68,50 @@ static const struct dri2_wl_visual {
>> uint32_t wl_drm_format;
>> uint32_t wl_shm_format;
>> int dri_image_format;
>> +   int alt_dri_image_format;
>

Thanks for the review.

> A comment here wouldn't hurt, to explain what this "alt" is to someone
> who sees the code after it landed :)
>

Will do, although i usually feel a bit guilty that my patches usually
suffer from over-commenting and essay length commit messages :)

>> int bpp;
>> unsigned int rgba_masks[4];
>>  } dri2_wl_visuals[] = {
>> {
>>   "XRGB2101010",
>>   WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
>> - __DRI_IMAGE_FORMAT_XRGB2101010, 32,
>> + __DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 32,
>>   { 0x3ff0, 0x000ffc00, 0x03ff, 0x }
>> },
>> {
>>   "ARGB2101010",
>>   WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
>> - __DRI_IMAGE_FORMAT_ARGB2101010, 32,
>> + __DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 32,
>>   { 0x3ff0, 0x000ffc00, 0x03ff, 0xc000 }
>> },
>> {
>>   "XBGR2101010",
>>   WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
>> - __DRI_IMAGE_FORMAT_XBGR2101010, 32,
>> + __DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 32,
>>   { 0x03ff, 0x000ffc00, 0x3ff0, 0x }
>> },
>> {
>>   "ABGR2101010",
>>   WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
>> - __DRI_IMAGE_FORMAT_ABGR2101010, 32,
>> + __DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 32,
>>   { 0x03ff, 0x000ffc00, 0x3ff0, 0xc000 }
>> },
>> {
>>   "XRGB",
>>   WL_DRM_FORMAT_XRGB, WL_SHM_FORMAT_XRGB,
>> - __DRI_IMAGE_FORMAT_XRGB, 32,
>> + __DRI_IMAGE_FORMAT_XRGB, __DRI_IMAGE_FORMAT_NONE, 32,
>>   { 0x00ff, 0xff00, 0x00ff, 0x }
>> },
>> {
>>   "ARGB",
>>   WL_DRM_FORMAT_ARGB, WL_SHM_FORMAT_ARGB,
>> - __DRI_IMAGE_FORMAT_ARGB, 32,
>> + __DRI_IMAGE_FORMAT_ARGB, __DRI_IMAGE_FORMAT_NONE, 32,
>>   { 0x00ff, 0xff00, 0x00ff, 0xff00 }
>> },
>> {
>>   "RGB565",
>>   WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
>> - __DRI_IMAGE_FORMAT_RGB565, 16,
>> + __DRI_IMAGE_FORMAT_RGB565, __DRI_IMAGE_FORMAT_NONE, 16,
>>   { 0xf800, 0x07e0, 0x001f, 0x }
>> },
>>  };
>> @@ -450,15 +451,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
>> int use_flags;
>> int visual_idx;
>> unsigned int dri_image_format;
>> +   unsigned int 

Re: [Mesa-dev] [PATCH 4/5] egl/wayland: Allow client->server format conversion for PRIME offload.

2018-05-21 Thread Eric Engestrom
On Saturday, 2018-05-19 05:32:41 +0200, Mario Kleiner wrote:
> Support PRIME render offload between a Wayland server gpu and a Wayland
> client gpu with different channel ordering for their color formats,
> e.g., between Intel drivers which currently only support ARGB2101010
> and XRGB2101010 import/display and nouveau which only supports ABGR2101010
> rendering and display on nv-50 and later.
> 
> In the wl_visuals table, we also store for each format an alternate
> sibling format which stores colors at the same precision, but with
> different channel ordering, e.g., ARGB2101010 <-> ABGR2101010.
> 
> If a given client-gpu renderable format is not supported by the server
> for import, but the alternate format is supported by the server, expose
> the client-gpu renderable format as a valid EGLConfig to the client. At
> eglSwapBuffers time, during the blitImage() detiling blit from the client
> backbuffer to the linear buffer, the client format is converted to the
> server supported format. As we have to do a copy for PRIME anyway,
> this channel swizzling conversion comes essentially for free.
> 
> Note that even if a server gpu in principle does support sampling
> from the clients native format, this conversion will be a performance
> advantage if it allows to convert to the servers preferred format
> for direct scanout, as the Wayland compositor may then be able to
> directly page-flip a fullscreen client wl_buffer onto the primary
> plane, or onto a hardware overlay plane, avoiding an extra data copy
> for desktop composition.
> 
> Tested so far under Weston with: nouveau single-gpu, Intel single-gpu,
> AMD single-gpu, "Optimus" Intel server iGPU for display + NVidia
> client dGPU for rendering.
> 
> Signed-off-by: Mario Kleiner 
> Cc: Daniel Stone 
> ---
>  src/egl/drivers/dri2/platform_wayland.c | 67 
> -
>  1 file changed, 58 insertions(+), 9 deletions(-)
> 
> diff --git a/src/egl/drivers/dri2/platform_wayland.c 
> b/src/egl/drivers/dri2/platform_wayland.c
> index 89a7f90118..fb364a6233 100644
> --- a/src/egl/drivers/dri2/platform_wayland.c
> +++ b/src/egl/drivers/dri2/platform_wayland.c
> @@ -68,49 +68,50 @@ static const struct dri2_wl_visual {
> uint32_t wl_drm_format;
> uint32_t wl_shm_format;
> int dri_image_format;
> +   int alt_dri_image_format;

A comment here wouldn't hurt, to explain what this "alt" is to someone
who sees the code after it landed :)

> int bpp;
> unsigned int rgba_masks[4];
>  } dri2_wl_visuals[] = {
> {
>   "XRGB2101010",
>   WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
> - __DRI_IMAGE_FORMAT_XRGB2101010, 32,
> + __DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 32,
>   { 0x3ff0, 0x000ffc00, 0x03ff, 0x }
> },
> {
>   "ARGB2101010",
>   WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
> - __DRI_IMAGE_FORMAT_ARGB2101010, 32,
> + __DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 32,
>   { 0x3ff0, 0x000ffc00, 0x03ff, 0xc000 }
> },
> {
>   "XBGR2101010",
>   WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
> - __DRI_IMAGE_FORMAT_XBGR2101010, 32,
> + __DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 32,
>   { 0x03ff, 0x000ffc00, 0x3ff0, 0x }
> },
> {
>   "ABGR2101010",
>   WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
> - __DRI_IMAGE_FORMAT_ABGR2101010, 32,
> + __DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 32,
>   { 0x03ff, 0x000ffc00, 0x3ff0, 0xc000 }
> },
> {
>   "XRGB",
>   WL_DRM_FORMAT_XRGB, WL_SHM_FORMAT_XRGB,
> - __DRI_IMAGE_FORMAT_XRGB, 32,
> + __DRI_IMAGE_FORMAT_XRGB, __DRI_IMAGE_FORMAT_NONE, 32,
>   { 0x00ff, 0xff00, 0x00ff, 0x }
> },
> {
>   "ARGB",
>   WL_DRM_FORMAT_ARGB, WL_SHM_FORMAT_ARGB,
> - __DRI_IMAGE_FORMAT_ARGB, 32,
> + __DRI_IMAGE_FORMAT_ARGB, __DRI_IMAGE_FORMAT_NONE, 32,
>   { 0x00ff, 0xff00, 0x00ff, 0xff00 }
> },
> {
>   "RGB565",
>   WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
> - __DRI_IMAGE_FORMAT_RGB565, 16,
> + __DRI_IMAGE_FORMAT_RGB565, __DRI_IMAGE_FORMAT_NONE, 16,
>   { 0xf800, 0x07e0, 0x001f, 0x }
> },
>  };
> @@ -450,15 +451,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
> int use_flags;
> int visual_idx;
> unsigned int dri_image_format;
> +   unsigned int linear_dri_image_format;
> uint64_t *modifiers;
> int num_modifiers;
>  
> visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
> assert(visual_idx != -1);
> dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
> +   linear_dri_image_format = dri_image_format;
> modifiers = u_vector_tail(_dpy->wl_modifiers[visual_idx]);

[Mesa-dev] [PATCH 4/5] egl/wayland: Allow client->server format conversion for PRIME offload.

2018-05-18 Thread Mario Kleiner
Support PRIME render offload between a Wayland server gpu and a Wayland
client gpu with different channel ordering for their color formats,
e.g., between Intel drivers which currently only support ARGB2101010
and XRGB2101010 import/display and nouveau which only supports ABGR2101010
rendering and display on nv-50 and later.

In the wl_visuals table, we also store for each format an alternate
sibling format which stores colors at the same precision, but with
different channel ordering, e.g., ARGB2101010 <-> ABGR2101010.

If a given client-gpu renderable format is not supported by the server
for import, but the alternate format is supported by the server, expose
the client-gpu renderable format as a valid EGLConfig to the client. At
eglSwapBuffers time, during the blitImage() detiling blit from the client
backbuffer to the linear buffer, the client format is converted to the
server supported format. As we have to do a copy for PRIME anyway,
this channel swizzling conversion comes essentially for free.

Note that even if a server gpu in principle does support sampling
from the clients native format, this conversion will be a performance
advantage if it allows to convert to the servers preferred format
for direct scanout, as the Wayland compositor may then be able to
directly page-flip a fullscreen client wl_buffer onto the primary
plane, or onto a hardware overlay plane, avoiding an extra data copy
for desktop composition.

Tested so far under Weston with: nouveau single-gpu, Intel single-gpu,
AMD single-gpu, "Optimus" Intel server iGPU for display + NVidia
client dGPU for rendering.

Signed-off-by: Mario Kleiner 
Cc: Daniel Stone 
---
 src/egl/drivers/dri2/platform_wayland.c | 67 -
 1 file changed, 58 insertions(+), 9 deletions(-)

diff --git a/src/egl/drivers/dri2/platform_wayland.c 
b/src/egl/drivers/dri2/platform_wayland.c
index 89a7f90118..fb364a6233 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -68,49 +68,50 @@ static const struct dri2_wl_visual {
uint32_t wl_drm_format;
uint32_t wl_shm_format;
int dri_image_format;
+   int alt_dri_image_format;
int bpp;
unsigned int rgba_masks[4];
 } dri2_wl_visuals[] = {
{
  "XRGB2101010",
  WL_DRM_FORMAT_XRGB2101010, WL_SHM_FORMAT_XRGB2101010,
- __DRI_IMAGE_FORMAT_XRGB2101010, 32,
+ __DRI_IMAGE_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XBGR2101010, 32,
  { 0x3ff0, 0x000ffc00, 0x03ff, 0x }
},
{
  "ARGB2101010",
  WL_DRM_FORMAT_ARGB2101010, WL_SHM_FORMAT_ARGB2101010,
- __DRI_IMAGE_FORMAT_ARGB2101010, 32,
+ __DRI_IMAGE_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ABGR2101010, 32,
  { 0x3ff0, 0x000ffc00, 0x03ff, 0xc000 }
},
{
  "XBGR2101010",
  WL_DRM_FORMAT_XBGR2101010, WL_SHM_FORMAT_XBGR2101010,
- __DRI_IMAGE_FORMAT_XBGR2101010, 32,
+ __DRI_IMAGE_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XRGB2101010, 32,
  { 0x03ff, 0x000ffc00, 0x3ff0, 0x }
},
{
  "ABGR2101010",
  WL_DRM_FORMAT_ABGR2101010, WL_SHM_FORMAT_ABGR2101010,
- __DRI_IMAGE_FORMAT_ABGR2101010, 32,
+ __DRI_IMAGE_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ARGB2101010, 32,
  { 0x03ff, 0x000ffc00, 0x3ff0, 0xc000 }
},
{
  "XRGB",
  WL_DRM_FORMAT_XRGB, WL_SHM_FORMAT_XRGB,
- __DRI_IMAGE_FORMAT_XRGB, 32,
+ __DRI_IMAGE_FORMAT_XRGB, __DRI_IMAGE_FORMAT_NONE, 32,
  { 0x00ff, 0xff00, 0x00ff, 0x }
},
{
  "ARGB",
  WL_DRM_FORMAT_ARGB, WL_SHM_FORMAT_ARGB,
- __DRI_IMAGE_FORMAT_ARGB, 32,
+ __DRI_IMAGE_FORMAT_ARGB, __DRI_IMAGE_FORMAT_NONE, 32,
  { 0x00ff, 0xff00, 0x00ff, 0xff00 }
},
{
  "RGB565",
  WL_DRM_FORMAT_RGB565, WL_SHM_FORMAT_RGB565,
- __DRI_IMAGE_FORMAT_RGB565, 16,
+ __DRI_IMAGE_FORMAT_RGB565, __DRI_IMAGE_FORMAT_NONE, 16,
  { 0xf800, 0x07e0, 0x001f, 0x }
},
 };
@@ -450,15 +451,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
int use_flags;
int visual_idx;
unsigned int dri_image_format;
+   unsigned int linear_dri_image_format;
uint64_t *modifiers;
int num_modifiers;
 
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);
dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
+   linear_dri_image_format = dri_image_format;
modifiers = u_vector_tail(_dpy->wl_modifiers[visual_idx]);
num_modifiers = u_vector_length(_dpy->wl_modifiers[visual_idx]);
 
+   /* Substitute dri image format if server does not support original format */
+   if (!(dri2_dpy->formats & (1 << visual_idx)))
+  linear_dri_image_format = 
dri2_wl_visuals[visual_idx].alt_dri_image_format;
+
+   assert(linear_dri_image_format != __DRI_IMAGE_FORMAT_NONE);
+
/* There might be a buffer release